转 Openfire 性能优化
Openfire 性能優化
2012年05月28日 星期一 15:58
http://blog.csdn.net/smm11230704/article/details/7468010
?
Openfire? 是一個XMPP協議的IM Server。
基于MINA的java nio服務器。
一般就是使用mysql來作為數據庫,保存配置配置信息、離線信息、用戶數據。
官網的數據是支持5000人同時在線,使用connectionManager可以實現支持3.3萬人在線。
這數據一點都不漂亮,只能作為一個類似騰訊通的局域網聊天工具使用。
首先說點題外話,我測試用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試試,盡管我沒試過,不過看過源碼,覺得還是比較可靠。
或者和我們一樣,自己寫通訊服務器。
轉載于:https://my.oschina.net/vdroid/blog/171386
總結
以上是生活随笔為你收集整理的转 Openfire 性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速排序算法-php实现
- 下一篇: Java数据解析---PULL