资讯专栏INFORMATION COLUMN

envoy 代理 socket.io

王伟廷 / 3021人阅读

摘要:代理最近在做长连接消息通道的方案与实现,目前的方案主要有。后端的是一个服务的集群,上图有个组成的连接管理服务。总体来看,数据经过两次代理,内部代理很简单,配置简单,只要配置和就可以。经测试,可以测试通过。这样就可以成功代理集群了。

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 和 后台建立连接的情况。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100652.html

相关文章

  • envoy 代理socket.io分析

    摘要:抓包的情况补图服务器的抓包情况情况情况其中返回失败可以看到的值是有填的。 client 抓包的情况 (补图) 服务器的抓包情况 service1 情况 showImg(https://segmentfault.com/img/bVbmEiR?w=1485&h=437); service 2 情况 showImg(https://segmentfault.com/img/bVbmEiZ?...

    DrizzleX 评论0 收藏0
  • 如何自建一个k8s ingress 思路

    摘要:如何自建一个思路接入方案我们都知道访问集群的服务需要接入。据我所知,接入的方案有种云厂商提供比如官方的实现第三方实现方案自建,比如使用这里重点记录一下,如何自建一个的思路。控制中心是一个叫的程序,监控对应的,数据代理是有组成。 如何自建一个k8s ingress 思路 ingress 接入方案 我们都知道访问k8s 集群的服务需要ingress 接入。 据我所知,ingress 接入的...

    JiaXinYi 评论0 收藏0
  • 微服务架构下 Service Mesh 会是闪亮的明天吗?

    摘要:以下内容根据魏巍分享整编,希望对大家了解有所帮助。数据平面由一组智能代理组成,代理部署为,其控制微服务之间所有的网络通信。 7月7日,时速云企业级容器 PaaS 技术沙龙第 10 期在上海成功举办,时速云容器架构负责人魏巍为大家详细讲解了 Service Mesh 中代表性的实践方案、并以 Istio 为例详细讲解了 Service Mesh 中的技术关键点,包括 Istio 控制平面...

    hlcfan 评论0 收藏0
  • 微服务架构下 Service Mesh 会是闪亮的明天吗?

    摘要:以下内容根据魏巍分享整编,希望对大家了解有所帮助。数据平面由一组智能代理组成,代理部署为,其控制微服务之间所有的网络通信。 7月7日,时速云企业级容器 PaaS 技术沙龙第 10 期在上海成功举办,时速云容器架构负责人魏巍为大家详细讲解了 Service Mesh 中代表性的实践方案、并以 Istio 为例详细讲解了 Service Mesh 中的技术关键点,包括 Istio 控制平面...

    Anonymous1 评论0 收藏0

发表评论

0条评论

王伟廷

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<