日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

记一次Socket.IO长链服务的性能压测

發(fā)布時間:2025/3/8 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 记一次Socket.IO长链服务的性能压测 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

網(wǎng)易云信IM系統(tǒng)中的Web版使用了Socket.IO實(shí)現(xiàn)瀏覽器環(huán)境下的長鏈服務(wù);區(qū)別于常規(guī)的長鏈服務(wù),為該服務(wù)的壓測提出了一些新的挑戰(zhàn),本文總結(jié)了測試過程中的一些收獲供參考。

Part1 測試工具選項

一、工具選型

  • Gatling

  • Node.js

  • JMeter

  • Java WebSocket

這些工具都是可以支持WebSocket協(xié)議的工具,主要從以下幾個方面進(jìn)行對比:

  • 上手難易程度

  • 測試資源開銷

  • 和性能測試平臺結(jié)合的難易程度

二、對比過程

對比場景

(1)5000個用戶,每秒鐘發(fā)送100個登錄請求,并保持連接

(2)5000個用戶,每隔5s發(fā)送一條點(diǎn)對點(diǎn)消息,即發(fā)送消息頻率1000

工具使用過程

1. Gatling

工具簡介:Gatling是一款基于Scala 開發(fā)的高性能服務(wù)器性能測試工具,它主要用于對服務(wù)器進(jìn)行負(fù)載測試,并分析和測量服務(wù)器的各種性能指標(biāo)。

工具語言:Scala語言

工具官網(wǎng)

http://gatling.io/docs/2.0.0-RC2/index.html#

相關(guān)代碼

遇到的問題

(1)scale語言比較陌生,腳本編寫時困難較多,目前暫未實(shí)現(xiàn)隔一定時間,即發(fā)心跳又發(fā)消息的場景;

(2)無法和性能測試平臺結(jié)合,系統(tǒng)整合成本比較高;

2. Node.js + Socket.IO

工具簡介:

Node.js是一個基于Chrome V8引擎的JavaScript運(yùn)行環(huán)境。Node.js使用了一個事件驅(qū)動、非阻塞式I/O的模型,使其輕量又高效;而Socket.IO是一個基于Node.js架構(gòu)體系的且原生支持WebSocket協(xié)議,可用作實(shí)時通信的軟件包。Socket.IO為跨瀏覽器構(gòu)建實(shí)時應(yīng)用提供了完整的封裝,且完全由JavaScript實(shí)現(xiàn),語言更容易理解。

工具語言:JavaScript

工具官網(wǎng):

? http://socket.io/docs/

? http://nodejs.cn/

相關(guān)代碼:

遇到問題:

(1)多節(jié)點(diǎn)并發(fā)分布式控制

(2)整合到現(xiàn)有的性能測試平臺

3. JMeter

工具簡介:

JMeter是比較常見的性能測試開源工具,支持多種協(xié)議并且可以自定義java請求,更加靈活。

工具語言:

(1)Java

(2)JMeter xml腳本文件

工具官網(wǎng):

http://jmeter.apache.org/usermanual/get-started.html

https://blog.flood.io/socket-io-and-websockets-with-gatling/

相關(guān)代碼:

遇到問題:

JMeter的工具本上是同步的,如果建立1萬個連接的話,需要啟動1萬個線程處理,因此不適合測試高并發(fā)長連接的場景。

4. Jetty WebSocket Client

工具簡介:

Jetty提供了功能更強(qiáng)的WebSocket API,使用一個公共的核心API供WebSocket的服務(wù)端和客戶端使用。

工具語言: Java

工具官網(wǎng):

http://www.eclipse.org/jetty/

相關(guān)代碼:

遇到問題:

需要自己寫并發(fā)控制

三、對比結(jié)果總結(jié)

因?yàn)橛脕碜鲂阅軌簻y,所以考慮到壓測客戶端需要實(shí)現(xiàn)高并發(fā)請求,選擇Gatling和Socket.IO做了簡單的對比測試。

Part2 長鏈服務(wù)端性能問題的定位

如第一部分所述,我們最終選擇用Socket.IO實(shí)現(xiàn)了并發(fā)壓測的長鏈客戶端,下面簡單說明下長鏈服務(wù)器端測試的一些收獲;

首先,簡單描述下被測試服務(wù)器的功能

