0%

文章简介: 这次分享的主题是 NGINX网络协议优化,这里有两个关键词,第一个是网络协议,因此不涉及 NGINX 的业务模块,比如Lua语言模块。第二个关键词是性能优化,我们的目标是让NGINX的性能达到目前硬件架构的极限。

很高兴大家回到这次深潜之旅,让我们继续挖掘 NGINX 的潜力。今天我的分享包括四个部分。首先从整体上来看一下 NGINX的协议栈如何进行优化。接着我们将按照 OSI七层网络模型,自上而下依次讨论HTTP协议栈、TLS/SSL协议栈以及TCP/IP协议栈。

首先要明确NGINX的优化方向。优化的目标在我看来可以用三个词表示——快、多、省

  • ”是指降低请求的时延,请求时延是用户能够感知到的最明显因素。
  • ”指的是 NGINX正在处理的所有TCP连接数量以及收发的总字节数,比如总吞吐量能否打满网卡。
  • ”指处理一个 TCP 连接时所消耗的资源要尽量的少,这样我们的并发连接才能够达到千万、亿级别。

在做协议栈优化时,我们必须同时兼顾知识深度广度。开发习惯从实现的角度看问题,知识面倾向深度。而运维更关注服务部署、运行,比如要了解IDC地理位置、网络规划、服务器硬件配置等情况,因此知识面是倾向广度的。NGINX运行在 Linux 或者 FreeBSD 等操作系统上,操作系统的内核协议栈和进程调度机制都会影响 NGINX 性能,所以优化内核参数时相对更需要深度。了解 NGINX 所在网络环境,针对丢包率、网卡特性、CPU特性、交换机和防火墙的规格、协议特性等要素优化 NGINX 时,相对又会偏重广度。

NGINX 协议栈优化方法论

首先我们看下面两张图,先同步下思路。

NGINX架构

第一张图由 NGINX 官方提供,我们从三个层面来解读它。
官方架构

阅读全文 »

开源版Nginx最为人诟病的就是不具备动态配置、远程API及集群管理的能力,而APISIX作为CNCF毕业的开源七层网关,基于etcd、Lua实现了对Nginx集群的动态管理。
apisix架构图

让Nginx具备动态、集群管理能力并不容易,因为这将面临以下问题:

  • 微服务架构使得上游服务种类多、数量大,这导致路由规则、上游Server的变更极为频率。而Nginx的路由匹配是基于静态的Trie前缀树、哈希表、正则数组实现的,一旦server_name、location变动,不执行reload就无法实现配置的动态变更;
  • Nginx将自己定位于ADC边缘负载均衡,因此它对上游并不支持HTTP2协议。这增大了OpenResty生态实现etcd gRPC接口的难度,因此通过watch机制接收配置变更必然效率低下;
  • 多进程架构增大了Worker进程间的数据同步难度,必须选择1个低成本的实现机制,保证每个Nginx节点、Worker进程都持有最新的配置;

等等。

APISIX基于Lua定时器及lua-resty-etcd模块实现了配置的动态管理,本文将基于APISIX2.8、OpenResty1.19.3.2、Nginx1.19.3分析APISIX实现REST API远程控制Nginx集群的原理。

阅读全文 »

Nginx是企业内网的对外入口,它常常同时对接许多应用,因此,Nginx上会同时监听多个端口、为多个域名提供服务。然而,匹配多级域名并不简单,Nginx为此准备了字符串精确匹配、前缀通配符、后缀通配符、正则表达式,当它们同时出现时,弄清楚HTTP请求会被哪个server{ }下的指令处理,就成了一件困难的事。

这是因为基于域名规范,请求匹配server{ }配置块时,并不会按照它们在nginx.conf文件中的出现顺序作为选择依据。而且对于不支持Host头部、没有域名的HTTP/1.0请求和无法匹配到合适server{ }的异常请求,我们都要区别对待。

另外,为了加快匹配速度,Nginx将字符串域名、前缀通配符、后缀通配符都放在了哈希表中,该设计充分使用了CPU的批量载入主存功能。如果不了解这些流程,既有可能导致请求没有被正确的server{ }块处理,也有可能降低了原本非常高效地哈希表查询性能。

阅读全文 »

上一篇文章介绍了HTTP请求匹配server{ }配置块的过程,接着请求会继续匹配location{ }配置块,并最终决定哪些指令及Nginx模块处理请求。本文将介绍location的匹配规则,以及rewrite指令与location匹配顺序的关系。

生产环境中的nginx.conf往往含有上百条location,这是因为Nginx常常身兼多职:充当提供静态资源CDN、作为负载均衡为分布式集群提供扩展性、作为API gateway提供接口服务等等。location一旦配置错误,Nginx上巨大的并发连接数会将错误放大上万倍,很容易导致严重的线上事故。

而location也很容易配置错误,它既支持前缀匹配,也支持正则表达式匹配,当二者同时出现时,为了获得更高的性能,Nginx设计了复杂的location匹配优先级。这是因为前缀匹配是对静态的location多叉树检索完成的,它的性能要比正则表达式高得多,唯有搞清楚具体的匹配流程,我们才能设计出匹配速度更快的location。

而且rewrite指令修改URL的功能也让location匹配变得更为复杂。特别是rewrite出现在server{ }和location{ } 里,会导致完全不同的结果。设计location时,我们还需要考虑到rewrite的效率,以及它是否会导致循环重定向。

阅读全文 »

WAF全称为Web Application Firewall,因此作为七层负载均衡的Nginx很适合实现Web应用层防火墙。许多C、Lua模块都在rewrite、access等处理阶段截获HTTP请求,基于可配置的规则过滤内容并判断安全后,再放行给content阶段的反向代理模块转发到上游服务。本次4节课我将从Web攻击方式讲起,看看Nginx是如何用作反向代理型WAF的。

阅读全文 »