Tengine 的目的
Tengine 是由淘宝技术团队(现阿里巴巴)基于 Nginx 开发的一款高性能 Web 服务器和反向代理服务器。它的主要目的是在 Nginx 的基础上增强性能、扩展功能、提升稳定性,并为大规模、高并发的互联网应用提供更高效的解决方案。
以下是 Tengine 的主要目的及其相关实现:
1. 提升高并发场景下的性能
目的:
在处理高并发连接和大流量请求时,提供比 Nginx 更高的性能,能够更好地满足企业级应用(如电商、社交媒体、搜索引擎等)的需求。
实现方式:
- 优化内存管理:提升内存分配和缓存机制的效率,减少资源消耗。
- 增强事件驱动模型:进一步优化事件分发和 I/O 处理,充分利用多核 CPU 的并发能力。
- 支持大连接数:通过优化连接管理机制,支持更高的连接数,适合高并发流量场景。
2. 提供企业级功能扩展
目的:
扩展 Nginx 的功能,满足企业级应用的复杂需求,例如动态负载均衡、健康检查、缓存、流量控制等。
实现方式:
-
动态负载均衡:
- 支持动态调整后端服务器的权重,无需重启服务即可生效。
- 支持多种负载均衡策略(轮询、权重、IP 哈希、一致性哈希等)。
-
健康检查:
- 内置健康检查模块,实时检测后端服务器的健康状态,并根据结果调整请求分发,确保高可用性。
-
缓存功能:
- 提供高效的静态文件缓存和代理缓存功能,加快资源响应速度。
-
流量控制:
- 支持限流和连接数限制,防止恶意流量攻击和资源耗尽。
-
增强日志与监控:
- 提供丰富的日志记录功能,支持实时流量统计和性能监控,便于运维和故障排查。
3. 支持动态模块加载
目的:
降低开发和维护成本,允许在无需重新编译的情况下动态加载新功能模块。
实现方式:
- 动态模块机制 :
- 支持通过
load_module
指令加载动态模块,无需重启服务。 - 允许企业根据需求定制化功能扩展,适应快速变化的业务需求。
- 支持通过
4. 提升稳定性和可靠性
目的:
针对大流量、高并发场景下的异常情况,提供更高的容错能力和系统稳定性。
实现方式:
-
异常保护:
- 提供多种保护机制,防止因单个请求或模块异常导致服务中断。
-
优雅重启:
- 支持平滑升级和优雅重启,保障服务在更新过程中不中断。
-
健康检查与故障剔除:
- 自动识别不可用的后端服务器并剔除,确保流量始终分发到健康的节点。
5. 满足互联网场景的特殊需求
目的:
根据中国互联网企业的业务特点和需求,在 Nginx 的基础上增加针对性的优化和扩展。
实现方式:
-
多语言支持:
- 支持多种编程语言和框架(如动态脚本 Lua 模块),便于企业灵活开发。
-
CDN优化:
- 增强静态资源分发的能力,优化内容分发网络(CDN)的性能。
-
安全增强:
- 提供 Web 应用防火墙(WAF)功能,防御常见的 Web 攻击(如 SQL 注入、XSS 跨站脚本攻击、DDoS 攻击等)。
6. 保持与 Nginx 的兼容性
目的:
在增强功能的同时,保证与原生 Nginx 的配置、模块、生态的兼容性,便于用户从 Nginx 平滑迁移到 Tengine。
实现方式:
-
完全兼容 Nginx 配置文件语法:
- 用户可以直接使用现有的 Nginx 配置文件,无需额外调整。
-
支持大多数 Nginx 模块:
- 继承了 Nginx 的核心模块,同时增强了其扩展能力。
8. 提升开发与运维效率
目的:
通过功能优化和工具支持,降低开发和运维的复杂度,缩短上线周期。
实现方式:
-
可视化监控:
- 支持实时流量监控和性能分析,帮助运维人员快速定位问题。
-
灵活的日志系统:
- 支持自定义日志格式和日志切割,便于调试和数据分析。
-
易于部署和扩展:
- 提供简单易用的编译和部署工具,支持快速扩展和更新。
Tengine 项目使用指南
Tengine 是一个基于 Nginx 的高性能 Web 服务器和反向代理服务器,适用于高并发、高流量的场景。它继承了 Nginx 的功能,并增加了许多扩展功能,如动态负载均衡、健康检查、WAF(Web 应用防火墙)等。本指南将介绍 Tengine 的安装、配置和常见功能的使用。
一、Tengine 的安装
Tengine 支持源码编译安装和预编译包安装,以下是两种方式的具体步骤。
1.1 源码编译安装
步骤:
-
下载源码
git clone https://github.com/alibaba/tengine.git cd tengine
-
配置编译选项
./configure --prefix=/usr/local/tengine --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-http_realip_module
--prefix
:指定安装目录。--with-*
:启用特定模块功能。
-
编译并安装
make && make install
-
验证安装
查看是否安装成功:
/usr/local/tengine/sbin/nginx -v
输出类似以下内容:
Tengine version: Tengine/2.x.x
-
启动 Tengine
启动 Tengine 服务:
/usr/local/tengine/sbin/nginx
1.2 使用预编译包安装
步骤:
-
下载预编译包
从 Tengine 官方下载页面 获取最新的预编译包。
-
解压并安装
tar -xvf tengine-2.x.x.tar.gz cd tengine-2.x.x ./configure make && make install
-
启动 Tengine
/usr/local/tengine/sbin/nginx
二、Tengine 的基本配置
Tengine 的配置文件默认路径为 /usr/local/tengine/conf/nginx.conf
,其语法与 Nginx 基本一致,同时增加了一些 Tengine 独有的配置选项。
以下是一个简单的 Tengine 配置文件示例:
# 全局配置
worker_processes 4; # 启动的工作进程数
worker_rlimit_nofile 65535; # 每个进程的最大文件句柄数
events {
worker_connections 1024; # 每个进程的最大连接数
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# Gzip 压缩
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain application/json text/css;
# 日志格式
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 logs/access.log main;
# 负载均衡配置
upstream backend {
server 192.168.1.101:8080 weight=5; # 后端服务器1
server 192.168.1.102:8080 weight=3; # 后端服务器2
server 192.168.1.103:8080 backup; # 备用服务器
}
# 服务器配置
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend; # 转发请求到 upstream 定义的后端
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 错误页面
error_page 404 /404.html;
location = /404.html {
root /usr/local/tengine/html;
}
}
}
三、Tengine 的常见功能使用
3.1 负载均衡
Tengine 提供了强大的负载均衡功能,支持多种策略,包括轮询(默认)、权重、IP 哈希等。
配置示例:
# 定义后端服务组
upstream backend {
server 192.168.1.101:8080 weight=5; # 权重为5
server 192.168.1.102:8080 weight=3; # 权重为3
server 192.168.1.103:8080 backup; # 备用服务器
}
# 使用负载均衡
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
负载均衡策略:
- 默认轮询:请求被依次分配给每个服务器。
- 权重(weight):根据权重分配流量。
- IP 哈希(ip_hash):根据客户端 IP 地址分配流量,使同一 IP 的用户访问同一台服务器。
IP 哈希示例:
upstream backend {
ip_hash; # 启用 IP 哈希
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
3.2 健康检查
Tengine 增强了 Nginx 的健康检查功能,可以定期检测后端服务器状态,并剔除故障服务器。
健康检查配置:
http {
upstream backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
# 开启健康检查
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD / HTTP/1.0
";
check_http_expect_alive http_2xx http_3xx;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
参数说明:
interval=3000
:检查间隔(单位毫秒)。rise=2
:连续检查 2 次成功视为健康。fall=5
:连续检查 5 次失败视为故障。timeout=1000
:检查超时时间(单位毫秒)。type=http
:健康检查类型(支持 TCP 或 HTTP)。check_http_send
:发送的 HTTP 请求内容。check_http_expect_alive
:期望的响应状态码。
3.3 动态模块
Tengine 支持动态加载模块,无需重新编译即可加载新功能模块。
加载动态模块:
在配置文件中使用 load_module
指令加载模块:
load_module modules/ngx_http_lua_module.so;
生成动态模块:
通过添加 --add-dynamic-module
参数编译模块:
./configure --add-dynamic-module=/path/to/module
make modules
生成的动态模块文件通常位于 objs/
目录下。
3.4 启用 HTTP/2
Tengine 支持 HTTP/2,可以通过以下配置启用:
server {
listen 443 ssl http2; # 启用 HTTP/2
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
root /usr/share/nginx/html;
}
}
3.5 WAF(Web 应用防火墙)
Tengine 提供了 Web 应用防火墙模块,可以防御常见的安全威胁,如 SQL 注入、XSS 攻击等。
启用 WAF 模块:
安装并加载 WAF 模块(如 ngx_http_lua 模块),然后在配置文件中启用:
location / {
access_by_lua_block {
-- Lua 脚本实现 WAF 规则
local args = ngx.req.get_uri_args()
if args["id"] and tonumber(args["id"]) < 0 then
ngx.exit(403)
end
}
}
四、Tengine 的管理命令
Tengine 提供了一些管理命令,用于控制服务器的运行状态。
启动 Tengine
/usr/local/tengine/sbin/nginx
重新加载配置
/usr/local/tengine/sbin/nginx -s reload
停止 Tengine
/usr/local/tengine/sbin/nginx -s stop
平滑升级
/usr/local/tengine/sbin/nginx -s quit
**检查配置
检查配置文件合法性
在修改配置文件后,可以使用以下命令检查其合法性:
/usr/local/tengine/sbin/nginx -t
输出结果:
-
如果配置正确:
nginx: the configuration file /usr/local/tengine/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/tengine/conf/nginx.conf test is successful
-
如果配置有误,会提示错误信息及出错的具体位置。
五、Tengine 的高级功能使用
5.1 动态负载均衡
Tengine 支持动态调整后端服务器的负载均衡权重,无需重启服务即可生效。
动态负载均衡配置:
http {
upstream backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
动态调整权重:
通过 tengine_upstream.conf
文件,动态调整后端服务器的权重。例如:
echo "192.168.1.101:8080 weight=10" > /usr/local/tengine/conf/tengine_upstream.conf
然后通过以下指令重新加载配置:
nginx -s reload
动态负载均衡可以结合健康检查模块使用,以保证流量分发到健康的服务器节点。
5.2 流量限速
Tengine 提供了流量限制功能,可以限制每个 IP 的并发请求数或每秒请求数,防止恶意请求或流量突增。
限速配置:
http {
# 定义限速区域
limit_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;
}
}
}
参数说明:
limit_req_zone
:定义限速规则,$binary_remote_addr
表示根据客户端 IP 地址限速。zone=req_zone:10m
:定义限速区域大小为 10MB。rate=10r/s
:每秒允许的请求数为 10。burst=5
:允许 5 个突发请求。
5.3 缓存加速
Tengine 支持内容缓存功能,可以将后端服务器的响应存储到本地磁盘或内存中,从而加速用户的访问。
缓存配置:
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;
}
}
}
参数说明:
proxy_cache_path
:定义缓存路径及参数。levels=1:2
:缓存文件的目录层级结构。keys_zone=my_cache:10m
:定义名为my_cache
的缓存区域,大小为 10MB。max_size=1g
:缓存目录最大占用空间为 1GB。inactive=60m
:60 分钟内未访问的缓存内容将被删除。
proxy_cache_valid
:设置缓存的有效时间。
5.4 日志切割与管理
Tengine 提供了强大的日志功能,可以记录访问日志、错误日志,并支持日志的自动切割。
日志配置:
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;
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
日志切割:
可以使用外部工具(如 logrotate
)实现日志切割,以下是一个 logrotate
配置示例:
/etc/logrotate.d/nginx
配置:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data www-data
sharedscripts
postrotate
/usr/local/tengine/sbin/nginx -s reopen
endscript
}
此配置会每天切割日志,保留 14 天的历史日志,并在切割后自动通知 Tengine 重新打开日志文件。
5.5 防盗链配置
Tengine 支持防盗链功能,可以限制某些外部链接直接访问服务器上的资源。
防盗链配置:
http {
server {
listen 80;
server_name example.com;
location /images/ {
valid_referers none blocked *.example.com;
if ($invalid_referer) {
return 403;
}
root /var/www/html;
}
}
}
参数说明:
-
valid_referers
:定义允许访问的Referer
。none
:允许没有Referer
的请求。blocked
:允许Referer
被代理隐藏的请求。*.example.com
:允许来自example.com
的请求。
-
$invalid_referer
:检查请求是否为无效来源。
六、Tengine 的常见问题与解决
6.1 配置文件错误
执行 nginx -t
检查时提示配置文件错误:
nginx: [emerg] "server" directive is not allowed here
原因:
server
指令必须写在http
块中。
解决方法:
检查配置文件的层级结构,确保 server
块在 http
块中定义。
6.2 服务启动失败
启动 Tengine 时提示端口占用:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
原因:
- 端口 80 已被其他服务占用。
解决方法:
-
检查端口占用:
netstat -tuln | grep 80
-
停止占用端口的服务,或修改 Tengine 的监听端口。
6.3 高并发下性能下降
原因:
- 可能是文件描述符不足或工作进程配置过少。
解决方法:
-
增大文件描述符限制:
ulimit -n 65535
-
修改
worker_processes
和worker_connections
配置:worker_processes auto; worker_rlimit_nofile 65535; events { worker_connections 65535; }
这句话是关于 Tengine 在微服务场景下的适用性描述,主要是指出 Tengine 并没有像 Spring Cloud Gateway 那样为微服务架构提供原生支持(比如直接与 Eureka、Consul 等服务发现组件集成),但 Tengine 仍然可以通过 反向代理的方式 与微服务架构组合使用,尤其是在 Kubernetes 环境中,通过 Ingress 的方式实现负载均衡和路由功能。
以下将详细解释这句话的含义,以及 Tengine 在微服务架构中的应用方式。
1. 什么是"无原生微服务支持"?
Tengine 是一个高性能的 Web 服务器和反向代理服务器,基于 Nginx 开发,定位是传统的 Web 和 API 网关解决方案,主要提供:
- 静态资源分发
- 反向代理
- 负载均衡
- 健康检查
- Web 应用防火墙(WAF)
然而,现代 微服务架构 中,常常需要 API 网关具有以下功能:
- 动态服务发现 :
- 微服务通常会动态注册到服务注册中心(如 Eureka 或 Consul),网关需要能够实时感知服务的变化。
- 动态路由 :
- 微服务的路由规则可能会随服务的上线、下线动态调整。
- 与微服务生态集成 :
- 微服务体系通常包含一整套组件(如服务注册、配置中心、分布式追踪、熔断等),网关需要能够无缝集成这些组件。
Tengine 的局限性
- 静态配置为主 :Tengine 的路由规则和负载均衡配置通常是静态的(通过配置文件
nginx.conf
写死),无法像 Spring Cloud Gateway 那样动态感知微服务的变化。 - 缺乏原生服务发现支持:Tengine 无法直接与服务注册中心(如 Eureka、Consul)交互。
- 微服务扩展功能不足:比如限流、熔断、动态认证等需要额外开发或依赖第三方模块。
2. 如何通过反向代理与微服务结合?
虽然 Tengine 缺乏原生的微服务支持,但它可以通过反向代理的方式与微服务结合,尤其是在 Kubernetes 环境中,通过 Ingress 配置实现简单的微服务流量管理。
反向代理的核心思想
- Tengine 作为流量的入口,负责接收客户端请求。
- 根据 URL 路径或主机名,将请求路由转发到不同的微服务。
- 微服务的实例地址可以手动配置,也可以通过动态脚本更新。
3. 在 Kubernetes 中作为 Ingress Controller
在 Kubernetes 中,Ingress 是一种 API 对象,用于定义 HTTP(S) 路由规则,将外部请求转发到集群内部的服务(Service)。
Tengine 可以作为 Ingress Controller 的实现,接管 Kubernetes 的流量入口。
Tengine + Kubernetes Ingress 的架构
客户端(外部请求)
↓
Tengine(Ingress Controller)
↓
Kubernetes Service(微服务的负载均衡)
↓
微服务实例(Pod)
如何通过反向代理支持微服务?
3.1 静态配置示例
在 Tengine 中,配置静态反向代理,将不同的路径转发到对应的微服务。
示例 nginx.conf
:
http {
upstream service_a {
server 10.0.0.1:8080; # 微服务 A 的实例 1
server 10.0.0.2:8080; # 微服务 A 的实例 2
}
upstream service_b {
server 10.0.0.3:9090; # 微服务 B 的实例 1
}
server {
listen 80;
# 路由规则
location /service-a/ {
proxy_pass http://service_a;
}
location /service-b/ {
proxy_pass http://service_b;
}
}
}
- 优点 :
- 简单直接,适合服务实例较少且变动不频繁的场景。
- 缺点 :
- 服务实例的地址需要手动维护,无法动态感知服务变化。
3.2 在 Kubernetes 中使用 Tengine Ingress
Tengine 可以作为 Kubernetes 的 Ingress Controller,通过 Ingress 资源动态配置路由规则。
部署步骤:
-
安装 Tengine Ingress Controller
- 使用 Tengine 社区提供的 Kubernetes Ingress Controller 镜像或自己编译。
- 在 Kubernetes 集群中部署 Tengine,并将其作为 Ingress 的实现。
-
定义 Ingress 资源
- 通过 Kubernetes 的 Ingress 资源定义路由规则,例如将不同的路径转发到不同的服务。
示例 Ingress 配置:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.org/force-ssl-redirect: "true"
spec:
rules:
- host: example.com
http:
paths:
- path: /service-a/
pathType: Prefix
backend:
service:
name: service-a
port:
number: 8080
- path: /service-b/
pathType: Prefix
backend:
service:
name: service-b
port:
number: 9090
- 动态更新路由规则
- Kubernetes 会动态将流量转发到对应的服务(通过 Service 和 Pod 的 DNS 映射),Tengine 无需手动更新配置。
4. 动态代理服务实例的解决方案
4.1 使用第三方工具更新 Tengine 配置
对于服务实例动态变化的场景,可以使用第三方工具(如 Consul Template 或 Lua 脚本)自动更新 Tengine 的配置文件并重新加载。
示例:使用 Consul Template
- 将服务实例注册到 Consul。
- 使用 Consul Template 自动生成 Tengine 的配置文件,并在服务变动时重新加载。
配置模板:
upstream service_a {
{{ range service "service-a" }}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 80;
location /service-a/ {
proxy_pass http://service_a;
}
}
4.2 使用动态反向代理(OpenResty/Lua)
通过引入 Lua 模块(如 OpenResty),实现动态服务发现和负载均衡。
示例:动态服务发现
location /service-a/ {
content_by_lua_block {
local service_a = {
"10.0.0.1:8080",
"10.0.0.2:8080"
}
local backend = service_a[math.random(#service_a)]
ngx.var.target = backend
}
proxy_pass http://$target;
}
5. 总结
Tengine 的微服务支持特点
- 静态配置为主:依赖手动配置路由和服务实例,适合服务实例较固定的场景。
- 动态代理方案 :
- 借助 Kubernetes Ingress 管理动态路由和服务发现。
- 使用工具(如 Consul Template 或 Lua 脚本)动态更新配置。
- 适用场景 :
- 高性能场景:需要处理高并发请求,或对静态资源分发有要求。
- 简单微服务架构:服务数量较少且路由规则简单。
对于复杂的微服务架构(如动态服务发现、大量路由规则、认证和限流),可以结合 Spring Cloud Gateway 或其他微服务网关组件使用。