envoy 代办 socket.io
近来在做web 长衔接音讯通道的计划与完成, 现在web 的计划重要有websocket。 厥后经由调研发明socket.io 的浏览器兼容性更好。因而
运用socket.io 作用通讯衔接。本文纪录在此过程当中碰到的题目。
重要的题目:
envoy 代办socket.io .
1. socket.io
socket.io 集成了websocket 和polling,并能够感知浏览器的是不是支撑websocket, 竖立websocket 衔接,假如不支撑websocket
就运用ajax polling. 故兼容性比较好, 详细能够google socket.io.
2. 为何会有envoy 代办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 的题目。
3. envoy 的负载平衡
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 和 背景竖立衔接的状况。
。