云原生小课堂 | Envoy请求流程源码解析(二):请求解析

本文深入探讨Envoy代理的outbound方向,讲解如何启动监听和建立连接。通过xDS或静态配置获取监听器信息,利用libevent进行事件处理。Envoy支持SO_REUSEPORT特性,提升连接分配的均匀性。在建立连接时,OriginalDstFilter用于获取原始目的地地址,并通过getBalancedHandlerByAddress找到实际的虚拟监听器。同时,分析了HTTP监听器如何处理请求,利用HTTP连接管理器进行过滤和路由。

前言

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

    void ListenerManagerImpl::addListenerToWorker(Worker& worker,
                                                  absl::optional<uint64_t> overridden_listener,
                                                  ListenerImpl& listener,
                                                  ListenerCompletionCallback completion_callback) {
      if (overridden_listener.has_value()) {
        ENVOY_LOG(debug, "replacing existing listener {}", overridden_listener.value());
        worker.addListener(overridden_listener, listener, [this, completion_callback](bool) -> void {
          server_.dispatcher().post([this, completion_callback]() -> void {
            stats_.listener_create_success_.inc();
            if (completion_callback) {
              completion_callback();
            }
          });
        });
        return;
      }
      worker.addListener(
          overridden_listener, listener, [this, &listener, completion_callback](bool success) -> void {
            // The add listener completion runs on the worker thread. Post back to the main thread to
            // avoid locking.
            server_.dispatcher().post([this, success, &listener, completion_callback]() -> void {
     
     
     
     
    void ListenSocketImpl::setupSocket(const Network::Socket::OptionsSharedPtr& options,
                                       bool bind_to_port) {
      setListenSocketOptions(options);
     
      if (bind_to_port) {
        bind(address_provider_->localAddress());
      }
    }
     
     
    ActiveTcpListener::ActiveTcpListener(Network::TcpConnectionHandler& parent,
                                         Network::ListenerConfig& config)
        : ActiveTcpListener(
              parent,
              parent.dispatcher().createListener(config.listenSocketFactory().getListenSocket(), *this,
                                                 config.bindToPort(), config.tcpBacklogSize()),
              config) {}
     
     
    class ActiveTcpListener : public Network::TcpListenerCallbacks,
                              public ActiveListenerImplBase,
                              public Network::BalancedConnectionHandler,
                              Logger::Loggable<Logger::Id::conn_handler> {
    public:
      ActiveTcpListener(Network::TcpConnectionHandler& parent, Network::ListenerConfig& config);
      ActiveTcpListener(Network::TcpConnectionHandler& parent, Network::ListenerPtr&& listener,
                        Network::ListenerConfig& config);
      ~ActiveTcpListener() override;
      bool listenerConnectionLimitReached() const {
        // TODO(tonya11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值