2012-03-25 52 views
1

使用EC2實例(以及Amazon Auto Scaling和Elastic Load Balancing)我有幾個在Amazon Web Services中運行的TCP服務器實例。每個EC2實例都有權訪問集中式數據庫(在Amazon RDS上運行)。爲了使這個後端可擴展,新的EC2實例(TCP服務器的實例)根據需求進行放大和縮小。在EC2實例上擴展TCP服務器的分佈式問題

服務器已經使用Python Twisted框架製造。該系統支持自定義即時消息服務,可以加入多個羣聊。

當用戶開始使用服務時,他們與其中一個TCP服務器建立TCP套接字。每個服務器在內存中存儲當前連接的用戶(即,開放的TCP套接字)以及每個用戶當前「進入」(並因此訂閱)的「羣組聊天」。所有創建的聊天數據都存儲在數據庫中。

的問題

當用戶A職位GroupChatZ消息,所有用戶在「GroupChatZ應收到該郵件。如果只有一個TCP服務器,這很簡單:它將在'該羣組聊天'中爲其所有用戶搜索內存並向他們發送新消息。但是,由於存在多個服務器,因此在創建新消息時,該服務器必須將消息傳遞給所有其他服務器(即EC2實例)。

這個問題最有效的解決方案是什麼? 也許使用AWS組件。


一個解決方案,我能想到的是爲每個服務器來存儲它的IP地址在數據庫中時,第一次啓動,並得到其他所有連接的服務器的IP地址和與他們建立TCP連接。當收到每條新消息時,處理該消息的服務器可以將其發送給所連接的所有其他服務器。

但是,TCP連接不是100%可靠的,這種解決方案增加了複雜性。


我懷疑居然還有使用一些Amazon Web服務組件來實現一個簡單的用戶,出版商型機制的好辦法(認爲Observer設計模式)。即其中一臺服務器添加了一些其他服務器實時收到的信息。

+0

快速更新,我剛剛開始關注Amazon SNS並創建每個Twisted服務器將訂閱的主題。迄今爲止的結果看起來很有希望 – 2012-03-27 01:27:23

回答

0

不僅是TCP連接不是100%可靠的,EC2實例也不是。他們可以隨時消失(並相信我,他們有時會這樣做)。實例的內部IP地址也可能會發生變化(例如,如果它重新啓動)。如果您使用彈性IP地址,則來自AWS數據中心外部的連接(例如聊天客戶端)將具有穩定(一組)IP連接。但是,使用彈性IP在服務器之間進行通信的速度相對較慢,因爲連接路由到AWS防火牆之外,然後返回(上次無論如何檢查)。

這裏有一些策略來考慮:

  1. 使用較大的EC2實例,可以處理所有的連接,具有雙機熱備,如果您的可用性要求,從而決定。如果知道流量的上限(例如,如果這是一個企業聊天應用程序而不是面向互聯網的應用程序),那麼您可能會發現擴展比擴展更便宜,如果它可以極大地簡化您的工程設計工作,則可以擴展。

  2. 如果您決定仍想擴展,請考慮使用事務性的分佈式緩存(例如EH Cache)來存儲聊天數據。這類問題已經解決。您將花費大量工程時間來處理已建立的分佈式緩存之一已處理的所有情況。

+0

單個EC2實例沒有冗餘。您如何使配置更改或部署保持高可用性?緩存的想法是一個很好的例子。 – Diego 2012-03-25 18:00:21

+0

@Diego:如果他需要高可用性,他需要一個反映主服務器當前狀態的熱備份(選項#1)。如果在服務器停機的情況下可以容忍5到10分鐘的停機時間,那麼就可以擁有一個基於EBS的AMI,它可以在啓動時知道如何從DB初始化聊天狀態。它將接管原始服務器的彈性IP(可以在啓動時編寫腳本)。 – 2012-03-25 18:14:07

0

我認爲Amazon SQS(簡單隊列系統)可以提供幫助。您爲每個服務器創建一個消息隊列。收到消息時,服務器將消息放入每個服務器的隊列中。服務器頻繁地輪詢新消息的隊列。如果服務器抓取指向未連接到該用戶的用戶的消息,則該消息將被忽略,否則將被傳遞。