高性能 Web 服务器之Tengine

一、概述

在这里插入图片描述
  Tengine 是一个由淘宝网发起的 Web 服务器项目。它基于 Nginx 然后针对大访问量网站的需求,添加了很多高级功能和特性,从 2011 年 12 月开始,Tengine 正式开源。Tengine 的性能和稳定性已经100多家大型网站如淘宝网,天猫商城、Youku、AliExpress、 Lazada 、Alibaba Cloud等得到了生产型检验。Tengine定位于打造一个高效、稳定、安全、易用的 Web 平台 目前已100% 兼容 Nginx的配置语法和模块,用户还可无缝迁移现有Nginx服务,同时享受增强功能,但需要注意安全漏洞,近期安全通报显示部分版本存在漏洞,请及时加固更新。另外,Tengine 没有像 Spring Cloud Gateway 那样为微服务架构提供原生支持(比如直接与 Eureka、Consul 等服务发现组件集成),但 Tengine 仍然可以通过 反向代理的方式 与微服务架构组合使用,尤其是在 Kubernetes 环境中,通过 Ingress 的方式实现负载均衡和路由功能。

  • 继承 Nginx-1.24.0 的所有特性,100% 兼容 Nginx 的配置;
  • 动态模块加载(DSO)支持。加入一个模块不再需要重新编译整个 Tengine,支持动态调整 servers, locations and upstreams而无需 reloading 或restarting worker 进程;
  • 支持HTTP/3 (QUIC v1 和draft-29方式);支持异步SSL/TLS模式,可以使用QAT(intel QuickAssist Technology)来卸载和加速SSL,显著提升性能。
  • 支持基于标准和自定义的 HTTP header, cookie, query and weights.来动态配置路由,可动态添加和追加自定义的http 头和请求参数;无需重新加载引擎的就可向HTTP响应添加自定义报头;支持动态配置TLS versions, timeout setting, SSL Redirects, CORS and enabling/disabling robots for the server and location;支持proxy_connection的隧道连接;
  • 更多负载均衡算法支持。如会话保持,一致性 hash 等;
  • 输入过滤器机制支持。通过使用这种机制 Web 应用防火墙的编写更为方便;
  • 动态脚本语言 Lua 支持。扩展功能非常高效简单;
  • 支持管道(pipe)和 syslog(本地和远端)形式的日志以及日志抽样;
  • 组合多个 CSS、JavaScript 文件的访问请求变成一个请求
  • 可以对后端的服务器进行主动健康检查,根据服务器状态自动上线下线;
  • 自动根据 CPU 数目设置进程个数和绑定 CPU 亲缘性;支持内核旁路的高速UDP传输,
  • 监控系统的负载和资源占用从而对系统进行保护,包括: asynchronous log & rollback, DNS caching, memory usage;
  • 显示对运维人员更友好的出错信息,便于定位出错机器;
  • 更强大的防攻击(访问速度限制)模块;
  • 更方便的命令行参数,如列出编译的模块列表、支持的指令等;
  • 可以根据访问文件类型设置过期时间;
  • 支持直接提交未缓冲的数据给到HTTP和FastCGI 后端服务器,避免了本地缓冲需先将文件数据写入磁盘缓冲区,然后再从缓冲区读取数据进行处理,这样可以减少磁盘I/O操作,提高文件处理速度;

关联资源:tengine仓库、tengine产品官网、tengine-ingress统一接入[Tengine-Ingress结束](https://mp.weixin.qq.com/s/VbNXHvjdCD07LOXaOIGXCw)

二、架构及原理

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.1 tengine对Nginx的主要改进模块

在这里插入图片描述
在这里插入图片描述

2.2 改进优化

1)计时器优化

Timers(计时器)是网络服务器中一个很重要的基础设置,它用来管理读写超时和应用逻辑的超时等。其常见操作有添加超时、删除超时以及查找最小的超时值。Nginx使用Red-black tree(红黑树)作为其计时器的数据结构。红黑树对应于添加、删除和查找最小值的算法复杂度都是O(logn)。在Tengine中,我们将Nginx的计时器数据结构改为了4-heap(四叉最小堆)。四叉堆是二叉堆的变种,比二叉堆有更浅的深度和更好的CPU Cache命中率。最小堆的添加、删除的复杂度和红黑树一样都是O(log n),但在查找最小值时,它的算法复杂度是0(1),即只要取出堆顶的第一个元素即可,因此比Nginx的红黑树更适合频繁获取最小值的场景,特别是在处理大量连接时,用最小堆性能提升比较明显。

