深入解读Service Mesh的数据面Envoy

 在前面的一篇文章中,详细解读了Service Mesh中的技术细节,深入解读Service Mesh背后的技术细节。

但是对于数据面的关键组件Envoy没有详细解读,这篇文章补上。

 

一、Envoy的工作模式

 

 

 Envoy的工作模式如图所示,横向是管理平面。

 

Envoy会暴露admin的API,可以通过API查看Envoy中的路由或者集群的配置。

 

例如通过curl http://127.0.0.1:15000/routes可以查看路由的配置,结果如下图,请记住路由的配置层级,后面在代码中会看到熟悉的数据结构。

 

 

routes下面有virtual_hosts,里面有带prefix的route,里面是route entry,里面是weight cluster,对于不同的cluster不同的路由权重,再里面是cluster的列表,有cluster的名称和权重。

 

再如通过curl http://127.0.0.1:15000/clusters可以得到集群也即cluster的配置,这里面是真正cluster的信息。

 

在另外一面,Envoy会调用envoy API去pilot里面获取路由和集群的配置,envoy API的详情可以查看https://www.envoyproxy.io/docs/envoy/v1.8.0/api-v2/http_routes/http_routes中的API文档,可以看到route的配置详情,也是按照上面的层级组织的。

 

当Envoy从pilot获取到路由和集群信息之后,会保存在内存中,当有个客户端要连接后端的时候,客户端处于Downstream,后端处于Upstream,当数据从Downstream流向Upstream的时候,会通过Filter,根据路由和集群的配置,选择后端的应用建立连接,将请求转发出去。

 

接下来我们来看Envoy是如何实现这些的。

 

二、Envoy的关键数据结构的创建

 

 

Envoy的启动会在main函数中创建Envoy::MainCommon,在它的构造函数中,会调用父类MainCommonBase的构造函数,创建Server::InstanceImpl,接下来调用InstanceImpl::initialize(...)

 

接下来就进入关键的初始化阶段。

 

加载初始化配置,里面配置了Listener Discover Service, Router Discover Service, Cluster Discover Service等。

 

InstanceUtil::loadBootstrapConfig(bootstrap_, options);

 

 创建AdminImpl,从而可以接受请求接口

 

admin_.reset(new AdminImpl(initial_config.admin().accessLogPath(), initial_config.admin().profilePath(), *this));

 

 创建ListenerManagerImpl,用于管理监听,因为Downstream要访问Upstream的时候,envoy会进行监听,Downstream会连接监听的端口。

 

listener_manager_.reset(new ListenerManagerImpl(*this, listener_component_factory_, worker_factory_, time_system_));

 

 在ListenerManagerImpl的构造函数中,创建了很多的worker,Envoy采用libevent监听socket的事件,当有一个新的连接来的时候,会将任务分配给某个worker进行处理,从而实现异步的处理。

 

复制代码
ListenerManagerImpl::ListenerManagerImpl(...) {   for (uint32_t i = 0; i < server.options().concurrency(); i++) {     workers_.emplace_back(worker_factory.createWorker());   } }
复制代码

 

 createWorker会创建WorkerImpl,初始化WorkerImpl需要两个重要的参数。

一个是allocateDispatcher创建出来的DispatcherImpl,用来封装libevent的事件分发的。

一个是ConnectionHandlerImpl,用来管理一个连接的。

 

我们接着看初始化过程,创建ProdClusterManagerFactory,用于创建Cluster Manager,管理上游的集群。

 

cluster_manager_factory_.reset(new Upstream::ProdClusterManagerFactory(...);

 

 在Prod

50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信