前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解析envoy处理http请求(下):事件模型和连接管理

解析envoy处理http请求(下):事件模型和连接管理

作者头像
灵雀云
发布2019-07-30 16:47:39
2.4K0
发布2019-07-30 16:47:39
举报
文章被收录于专栏:云原生技术社区

Envoy是istio的核心组件之一,以sidecar的方式与服务运行在一起,对服务的流量进行拦截转发。 具有路由,流量控制等等强大特性。 本文以istio1.1所对应的Envoy版本进行源码流程分析。

Envoy并发架构

摘自 https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310

  • Envoy进程由一个Main Thread和多个Worker Thread 组成
  • 每个Main和Worker包含一个eventloop,所有的处理都是由eventloop触发开始
  • Main负责xDS等功能,Worker负责处理连接和请求
  • 当一个client向Envoy建立连接的时候,因为所有Worker的EventLoop都注册了listening fd,会由内核决定分配给哪个Worker
  • 当一个下游client连接到了Envoy,在保持连接不断的情况下,会和同一个Worker进行通讯

libevent函数

  • evconnlistener_new 把一个 已经bind port 的listening fd和callback注册到eventloop,当accept到新连接的时候会触发callback。Envoy里面采用这个函数把同一个listening fd注册到所有的Worker的eventloop中,当新连接来的时候,由内核选择应该分发给哪个Worker
  • event_assign 把一个fd和一个callback注册到eventloop,当read write closed事件触发的时候触发callback
  • event_active 立即触发一个eventloop中的event,执行callbac

事件触发各阶段

1. client向Envoy建立连接

2. client发送请求到Envoy,Envoy挑选节点向上游Server建立连接(如果连接池有空闲连接直接发送请求)

3. Envoy向上游建连接成功,发送请求

4. 上游server返回响应给Envoy

5. Envoy返回请求给下游的client

Cluster管理 (HTTP1)

层次结构图

  • 上面的实线表示下方的头部是上方的属性之一
  • 虚线表示两者相关
  • ClusterManagerImpl是Envoy内的单例,用于管理多个Worker上ThreadLocalClusterManagerImpl
  • ThreadLocalCusterManagerImpl 每个Worker都拥有一个,用于管理上游的连接和负载均衡上下文

连接结构简介

1. 负载均衡器只挑选host,然后会从conn_pool_map取出对应host的连接池

2.每个worker都都包含自己独立的连接池和负载均衡上下文

(此处有发现设置RoundRobin负载均衡策略的时候,只有client保持长连接(不换worker)的情况下,才是严格的轮询)

3.同一个上游节点的不同协议(http10, http11, http2, tcp)的连接池都是分开的 连接管理

对于同一个Worker,同一个Host,同一个协议,Envoy会维护一个连接池,连接池中http1有关属性如下(一下情况没有对Limit做说明,实际各个阶段会有stats和config limit来进行限制):

  • busy_clients_ 当前发送了请求,还没处理响应的connection

变多:

-有新的请求需要发送的时候,如果ready_clients非空, 就会把ready_clients_.front()移到busy_clients.front(), 并发送请求;

-向上游的连接connected时,如果 (!pending_requests_.empty() && !ready_clients_.empty()) 就会把ready_clients_.front() 移到busy_clients_;

-当有连接close的时候,如果pending_requests_.size() > (ready_clients_.size() + busy_clients_.size()),就会创建新的connection到busy_clients_并发送请求;

变少: -connpool被删除,busy_clients_会被清空; -连接关闭时,如果是正在包含stream_wrapper (正在发送请求)的client,就会从busy_clients移除;

  • ready_clients_ 空闲连接

变多: -((连接connected的时候 || 有响应完成的时候) && pending_requests_ 为空) ,就会加入ready_clients 变少: -在有新的请求需要发送的时候,如果ready_clients非空, 就会把ready_clients_.front()移到busy_clients.front()

-向上游的连接connected时,如果 (!pending_requests_.empty() && !ready_clients_.empty()) 就会把ready_clients_.front() 移到busy_clients_

-connpool被删除,ready_clients_会被清空

-空闲的连接被关闭的时候,会从ready_clients_ 中移除

  • pending_requests_ 代发送的请求

变多: -ready_clients 为空的时候,有新的请求,就会加入到pending_requests

变少: -当上游连接connected时,发送请求到连接,并从pending_requests 中移除 -请求被终止的时候(超时,或者收到上游的响应结束 ),就会从pending_requests 中移除

总结

1.每个Worker的连接池和负载均衡上下文都是独立的。

2.连接池内的连接都是同一worker,同一upstream host,同一协议。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云原生技术社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Envoy并发架构
  • libevent函数
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档