1. 和前端Socket.IO客戶端保持長連接;

2. 解析前端JSON結(jié)構(gòu)的數(shù)據(jù)包,并作二次封裝后抓發(fā)給后端APP服務(wù),并且將后端APP服務(wù)轉(zhuǎn)發(fā)過來的響應(yīng)包轉(zhuǎn)換成為socketio可以識別的json數(shù)據(jù)包,并發(fā)送給客戶端

為此,我們確定該服務(wù)主要的測試點(diǎn)為

1. 測試服務(wù)器可以支撐的最大連接數(shù):該測試點(diǎn)涉及到了TCP連接,以及我們需要注意哪些參數(shù),才可以保證用戶建立的連接數(shù)目不會因?yàn)橄拗贫_(dá)不到目標(biāo)。

2. 每秒鐘可以解析的包的數(shù)量:該測試點(diǎn)涉及到了網(wǎng)絡(luò)流量,如果已經(jīng)達(dá)到了網(wǎng)絡(luò)流量的峰值時,會出現(xiàn)什么樣的問題。

以下是這次測試過程中遇到的一系列問題:

問題1:最大連接數(shù)只能達(dá)到65K+

65535,對于程序員來說,這是一個很敏感的數(shù)字,因?yàn)橐慌_服務(wù)器,限制的最大端口號即為65535,所以出現(xiàn)這個問題后:

  • 第一反應(yīng):端口號不夠用了。 分析認(rèn)為Link服務(wù)作為服務(wù)端,對外提供的服務(wù)端口僅有一個,所以不存在服務(wù)端端口號不夠用的情況;

  • 第二反應(yīng):句柄數(shù)不夠用了。文件句柄數(shù)相當(dāng)于文件的標(biāo)識符,建立一條socket鏈接,同樣會使用一個文件句柄,而系統(tǒng)默認(rèn)的單個進(jìn)程使用的文件句柄為1024;

對于這種需要保持大量連接的服務(wù)來說,一般情況下都是需要修改文件句柄數(shù)的,文件句柄數(shù)修改的方法如下:

?A)查看單個進(jìn)程使用的最大文件句柄數(shù)的方法:

B)查看當(dāng)前進(jìn)程打開了多少個文件句柄呢:

C)修改Linux的最大文件句柄數(shù)限制的方法:

? 1)ulimit -n 65535

在當(dāng)前session有效,用戶退出或者系統(tǒng)重新后恢復(fù)默認(rèn)值

? 2)修改用戶下的.profile文件:在.profile文件中添加:ulimit -n 65535

? 只對當(dāng)前用戶有效

?3)修改文件/etc/security/limits.conf,在文件中添加:

(立即生效-當(dāng)前session中運(yùn)行ulimit -a命令無法顯示)

4)修改文件/etc/sysctl.conf添加:

運(yùn)行命令:/sbin/sysctl -p 使配置生效

但是修改文件句柄的限制后,該問題依然沒有得到解決。

這個時候想到可以使用dmesg查看系統(tǒng)日志,dmesg命令可以顯示Linux內(nèi)核的環(huán)形緩沖區(qū)信息,可以從中獲得諸如系統(tǒng)架構(gòu)、CPU和掛載的硬件,RAM等運(yùn)行級別的大量系統(tǒng)信息,因此dmesg命令在設(shè)備故障的診斷方面是非常重要的。通過dmesg,查看到了如下問題:

從上面的信息可見conntrack表滿了,那么conntrack表是做什么的?

nf_conntrack/ip_conntrack用來跟蹤連接條目,會使用一個哈希表來記錄 established 的記錄

nf_conntrack 在 2.6.15 被引入,而 ip_conntrack 在 2.6.22 被移除,如果該哈希表滿了dmesg命令就會出現(xiàn):

nf_conntrack: table full, dropping packet

如何修改conntrack表的大小

到此為止,這個問題我們算是解決了,總結(jié)下,遇到的網(wǎng)絡(luò)相關(guān)的知識點(diǎn)包括 文件句柄 和conntrack表。

問題2:在某些用例場景下,穩(wěn)定連接只能建立3800+

這個問題的前提是某些時候,也就是說偶現(xiàn)的,這種情況基本上可以排除是應(yīng)用程序內(nèi)部的問題。那對于這個問題我們使用了哪些定位手段呢?

