成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

使用Spring/Spring Boot集成JMS的陷阱

xcold / 2520人閱讀

摘要:本文旨在指出中集成的一些性能陷阱,在另一篇文章各組件詳解里有組件介紹及如何正確使用的內(nèi)容。因此的做法會(huì)大大降低性能,并且將大部分的時(shí)間都花在反復(fù)重建這些對(duì)象上。提供的可以讓使用避免頻繁創(chuàng)建的問(wèn)題。至于使用的性能測(cè)試則留給同學(xué)自己做了。

Github

本文旨在指出Spring/Spring Boot中集成JMS的一些性能陷阱,在另一篇文章Spring JMS各組件詳解里有Spring JMS組件介紹及如何正確使用的內(nèi)容。

JmsTemplate性能問(wèn)題

Spring提供了JmsTemplate用來(lái)簡(jiǎn)化JMS的操作,但是JmsTemplate的性能是有很大問(wèn)題的,主要體現(xiàn)在以下幾個(gè)方面:

頻繁創(chuàng)建connection,session,producer

根據(jù)Artemis官方文檔的說(shuō)法,JmsTemplate是一種anti-pattern,如果在使用JmsTemplate的情況下覺(jué)得很慢,那么就不要怪Artemis。

并且Connection,SessionProducer,Consumer這些對(duì)象本身設(shè)計(jì)上是可以復(fù)用的。因此JmsTemplate的做法會(huì)大大降低性能,并且將大部分的時(shí)間都花在反復(fù)重建這些對(duì)象上。

Spring提供的Workaround

可以讓JmsTemplate使用SingleConnectionFactory避免頻繁創(chuàng)建Connection的問(wèn)題?;蛘咂渥宇?lèi)CachingConnectionFactory避免頻繁創(chuàng)建ConnectionSession,Producer,Consumer的問(wèn)題。

頻繁創(chuàng)建臨時(shí)Queue

JmsTemplate#sendAndReceive方法可以用來(lái)模擬RPC調(diào)用過(guò)程,內(nèi)部原理是:

A程序創(chuàng)建一個(gè)臨時(shí)Queue作為接受相應(yīng)的Queue

send一個(gè)Message到Queue,并在這個(gè)臨時(shí)Queue上等待結(jié)果

B程序consume了這個(gè)Message把結(jié)果send到那個(gè)臨時(shí)Queue

A接受到結(jié)果,把這個(gè)臨時(shí)Queue干掉

當(dāng)然整個(gè)過(guò)程中還包括前面提到的創(chuàng)建Connection,Session,ProducerConsumer的動(dòng)作。

不出所料,Artemis官方文檔也提到了,頻繁創(chuàng)建臨時(shí)Queue是一種anti-pattern,會(huì)大大影響性能。

@JmsListener性能問(wèn)題 使用sync方法consume消息

使用@JmsListener注解可以很方便的用來(lái)consume消息,但它是同步而非異步,這個(gè)和官方文檔所說(shuō)的恰恰相反(關(guān)于sync/async consume消息的資料)。

Spring Boot的JmsAnnotationDrivenConfiguration默認(rèn)使用DefaultJmsListenerContainerFactory生成DefaultMessageListenerContainer ,而它的內(nèi)部原理是使用TaskExecutor發(fā)起多個(gè)線(xiàn)程同時(shí)從Queue中拉取消息,這也就是為什么Spring官方文檔里說(shuō)如果監(jiān)聽(tīng)的是Topicconcurrency > 1,那么可能會(huì)收到重復(fù)消息的原因。

DefaultMessageListenerContainer的javadoc中說(shuō)道:

Actual MessageListener execution happens in asynchronous work units which are created through Spring"s TaskExecutor abstraction

這里就有個(gè)矛盾,如果使用async的方式consume消息,那么只需給consumer設(shè)置MessageListener就行了,何必使用TaskExecutor呢?

一看代碼果然不出所料:

DefaultMessageListenerContainer#runcallinvokeListener

然后callAbstractPollingMessageListenerContainer#receiveAndExecute

然后calldoReceiveAndExecute

