1. 功能概述

Envoy启动时,会启动一个进程,并在这个进程中启动很多线程,这样,可以启动很多worker线程,一般worker线程数与核心数相同,每个worker线程处理所有已配置的listener上的请求,管理连接并处理filterchain,非阻塞;同时,在这个进程中会启动一个主线程,它负责启动和停止envoy,也是通过API提供配置管理的线程,同时它收集不同的指标,管理其它线程,也是非阻塞的。

2. 重要数据结构定义

2.1 Filter

过滤器,包括listener filter、network filter和http filter。Listener filter可以用于操作连接元数据,在新接收的套接字上进行操作,例如获取原始目的地址,重定向连接等;network filter主要负责数据读写;http filter主要负责数据处理。

2.2 Listener

监听器,envoy中支持在每个线程中配置任意数量的监听器,每个监听器独立配置一定数量的network filter,也可以选择性的配置listener filter,listener filter在连接建立之前处理,network filter在连接建立之后处理。

2.3 Worker

一个worker对应一个envoy的执行线程,将listener绑定在worker上,worker负责监听、过滤和转发,每个连接的生命周期会绑定在一个单独的worker上,通常情况下,envoy实现了100%的非阻塞。

3. 代码流程

3.1 流程概述

Envoy启动时,首先启动主线程,在主线程中对listener和filter进行初始化操作,然后将listener绑定到worker上,并由主线程拉起worker线程,由worker线程负责监听新连接。

3.2 初始化

3.2.1 main入口

main函数是envoy启动的总入口,首先生成main_common,用于后面的初始化。

3.2.2 初始化main_common

在main_common里面会生成maincommonbase,它会做server instance的初始化,一个instance是一个服务的实例.

3.2.3 Instance初始化

在maincommonbase里调用InstanceImpl函数后,首先对启动携带的配置信息进行注册,然后执行instance的初始化。

Instance的初始化包括两部分:

① 将当前instance注册到ListenerManager,来管理更新;

② 创建并初始化MainImpl,MainImpl用来初始化监听listener;

MainImpl根据配置文件获取静态监听listener列表,将它们实例化并注册到ListenerManager。

3.2.4 初始化listener

对于每个静态listener,根据配置文件为它创建ListenerFilterFactoryList,并根据配置为它添加ListenerFilterFactory。

listener filter有三个:original dst filter,proxy protocol filter, TLS inspector filter,一一按照配置判断是否加入ListenerFilterFactoryList。

配置ListenerFilterFactoryList的同时,也会根据配置为这个listener创建NetworkerFilterFactoryList,供后续建立在这个listener上的连接使用。

3.3 启动

3.3.1 启动入口

在main_common初始化正常完成后,执行main_common→run()启动,从而后续执行instance的run()方法,在instance的run()方法,会执行网络级别上的listener初始化。

3.3.2 启动worker,将listener绑定到worker上

此处,会将从配置文件读取的所有listener绑定到所有的worker上,worker是服务的并发线程,数目一般和核心数相同,将listener绑定到worker上后会通过connectionhandler模块将其初始化。

3.3.3 Listener初始化

Listener的初始化过程首先生成ActiveListener,通过ActiveListener调用network包内的创建函数来对listener进行网络级别的初始化。

3.3.5 启动worker线程,进入监听

Listener绑定在worker上,当listener初始化完成后,需要启动worker服务才能真正进入监听流程。

此处,为每个worker启动新线程,并调用libevent的event_base_loop进入监听,等待连接事件到达触发后,回调onAccept进入处理流程。

4. 总结

本文从程序入口main函数开始,分析了envoy如何启动,以及如何对listener、worker这些核心数据结构进行初始化,并详细阐述了从envoy主线程启动到worker线程进入监听行为的全过程。

相关服务请访问https://support.huaweicloud.com/cce/index.html?cce_helpcenter_2019