1. watch和netstat 兩個命令

  • watch -d 定期查看一些信息,默認(rèn)是2s;

  • netstat -st | grep ignored 查看TCP連接的一些統(tǒng)計信息;

可見有SYNs to LISTEN sockets ignored在不停增加,這表明收到連接建立過程中的三次握手的ACK包,但是因各種原因(包括accept隊列滿) 創(chuàng)建socket失敗;

2. ss -ln : 查看進(jìn)程對應(yīng)的backlog的使用情況

backlog:簡單理解來說,連接已經(jīng)在TCP層建立成功(完成了三次握手的過程)但是還沒有被應(yīng)用程序所接受,這種情況下,該連接會存放到backlog這樣一個緩沖隊列內(nèi)

通過上面這個命令可以看到應(yīng)用程序的backlog隊列已經(jīng)滿了,但是即便把這個值調(diào)整為1024,該隊列還是會滿的。

到這兒,我們的定位過程陷入了僵局,下一步該怎么定位呢?這期間我們查看了內(nèi)存信息,CPU使用情況等,均沒有找對地方;但是在定位過程中,我們發(fā)現(xiàn),有時候JStack、JProfiler等工具都無法連上該服務(wù)了。

突然想到文件句柄是不是滿了?又執(zhí)行了以下幾條命令:

/proc/{pid}這個目錄下了對應(yīng)了所有在運(yùn)行的進(jìn)程的相關(guān)信息,

通過查看/proc/{pid}/fd目錄下的個數(shù)我們可以看到當(dāng)前進(jìn)程使用的文件句柄數(shù)有多少。

通過查看limits文件里面的值,可以看到系統(tǒng)對該進(jìn)程的一些限制,不幸的是,出現(xiàn)這個問題的時候,max open files這個值被限制為了4096。

調(diào)整該值之后最終解決了這個問題

問題3:大量的連接建立不成功

當(dāng)我們解決了一個又一個的問題后,突然發(fā)現(xiàn)高壓力下存在大量的連接建立不成功的問題,主要表現(xiàn)在:

原來:每秒鐘500個連接建立的請求時,5w個用戶都可以建立成功;

現(xiàn)在:每秒鐘500個連接建立的請求時,5w個用戶只有4w左右的連接可以建立成功;

這個問題也花費(fèi)了不短的時間,我們使用了各種命令查看各種網(wǎng)絡(luò)指標(biāo)

  • 通過netstat查看到send-q中有大量的消息堆積;

  • 通過sar查看到有大量的重傳;

  • 總結(jié)起來還是TcpDump抓包比較效果更好,從測試的開始,我們就只抓這一條鏈路上的包,且發(fā)送方和接收方,雙方都抓包:

    然后通過Wireshark分析,可以看到

    • 發(fā)送方/客戶端:存在一定時間段發(fā)送出大量的重傳包

    • 接收方/服務(wù)端:客戶端發(fā)送大量重傳包的這個過程中,什么都沒有收到

    這基本說明網(wǎng)絡(luò)有問題

    然后我們通過netperf測試了下網(wǎng)絡(luò)帶寬的情況,發(fā)現(xiàn)這兩臺機(jī)器之間的網(wǎng)絡(luò)上限只有21Mb,而且測試過程中的網(wǎng)絡(luò)請求量是超過這個值的。由于是在云主機(jī)環(huán)境上,通過咨詢云網(wǎng)絡(luò)相關(guān)的同事發(fā)現(xiàn),問題原因是因?yàn)樵浦鳈C(jī)之間的網(wǎng)絡(luò)QoS開啟限制導(dǎo)致的,限制了每臺云主機(jī)之間的網(wǎng)絡(luò)帶寬最高位21Mb,超過這個值則會被丟包。

    TCP的鏈接狀態(tài)圖

    最后總結(jié)下在定位類似的網(wǎng)絡(luò)問題中一些常規(guī)的命令、工具和關(guān)注的方向

    可以使用以下命令

    推薦使用以下工具

    重點(diǎn)關(guān)注以下指標(biāo)

    點(diǎn)擊下方“閱讀原文”,技術(shù)干貨

    ↓↓

    總結(jié)

    以上是生活随笔為你收集整理的记一次Socket.IO长链服务的性能压测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。