关于service-mesh:云原生小课堂-Envoy请求流程源码解析二请求解析

49次阅读

共计 2716 个字符,预计需要花费 7 分钟才能阅读完成。

前言

Envoy 是一款面向 Service Mesh 的高性能网络代理服务。它与应用程序并行运行,通过以平台无关的形式提供通用性能来形象网络。当基础架构中的所有服务流量都通过 Envoy 网格时,通过统一的可观测性,很容易地查看问题区域,调整整体性能。

Envoy 也是 istio 的外围组件之一,以 sidecar 的形式与服务运行在一起,对服务的流量进行拦挡转发,具备路由,流量管制等等弱小个性。本系列文章,咱们将不局限于 istio,envoy 的官网文档,从源码级别切入,分享 Envoy 启动、流量劫持、http 申请解决流程的进阶利用实例,深度剖析 Envoy 架构。

本篇是 Envoy 申请流程源码解析的第二篇, 次要分享 Envoy 的 outbound 方向上篇,蕴含启动监听和建设连贯。注:本文中所探讨的 issue 和 pr 基于 21 年 12 月。

envoy 当中基于 libevent 进行封装了各种文件,定时器事件等操作,以及 dispatch 对象的散发,和提早析构,worker 启动,worker listener 绑定等局部不在这里作解读,后续有空能够独自再进行剖析。跳过 envoy 当中的事件循环模型,这里以申请触发开始。

outbound 方向

filter 解析

启动监听

  1. 通过 xDS 或者动态配置,取得 Envoy 代理的监听器信息
  2. 如果监听器 bind_to_port,则间接调用 libevent 的接口,绑定监听,回调函数设置为 ListenerImpl::listenCallback

对于 reuseport

  1. https://github.com/envoyproxy…
  2. https://github.com/envoyproxy…
  3. https://lwn.net/Articles/542629/
  4. https://tech.flipkart.com/lin…

多个 server socket 监听雷同的端口。每个 server socket 对应一个监听线程。内核 TCP 栈接管到客户端建设连贯申请 (SYN) 时,按 TCP 4 元组(srcIP,srcPort,destIP,destPort) hash 算法,抉择一个监听线程,唤醒之。新连贯绑定到被唤醒的线程。所以绝对于非 SO_REUSEPORT,连贯更为均匀地散布到线程中(hash 算法不是相对均匀)

envoy 当中是反对在 listener 去设置开启这个个性,然而热重启场景时,对内核版本有肯定要求(4.19-rc1)

https://www.envoyproxy.io/doc…

验证察看

默认未开启,通过 envoyfilter 进行开启后,可见 15001 的端口被开启


须要重启 POD

而对于没有利用 reuseport

大抵的均匀

对于相对的链接均衡,能够试试 Listener 的配置 connection_balance_config:exact_balance,不过因为有锁,对高频新连贯应该有肯定的性能损耗。目前只实用于 TCP 监听器


建设连贯

  1. DispatcherImpl 通过 libevent,接管到申请,调用 ListenerImpl::listenCallback
  2. client 向 envoy 发动连贯,envoy 的 worker 接管 eventloop 的 callback,触发 Envoy::Network::ListenerImpl::listenCallback(port: 15001)
  3. 15001 的 useOriginalDst”: true,accept_filters_中会带有 OriginalDstFilter
  4. 在 OriginalDstFilter.OnAccept 中用 os_syscalls.getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, &orig_addr, &addr_len)获取在 iptables 批改之前 dst ip iptables 与 getsockopt

  1. 在 newconnection 当中,还会通过 getBalancedHandlerByAddress 寻找到理论的虚构 listener

  1. 通过 ConnectionHandlerImpl::findActiveListenerByTag

查到 addr 对应的 Listener

● 先查找 Listener.IP==addr.ip && Listener.Port==addr.port 的 Listener

● 再查找 Listener.IP==0.0.0.0 && Listener.Port==addr.port 的 Listener (对于 tcp 服务,ip 会有值,对于 http 服务,ip 为 4 个 0)

  1. dispatcher.createServerConnection 传入 accept 到的 fd 创立 Server 连贯对象 ConnectionImpl,并把 onFileEvent 注册到 eventloop,期待读写事件的到来,因为 socket 是由一个 non-blocking listening socket 创立而来,所以也是 non-blocking
  2. 且注册的触发形式为 epoll 的边缘触发

  1. http 的 listener 里 filters 为 envoy.http_connection_manager,buildFilterChain 里会把 HTTP::ConnectionManagerImpl 退出到 upstream_filters_(list)中,这样在申请数据达到的时候,就能够应用 http_connection_manager 的 on_read 办法

  1. 当连贯刚刚退出 eventloop 的时候,Write Event 会被立刻触发,但因为 write_buffer_没有数据,所以不会写入任何数据

ASM 试用申请

Envoy 是 Istio 中的 Sidecar 官网标配,是一个面向 Service Mesh 的高性能网络代理服务。

以后 Service Mesh 是 Kubernetes 上微服务治理的最佳实际,灵雀云微服务治理平台 Alauda Service Mesh(简称:ASM)可残缺笼罩微服务落地所须要的基础设施,让开发者真正聚焦业务。

如果您想深刻体验 ASM,扫描下方二维码即可报名!

对于【云原生小课堂】

【云原生小课堂】是由灵雀云、Kube-OVN 社区、云原生技术社区联结开设的公益性技术分享类专题,将以丰盛详实的精品内容和灵活多样的出现模式,继续为您分享云原生前沿技术,带您理解更多云原生实际干货。
在数字化转型的背景下,云原生曾经成为企业翻新倒退的外围驱动力。作为国内最早将 Kubernetes 产品化的厂商之一,灵雀云从出世便携带“云原生基因”,致力于通过革命性的技术帮忙企业实现数字化转型,咱们期待着云原生给这个世界带来更多扭转。关注咱们,学习更多云原生常识,一起让扭转产生。

正文完
 0