Erlang C1500K長連接推送服務-性能


Whatsapp已經使用Erlang在生產環境跑到96GB內存單機 3M長連接,參加:WhatsApp的Erlang世界。畢竟業務級別能達到Whatsapp那樣極少,現在只有千萬級,單機太多掛一台影響太大,再者就是沒有多線接入,每個機房都得扔那么幾台機器吧,所以1M就能滿足要求。

Erlang 作為長連接網關有着天生的優勢:

- 擅長與IO密集型業務,也要求將網關設計盡量簡單,認證完后,簡單解析報頭,就直接將請求轉發給后端服務處理

- 網絡層有beam c 實現得非常高效 ,erlang 代碼只是簡單流程控制,也就是說代碼性能很接近優化的很好c程序

- 代碼簡單,易維護,erlang 進程和連接一對一關系,代碼500行左右

- 基於進程GC,node 內存多大也不用擔心stop of word

- 熱升級,網關設計本盡量簡單,減少升級,但也不可避免,熱升級保證不斷連接

- 穩定,beam 足夠穩定,即使天天更新的服務,連續一兩年不重啟也正常

- 多語言混合,后端可很容易使用其他語言實現

 

劣勢:CPU密集型業務,性能差,如果不想用c解包,盡量使用二進制協議,盡量將包協議標識放在包體固定位置,方便dispatch

 

1. 測試環境

  - 服務端: R620 2*(E5-2620 6核心12線程)/mem:128GB

  - 客戶端:R620 2*(E5-2620 6核心12線程)/mem:48GB(5台*5 IP,共25IP)

 

2. 調優

  1. beam 啟動參數

  +sbt db 綁定調度器與CPU的親緣性

  +P 2000000 進程數限制(合適即可)

  +K true 啟用epoll

  +sbwt none 關閉beam 調度器 spinlock,降低CPU

  +swt low 提高調度器喚醒靈敏度,避免長時間運行睡死問題

  參考我另外一篇:erlang cpu 相關參數調整

 

  2. Erlang 網絡庫:ranch 需要修改

    - 配置acceptors 數量1024,backlog 32768

    同時系統backlog調整: net.core.somaxconn, net.core.netdev_max_backlog, net.ipv4.tcp_max_syn_backlog 32768

    - 刪除新加連接時的 ranch_sup 和 connection monitor,占用內存且用處不大,同時單進程熱點問題,也造成backlog 無法及時處理

    - acceptor 設置 process_flag(prority, high),否則因為公平調度問題,即使CPU不高,backlog 無法及時得到處理

 

       3. Erlang內存占用

   因為Erlang GC 基於進程,每個連接對應一個進程,每個連接的業務量都很小。那樣就會造成一種現象數百w進程內都有一點垃圾,無法得到GC。

   使用hibernate,erlang:hibernate 會清空但前調用棧,並強制GC,下次進程收到消息后,會通過參數MFA繼續執行。

   使用gen_server 簡單的在沒有個包處理完后,都加上hibernate, CPU無明顯增加情況下,可將內存使用降低到1/3 以下,非常值得使用。

 

3. 壓測場景

  - 客戶端在5台機器,25個IP,開啟 tcp_tw_reuse tcp_tw_recycle 后每個IP穩定跑6w連接還是沒問題的。

  - 6K/s 登陸、認證、心跳、退出 操作

  - 1w/s 消息推送、ack

  - 運行12 小時

 

4. 結果

 ss -s
Total: 1500254 (kernel 1500317)
TCP:   1500090 (estab 1500077, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 74

Transport Total     IP        IPv6
*      1500317   -         -
RAW      0         0         0
UDP      0         0         0
TCP      1500090   1500090   0
INET      1500090   1500090   0
FRAG      0         0         0

 

  網關機器:

  - CPU 500%

  - 網卡 6w/s tcp packet in/out

  - node mem 12GB (內部memory(total) 顯示實際使用9GB)

  - kernel mem 11GB

 

  - 也就是150w連接,使用了23GB內存,每個連接占用15KB,約一半是內核使用,erlang 使用內存並不多。

  - 在如此業務量壓力下,500% CPU表現也不俗,隨無法和c相比,但其多核擴展性好。

  - 服務器有24核心,但環境其他服務、客戶端IP數限制,沒有繼續增大壓力,理論上單機200~300w 連接,5w/s 消息推送 應該不是問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM