摘要:代理最近在做長連接消息通道的方案與實現,目前的方案主要有。后端的是一個服務的集群,上圖有個組成的連接管理服務。總體來看,數據經過兩次代理,內部代理很簡單,配置簡單,只要配置和就可以。經測試,可以測試通過。這樣就可以成功代理集群了。
envoy 代理 socket.io
最近在做web 長連接消息通道的方案與實現, 目前web 的方案主要有websocket。 后來經過調研發現socket.io 的瀏覽器兼容性更好。于是1. socket.io
使用socket.io 作用通信連接。本文記錄在此過程中遇到的問題。
主要的問題:
envoy 代理socket.io .
socket.io 集成了websocket 和polling,并可以感知瀏覽器的是否支持websocket, 建立websocket 連接,如果不支持websocket
就使用ajax polling. 故兼容性比較好, 具體可以google socket.io.
這和我們是實現方案有關, 下面是我們的服務簡單的部署拓撲。
這個方案是基于mesh service 的sidecar 方式部署, 前面有一個front-Envoy 作為一個接入層。
front-evnoy 其實就是在docker里部署一個envoy。
后端的services 是一個服務的集群, 上圖有2個socket.io service 組成的連接管理服務。
總體來看,數據經過兩次代理,sidecar 內部代理很簡單,配置簡單,只要配置envoy websocket 和http 就可以。
要設置route_config 相應virtual_hosts 設置use_websocket 為true 。
另外一個代里是本文記錄的重點。
就是front-evnoy 到后端的service 集群。 簡單分析可知,socket.io service 其實是一個有狀態的服務, 它一個連接管理器。
假設client A 要使用socket.io 建立長連接, front-envoy 要正常工作必須保證, A 的后續的所用的包都發送到后端的同一個service.
這就是envoy 如何代理socket.io 的問題。
envoy 支持很多很多中負載均衡方式, 但是目前滿足我們需求的只有ring hash 這種負載均衡。
可以參考envoy 文檔
envoy ring hash
ring hash 可以配置一個http header的字段作用hash key.
經考察,我使用了這個x-forwarded-for字段, x-forwarded-for 這字段一般填的是client 的ip.
部分配置如下:
lister 增加 user_remote_address:true
這樣,envoy 會加上remote_address
"listeners": [ { "address": "tcp://0.0.0.0:80", "filters": [ { "type": "read", "name": "http_connection_manager", "config": { "codec_type": "auto", "stat_prefix": "ingress_http", "use_remote_address": true, "idle_timeout_s" : 300, "rds" : { "cluster" : "rds_cluster", ... "route_config": { "virtual_hosts": [ { "name" : "backend", "domains" : ["*"], "routes" : [ { "prefix" : "/", "cluster": "websocket_cluster", "use_websocket": true, "hash_policy": { "header_name": "x-forwarded-for" } } ] } ] }, ... { "name":"websocket_cluster", "type":"static", "connect_timeout_ms":2500, "lb_type":"ring_hash", "ring_hash_lb_config": { "minimum_ring_size": 1024, "use_std_hash": false }, "hosts":[{"url":"tcp://10.10.62.120:3000"},{"url":"tcp://10.10.62.121:3000"}] }4. envoy 代理socket.io 出錯
測試發現,測試有40% 的連接是失敗的。 其中報錯:
/favicon.ico:1 Failed to load resource: the server responded with a status of 404 (Not Found) index.js:83 WebSocket connection to "ws://10.10.62.122/socket.io/? EIO=3&transport=websocket&sid=xiqvvCber8gofbxrAAAA" failed: Error during WebSocket handshake: Unexpected response code: 400 r.doOpen @ index.js:83
表面websocket 建立連接失敗,服務器返回400。
5. 一個解決辦法其實socket.io 后后臺通信,先會建一個http/tcp 發送 poling 請求。
接著,會建立一個新的連接(http/tcp), 通過http upgrade 成一個websocket.
這條新的upgrade 連接,可能會被envoy 代理到另一個service.
還帶了sid 字段。 service 就認為這個不完整的請求,返回400.
socket.io 服務器有一個邏輯, 如果http 請求參數帶了sid, 但是有沒有建立相應的session, 就會返回400
通過修改socket.io transports 優先級可以解決這種情況。
socket.io transport 順序是polling, websocket.
修改客戶端和服務器都修改成為{transports:["websocket", "polling"]})。
client 修改
//var socket = io(); 修改 var socket = io({transports:["websocket", "polling"]});
server 也做對應的修改。
經測試,可以測試通過。
這樣envoy 就可以成功代理socket.io 集群了。
后面有時間寫一下, socket.io 和 后臺建立連接的情況。
。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100652.html
摘要:抓包的情況補圖服務器的抓包情況情況情況其中返回失敗可以看到的值是有填的。 client 抓包的情況 (補圖) 服務器的抓包情況 service1 情況 showImg(https://segmentfault.com/img/bVbmEiR?w=1485&h=437); service 2 情況 showImg(https://segmentfault.com/img/bVbmEiZ?...
摘要:如何自建一個思路接入方案我們都知道訪問集群的服務需要接入。據我所知,接入的方案有種云廠商提供比如官方的實現第三方實現方案自建,比如使用這里重點記錄一下,如何自建一個的思路。控制中心是一個叫的程序,監控對應的,數據代理是有組成。 如何自建一個k8s ingress 思路 ingress 接入方案 我們都知道訪問k8s 集群的服務需要ingress 接入。 據我所知,ingress 接入的...
摘要:以下內容根據魏巍分享整編,希望對大家了解有所幫助。數據平面由一組智能代理組成,代理部署為,其控制微服務之間所有的網絡通信。 7月7日,時速云企業級容器 PaaS 技術沙龍第 10 期在上海成功舉辦,時速云容器架構負責人魏巍為大家詳細講解了 Service Mesh 中代表性的實踐方案、并以 Istio 為例詳細講解了 Service Mesh 中的技術關鍵點,包括 Istio 控制平面...
摘要:以下內容根據魏巍分享整編,希望對大家了解有所幫助。數據平面由一組智能代理組成,代理部署為,其控制微服務之間所有的網絡通信。 7月7日,時速云企業級容器 PaaS 技術沙龍第 10 期在上海成功舉辦,時速云容器架構負責人魏巍為大家詳細講解了 Service Mesh 中代表性的實踐方案、并以 Istio 為例詳細講解了 Service Mesh 中的技術關鍵點,包括 Istio 控制平面...
閱讀 1141·2021-11-23 10:04
閱讀 2401·2021-11-22 15:29
閱讀 2743·2021-11-19 09:40
閱讀 715·2021-09-22 15:26
閱讀 2117·2019-08-29 16:27
閱讀 2484·2019-08-29 16:10
閱讀 1918·2019-08-29 15:43
閱讀 3275·2019-08-29 12:43