WebSocket是一種在單個TCP串連上提供全雙工系統通訊渠道的網路通訊協定。WebSocket的設計使得用戶端和伺服器之間可以實現持久串連,都能夠主動地向對方發送資料或接收資料,減少了頻繁建立串連的開銷和延遲,這通常比傳統的HTTP請求和響應模式更高效。WebSocket主要應用於需要即時通訊功能的情境,ALB預設支援WebSocket協議。
WebSocket簡介
為什麼使用WebSocket
隨著互連網技術的迅速發展,Web應用的多樣化趨勢日益顯著,其中不少應用情境,例如直播間聊天室、即時彈幕等,都需要伺服器具備即時推送資料的能力。傳統的實現方式是通過輪詢技術,即用戶端瀏覽器在固定的時間間隔(例如每1秒)向伺服器發起HTTP請求,伺服器隨後將最新資料返回給用戶端。然而,這種模式存在顯著的不足,用戶端需要頻繁地發起請求,而HTTP請求的頭部資訊通常較長,有效資料卻相對較少,這不僅增加了伺服器的負擔,也造成了頻寬資源的極大浪費。
為瞭解決這些問題,HTML5引入了WebSocket協議,它為伺服器與用戶端之間的通訊提供了更為高效的解決方案。WebSocket協議支援全雙工系統通訊,這意味著伺服器和用戶端可以同時進行資料的發送和接收,從而允許伺服器在有新資料時主動推送給用戶端,無需用戶端不斷輪詢。這種雙向即時通訊機制顯著提高了資料轉送的效率,減少不必要的網路請求,有效節省伺服器資源和頻寬,同時為使用者帶來更為流暢和即時的互動體驗。
WebSocket協議的特性
WebSocket通訊前,首先用戶端與伺服器要進行TCP三向交握串連,然後進行一次叫做“握手”的特殊HTTP請求進行協議升級,完成協議升級後原始的HTTP串連被升級到WebSocket串連。在協議升級後,用戶端和伺服器之間的通訊將使用WebSocket協議進行而不再是HTTP,可以在同一個WebSocket串連上進行雙向通訊。
WebSocket串連一旦經過握手協商成功建立,便能維持活躍狀態,使得雙方能如同使用原始通訊端(Socket)那樣進行連續不斷的雙向資料轉送,而不必為每個通訊回合重新發起串連或等待確認。通過WebSocket,用戶端和伺服器之間得以建立一種持久、低延遲的串連,極大地提升了資料交換效率。
WebSocket通過資料幀進行通訊,它有自己的幀協議格式,頭資訊更簡潔,資料可以作為文本或二進位傳輸。這種方式減少了持久串連上額外的協議開銷,允許更高效的網路互動,能夠在節省伺服器資源和頻寬的同時,提供更優質的即時互動體驗。
關於WebSocket協議的更多資訊,可參考官方文檔The WebSocket Protocol。
WebSocket應用情境
WebSocket主要適用於需要快速、即時的雙向通訊的應用情境,例如AI應用、線上聊天室、即時通知系統、多人線上遊戲、即時市場資訊推送等。
情境樣本
某公司需要在阿里雲上部署Web線上聊天應用,使用者可以通過訪問網域名稱來接入後端服務進行即時交流。該應用由於其即時通訊的特性,要求使用者之間的資訊傳遞必須具備低延遲、高效率和雙向即時的特點。
該公司的網站服務面臨的挑戰是高並發與長串連管理。隨著使用者數量的增長,傳統的HTTP模式無法滿足大量使用者同時線上並保持即時通訊的需求,因為每次通訊都需要重建立立串連,這會導致伺服器壓力劇增且效能低下。
在這個情境下,選用ALB結合WebSocket協議,能夠有效解決高並發下的長串連管理問題。通過後端伺服器組多伺服器部署WebSocket應用程式,並使用Redis進行訊息同步,確保服務的高可用性,從而為線上聊天室應用提供了一個可靠、高效的即時資訊推送解決方案。
注意事項
ALB的HTTP監聽預設支援WebSocket協議。ALB預設支援熱更新,即配置變更時不會影響已有長串連。
使用時需要注意如下事項:
若ALB與後端伺服器的串連採用某個版本的HTTP協議(例如HTTP/1.1),建議後端伺服器採用支援同樣HTTP協議版本的Web Server。
HTTP監聽的預設串連請求逾時時間為60秒,即如果ALB與後端服務超過60秒無訊息互動,會主動中斷連線。
如果60秒無法滿足您的需求,您可以通過修改監聽的串連請求逾時時間欄位,調整該時間值。
如果需要維持串連一直不中斷,需要主動實現保活機制,每60秒內進行一次報文互動。
前提條件
已建立公網ALB執行個體。具體操作,請參見建立和管理ALB執行個體。
已準備3個Elastic Compute Service01、ECS02、ECS03。
ECS01、ECS02用於部署WebSocket應用程式,ECS03用於部署Redis。
本文樣本中伺服器作業系統統一為CentOS7.9。
ECS01、ECS02、ECS03建議處於同一安全性群組中。如果分配了不同的安全性群組,注意互相允許存取伺服器需要通訊的連接埠。
操作步驟
步驟一:部署服務
您需要在您的ECS03伺服器中部署Redis,在ECS01、ECS02伺服器中部署WebSocket應用程式。
本文以CentOS 7.9為樣本,示範使用Python快速部署一個簡易的線上聊天室測試服務。樣本僅供參考,實際使用過程中以您自己開發的程式和服務為準。
在ECS03部署Redis服務
登入ECS03伺服器後台。
複製粘貼如下命令,並執行,完成Redis部署與配置。
# 安裝 EPEL (Extra Packages for Enterprise Linux) sudo yum install epel-release -y # 安裝 Redis sudo yum install redis -y # 啟動並啟用 Redis 服務 sudo systemctl start redis sudo systemctl enable redis # 檢查並編輯 Redis 設定檔,允許遠端連線 sudo sed -i 's/^bind 127.0.0.1$/bind 0.0.0.0/' /etc/redis.conf sudo sed -i 's/^protected-mode yes/protected-mode no/' /etc/redis.conf # 重啟 Redis 服務以使更改生效 sudo systemctl restart redis # 檢查 Redis 是否運行 sudo systemctl status redis
命令執行無報錯,並且命令運行完成後,返回如下資訊並顯示Redis服務為active(running)狀態,表示部署與配置成功。
在ECS01中部署WebSocket應用程式
登入ECS01伺服器後台。
執行
sudo pip3 install flask flask-socketio flask-cors redis
,安裝依賴庫。執行
vi ECS01_ws.py
,按i
鍵進入編輯模式。複製並粘貼如下代碼:
按
Esc
鍵,輸入:wq
儲存修改。執行
sudo python3 ECS01_ws.py
命令,運行指令碼。當最後顯示如下執行結果時,表示WebSocket應用程式已啟動,連接埠為5000。
Server initialized for threading. * Serving Flask app 'ECS01_ws' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on all addresses. WARNING: This is a development server. Do not use it in a production deployment. * Running on http://192.168.*.*:5000/ (Press CTRL+C to quit)
如果出現啟動失敗,需要排查下連接埠是否已被佔用,或者命令及代碼是否複製粘貼錯誤。
在ECS02中部署WebSocket應用程式
登入ECS02伺服器後台。
執行
sudo pip3 install flask flask-socketio flask-cors redis
,安裝依賴庫。執行
vi ECS02_ws.py
,按i
鍵進入編輯模式。複製並粘貼如下代碼:
按
Esc
鍵,輸入:wq
儲存修改。執行
sudo python3 ECS02_ws.py
命令,運行指令碼。當最後顯示如下執行結果時,表示WebSocket應用程式已啟動,連接埠為5000。
Server initialized for threading. * Serving Flask app 'ECS02_ws' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on all addresses. WARNING: This is a development server. Do not use it in a production deployment. * Running on http://192.168.*.*:5000/ (Press CTRL+C to quit)
如果出現啟動失敗,需要排查下連接埠是否已被佔用,或者命令及代碼是否複製粘貼錯誤。
步驟二:設定管理員組
在頂部功能表列,選擇執行個體所屬的地區。
在左側導覽列,選擇伺服器組。
單擊建立伺服器組。在建立伺服器組頁面配置以下資訊,其他參數可保持預設值或根據實際情況修改。完成後單擊建立。
配置
說明
伺服器群組類型
選擇伺服器類型。
VPC
選擇後端伺服器即ECS01、ECS02所在的VPC。
後端伺服器需要與ALB執行個體處於同一VPC中。
在彈出的伺服器組建立成功視窗中,單擊添加後端伺服器。
在添加後端伺服器配置頁面,選中ECS01與ECS02並完成添加,注意連接埠需要配置為WebSocket應用程式連接埠。本文程式碼範例中WebSocket應用程式連接埠為5000。
步驟三:配置HTTP監聽
在頂部功能表列,選擇執行個體所屬的地區。
在左側導覽列,選擇執行個體。
在執行個體頁面,找到目標執行個體,然後在操作列單擊建立監聽。
在配置監聽頁面配置以下資訊,其他參數可保持預設值或根據實際情況修改。完成後單擊下一步。
配置
說明
選擇監聽協議
選擇HTTP。
監聽連接埠
本文配置連接埠5000。
在選擇伺服器組頁面配置以下資訊,其他參數可保持預設值或根據實際情況修改。完成後單擊下一步。
配置
說明
選擇伺服器組
選擇此前已建立好的伺服器組。
在組態稽核頁面,檢查配置參數是否有誤,無誤的話單擊提交,等待監聽建立完成。
步驟四:佈建網域名解析
實際業務情境中,建議您使用自有網域名稱,通過CNAME解析的方式將自有網域名稱指向ALB執行個體網域名稱。
在左側導覽列,選擇
在執行個體頁面,複製已建立的ALB執行個體的DNS名稱。
執行以下步驟添加CNAME解析記錄。
說明對於非阿里雲註冊網域名稱,需先將網域名稱添加到雲解析控制台,才可以進行網域名稱解析設定。具體操作,請參見網域名稱管理。如果您是阿里雲註冊的網域名稱,請直接執行以下步驟。
登入網域名稱解析控制台。
在權威網域名稱解析頁面,找到目標網域名稱,在操作列單擊解析設定。
在解析設定頁面,單擊添加記錄。
在添加記錄面板,配置以下資訊完成CNAME解析配置,然後單擊確定。
配置
說明
記錄類型
在下拉式清單中選擇CNAME。
主機記錄
您的網域名稱的首碼。本文輸入@。
說明建立網域名稱為根網域名稱時,主機記錄為
@
。解析請求來源
選擇預設。
記錄值
輸入欄位名對應的CNAME地址,即您複製的ALB執行個體的DNS名稱。
TTL
全稱Time To Live,表示DNS記錄在DNS伺服器上的緩衝時間,本文使用預設值。
步驟五:結果驗證
準備2個不同IP地址的能夠訪問公網的終端電腦,通過在瀏覽器輸入聊天訊息並查看效果,驗證ALB使用WebSocket協議實現資訊即時推送。
在瀏覽器中輸入
http://網域名稱:5000
,訪問線上聊天室應用。頁面訪問成功樣本:
如果您開啟了瀏覽器開發人員工具,您可以在網路或Network頁簽看到,瀏覽器已經在使用WebSocket協議進行通訊。
輸入使用者名稱用於後續聊天互動,完成後單擊設定使用者名稱。
在不同終端電腦中,分別輸入多條聊天訊息並單擊發送,進行測試。
所有瀏覽器中,均可以即時收到訊息。
如上驗證過程表明,通過ALB使用WebSocket協議實現了資訊即時推送,並且實現了高可用。
常見問題
如何使用WebSocket Secure協議?
WebSocket Secure是WebSocket協議的加密版本。
HTTPS監聽預設支援WebSocket Secure協議。您在配置監聽時,選擇使用HTTPS監聽,即可使用WebSocket Secure協議。
使用WebSocket收費嗎?
WebSocket和WebSocket Secure協議不額外收取費用。
哪些地區支援WebSocket?
ALB支援的所有地區,都已支援WebSocket和WebSocket Secure。
相關文檔
本文的樣本中使用了在ECS部署Redis的簡單方式,便於您做業務測試,如果Redis伺服器出現問題可能造成系統單點故障。在實際生產環境中,建議您使用雲資料庫 Tair(相容 Redis),提升應用系統整體高可用性。雲資料庫Tair(相容Redis)如何快速入門?