2)浏览器和爬虫的判断优化

判断浏览器的类型是Web服务器的一个常见需求。Nginx中判断浏览器的方法是对关注的浏览器种类在User-Agent头中做暴力查找(strstr) 。strstr本身的算法复杂度是0(n2),Nginx查找的是多个串,因此其最终算法复杂度是0(n3)。随
着现在移动端的浏览器增多,原有模块的复杂度成指数增长,性能不高。在Tengine中,我们开发了一个全新的user_agent模块,使用了trie(前缀
树)来搜索多个可能的浏览器匹配串。它将所有的匹配字符串构造出一个自动机,每次匹配,它的算法复杂度只需要O(n)。因此复杂度不会随着匹
配串数量的增加而增加。

3)自动绑定CPU亲缘性

原有的Nginx CPU绑定需要手工操作,在Tengine中我们将Worker进程和CPU进行自动绑定,可以减少因CPU的Cache失效带来的性能损失,从而提高性能。另外,这样也减少了运维配置的工作量。

4)Lua模块(ngx_lua) 将Lua直接嵌入进Nginx核中

这样,借助Lua的协程和Nginx的事件模型实现同步、非阻塞的I/O操作,开发者在Nginx配置文件中可串行同步编写Lua脚本来处理业务逻辑,既可以用它来黏合各种上游(Proxy、Drizzle、Redis、Memcached等)的输出,也可以使用它的Cosocket接口来编写访问上游的客户端。得益于Lua解释器极低的开销和JIT技术(LuaJIT),用户不用编写复杂的C模块就能获得极高的吞吐性
能。也可以动态更改逻辑,不用再重新编译Nginx代码,从而带来了极大的灵活性。
在这里插入图片描述

Lua模块在初始化时为每个Nginx工作进程创建一个Lua/LuaJIT实例(LuaVM),同一进程处理的所有请求将共享该实例,并且Lua模块将用户Lua代码包装为协程工厂缓存在Nginx内,一个请求到来时协程工厂为它分配一个独立协程来运行业务逻辑。在需要进行阻塞的I/O操作时,Lua模块自动将I/O操作委托给Nginx的事件处理模型,并保存正在运行的协程上下文,返回到Nginx工作进程中处理其他请求,等到I/O操作完成时,又会恢复该协程继续运行。

5)动态模块支持

Tengine中加入了动态模块功能,对模块实现了动态编译,加入模块不再需要静态编译整个Tengine代码。使用方法类似Apache,在使用时可以当场
动态编译想加人的模块,非常方便。

  • 1.我们提供类似apxs的编译工具,将模块编译成动态链接库。
  • 2.在Tengine启动时通过动态链接库读入模块的模块结构体,这个结构体包含了模块处理的所有信息。
  • 3.Tengine有内置的模块加载顺序表,也可在配置文件中显式的指定模块的加载顺序,保证模块加载顺序正常。
  • 4.Tengine内部通过两个版本号(Major和Minor)来控制动态链接库(.so文件)的前后兼容性。当Major版本号相同时,较新版本的Tengine兼容较旧版本的.so文件(Tengine的Minor大于.so文件)。只有当Tengine的API发生重大变化时,Major的版本号才发生变化。增加新的API只会增加Minor版本号。

2.3 Tengine-Ingress 高性能高可用的云原生网关架构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、部署配置

在这里插入图片描述

3.1 编译安装

