jvm高并发_在JVM上对高并发HTTP服务器进行基准测试
jvm高并發(fā)
在第一篇關(guān)于HTTP客戶端的文章 (我將您重定向到JVM上的高效HTTP的介紹)之后,現(xiàn)在讓我們來談?wù)凥TTP 服務(wù)器 。
有一些關(guān)于HTTP服務(wù)器的基準(zhǔn)測(cè)試,但通常受到諸如以下缺點(diǎn)的阻礙:
- 沒有有效地執(zhí)行高并發(fā)方案,并且更普遍地考慮了不現(xiàn)實(shí)和不具有代表性的方案,例如:
- 純開銷方案,其中請(qǐng)求處理基本上為零(在實(shí)踐中,總有一些處理需要完成)。
- 實(shí)際不連接,隔離和/或確定負(fù)載生成和負(fù)載目標(biāo)過程的尺寸。
- 沒有分配可比的系統(tǒng)資源來加載目標(biāo)。
- 不包括足夠廣泛的方法(例如,僅專注于“同步”或“異步”服務(wù)器)。
- 不分析數(shù)據(jù)以產(chǎn)生結(jié)果 。
我們將分析新的基準(zhǔn),這些基準(zhǔn)試圖解決上述問題,并且產(chǎn)生了非常有趣的,有時(shí)甚至是意外的結(jié)果:
- 如果請(qǐng)求的壽命不是很長(zhǎng),同步的線程阻塞Jetty和Undertow服務(wù)器也可以有效地用于高并發(fā)情況。
- 當(dāng)請(qǐng)求需要保持很長(zhǎng)時(shí)間(例如,長(zhǎng)輪詢,服務(wù)器推送)時(shí),異步服務(wù)器和使用Quasar光纖的服務(wù)器可以支持更多并發(fā)活動(dòng)請(qǐng)求。
- 異步API相當(dāng)復(fù)雜,而光纖則很簡(jiǎn)單(與傳統(tǒng)的線程阻塞一樣多),并且不僅在高并發(fā)情況下而且在各種情況下都表現(xiàn)出色。
基準(zhǔn)和負(fù)載生成器
高并發(fā)方案已成為重要的使用和基準(zhǔn)案例。 它們可能是由于特定功能(例如聊天)和/或有時(shí)是不需要的技術(shù)狀況(例如“冥想”數(shù)據(jù)層)導(dǎo)致的長(zhǎng)期請(qǐng)求所致。
和以前一樣 ,使用的負(fù)載生成器是Pinterest的jbender ,后者又基于Quasar和Comsat的HTTP客戶端 。 多虧Quasar光纖, jbender甚至支持來自單個(gè)節(jié)點(diǎn)的大量并發(fā)請(qǐng)求,一個(gè)不錯(cuò)的同步API,并且作為負(fù)載測(cè)試框架而不是單個(gè)工具,它提供了很多靈活性和便利性(包括例如響應(yīng)驗(yàn)證)。
在基準(zhǔn)測(cè)試特定的等待之后,加載目標(biāo)提供最小的“ hello” HTTP響應(yīng)1 ,這是測(cè)試并發(fā)性的非常簡(jiǎn)單的方法:等待時(shí)間越長(zhǎng),請(qǐng)求持續(xù)時(shí)間和加載目標(biāo)必須支持的并發(fā)級(jí)別越高避免請(qǐng)求隊(duì)列。
對(duì)于負(fù)載情況,只有第一個(gè)基準(zhǔn)是最大并發(fā)基準(zhǔn),它的唯一目的是測(cè)量可以同時(shí)處理的實(shí)際最大請(qǐng)求數(shù)。 為此,它會(huì)啟動(dòng)盡可能多的請(qǐng)求,并讓它們等待很長(zhǎng)時(shí)間。 其余所有負(fù)載情況都是目標(biāo)速率 ,這意味著它們衡量負(fù)載目標(biāo)在某個(gè)目標(biāo)請(qǐng)求頻率下的行為方式,而不管它們是否可以(或不能)以足夠快的速度分派請(qǐng)求2 。 更詳細(xì)的描述如下:
由于我們正在測(cè)試JVM服務(wù)器,并且HotSpot JVM包含JIT配置文件引導(dǎo)的優(yōu)化編譯器 ,因此在上述基準(zhǔn)測(cè)試2-4之前,我始終以固定的并發(fā)級(jí)別1000個(gè)請(qǐng)求運(yùn)行初步的100k請(qǐng)求預(yù)熱。 每個(gè)圖都是10次運(yùn)行的最佳結(jié)果,在這10次運(yùn)行中,既未停止裝入目標(biāo)也未停止裝入生成器,以便為JVM提供最佳機(jī)會(huì)來優(yōu)化代碼路徑。
基于comsat-httpclient JBender負(fù)載生成器(基于Apache的異步HTTP客戶端 4.1 )已用于基準(zhǔn)測(cè)試1、2和3以及預(yù)熱測(cè)試,而comsat-okhttp (基于OkHttp 2.6異步) ,它對(duì)于短期請(qǐng)求的性能往往更好,已用于基準(zhǔn)測(cè)試4。兩者的設(shè)置如下:
- 沒有重試。
- 1h讀/寫超時(shí)。
- 最大連接池。
- 工作線程的數(shù)量等于內(nèi)核的數(shù)量。
- Cookie禁用,因此每個(gè)請(qǐng)求都屬于一個(gè)新創(chuàng)建的會(huì)話3 。
系統(tǒng)篇
已采取一些系統(tǒng)預(yù)防措施:
- 我們不希望負(fù)載生成器和服務(wù)器進(jìn)程相互竊取資源,因此必須將它們分開到足以實(shí)現(xiàn)資源隔離的程度。
- 我們不希望負(fù)載生成器成為瓶頸,因此讓它使用大量資源(相對(duì)于服務(wù)器)和最佳JVM性能設(shè)置(當(dāng)然,我們也希望使用服務(wù)器)是最安全的。
- 我們希望網(wǎng)絡(luò)實(shí)際上在那兒,以便我們模擬一個(gè)現(xiàn)實(shí)的場(chǎng)景,但我們也希望它盡可能快,這樣它也不會(huì)成為瓶頸。
考慮到上述注意事項(xiàng),已設(shè)置以下基準(zhǔn)測(cè)試AWS環(huán)境:
- 加載目標(biāo) :
- AWS EC2 Linux m4.large(8 GB,2 vcpus,具有增強(qiáng)的網(wǎng)絡(luò)性能,網(wǎng)絡(luò)性能中等)
- 負(fù)載生成器 :
- AWS EC2 Linux m4.xlarge(16 GB,4 vcpus,具有增強(qiáng)網(wǎng)絡(luò)功能的高性能網(wǎng)絡(luò))
與“ t”等其他一些類型相比,AWS EC2“ m”個(gè)虛擬實(shí)例旨在提供更可預(yù)測(cè)的性能。
AWS內(nèi)部網(wǎng)絡(luò)承擔(dān)基準(zhǔn)負(fù)載,并且實(shí)例位于相同的區(qū)域和可用的區(qū)域中,以實(shí)現(xiàn)最佳連接。
有關(guān)JVM設(shè)置的一些注意事項(xiàng):
- 負(fù)載生成器使用了12GB的堆內(nèi)存。 G1垃圾收集器試圖最大程度地減少暫停并保持高吞吐量,已成為6GB堆以上的可行選擇,并且已被用來在負(fù)載生成期間最大程度地減少抖動(dòng)。
- 加載目標(biāo)使用了4GB的堆內(nèi)存; 這是一個(gè)適中的數(shù)量,但不足以利用G1,因此改用了默認(rèn)的吞吐量?jī)?yōu)化收集器。 基本原理是代表服務(wù)器環(huán)境,在該環(huán)境中內(nèi)存可用性足夠但仍然受到一定限制(例如,出于成本原因,例如基于云的服務(wù)器機(jī)群)。
基于JBender建議的一些細(xì)微變化,已經(jīng)在負(fù)載生成器和服務(wù)器系統(tǒng)上執(zhí)行了Linux OS調(diào)整。
負(fù)載目標(biāo)和負(fù)載生成器代碼
這些基準(zhǔn)測(cè)試的代碼最初是由nqzero的jempower派生的 ,該功能在最近的基準(zhǔn)測(cè)試帖子中 jempower介紹,該帖子又來自TechEmpower的。 使用Capsule (而不是腳本)將其轉(zhuǎn)換為完整的JVM,多模塊Gradle項(xiàng)目。
為了使處理程序與服務(wù)器技術(shù)和負(fù)載目標(biāo)分離,代碼也進(jìn)行了實(shí)質(zhì)性的重構(gòu),每個(gè)處理程序都將處理程序與支持其API的技術(shù)集成在一起。 還對(duì)其進(jìn)行了重構(gòu),以共享盡可能多的邏輯和設(shè)置。
我還為線程阻塞和Comsat(光纖阻塞)同步API以及有趣的異步變量添加了更多的加載目標(biāo),并且由于庫(kù)似乎沒有維護(hù),我刪除了Kilim目標(biāo)。
匹配的API和服務(wù)器技術(shù):加載目標(biāo)
基準(zhǔn)測(cè)試包含基于多種API和服務(wù)器技術(shù)的多個(gè)負(fù)載目標(biāo):
- 以下服務(wù)器技術(shù)上的標(biāo)準(zhǔn)同步JEE Servlet API:
- 未完成 1.3.15.Final
- 標(biāo)準(zhǔn)異步JEE Servlet API( startAsync &friends,3.0 +),具有容器提供的執(zhí)行器( dispatch )和用戶提供的執(zhí)行器( complete ),它們都與上述服務(wù)器技術(shù)相同。
- 非標(biāo)準(zhǔn)化的Comsat Web Actors API 0.7.0-SNAPSHOT ( 0.6.0 ,進(jìn)一步修復(fù)和改進(jìn)了Web actor),它將傳入(請(qǐng)求)和出站(響應(yīng))隊(duì)列附加到接收傳入請(qǐng)求的真正的輕量級(jí)順序進(jìn)程(光纖)并通過簡(jiǎn)單,同步和有效的(特別是光纖阻塞而不是線程阻塞) receive和send操作發(fā)送響應(yīng)。 這些過程是成熟的Erlang風(fēng)格的參與者 4 。 目前,Web Actor可以在servlet容器上運(yùn)行,既可以作為Undertow處理程序 ,也可以作為本地Netty處理程序運(yùn)行 ; 本機(jī)Netty和Undertow部署已包含在基準(zhǔn)測(cè)試中。 Netty版本是4.0.34.Final和Undertow與上面相同。
- 與上述相同的Jetty上的非標(biāo)準(zhǔn)化Jetty嵌入式API (同步和異步5) 。
- 與上述相同的Undertow上的非標(biāo)準(zhǔn)化的Undertow處理程序API (同步和異步)。
- 使用Jetty 9.3.2.v20150730的非標(biāo)準(zhǔn)化Spark服務(wù)器/處理程序API 2.3 。
同步處理程序是最簡(jiǎn)單的處理程序:它們將在啟動(dòng)該請(qǐng)求的同一OS線程(或使用Comsat時(shí)使用fiber )中執(zhí)行整個(gè)請(qǐng)求處理。 通過直接的線程(或光纖)睡眠來實(shí)現(xiàn)響應(yīng)之前的等待。
異步處理程序更加復(fù)雜,因?yàn)樗鼈兺七t了請(qǐng)求的完成,并且需要執(zhí)行其他簿記和調(diào)度工作。 所有這些都將通過立即將待處理的請(qǐng)求存儲(chǔ)在靜態(tài)數(shù)組中開始,以后每隔10毫秒安排一次的TimerTask從中提取它們以進(jìn)行處理,這時(shí)策略會(huì)根據(jù)處理程序而有所不同:
- 使用dispatch異步處理程序會(huì)將請(qǐng)求處理作業(yè)調(diào)度到服務(wù)器提供的執(zhí)行程序。 當(dāng)?shù)却龝r(shí)間不為0時(shí),將通過直接線程Hibernate來實(shí)現(xiàn)。
- 其他異步處理程序不依賴服務(wù)器提供的執(zhí)行程序,而是使用以下不同策略開始處理請(qǐng)求。 但是,如果等待時(shí)間不為0,則所有這些對(duì)象都將進(jìn)一步將完成作業(yè)分派給ScheduledExecutorService :這將模擬一個(gè)完全非阻塞的實(shí)現(xiàn),其中通過異步API執(zhí)行外部(例如,DB,微服務(wù)等)調(diào)用也一樣 ScheduledExecutor的最大線程數(shù)將與服務(wù)器提供的執(zhí)行器的最大線程數(shù)相同。
- FJP :使用默認(rèn)設(shè)置將請(qǐng)求處理作業(yè)分派到fork-join池。
“每個(gè)會(huì)話” Web Actor的目標(biāo)是每個(gè)會(huì)話產(chǎn)生一個(gè)actor,并且由于cookie被禁用,這意味著每個(gè)請(qǐng)求都由由其自己的光纖6支持的不同actor處理。
HTTP服務(wù)器資源設(shè)置偏向于基于線程的同步技術(shù),該技術(shù)可以使用比異步/光纖線程更多的OS線程:這是因?yàn)閷?shí)際上,如果要以高并發(fā)性使用它們,將不得不這樣做。場(chǎng)景。 除此之外,相同的HTTP服務(wù)器設(shè)置已盡可能統(tǒng)一地使用:
- 同步服務(wù)器和使用dispatch異步服務(wù)器在進(jìn)行區(qū)分的Undertow上最多使用5k I / O線程加5k工作者線程,在Tomcat,Jetty和Spark上最多使用10k通用處理線程。
- 在Tomcat,Jetty和Netty上運(yùn)行的其他異步服務(wù)器最多使用100個(gè)處理線程。
- 在Undertow上運(yùn)行的其他異步服務(wù)器最多可以使用50個(gè)I / O線程和50個(gè)工作線程。
- 套接字接受隊(duì)列(又稱積壓)最多可以保持10k個(gè)連接。
- 會(huì)話有效期為1分鐘。
- 對(duì)于Tomcat,Jetty,Netty和Undertow TCP_NODELAY明確設(shè)置為true 。
- 對(duì)于Jetty,Netty和Undertow SO_REUSEADDR顯式設(shè)置為true 。
數(shù)據(jù)
您可以直接訪問基準(zhǔn)的電子表格,這是統(tǒng)計(jì)信息:
| 加載目標(biāo) | 最高 | 錯(cuò)誤編號(hào) | 時(shí)間平均(毫秒) | 最長(zhǎng)時(shí)間(毫秒) | 錯(cuò)誤(#) | 時(shí)間平均(毫秒) | 最長(zhǎng)時(shí)間(毫秒) | 誤差(%) | 時(shí)間平均(毫秒) | 最長(zhǎng)時(shí)間(毫秒) | 錯(cuò)誤(#) |
| Comsat Jetty Servlet同步 | 54001 | 0 | 1000.777 | 1088.422 | 0 | 110.509 | 1103.102 | 0 | 189.742 | 3015.705 | 0 |
| Jetty Servlet同步 | 9997 | 0 | 1000.643 | 1044.382 | 0 | 112.641 | 1114.636 | 0 | 222.452 | 2936.013 | 0 |
| Jetty Servlet異步(調(diào)度) | 9997 | 0 | 1005.828 | 1083.179 | 0 | 121.719 | 1173.357 | 0 | 289.229 | 3066.036 | 0 |
| Jetty Servlet Aync(FJP /隊(duì)列) | 45601 | 4435 | 1005.769 | 1041.236 | 0 | 119.819 | 1120.928 | 0 | 281.602 | 5700.059 | 0 |
| 碼頭同步 | 9997 | 54 | 1000.645 | 1043.857 | 0 | 113.508 | 1143.996 | 0 | 193.487 | 1779.433 | 0 |
| 碼頭異步(FJP /完整) | 47970 | 1909年 | 1005.754 | 1041.76 | 0 | 109.067 | 1120.928 | 0 | 266.918 | 4408.214 | 0 |
| 碼頭異步(調(diào)度) | 9997 | 0 | 1005.773 | 1045.43 | 0 | 127.65 | 1385.169 | 0 | 397.948 | 4626.317 | 0 |
| Spark(碼頭)Spark Handler | 9997 | 58 | 1000.718 | 1245.708 | 0 | 134.482 | 3118.465 | 0 | 391.374 | 7021.265 | 0 |
| Comsat Tomcat Servlet同步 | 26682 | 13533 | 1000.636 | 1039.139 | 0 | 不適用 | 不適用 | 不適用 | 307.903 | 5523.898 | 0 |
| Tomcat Servlet同步 | 9999 | 0 | 1000.625 | 1087.373 | 0 | 不適用 | 不適用 | 不適用 | 329.06 | 7239.369 | 0 |
| Tomcat Servlet異步(調(diào)度) | 9999 | 0 | 1005.986 | 1108.345 | 0 | 不適用 | 不適用 | 不適用 | 289.703 | 4886.364 | 0 |
| Tomcat Servlet異步(FJP /完整) | 9999 | 29965 | 1005.891 | 1041.76 | 0 | 不適用 | 不適用 | 不適用 | 159.501 | 4483.711 | 0 |
| Comsat Undertow Servlet同步 | 53351 | 0 | 1000.648 | 1060.635 | 0 | 107.757 | 1309.671 | 0 | 204.795 | 4273.996 | 0 |
| Undertow Servlet同步 | 4999 | 7758 | 1000.723 | 1089.47 | 0 | 110.599 | 1319.109 | 0 | 193.436 | 4307.55 | 0 |
| Undertow Servlet異步(調(diào)度) | 4999 | 576 | 1006.011 | 1123.025 | 0 | 1756.198 | 15183.38 | 83 | 697.811 | 6996.099 | 0 |
| Undertow Servlet異步(FJP /完整) | 52312 | 1688 | 1005.81 | 1071.645 | 0 | 108.324 | 1113.588 | 0 | 214.423 | 4408.214 | 0 |
| 同步下 | 4999 | 0 | 1000.644 | 1049.625 | 0 | 108.843 | 3114.271 | 0 | 316.991 | 4789.895 | 0 |
| Undertow異步(調(diào)度) | 49499 | 4501 | 1005.742 | 1162.871 | 0 | 121.554 | 3116.368 | 0 | 318.306 | 5486.15 | 0 |
| Undertow異步(FJP /隊(duì)列) | 33720 | 0 | 1005.656 | 1040.712 | 0 | 109.899 | 1113.588 | 0 | 236.558 | 3632.267 | 0 |
| Comsat Netty網(wǎng)絡(luò)演員 | 53448 | 0 | 1000.701 | 1085.276 | 0 | 107.697 | 1106.248 | 0 | 320.986 | 2917.138 | 0 |
| Comsat Undertow網(wǎng)絡(luò)演員 | 53436 | 0 | 1000.674 | 1037.042 | 0 | 123.791 | 3118.465 | 0 | 358.97 | 7046.431 | 0 |
這是圖形:
結(jié)果
錯(cuò)誤主要是“連接重置”(可能是由于接受時(shí)變慢),盡管在極端情況下,處理變慢導(dǎo)致并發(fā)超過了網(wǎng)絡(luò)接口可用的端口數(shù)。
一些特定于基準(zhǔn)的注意事項(xiàng):
請(qǐng)求完成時(shí)間的分布也有一些考慮因素:該基準(zhǔn)測(cè)試的負(fù)載生成器使用了由JBender提供的基于Gil Tene的HDRHistogram的事件記錄器。 您可以直接訪問直方圖數(shù)據(jù)。
關(guān)于“慢請(qǐng)求”基準(zhǔn)的最短最長(zhǎng)時(shí)間的直方圖顯示,Comsat Tomcat Servlet(次優(yōu))在絕對(duì)最小的1秒(睡眠時(shí)間)的1毫秒內(nèi)完成了100000個(gè)請(qǐng)求中的98147個(gè)請(qǐng)求,而其余請(qǐng)求的完成時(shí)間分布在1001.39毫秒和1039.139毫秒之間(最大值):
Comsat Undertow Servlet的最大延遲時(shí)間最短,但是平均延遲會(huì)稍差一些,因?yàn)樗?001毫秒內(nèi)完成了約96%的請(qǐng)求,而其余的則均勻地分布到1037.042毫秒(最大):
另一方面,Spark(最差)的分布不太均勻:它在1001ms(99221)內(nèi)完成的工作更多,但很少有其他請(qǐng)求可以占用1245.708ms(最大):
在“ Realistic High Concurrency”中,Comsat Jetty Servlet產(chǎn)生了最短的最大延遲,但是線程阻塞Jetty Servlet的目標(biāo)緊隨其后:它在101ms內(nèi)完成了78152個(gè)請(qǐng)求(最小等于100ms的睡眠時(shí)間)并完成了其余的分布在兩個(gè)不同的群集中,一個(gè)群集從100ms到367ms有規(guī)律地分布,另一個(gè)群集在1100ms到1114.636ms的最大值之間:
Comsat Jetty Servlet的目標(biāo)行為非常相似:75303個(gè)請(qǐng)求在101ms內(nèi)完成,幾乎所有其余請(qǐng)求在328.466ms內(nèi)完成,只有48個(gè)在1097ms左右(最大1103.102ms)內(nèi)完成:
有趣的是,從主群集到“尾巴”的距離大致對(duì)應(yīng)于該運(yùn)行的最大GC暫停時(shí)間(576毫秒)。
基于稍早的9.3 Jetty構(gòu)建的Spark表現(xiàn)出類似的行為,但是第一個(gè)集群的時(shí)間分布更多(超過一半,或者請(qǐng)求在101ms和391ms之間完成),另外還有大約1300ms和3118ms(其“尾”集群)距離太粗略地對(duì)應(yīng)于該運(yùn)行的最大GC時(shí)間(即1774ms):
Comsat Netty Web Actor的分布(每次會(huì)話)是不同的:大約66%的分布在101毫秒內(nèi)完成,而85%的分布在103.5毫秒內(nèi),然后直到c??a. 260毫秒,此時(shí)有一個(gè)中斷,一個(gè)群集發(fā)生在334毫秒,最后一個(gè)群集發(fā)生在1098毫秒至1106毫秒之間。 在這種情況下,似乎與GC活動(dòng)無關(guān),后者與預(yù)期的要高得多,并且最長(zhǎng)GC時(shí)間超過4s:
相反,Undertow的GC開銷非常低,包括與Quasar光纖集成時(shí)(在后一種情況下,運(yùn)行6個(gè)GC時(shí)最長(zhǎng)為407ms)。 具體來說,Comsat Undertow Servlet在101毫秒內(nèi)完成了超過92.5%的請(qǐng)求,一個(gè)長(zhǎng)達(dá)341毫秒的主集群包含了99.5%的請(qǐng)求,以及另外兩個(gè)似乎與GC活動(dòng)沒有嚴(yán)格關(guān)聯(lián)的集群:
Undertow Sync的圖形非常相似,主群集更加緊密,在101毫秒內(nèi)完成了90%以上的請(qǐng)求,從而獲得了非常好的平均值,但附加的尾部群集使最大值進(jìn)一步超過了3秒。
最終,使用dispatch調(diào)用的Undertow異步Servlet的性能最差,并且其多集群分發(fā)在15秒內(nèi)非常緩慢地上升! 群集距離似乎與最大GC運(yùn)行時(shí)間沒有特別的關(guān)系:
在“現(xiàn)實(shí)開銷”基準(zhǔn)中,此負(fù)載目標(biāo)的性能也很差,這表明Undertow可能不太理想地實(shí)現(xiàn)了dispatch servlet異步調(diào)用。
這些觀察結(jié)果認(rèn)為,在中高并發(fā)情況下,高延遲似乎與底層網(wǎng)絡(luò)/ HTTP技術(shù)的關(guān)聯(lián)更多,而不是與請(qǐng)求處理技術(shù)或API的關(guān)聯(lián),在某些情況下,更具體地,與敏感性相關(guān)。由GC活動(dòng)引起的抖動(dòng)。 它還表明分布的主要集群也與基礎(chǔ)網(wǎng)絡(luò)/ HTTP技術(shù)相關(guān)。
除了使用dispatch Undertow Servlet Async之外,“現(xiàn)實(shí)開銷”直方圖顯示了具有2或3個(gè)不同趨勢(shì)的所有目標(biāo)所共有的均勻分布的結(jié)構(gòu):一個(gè)關(guān)于快速完成的請(qǐng)求,直到一個(gè)目標(biāo)特定的數(shù)目,另一個(gè)關(guān)于包括已完成的剩余請(qǐng)求的請(qǐng)求更慢。
例如,Jetty Sync Handler目標(biāo)(最佳)在31.457毫秒內(nèi)完成了75%的請(qǐng)求,而其他請(qǐng)求似乎平均分配,直到最大1779.433毫秒:
它的GC活性也非常有限(3次運(yùn)行,最長(zhǎng)113ms)。
Tomcat Servlet最差,其中65%的請(qǐng)求在32.621ms內(nèi)完成,99219個(gè)請(qǐng)求在2227ms內(nèi)完成,并且進(jìn)一步的趨勢(shì)是,僅ca的完成時(shí)間增加了5s。 80個(gè)請(qǐng)求。 在這種情況下,GC干預(yù)也很低(盡管比Jetty更高):
經(jīng)驗(yàn)教訓(xùn)
結(jié)果導(dǎo)致一些重要的考慮:
- 如果您不處理高并發(fā)情??況,則無需考慮異步庫(kù),因?yàn)榛诠饫w和線程的服務(wù)器可以完美運(yùn)行,并且同樣重要的是,它們將允許您編寫高度可讀,可維護(hù)且面向未來的同步代碼。
- 即使在高并發(fā)情況下,也確實(shí)不需要跳入異步陷阱,因?yàn)榛诠饫w的服務(wù)器具有廣泛的適用性:借助Quasar光纖,您可以在一個(gè)單一的服務(wù)器中獲得非常高的并發(fā)性,非常好的通用性能和面向未來的代碼包。
- 必須說,即使在高并發(fā)情況下,某些同步的線程阻塞服務(wù)器也設(shè)法獲得良好的性能,并且確切地了解這絕對(duì)是一個(gè)有趣的研究。 它們的實(shí)際最大并發(fā)性比異步或Quasar的低得多,因此,如果您希望盡早開始處理盡可能多的請(qǐng)求,則最好還是使用異步/光纖技術(shù)。
- 在零請(qǐng)求處理時(shí)間的情況下,即使是同步單線程服務(wù)器也可以很好地工作:當(dāng)請(qǐng)求處理時(shí)間增加并且并發(fā)效應(yīng)開始時(shí),麻煩就開始了。
同樣,在運(yùn)行基準(zhǔn)測(cè)試時(shí)(甚至在分析結(jié)果之前)所觀察到的(和錯(cuò)誤)也強(qiáng)調(diào)了充分應(yīng)對(duì)某些JVM特有特征的重要性:
- JVM在使用運(yùn)行時(shí)信息優(yōu)化代碼方面做得非常出色:如果您不相信我嘗試使用帶有-Xcomp標(biāo)志(不-Xcomp標(biāo)志)來運(yùn)行您的應(yīng)用程序,該標(biāo)志將執(zhí)行預(yù)運(yùn)行JIT,并親自了解如何獲得最佳結(jié)果(提示: -Xcomp可能會(huì)產(chǎn)生明顯較差的性能)。 另一方面,這意味著逐漸進(jìn)行JVM預(yù)熱是將HTTP服務(wù)器暴露于傳入請(qǐng)求之前必須執(zhí)行的重要步驟,因?yàn)槲磧?yōu)化的代碼路徑很容易無法跟上突然的高并發(fā)和/或高速率負(fù)載會(huì)導(dǎo)致或多或少的嚴(yán)重故障。
- 抖動(dòng)/打cup是一個(gè)嚴(yán)重的問題,尤其是對(duì)于最大延遲而言,但如果它發(fā)生在“糟糕”的時(shí)刻(例如,大量傳入請(qǐng)求),它甚至可能使系統(tǒng)崩潰。 GC暫停是造成抖動(dòng)的一個(gè)重要原因,因此通常最好仔細(xì)考慮JVM內(nèi)存設(shè)置和將要使用的GC。 特別是,基準(zhǔn)測(cè)試中的最大延遲似乎受到影響,甚至在某些情況下甚至與GC運(yùn)行有關(guān)。 朝著這個(gè)方向的另一個(gè)提示是,即使在低并發(fā)情況下,由于即使在較簡(jiǎn)單的服務(wù)器上,GC壓力也會(huì)增加,因此使用較小的1GB堆運(yùn)行的基準(zhǔn)測(cè)試仍偏愛更復(fù)雜的技術(shù)(異步和光纖)。 這意味著減少GC的數(shù)量和持續(xù)時(shí)間是值得的,但是我們?cè)撛趺醋瞿?#xff1f; 一種方法是準(zhǔn)確選擇JVM內(nèi)存設(shè)置,并在可能的情況下使用較低延遲的GC(例如G1或商用JVM Azul Zing) 。 另一種方法是再次選擇最簡(jiǎn)單的工具來完成這項(xiàng)工作:如果您不處于高并發(fā)情況下,請(qǐng)使用最簡(jiǎn)單的技術(shù),因?yàn)榕c更復(fù)雜的技術(shù)相比,它們將產(chǎn)生更少的垃圾。
- 出于類似的原因,如果您需要會(huì)話,則每個(gè)會(huì)話的Web Actor很棒,因?yàn)樗鼈兓旧弦蚕馝rlang一樣啟用“每個(gè)用戶的Web服務(wù)器”范例 。 另一方面,如果您不需要會(huì)話或那種可靠性,那么您將獲得GC開銷,因?yàn)榭赡苄枰獮槊總€(gè)請(qǐng)求實(shí)例化(然后稍后進(jìn)行垃圾收集)新的參與者(及其對(duì)象圖) 。 這反映在“現(xiàn)實(shí)開銷”結(jié)果中。
進(jìn)一步的工作
雖然此基準(zhǔn)可以作為您評(píng)估的一個(gè)很好的起點(diǎn),但它絕不是詳盡無遺的,可以通過許多方式加以改進(jìn),例如:
- 添加更多的負(fù)載目標(biāo)。
- 添加基準(zhǔn)案例。
- 在其他系統(tǒng)(例如硬件,其他云,其他AWS實(shí)例)上進(jìn)行基準(zhǔn)測(cè)試。
- 在非Oracle JVM上進(jìn)行基準(zhǔn)測(cè)試。
- 使用不同的JVM設(shè)置進(jìn)行基準(zhǔn)測(cè)試。
- 進(jìn)一步分析系統(tǒng)數(shù)據(jù)。
- 研究奇怪的行為,包括令人驚訝的好行為(例如,高并發(fā)情況下的Jetty線程阻塞同步服務(wù)器)和出奇的壞行為(例如,Undertow的基于dispatch的處理程序和Tomcat Servlet)。
- 更好地分析相關(guān)性,例如GC引起的抖動(dòng)和統(tǒng)計(jì)數(shù)據(jù)之間的相關(guān)性。
盡管這是一項(xiàng)昂貴的工作,但我認(rèn)為通常仍需要更多的基準(zhǔn)測(cè)試,因?yàn)檫@實(shí)際上可以更好地理解,改進(jìn)和評(píng)估軟件系統(tǒng)。
結(jié)論
此處的主要目標(biāo)是查看不同的HTTP服務(wù)器API和技術(shù)如何在更接近真實(shí)的場(chǎng)景中執(zhí)行,在這些場(chǎng)景中,具有預(yù)定系統(tǒng)資源的單獨(dú)的客戶端和服務(wù)器JVM進(jìn)程通過真實(shí)網(wǎng)絡(luò)進(jìn)行通信,并且請(qǐng)求處理為非零時(shí)間。
事實(shí)證明,Quasar光纖可用于構(gòu)建承受高并發(fā)負(fù)載的多功能執(zhí)行器,并且至少同樣重要的是,與異步API相比,它們是更好的軟件編寫工具。 事實(shí)再次證明,沒有靈丹妙藥:不同的情況需要不同的解決方案,甚至有時(shí)被認(rèn)為是過時(shí)的技術(shù)(例如線程阻塞服務(wù)器(甚至單線程服務(wù)器))也可以勝任。
除了性能以外,API的選擇還應(yīng)在您的決定中起主要作用,因?yàn)檫@將決定服務(wù)器代碼的未來。 根據(jù)情況,根據(jù)項(xiàng)目的需求和開發(fā)環(huán)境,非標(biāo)準(zhǔn)API(及其相關(guān)風(fēng)險(xiǎn),采用和退出成本)可能是可行的,也可能不是可行的選擇。 要考慮的另一件事是,異步API比同步API難用得多,并且傾向于通過異步7感染整個(gè)代碼庫(kù),這意味著使用異步API可能會(huì)妨礙代碼的可維護(hù)性并縮短其未來。
也就是說,我完全意識(shí)到以下事實(shí):性能基準(zhǔn)會(huì)盡力而為,以有限的工具和知識(shí)不斷變化的局面(和使用)不斷變化,設(shè)計(jì),運(yùn)行和發(fā)布基準(zhǔn)是一項(xiàng)艱苦的工作,也是一項(xiàng)重大的投資。 。
我希望這一輪對(duì)許多人有用,我將熱烈歡迎和贊賞并鼓勵(lì)任何建議,改進(jìn)和進(jìn)一步的努力。
翻譯自: https://www.javacodegeeks.com/2016/05/benchmarking-high-concurrency-http-servers-jvm.html
jvm高并發(fā)
總結(jié)
以上是生活随笔為你收集整理的jvm高并发_在JVM上对高并发HTTP服务器进行基准测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: couchbase集群_使用CLI扩展和
- 下一篇: 安卓无限重启怎么办(安卓无限重启)