Nginx是Envoy出现之前网络通信中间件领域非常有代表性的开源系统,功能强大,性能出色,扩展性很强,已经形成了强大的生态,成为HTTP流量管理领域事实上的标杆。Envoy作为后起之秀,虽然定位和目标上与Nginx有不少差异,但架构设计层面,Envoy和Nginx都有很多的可取之处,下面会从功能定位、整体网络模型、连接处理、请求解析、插件机制、配置管理、部署和运维、管理方式等诸多维度,对Envoy和Nginx进行详细剖析和比较,通过与Nginx功能和架构层面的全方位对比,大家也可以对Envoy的架构设计有更立体的认识。
功能与定位Nginx最核心的功能是Web服务器和反向代理服务器,Web服务器完成对HTTP请求协议的解析和以HTTP协议格式响应请求、缓存、日志处理这些基本Web服务器功能;反向代理服务器完成对请求的转发、负载均衡、鉴权、限流、缓存、日志处理等代理常用功能。除了对Nginx协议的支持外,Nginx还支持普通的TCP、UDP反向代理功能,同时以stream方式支持通用的基于4层协议的反向代理,比如MySQL代理、Memcached代理等。Envoy的目标比较远大,定位是透明接管微服务之间的通信流量,将通信和服务治理功能从微服务中解耦,通过Envoy可以方便地增加对自定义协议的支持。概括起来,Nginx的关键词是Web服务器和反向代理,Envoy是透明接管流量,更加体现对流量的控制和掌控力。另外,从使用方式上看,微服务对Nginx是显式调用,通过Nginx完成负载均衡等相关功能,对Envoy是隐式调用,业务微服务不需要感知Envoy的存在,和使用Envoy使用相同的方式进行通信,只不过不再需要
网络模型网络模型上,Nginx采用的是经典的多进程架构,由master进程和worker进程组成。其中,master进程负责对worker进程进行管理,具体包含监控worker进程的运行状态,根据外部输入的一些管理命令向worker进程发送处理信号以及worker进程退出时启动新的worker进程。worker进程负责处理各种网络事件,各个worker进程之间相互独立,一同竞争来自客户端的新的连接和请求,为了保证请求处理的高效,一个请求处理的全部过程在同一个worker进程中。worker进程的个数推荐配置为与当前环境的CPU核数相同。自从Nginx诞生以来,一直使用上述经典的多进程架构。这种架构下,请求处理过程中如果遇到特别耗时的操作,比如磁盘访问、第三方服务同步访问等,会导致处理该请求的进程被夯住,不仅CPU资源没有得到充分利用,夯住时间比较长时不仅会影响当前请求,严重时会导致本进程的待处理请求大量超时。为了解决这种问题,Nginx从1.7.11版本开始引入了线程池的概念,如果遇到耗时特别长的逻辑,可以增加线程池配置,放到线程池中进行处理。线程池机制的引入对Nginx架构来说是个很关注通信和链路治理的细节。
rker能够建立的最大连接数,从Nginx网络模型可以看出,客户端连接到来时,所有空闲的进程都会去竞争这个新连接。这种竞争如果导致某个进程得到的新连接比较多,同时该进程的空闲连接也会很快用完,如果不进行控制,后续该进程获取新连接时会遇到没有空闲连接而丢弃,而有的进程有空闲连接却获取不到新连接。那么直接按照均等的方式将连接分配给各个进程是否可行呢?这种方式其实也是有问题的,不同连接上可能承载的请求QPS差异很大,可能会出现两个进程处理相同连接数,但一个特别忙另外一个特别闲的现象,因此为了保证各个工作进程都能够最大限度地提供自己的计算能力,需要对连接进行精细化管理,Nginx采取的方式是各工作进程根据自身的忙闲程度,动态调整获取新连接的时机,具体实现是:当本进程当前连接数达到最大worker_connections的7/8时,本worker进程不会去试图拿accept锁,也不会去处理新连接,这样其他worker进程就更有机会去处理监听句柄,建立新连接。而且,由于超时时间的设定,使得没有拿到锁的worker进程去拿锁的频率更高,通过这种方式,Nginx解决了worker进程之间的负载均衡问题。
8 观测与诊断从服务的可观测以及诊断上说,Envoy投入了大量的精力,已经全面支持Log、Metric、Trace等可观测机制,并且每种观测方式均提供相应的扩展机制,Nginx在这方面相对逊色很多,可观测以及诊断支持上相对弱一些,当前可能是为了和商业版进行区分,Nginx商业版有完善的运维和问题诊断支持。