yum -y install gcc pcre-devel openssl-devel
useradd -r -s /sbin/nologin nginx
#下载源码包编译
cd /usr/local/src
wget https://tengine.taobao.org/download/tengine-2.4.1.tar.gz
md5sum tengine-2.4.1.tar.gz #8a3c754741539723af977246dfb260dd
tar xf tengine-2.4.1.tar.gz
cd tengine-2.4.1/
#或
git clone https://github.com/alibaba/tengine.git
cd tengine./configure --prefix=/usr/local/tengine-2.4.1 --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcremake && make install
ln -s /usr/local/tengine-2.4.1/sbin/* /usr/sbin/
#启动
nginx#动态添加 Lua 模块
yum -y install lua-devel
./configure --prefix=/usr/local/tengine-2.4.1 --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-http_lua_module=shared
#将动态模块的so文件拷贝到目标目录,这个目录可以通过'--dso-path'设置。默认是在Tengine安装目录下面的modules目录
make dso_install
#或如下这样简化生产动态模块,--add-dynamic-module 参数编译模块
./configure --add-dynamic-module=/path/to/module
make modules
#更新配置文件以加载 Lua 模块,生成的动态模块文件通常位于 objs/ 目录下
vim /usr/local/tengine-2.4.1/conf/nginx.conf #如下所示
dso {load ngx_http_lua_module.so;
}
#或配置文件中使用 load_module 指令加载模块:
server {listen 443 ssl http2;      # 启用 HTTP/2server_name example.com;load_module modules/ngx_http_lua_module.so;ssl_certificate /path/to/cert.pem;ssl_certificate_key /path/to/key.pem;location / {root /usr/share/nginx/html;}
}
#检查配置并重启 Tengine:
nginx -t
nginx -s reload#Concat 模块:Concat 模块用于合并多个文件在一个响应报文中,类似于 Apache 的 mod_concat 模块。这有助于减少 HTTP 请求数量,提高网站加载速度和用户体验
./configure --help | grep http_concat  #检查当前tengine支持的Concat 模块版本
#编译
./configure --prefix=/usr/local/tengine-2.4.1 --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-http_lua_module=shared --with-http_concat_module=shared
make dso_install
#完成后,更新配置
location /static/css/ {concat on;concat_max_files 20;
}location /static/js/ {concat on;concat_max_files 30;
}
#加载
nginx -t
nginx -s reload## 查看加载模块
tengine -V 2>&1 | grep dynamic

3.2 配置示例

worker_processes auto;
worker_rlimit_nofile 65535;
events {worker_connections 65535;
}
http {
#以备日志切割
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" '' "$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main;
gzip_min_length 1k;# 负载均衡,默认轮询:请求被依次分配给每个服务器;IP 哈希(ip_hash):根据客户端 IP 地址分配流量,使同一 IP 的用户访问同一台服务器
upstream backend {server 172.18.1.101:8080 weight=5;  # 权重为5server 172.18.1.102:8080 weight=3;  # 权重为3server 172.18.1.103:8080 backup;    # 备用服务器
}
#或
upstream backend {ip_hash;                          # 启用 IP 哈希server  172.18.1.101:8080;server  172.18.1.102:8080;
}# 开启健康检查,rise=2:连续检查 2 次成功视为健康;fall=5:连续检查 5 次失败视为故障;timeout=1000:检查超时时间(单位毫秒);check_http_send:发送的 HTTP 请求内容;check_http_expect_alive:期望的响应状态码。check interval=3000 rise=2 fall=5 timeout=1000 type=http;check_http_send "HEAD / HTTP/1.0\r\n\r\n";check_http_expect_alive http_2xx http_3xx;# 使用负载均衡
server {listen 80;location / {proxy_pass http://backend;}
}
#waf示例
location / {access_by_lua_block {#Lua 脚本实现 WAF 规则local args = ngx.req.get_uri_args()if args["id"] and tonumber(args["id"]) < 0 thenngx.exit(403)end}
}
#流量限速:限制每个 IP 的并发请求数或每秒请求数,防止恶意请求或流量突增
http {# 定义限速区域,$binary_remote_addr 表示根据客户端 IP 地址限速,限速区域大小为 10MBlimit_req_zone $binary_remote_addr zone=req_zone:10m rate=10r/s; server {listen 80;location / {limit_req zone=req_zone burst=5;  # 每秒限制 10 个请求,允许 5 个突发请求proxy_pass http://backend;}}
}#缓存加速:可以将后端服务器的响应存储到本地磁盘或内存中,从而加速用户的访问
http {proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;server {listen 80;location / {proxy_cache my_cache;                   # 启用缓存proxy_cache_valid 200 302 10m;          # 状态码 200 和 302 的内容缓存 10 分钟proxy_cache_valid 404 1m;               # 状态码 404 的内容缓存 1 分钟proxy_pass http://backend;}#防盗链,定义允许访问的 Referer,none:允许没有 Referer 的请求;blocked:允许 Referer 被代理隐藏的请求。location /images/ {valid_referers none blocked *.example.com;if ($invalid_referer) {return 403;}}
}
#日志切割
vi /etc/logrotate.d/nginx  #保存半年
/var/log/nginx/*.log {dailymissingokrotate 190compressdelaycompressnotifemptycreate 0640 www-data www-datasharedscriptspostrotate/usr/local/sbin/nginx -s reopenendscript
}

3.3 图形管理工具

1)Tengine Dashboard功能

2)Prometheus监控方案+Grafana可视化面板

3)ELK日志分析方案

四、应用案例

4.1、电商场景

1)大促期间动态限流配置

upstream mall {check interval=3000 rise=2 fall=3;server 172.18.1.101:8080;
}
location ~* \.(jpg|css)$ {expires 30d;
}

2)静态资源加速方案

4.2 金融行业

1)双向证书校验实现

2)敏感数据加密传输

3)长连接保持配置

4.3 MQTT协议支持案例

五、FAQ

1)兼容性问题

2)与原生Nginx模块冲突处理

3)版本升级注意事项

4)性能问题

5)高并发场景优化建议

6)TIME_WAIT状态处理

7)动态加载模块失败排查

8)自定义日志格式配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/87284.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/87284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单实现HTML在线编辑器

我们继续来看一下如何开发一个简单的html在线编辑器&#xff0c;要求很简单 能够同时编辑html&#xff0c;css&#xff0c;js代码&#xff0c;并且运行之后可以同时预览效果 一&#xff1a;前置知识 在H5中设置了一个新的标签&#xff0c;<iframe>&#xff0c; 用于在当前…

【Bluedroid】蓝牙启动之核心模块(startProfiles )初始化与功能源码解析

本文深入解析Android蓝牙协议栈中 start_profiles 函数及其调用的核心模块初始化逻辑,涵盖 BNEP、PAN、A2DP、AVRC、HID Host、BTA_AR 等关键配置文件和应用层模块。通过代码分析与流程梳理,阐述各模块如何通过全局控制块、状态机、回调机制实现功能初始化、连接管理及数据交…

RK3576 Android14 DMIC调制

一、背景 近期项目中有个DMIC调试的需求&#xff0c;搁置了较长时间&#xff0c;现今着手调试&#xff0c;遂作记录。 二、开发环境 OS&#xff1a;Android14 Platform&#xff1a;RK3576 Linux Version&#xff1a;6.1.99 SDK Version&#xff1a;android-14.0-mid-rkr6 …

使用 Prometheus 监控 Spring Boot 应用

SpringBoot+Prometheus+Grafana实现监控 逻辑如图 应用程序在生产环境中运行时,监控其运行状况是非常必要的。通过实时了解应用程序的运行状况,才能在问题出现之前得到警告,也可以通监控应用系统的运行状况,优化性能,提高运行效率。 一、监控 Spring Boot 应用 下面我们…

简易计算器 Python 实现

目录 一、代码逐步分析&#xff08;适合刚入门的朋友看&#xff09; 1.定义了一个名为simple_calculator的函数&#xff0c;封装了整个计算器的逻辑。 二、深入分析代码块&#xff0c;用更加官方的语词来说&#xff08;适合想要深入学习的朋友&#xff09; 主循环结构 退出…

开源编译器介绍

文章目录 基本构成传统编译器编译器的发展历史&#xff08;History of Compiler&#xff09;GCC 编译过程与原理&#xff08;GCC Process and Principle&#xff09;LLVM/Clang 编译过程与原理&#xff08;LLVM/Clang Process and Principle&#xff09;GCC与与 LLVM/Clang 的对…

C++ String知识点

当然可以&#xff01;下面我将以系统全面、通俗易懂、深入浅出的方式&#xff0c;为你讲解 C 中非常核心但也容易被低估的内容 —— std::string。 &#x1f31f; C std::string 全面详解 &#x1f4cc; 一、string 是什么&#xff1f; C 的 std::string 是 C 标准库中封装好…

全新NVIDIA Llama Nemotron Nano视觉语言模型在OCR基准测试中准确率夺冠

全新NVIDIA Llama Nemotron Nano视觉语言模型在OCR基准测试中准确率夺冠 PDF、图表、图形和仪表板等文档是丰富的数据源&#xff0c;当这些数据被提取和整理后&#xff0c;能够为决策制定提供有价值的洞察。从自动化财务报表处理到改进商业智能工作流程&#xff0c;智能文档处…

gradle的 build时kaptDebugKotlin 处理数据库模块

gradle的 build时输出&#xff1a; Task :app:kaptDebugKotlin 注: Processing class HDCoinBean 注: Processing class HDCurrencyBean 注: Processing class HDSelfAddCoin 注: Processing class MN 注: Creating DefaultRealmModule <—> 80% EXECUTING [7m 56s] IDLE…

二叉树的节点操作算法

235. 二叉搜索树的最近公共祖先 力扣题目链接(opens new window) 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大…

【ubuntu驱动安装】安装nvidia驱动和cuda环境

1、安装驱动 首先查看环境和显卡&#xff1a; 更新apt 查看nouveau是否禁用 如果有返回值禁用nouveau(nouveau是通用的驱动程序)&#xff08;必须&#xff09;&#xff0c;两种文件&#xff0c;22.04是下面那个 添加如下&#xff1a; 终端输入后更新 重启电脑sudo reboo…

力扣HOT100之终章:一些随笔

今天终于把力扣HOT100系列给刷完了&#xff0c;每一道题都记录了自己的思考过程和解题过程中参考的一些题解和视频&#xff0c;方便自己以后再刷的时候快速复习&#xff0c;从2025年3月4日写下第一篇博客&#xff0c;到2025年6月12日完成最后一题并写下最后一篇博客&#xff0c…

榕壹云家政系统:基于Spring Boot与UniApp的智能家政服务解决方案

在数字化浪潮下&#xff0c;传统家政行业正面临效率与服务质量的升级挑战。榕壹云公司依托前沿技术&#xff0c;推出了一款用户端与师傅端二合一的家政服务小程序&#xff0c;通过整合预约上门、分销、储值、优惠券等功能&#xff0c;为家政服务行业提供了一套高效、灵活的数字…

CSRF扩展 JSONP劫持

介绍&#xff1a;JOSNP&#xff08;JSONP with Override Security Negotiation Protocol&#xff09;劫持是一种利用JSONP &#xff08;JSON with Padding&#xff09;跨域数据获取机制的安全漏洞&#xff0c;攻击者通过篡改或伪造JSONP回调函数窃 取用户敏感数据。由于JSONP…

HTTP/HTTPS 协议解析

前言 在当今互联网时代&#xff0c;HTTP/HTTPS 协议作为 Web 通信的基石&#xff0c;承载着几乎所有的网络内容传输。对于我们而言&#xff0c;深入理解这些协议不仅是技术素养的体现&#xff0c;更是构建高性能、安全、可靠 Web 应用的必要条件。 为什么我们需要深入了解 HT…

Flask-login 处理授权逻辑

认证 vs 授权&#xff1a; 在 Web 应用程序的安全机制中&#xff0c;认证&#xff08;Authentication&#xff09; 和 授权&#xff08;Authorization&#xff09; 是两个核心概念&#xff0c;它们虽然紧密相关&#xff0c;但职责和作用不同。 认证&#xff08;Authenticatio…

xenomai3+linux构建linux实时操作系统-基于X86_64和arm

简介&#xff1a; Xenomai是一个实时性解决方案&#xff0c;通过在Linux上添加实时内核Cobalt来增强实时性能。它有三个主要部分&#xff1a;libcobalt&#xff08;用户空间实时库&#xff09;、Cobalt&#xff08;内核空间实时内核&#xff09;和硬件架构特定层&#xff08;ip…

Linux核心文件(core file)详解

一、核心文件&#xff08;core file&#xff09;概述 1.1 什么是核心文件 核心文件&#xff08;core file&#xff09;是Linux操作系统在程序崩溃时生成的一种转储文件。它包含了程序崩溃时的内存内容、寄存器状态和执行状态。通过分析核心文件&#xff0c;开发者可以找到程序…

java中跨域问题及解决方案

1. 什么是跨域 从不同的地址访问另外一个地址就是跨域 2.跨域一定会有异常吗 跨域异常只会在前端发生&#xff0c;后端跨域不会产生异常 因为浏览器有一个叫做同源策略的东西&#xff0c;它发现不同域之间的访问是不安全的行为&#xff0c;会禁止&#xff0c;所以会抛出异常…

网络层协议 IP 协议介绍 -- IP 协议,网段划分,私有 IP 和 公网 IP,路由

目录 1 IP 协议 1.1 IP 协议格式 2. 网段划分 2.1 网络号和主机号 2.2 传统 IP 地址分类和 CIDR 技术 2.3 特殊的 IP 地址 2.4 IP 地址的数量限制 2.5 私有 IP 和公网 IP 3. 路由 网络层主要作用是实现不同局域网之间的通信连接&#xff0c;并为数据在复杂网络环境中的…