Openfire 性能優化


Openfire  是一個XMPP協議的IM Server。

 

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試試,或者和我們一樣,自己寫通訊服務器。

 

 

 以下內容參考文章:http://blog.csdn.net/jinzhencs/article/details/50404574

其他設置以及優化

插件

  • Subscription插件:自動同意好友請求,添加插件后在服務器設置最下面設置方式。

服務器設置

  • 把沒用的一些設置關掉,例如HTTP綁定等等

優化

  • 修改打開最大文件數目:ulimit –n 65535
  • 設置服務器緩存大小,系統屬性加入:
// 注意不能有空格,特別是 size后面
// -1代表無窮大 100000000即是95M
ClientSessionInfoCache:     cache.ClientSessionInfoCache.size
Roster:                     cache.username2roster.size
user:                       cache.userCache.size
group:                      cache.group.size
groupMeta:                  cache.groupMeta.size
offline message:            cache.offlinemessage.size
offlinePresence:            cache.offlinePresence.size
Last Activity Cache:        cache.lastActivity.size
VCard:                      cache.VCard.size
// 以上都是高壓下容易飄紅的

 

 

 

 

 

 

 

 

 要重啟openfire服務才能更新過來哦

 

 

 

未來需要優化的幾個點:

1.加大服務器內存 20G變成150G 2.之前源碼修改的是3.10.2,之后把新版本的源碼下載下來重新修改,而后打包部署. 以解決3.10.2遺留的BUG(現在4.0beta版本出來了,可能過段時間會開源,改了很多bug) 3.根據需求定制openfire,即去除無用的組件,出去無用的消耗資源的一些cache或hashMap,變量之類 4.移出session,把session存入到redis中。 5.除了session,其他的很多cache(服務器緩存)全部移入redis。

 openfire不使用mysql,使用redis作為數據庫存儲數據,再做個mysql持久化及主從就行了。

論壇有牛人說過:openfire使用了它那不知所謂的cache(其實就是HashMap),就注定無法支撐數十萬連接。 
(強哥說了:HashMap存儲超過幾萬后,會有問題,好像是jdk自帶的問題)


另外一個最重要的優化的方面,就是保證連上服務器的是 有用 的用戶。
譬如我們服務器之前連了10W,但是其實真正用戶綁定並使用XX系統的只有1W,但是10W個客戶端卻是連着的。 (舉例子,之前我們的系統就好比進入淘寶后台自動登錄旺旺,那么進淘寶多少人就有多少人登錄了旺旺,但是其實真正使用旺旺的只有十分之一甚至更少,我們只需要讓用戶在需要旺旺對話的時候才連接服務器的話,那么瞬間服務器壓力能減少 90% 這是比任何優化方案都有效的解決方法。是從業務本身去思考並優化,這個需要集思廣益。)







免責聲明!

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



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