看了一下源碼,無(wú)論是向單個(gè) uid,向群組還是向全部,都會(huì)向所有的 gateway 進(jìn)程發(fā)送消息,如果是單個(gè)或者群組,每個(gè) gateway 自己尋找當(dāng)前進(jìn)程中是否有指定用戶的連接,然后向這個(gè)鏈接發(fā)送消息。
這樣的話,假定連接數(shù)非常多,gateway 進(jìn)程也很多,比如有 1000 個(gè) gateway 進(jìn)程,那每次向指定的一個(gè)人發(fā)送都會(huì)向這 1000 個(gè)進(jìn)程發(fā)一次消息,然后只有其中一個(gè)進(jìn)程會(huì)向用戶發(fā)數(shù)據(jù),而其它999個(gè)進(jìn)程檢查當(dāng)前進(jìn)程沒有此連接后忽略,也就是說(shuō) BusinessWorker 進(jìn)程發(fā)到 Gateway 的數(shù)據(jù)中,有999份是浪費(fèi)無(wú)用的,只有1份是正常的。
這種做法感覺有很大的性能和內(nèi)部流量浪費(fèi),有沒有什么辦法能改進(jìn) GatewayWorker 讓向指定的某些用戶發(fā)消息時(shí)能具體定位到指定的 gateway 進(jìn)程,而不是向其它無(wú)關(guān)的進(jìn)程都發(fā)送呢?
假如這個(gè)服務(wù)全球七十多億人,假定一個(gè)進(jìn)程能維護(hù)10萬(wàn)的連接,也要7千個(gè)進(jìn)程,那向一個(gè)人發(fā)送消息,就會(huì)導(dǎo)致 6999 個(gè)浪費(fèi),多么可怕。。。。
如果是1000個(gè)gateway進(jìn)程,說(shuō)明是一個(gè)比較繁忙的系統(tǒng)了。
用sendToUid是會(huì)有浪費(fèi),可以自己做綁定,方法類似如下
新的bindUid內(nèi)部機(jī)制改為 將uid和client_id的映射關(guān)系存儲(chǔ)起來(lái)(redis集群等都可以)。
新的sendToUid機(jī)制改為 把uid對(duì)應(yīng)的client_id取出來(lái),然后Gateway::sendToAll發(fā)送,不會(huì)有任何的通訊浪費(fèi)。
不過99.9%的業(yè)務(wù)沒有1000個(gè)進(jìn)程那么大的量,更不用說(shuō)七十多億人了。
目前的GatewayWorker能滿足絕大多數(shù)業(yè)務(wù)場(chǎng)景的量級(jí)了,不用考慮這些。
另外手冊(cè)有建議gatewaway進(jìn)程數(shù)和cpu核數(shù)想等,所以gateway進(jìn)程數(shù)不會(huì)很多,每個(gè)cpu處理一個(gè)gateway進(jìn)程,還是小菜一碟。
其實(shí)gatewayWorker瓶頸不是這里,而是當(dāng)有大量廣播或者群租發(fā)送時(shí),產(chǎn)生的巨大流量,可以輕松把網(wǎng)卡打滿,所以當(dāng)用戶量很大時(shí),需要考慮如何避免頻繁的廣播或者群組發(fā)送。
那假如這么多個(gè)進(jìn)程都去連 redis 集群,在消息有可能傳遞給任何人的情況下,進(jìn)程與 redis 之間的連接數(shù)有沒有可能成為瓶頸呢。。