envoy 代办 socket.io

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 ?

这和我们是完成计划有关, 下面是我们的效劳简朴的布置拓扑。

《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 和 背景竖立衔接的状况。

    原文作者:Allenchen
    原文地址: https://segmentfault.com/a/1190000017751461
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