然后callreceiveMessage

然后callreceiveFromConsumer

然后callJmsDestinationAccessor#receiveFromConsumer這個(gè)方法調(diào)用了MessageConsumer#consume

也就是說(shuō)Spring只是使用一個(gè)或多個(gè)線(xiàn)程在不停的同步的consume消息而已。

雖然可以使用concurrency參數(shù)提高并發(fā),但是多線(xiàn)程從Queue/Topic中consume消息的性能比javax.jms.MessageConsumer#setMessageListener的方法要低上很多。

有興趣的同學(xué)可以使用Artemis Example(下載地址)里的JMS Perf代碼做一下測(cè)試,它的測(cè)試代碼用的是javax.jms.MessageConsumer#setMessageListener的方式來(lái)consume消息的,在配置正確的情況下可以達(dá)到接近10w/s。至于使用MessageConsumer.receive的性能測(cè)試則留給同學(xué)自己做了。

為@JmsListener創(chuàng)建的session默認(rèn)transacted=true

還是之前提到的JmsAnnotationDrivenConfiguration,使用的DefaultJmsListenerContainerFactoryConfigurer默認(rèn)是把session設(shè)置為transacted的。

根據(jù)測(cè)算,當(dāng)一個(gè)session是transacted的時(shí)候其性能會(huì)相差20%,有興趣的同學(xué)可以使用Artemis Example(下載地址)里的JMS Perf代碼做一下測(cè)試。

下載之后找到examples/jms/perf目錄,看這個(gè)目錄下的readme.html獲得執(zhí)行方法,在執(zhí)行之前修改src/main/resources/perf.properties文件,下面是部分參數(shù)的解釋?zhuān)?/p>

num-messages,測(cè)試多少個(gè)消息

num-warmup-messages,熱身用的消息數(shù),熱身過(guò)之后性能會(huì)提升

durable,對(duì)應(yīng)DeliveryMode

transacted,是否transacted

batch-size,批量commit的大小

drain-queue,是否測(cè)試前先把隊(duì)列里已有的消息都清空

可以使用以下兩套配置對(duì)比transacted的性能差別:

配置一,transacted=false:

num-messages=100000
num-warmup-messages=1000
message-size=1024
durable=false
transacted=false
batch-size=1
drain-queue=true
destination-lookup=perfQueue
connection-factory-lookup=/ConnectionFactory
throttle-rate=-1
dups-ok-acknowledge=false
disable-message-id=true
disable-message-timestamp=true

配置二,transacted=true:

num-messages=100000
num-warmup-messages=1000
message-size=1024
durable=false
transacted=true
batch-size=1
drain-queue=true
destination-lookup=perfQueue
connection-factory-lookup=/ConnectionFactory
throttle-rate=-1
dups-ok-acknowledge=false
disable-message-id=true
disable-message-timestamp=true
@JmsListener創(chuàng)建的session默認(rèn)加入了事務(wù)控制

關(guān)于加入事務(wù)控制是否會(huì)有性能問(wèn)題沒(méi)有實(shí)際測(cè)試過(guò),不過(guò)值得注意的這是Spring Boot的默認(rèn)行為。

相關(guān)連接:代碼1, 代碼2,代碼3,Javadoc。

Spring Boot配置 ConnectionFactory全局只有一個(gè)實(shí)例

Spring將JMS的集成變得非常簡(jiǎn)單,只需提供幾個(gè)配置參數(shù)就可以了,但是只能提供一種默認(rèn)配置,不管業(yè)務(wù)場(chǎng)景如何都使用同一種配置是非常有問(wèn)題的。

spring-boot提供了以下幾種方式(文檔)集成JMS:

JNDI

Artemis, native模式和embedded模式

ActiveMQ

這幾種模式的缺點(diǎn)都是只能配置一個(gè)ConnectionFactory,這對(duì)于簡(jiǎn)單應(yīng)用來(lái)說(shuō)沒(méi)問(wèn)題,對(duì)于復(fù)雜應(yīng)用來(lái)說(shuō)就顯得不夠用了,這讓你喪失了針對(duì)不同場(chǎng)景配置不同ConnectionFactory的機(jī)會(huì)。
而且Artemis的native模式只支持host:port,不支持更豐富參數(shù)的url模式。

