Openfire 性能優化

Openfire  是一個XMPP協議的IM Server。java

基於MINA的java nio服務器。mysql

通常就是使用mysql來做爲數據庫,保存配置配置信息、離線信息、用戶數據。linux

官網的數據是支持5000人同時在線,使用connectionManager能夠實現支持3.3萬人在線。redis

這數據一點都不漂亮,只能做爲一個相似騰訊通的局域網聊天工具使用。sql

 

首先說點題外話,我測試用connectionManager。數據庫

這是一個openfire提供的鏈接管理器,做用實際上是數據整流。緩存

源碼裏是經過阻塞式多線程將信息經過特定端口與openfire提交數據。服務器

測試以後的結果,這玩意嚴重影響效率,放棄,咱們的目標不僅是3.3萬人。網絡

 

Openfire使用mysql配合它不知所謂幾乎無效的的Cache機制就註定沒法支撐高併發,多線程

因此第一步,將數據庫切換爲比較強一點的MongoDB。

可是MongoDB也是有問題的,在高併發時纔會發現,MongoDB的鎖表十分嚴重,

通過調查發現,MongoDB也比較坑爹,他是使用「全局鎖」的,也就是說,你更新A表的時候,會鎖住B表,數據更新後解鎖。

因此做爲實時查詢數據庫即便是使用MongoDB的master/slave模式依然不能勝任。

 

增長解決方案,緩存層,使用redis做爲MongoDB的數據緩存,在訪問時數據時,首先進入Cache層訪問redis,若是沒有,再去訪問MongoDB,而後再回頭填充Redis。

OK,數據源解決了,接下來確認須要在什麼地方切入。

 

1,首先是將用戶信息數據切換到MongoDB中。並中止Openfire本身的Roster服務,在管理控制檯設置 xmpp.client.roster.active = false

2,AuthProvider,這裏是登錄模塊,能夠繼承接口重寫一個屬於本身的Provider。

重寫authenticate方法,將登錄驗證請求交給cache層。

3,離線信息的存儲在以後也會成爲負擔,那麼繼承OfflineMessageStore類,重寫屬於本身的離線信息策略,將離線信息保存到Redis中。

4,重寫狀態更新的廣播:PresenceUpdateHandler中的broadcastUpdate方法。

 

好了,這時候Openfire已經被修改的面目全非,可是效率已經不可同日而語了。

這時候還有一個問題,就是Openfire沒有消息保障機制,也就是說,網絡不穩定的時候,客戶端異常斷線,信息就會發送到空氣中,

須要再發送信息的時候實現「握手機制」來保障信息的可靠性。不細說了,本身百度。

 

這時候Openfire的在線用戶能夠飈到6W無壓力,可是死活上不去了,又被限制了。

在error.log中會發現相似 「open files too larger」 一類的錯誤,這些是linux系統參數:最大文件打開數。

在linux下執行ulimit -a就能觀察最大的文件打開數,執行ulimit -n 350000設置爲35萬,而後kill掉openfire退出控制檯,從新鏈接控制檯使其生效,從新啓動Openfire。

好吧,這時候用戶量能夠飆6W以上了。

XMPP服務器的測試工具,比較簡單的可使用tsung來實現,簡單的配置,模擬成千上萬的用戶登錄,而且能夠模擬HTTP等其餘請求。

 

接下來就是單臺服務器容量的問題了,咱們服務器是Dell R710, 64G內存 16核CPU,15000轉硬盤。

服務器在這種架構下在線用戶數據在29W左右,幾乎已是單臺Openfire封頂了。

開始考慮集羣,不過Openfire的幾種集羣都測試過,效果不理想,有一個神馬war包的插件,弄上去時好時壞,放棄。

還有一個oracle的集羣插件,不過在高壓下多臺Openfire直接脫離集羣,本身玩本身的了。。。日。

 

若是到了十萬二十萬左右的在線用戶級別,就放棄掉Openfire,能夠嘗試使用tigase試試,儘管我沒試過,不過看過源碼,以爲仍是比較可靠。

或者和咱們同樣,本身寫通信服務器。

相關文章
相關標籤/搜索