<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      即時通信服務器架構的一些思考

      對于一個即時通信服務器來說,在用戶量少的時候,一臺服務器就足以提供所有的服務。而這種架構也最簡單,舉個例子,用戶A與用戶B互為好友,A向B發消息,服務器接收到消息時,解析出接收消息的人,直接轉發給B即可。可是當用戶數量越來越多時,一臺服務器已經無法所有用戶的需求,這時就要進行服務擴容,進行分布式部署

                                               

      如圖所示,不同的用戶可能登錄到不同的服務器上,那么用戶A給用戶B發消息時,服務器收到消息,首先判斷B是否也登錄在本服務器上,如果是,那么直接轉發消息即可。如果B不在本服務器上,那應該往哪里轉發這條消息呢?最簡單的做法就是向服務器集群中的其他服務器廣播這條消息,對于每個收到這條消息的服務器,首先判斷消息的目的用戶是否登錄在自己身上,如果不是,直接忽略該消息。如果是,那么向目的用戶轉發該消息。固然,這種暴力粗獷的做法是最簡單直接的,但是會產生很多無效的消息轉發,對于服務器性能產生很大的影響。曾看過蘑菇街開源的即時通信軟件Teamtalk的代碼,服務器就是這種實現方式。其服務器架構如下:

                                         

                                                    

      不同的msg服務器連接到同一臺route server上,所有msg服務器之間的轉發全部通過route server。這無疑會加重route server的負載。即時msg server部署的再多,根據木桶理論,一個系統的性能是由其最薄弱的環節所決定的。所以也注定這樣的架構,其系統容量也是有限的。那么如何改善這種系統呢,很明顯服務器之間的消息轉發不能直接全部廣播,而應該有一套明確的路由系統,即服務器在轉發消息時,應該知道這條消息應該轉發到哪一臺服務器,這樣就不需要每條消息都在所有服務器之間廣播了。

      那么如何實現這樣一套路由系統呢?

      簡單的做法是,每個用戶上線時,通過其連接的msg server向其他所有msg server廣播自己的登錄信息,告知其他服務器自己登錄在哪臺服務器上面。這樣當某個用戶向其好友發消息時,首先通過好友id查看其登錄的msg server。如果好友與自己是同一臺服務器,那么直接轉發即可;如果不是,服務器向route server發送轉發該消息,并且帶上目標msg server的id.這樣route server 收到消息后,解析出目標的msg server,進行一次轉發即可,省去了大量的廣播消息。這種方式雖然解決了廣播消息的問題,但是在每臺msg server上都要保存所有用戶的路由信息。當所有用戶都登錄時,幾乎就退化成了單點模型,msg server肯定承受不了。

      那么如何解決這個問題呢?試想一下,既然所有的msg server上都保存著同樣的路由信息,那么我們可以把這些數據從msg server剝離出來,存在一個單獨的服務器上,供msg server查詢。我們暫且把這個服務器叫做route info server(路由信息服務器).對于一個用戶要存儲的數據為

      {

         userid,

         msgserverid

      }

      假設這兩個數據都是32Byte,那么存儲一億個用戶需要的內存32B*10^8=3.2G。目前好點的服務器都有50G的內存,很顯然內存不是問題。那么就剩訪問量的問題。如果所有的msg server都從這一臺服務器上讀取數據, 肯定會影響整個系統的性能。所以路由信息服務器不能采用這種單點模型。考慮到這種路由信息的特點,很明顯是一種讀多寫少的數據。一個用戶只有在登錄的時候才會寫一次路由信息,其他時候就是轉發消息的時候讀取路由信息了。那么可以采用類似數據庫的主備模型,主服務器用來寫路由信息,備服務器用于查詢路由信息。而且可以設置多臺備服務器,分擔msg server的讀壓力。其實我們也可以使用一些成熟的緩存系統來完成路由信息服務器的功能,比如redis. redis擁有現成的主備方案,只是像這種通用的緩存服務器在存儲數據時,消耗的內存會大些。研究過redis源碼的,大多都能理解。其key value都存儲在redisobject的結構體當中,有一些附加的信息,所以比自己寫一個這樣的服務所消耗的內存肯定會大些。

      OK,說完了路由信息服務器,我們再回到msg server上來。那么msg server在轉發消息時,首先根據目的用戶的id 到路由信息服務器上查找其所在的msg server用于消息轉發。但是這也會存在一個,每次轉發消息時,都要查詢一次路由信息,這無疑會影響消息的轉發速度,而且也會增大路由信息服務器的訪問壓力。如果在發送消息之后,將路由信息保存到本地,那么下次發送消息,就無需再去路由信息服務器重復查詢了。但是也不能把所有的路由全部保存到本地,那樣又會嚴重消耗msg server的內存。于是,就有我們想到一種折中的方案,使用一個lru的緩存隊列,在需要保存新的路由信息時,首先查看緩存隊列是否已滿,如果未滿,直接插入到隊首,如果隊列已滿,淘汰到隊尾的數據。緩存列隊大小可根據內存大小靈活設置。考慮到在我們平時在使用qq時,大部分人都登錄著,但是發消息的人并不多。對于路由信息,在其首次轉發消息是,從路由信息服務器查詢一次路由,在其整個回話過程中,路由信息都緩存在本地。在其會話結束后,將最近最久未使用的路由數據淘汰出去,這種做法再考慮到內存使用的同時,又大大減少了服務器的訪問次數,算是一種較好的折中方案. 在完成了路由信息系統之后,route server也可以進行水平擴展,route server要做的僅僅是轉發消息,并不需要存儲數據,擴展起來非常方便。最終的系統架構如下:

       

                                 

      總結:

      1. 本文所描述的即時通信服務器架構,著重討論的是消息如何路由的問題,但這并不代表一個完整的即時通信服務器系統,諸如注冊,登錄,離線消息,文件等功能這些都未在本文的討論范圍之類

      2. 本文中所提的方案也是一種設想,并未真正進行實現,肯定也有很多細節問題沒有考慮到。歡迎大家留言討論

      3. 對于本文所提的系統,可稱之為一個服務集群。而像qq這樣數量用戶的系統,在全國分布了很多個集群。本文所討論的也僅僅局限于一個集群內的通信設計,而集群之間的通信又如何通信呢。每個集群的路由數據,如果全同步到其他集群,這種做法顯然不是最優。如果有更好的想法,也歡迎留言討論

      posted @ 2016-11-19 17:51  myd620  閱讀(18427)  評論(50)    收藏  舉報
      主站蜘蛛池模板: 波多野结衣无内裤护士| 日韩久久久久久中文人妻| 伊人欧美在线| 国产首页一区二区不卡| 日韩熟女乱综合一区二区| 国产精品乱人伦一区二区| 免费人成网上在线观看网址| 无套内谢少妇高清毛片| 日韩av在线不卡一区二区| 国产精品国产自产拍高清| 日本不卡三区| 国产日韩一区二区在线| 福利一区二区不卡国产| 国产一级av在线播放| 亚洲AV日韩AV激情亚洲| 色噜噜一区二区三区| 国产a在视频线精品视频下载 | 国内精品亚洲成av人片| 亚洲av色香蕉一区二区三| 久久精品国产亚洲AV成人毛片| 久久精品免视看国产成人| 内射合集对白在线| 四虎国产精品永久入口| 中国女人和老外的毛片| 豆国产97在线 | 亚洲| 五月婷之久久综合丝袜美腿| 亚洲国产一区二区三区久| 2021亚洲国产精品无码| 久久无码中文字幕免费影院蜜桃| 无码国产偷倩在线播放| 欧美激情精品久久| 亚洲中文字幕人妻系列| 性色av一区二区三区精品| 久久高潮少妇视频免费| 丰满少妇高潮无套内谢| 日本高清视频网站www| 亚州中文字幕一区二区| 亚洲日韩欧洲乱码av夜夜摸| 国产区一区二区现看视频| 麻豆亚州无矿码专区视频| 永久免费AV无码网站YY|