idou老师教你学Istio 29:Envoy启动流程的更多相关文章

  1. idou老师教你学Istio 07: 如何用istio实现请求超时管理

    在前面的文章中,大家都已经熟悉了Istio的故障注入和流量迁移.这两个方面的功能都是Istio流量治理的一部分.今天将继续带大家了解Istio的另一项功能,关于请求超时的管理. 首先我们可以通过一个简 ...

  2. idou老师教你学Istio :如何用istio实现监控和日志采集

    大家都知道istio可以帮助我们实现灰度发布.流量监控.流量治理等功能.每一个功能都帮助我们在不同场景中实现不同的业务.那Istio是如何帮助我们实现监控和日志采集的呢? 这里我们依然以Bookinf ...

  3. idou老师教你学Istio:如何用 Istio 实现速率限制

    使用 Istio 可以很方便地实现速率限制.本文介绍了速率限制的使用场景,使用 memquota\redisquota adapter 实现速率限制的方法,通过配置 rule 实现有条件的速率限制,以 ...

  4. idou老师教你学Istio 28:istio-proxy check 的缓存

    功能概述 istio-proxy主要的功能是连接istio的控制面组件和envoy之间的交互,其中check的功能是将envoy收集的attributes信息上报给mixer,在istio中有几十种a ...

  5. idou老师教你学Istio :5分钟简析Istio异常检测

    异常检测 异常检测和踢出异常主机是一个动态检查上游主机是否正常工作,对不健康主机进行移除的过程.异常检测是一种被动健康检查,根据返回状态码来判断是否满足移除条件,最后将主机移除,首先我们来了解下驱逐算 ...

  6. idou老师教你学Istio 27:解读Mixer Report流程

    1.概述 Mixer是Istio的核心组件,提供了遥测数据收集的功能,能够实时采集服务的请求状态等信息,以达到监控服务状态目的. 1.1 核心功能 •前置检查(Check):某服务接收并响应外部请求前 ...

  7. idou老师教你学Istio 25:如何用istio实现监控和日志采集

    大家都知道istio可以帮助我们实现灰度发布.流量监控.流量治理等功能.每一个功能都帮助我们在不同场景中实现不同的业务.那Istio是如何帮助我们实现监控和日志采集的呢? 这里我们依然以Bookinf ...

  8. idou老师教你学Istio 24:如何在Istio使用Prometheus进行监控

    使用Prometheus进行监控是Istio提供的监控能力之一.Istio提供丰富的监控能力,为网格中的服务收集遥测数据.Mixer是负责提供策略控制和遥测收集的Istio组件. Istio通过Mix ...

  9. idou老师教你学Istio 23 : 如何用 Istio 实现速率限制

    使用 Istio 可以很方便地实现速率限制.本文介绍了速率限制的使用场景,使用 memquota\redisquota adapter 实现速率限制的方法,通过配置 rule 实现有条件的速率限制,以 ...

随机推荐

  1. SSRS 2016 Forms Authentication

    SSRS 2016 comes with completely new report manager web interface and implementing form authenticatio ...

  2. php csv 简单的导入

    if($act == 'user_upload_do'){ global $db; $filename = $_FILES['file']['tmp_name']; if (empty ($filen ...

  3. Go之接口interface(1)

    1. 什么是interface在此之前,我们遇到的都是具体的类型,比如数字类型.切片类型等等.对于这些具体的类型,我们总是能知道它是什么.可以利用它来做什么,比如对于一个数字类型,我们知道可以对其进行 ...

  4. 乐字节Java反射之三:方法、数组、类加载器和类的生命周期

    本文承接上一篇:乐字节Java发射之二:实例化对象.接口与父类.修饰符和属性 继续讲述Java反射之三:方法.数组.类加载器 一.方法 获取所有方法(包括父类或接口),使用Method即可. publ ...

  5. 《Tsinghua os mooc》第11~14讲 进程和线程

    第十一讲 进程和线程 进程 vs 程序 程序 = 文件 (静态的可执行文件) 进程 = 执行中的程序 = 程序 + 执行状态 进程的组成包括程序.数据和进程控制块 同一个程序的多次执行过程对应为不同进 ...

  6. java积累的细节问题

    一.将几个数字进行拼接,拼接成字符串 一定要将""放到几个数字之前,否则就会把数字相加之后的数转化成字符串 如你需要拼接年份,月份,和日 如果:2018+12+13+"& ...

  7. java输入输出 -- I/O模型简述

    一.简介 本文向大家介绍五种I/O模型.分别是阻塞I/O.非阻塞I/O.I/O复用.信号驱动式I/O.异步I/O等.内容参考<UNIX网络编程>,大家想进深入学习网络编程,建议去读读这本书 ...

  8. MongoDB 范围查询

    查询价格在200-9000    $gt  大于      $lt    小于 //查询价格200-9000范围的数据 db.prodgory.find({"}}) 查询给定范围数据   $ ...

  9. k8s-部署策略

    在Kubernetes中有几种不同的方式发布应用,所以为了让应用在升级期间依然平稳提供服务,选择一个正确的发布策略就非常重要了. 选择正确的部署策略是要依赖于我们的业务需求的,下面我们列出了一些可能会 ...

  10. 附录:ARM 手册 词汇表

    来自:<DDI0406C_C_arm_architecture_reference_manual.pdf>p2723 能够查询到:“RAZ RAO WI 等的意思” RAZ:Read-As ...