rabbitmq最大连接数(Socket Descriptors)
RabbitMQ自帶了顯示能夠接受的最大連接數,有2種比較直觀的方式:
1. rabbitmqctl命令。
| 1 2 3 4 5 6 7 8 9 10 11 12 | <span style="color: rgb(102, 102, 102);">n$ </span>rabbitmqctl status Status of node <span style="color: rgb(255, 0, 0);">'rabbit@10-101-17-13'</span> ... <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(122, 8, 116); "><strong>{</strong></span>pid,23658<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,......<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>file_descriptors,<span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(122, 8, 116); "><strong>{</strong></span>total_limit,924<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>total_used,10<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>sockets_limit,829<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>sockets_used,10<span style="color: rgb(122, 8, 116); "><strong>}</strong></span><span style="color: rgb(122, 8, 116); "><strong>]</strong></span><span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,...... <span style="color: rgb(122, 8, 116); "><strong>]</strong></span> ...done. |
2. rabbitmq_management WebUI插件。
本文關注當RabbitMQ可用連接數耗盡時客戶端的影響以及如何增加最大連接數默認值。
RabbitMQ的socket連接數(socket descriptors)是文件描述符(file descriptors,fd)的一個子集。也就是說,RabbitMQ能同時打開的最大連接數和最大文件句柄數(文件系統,管道)都是受限于操作系統關于文件描述符數量的設置,兩者是此消彼長的關系。初始時,可用socket描述符與可用fd數量的比率大概在0.8-0.9左右,這個值并不固定,當socket描述符有剩余時,RabbitMQ會使用盡量多的文件描述符用于磁盤文件讀寫。隨著服務器建立越來越多的socket連接,文件句柄開始回收,數量減少。總之,RabbitMQ會優先將文件描述符用于建立socket連接,寧可犧牲頻繁打開/關閉文件帶來的磁盤操作性能損耗,這種取舍很容易理解,作為網絡服務器,當然優先保障網絡吞吐率了。因此,對于高并發連接數的多隊列讀寫時,隊列性能會稍微差那么一點,比如用RabbitMQ做RPC。
當服務器建立的socket連接已經達到限制(sockets_limit)時,服務器不再接受新連接。這里要區分清楚,RabbitMQ不再接收的是AMQP連接,而不是傳輸層的TCP連接,通過簡單抓包分析即可清楚流程:
| 1 2 3 4 5 6 7 8 | $ <span style="color: rgb(194, 12, 185); "><strong>sudo</strong></span> tcpdump host 10.101.17.13 and port 5672 17:24:12.214186 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>S<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 3319779561, win 65535, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>mss 1368,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,wscale 5,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006381554 ecr 0,sackOK,eol<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0 17:24:12.214231 IP 10.101.17.13.amqp <span style="font-weight: bold;">></span> 10.101.17.166.56925: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>S.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 1636058035, ack 3319779562, win 14480, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>mss 1460,sackOK,TS val 24529834 ecr 1006381554,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,wscale 5<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0 17:24:12.218795 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, ack 1, win 4110, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006381560 ecr 24529834<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0 17:24:12.243184 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>P.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 1:9, ack 1, win 4110, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006381583 ecr 24529834<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 8 17:24:12.243201 IP 10.101.17.13.amqp <span style="font-weight: bold;">></span> 10.101.17.166.56925: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, ack 9, win 453, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 24529841 ecr 1006381583<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0 17:24:22.247907 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>F.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 9, ack 1, win 4110, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006391550 ecr 24529841<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0 17:24:22.284914 IP 10.101.17.13.amqp <span style="font-weight: bold;">></span> 10.101.17.166.56925: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, ack 10, win 453, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 24532352 ecr 1006391550<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0 |
line 2-4是TCP握手包,成功建立TCP連接。line 5開始客戶端向服務器端發送AMQP協議頭字符串“AMQP0091”,共8個字節,開始AMQP握手。line 6是服務器回給客戶端的ack包,但未發送AMQP connection.start方法,導致客戶端一直等到超時(line 7-8),發送FIN包關閉TCP連接。至此,AMQP連接建立失敗。
從客戶端(Java SDK)來看上述這個過程,客戶端通過ConnectionFactory實例的newConnection()方法創建一條AMQP連接。在網絡層,它首先通過java.net.Socket與服務器建立一條TCP連接,發送協議協商字符串“AMQP0091”,然后啟動MainLoop線程,通過封裝的Frame實例來循環讀取幀(readFrame()),注意readFrame()方法可能會有一個SocketTimeoutException的超時異常,這個超時時間是由socket實例setSoTimeout方法寫入,默認是10s,由AMQConnection.HANDSHAKE_TIMEOUT常量指定。當超時發生在AMQP連接握手階段時,就拋出一個SocketTimeoutException異常,發生在其他階段(除心跳超時)時,什么都不做繼續下一個循環:
| 1 2 3 4 | [java]?view plaincopy |
這里的socket讀取超時很容易跟連接超時搞混。連接超時由ConnectionFactory實例的setConnectionTimeout()方法指定,對應著網絡層Socket實例connect()方法中的timeout參數,指的是完成TCP三次握手的超時時間;而讀取超時是從socket中讀取字節流的等待時間,前文已經說過,由Socket實例的setSoTimeout()指定。這在各種網絡庫中應該很常見,比如HttpClient。
私以為這種情況下更好的設計是應該由RabbitMQ主動斷開與客戶端的TCP連接,減少客戶端等待時間。
最后一個問題,如何增加RabbitMQ的能夠同時打開的連接數。通過前文可知,最大并發連接數由此進程可打開的最大文件描述符數量(乘以一個比例系數)決定,因此只要增加單個進程可打開的文件描述符數量即可。有幾個常規方法,按作用范圍可以歸納為以下幾類:
1. 進程級別。在啟動腳本rabbitmq-server中加入ulimit -n 10240命令(假設將最大文件描述符數量設置為10240,下同),相當于在shell中執行,由此shell進程fork出來的進程都能繼承這個配置。
2. 用戶級別。修改/etc/security/limits.conf文件,添加以下配置,重新登錄生效:
| 1 2 | user soft nofile 10240 user hard nofile 10240 |
3. 系統級別。
| 1 | <span style="color: rgb(102, 102, 102);"># </span><span style="color: rgb(122, 8, 116); "><strong>echo</strong></span> 10240 <span style="font-weight: bold;">></span> <span style="font-weight: bold;">/</span>proc<span style="font-weight: bold;">/</span>sys<span style="font-weight: bold;">/</span>fs<span style="font-weight: bold;">/</span>file-max |
上述設置只是針對proc文件系統,相當于修改了操作系統的運行時參數,重啟后失效。要想永久生效,需要修改/etc/sysctl.conf文件,加入配置項fs.file-max=10240。
一個進程能打開的最大文件描述符數量受限于上述三個級別配置中的最小值。理論上,系統級別的配置數值必須要大于用戶級別,用戶級別的要大于進程級別的,只有這樣配置才是安全的,否則進程容易因為打開文件數量問題受到來自操作系統的種種限制。操作系統為什么要限制可打開的文件描述符數量?為了系統安全。因為文件描述符本質上是一種內存中的數據結構,如果不加以限制,很容易被進程無意或惡意耗盡內存,比如fork bomb。
轉載于:https://www.cnblogs.com/405845829qq/p/6490343.html
總結
以上是生活随笔為你收集整理的rabbitmq最大连接数(Socket Descriptors)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core MVC上传、导
- 下一篇: bzoj3589 动态树