@JmsListener的默認(rèn)配置也就只提供一種

看過(guò)DefaultJmsListenerContainerFactoryConfigurerJmsAnnotationDrivenConfiguration的代碼就明白了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64939.html

相關(guān)文章

  • Spring Framework 參考文檔(概述)

    摘要:除此之外,還為不同的應(yīng)用程序體系結(jié)構(gòu)提供了基礎(chǔ)支持,包括消息傳遞事務(wù)數(shù)據(jù)和持久性以及,它還包括基于的框架,以及與之并行的反應(yīng)性框架。還支持依賴(lài)項(xiàng)注入和公共注解規(guī)范,應(yīng)用程序開(kāi)發(fā)人員可以選擇使用這些規(guī)范,而不是提供的特定于的機(jī)制。 概述 Spring使創(chuàng)建Java企業(yè)應(yīng)用程序變得很容易,它提供了在企業(yè)環(huán)境中使用Java語(yǔ)言所需要的一切,支持Groovy和Kotlin作為JVM上的替代語(yǔ)言...

    silencezwm 評(píng)論0 收藏0
  • Spring、Spring Boot和TestNG測(cè)試指南 - 使用Spring Boot Test

    摘要:地址前面一個(gè)部分講解了如何使用工具來(lái)測(cè)試項(xiàng)目,現(xiàn)在我們講解如何使用工具來(lái)測(cè)試項(xiàng)目。所以我們可以利用這個(gè)特性來(lái)進(jìn)一步簡(jiǎn)化測(cè)試代碼。因?yàn)橹挥羞@樣才能夠在測(cè)試環(huán)境下發(fā)現(xiàn)生產(chǎn)環(huán)境的問(wèn)題,也避免出現(xiàn)一些因?yàn)榕渲貌煌瑢?dǎo)致的奇怪問(wèn)題。 Github地址 前面一個(gè)部分講解了如何使用Spring Testing工具來(lái)測(cè)試Spring項(xiàng)目,現(xiàn)在我們講解如何使用Spring Boot Testing工具來(lái)測(cè)...

    Anshiii 評(píng)論0 收藏0
  • 次世代會(huì)話(huà)管理項(xiàng)目 Spring Session

    摘要:會(huì)話(huà)管理一直是企業(yè)級(jí)應(yīng)用的重要部分。傳統(tǒng)會(huì)話(huà)管理技術(shù)的問(wèn)題的目的是解決傳統(tǒng)的會(huì)話(huà)管理技術(shù)的各種問(wèn)題。對(duì)如和之類(lèi)的閉源產(chǎn)品,找到適合它們的會(huì)話(huà)管理技術(shù)的替代實(shí)現(xiàn)則通常是不可能的。典型的應(yīng)用會(huì)將當(dāng)前用戶(hù)的身份及其安全級(jí)別或角色存儲(chǔ)在會(huì)話(huà)里面。 歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實(shí)踐干貨哦~ 本文來(lái)自云+社區(qū)翻譯社,由Tnecesoc編譯。 會(huì)話(huà)管理一直是 Java 企業(yè)級(jí)應(yīng)用的...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • Spring核心 Spring簡(jiǎn)介

    摘要:基于工廠,會(huì)有多種應(yīng)用上下文的實(shí)現(xiàn)的模塊在模塊中,面向切面編程提供了豐富的支持,該模塊是應(yīng)用系統(tǒng)中開(kāi)發(fā)切面的基礎(chǔ),可以幫助應(yīng)用對(duì)象解耦。的主頁(yè)安全對(duì)于許多應(yīng)用都是一個(gè)非常關(guān)鍵的切面。 簡(jiǎn)化Java開(kāi)發(fā) JavaBean:Enterprise JavaBean、EJBJDO:Java數(shù)據(jù)對(duì)象、Java Data ObjectPOJO:Plain Old Java ObjectDI:依賴(lài)注...

    sixgo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<