OpenResty、Tengine、Nginx
OpenResty
官网地址:https://openresty.org/cn/
OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应
OpenResty其实就是一个基于Nginx的Web平台,但它最牛的地方在于集成了LuaJIT和很多精心编写的Lua库。简单来说,就是让你可以在Nginx里面写Lua代码,这听起来可能没什么,但用过的人都知道这有多香。
比如,你产品经理突然要求在用户访问某个页面时,根据用户的地理位置显示不同的内容。如果用传统的方式,要么改后端代码重新发布,要么搭建一套复杂的CDN规则。但用OpenResty,我直接在nginx.conf里写了几行Lua代码就搞定了:
location /api/content {
access_by_lua_block {
local ip = ngx.var.remote_addr
local geo = require "resty.geoip"
local country = geo.lookup(ip)
if country == "CN" then
ngx.var.backend = "china_backend"
else
ngx.var.backend = "global_backend"
end
}
proxy_pass http://$backend;
}
这种灵活性是原生Nginx根本做不到的。你想想,如果每次这种小需求都要动用整个开发流程,那得多麻烦。
OpenResty的安装也很简单,在Rocky Linux release 8.10上直接用yum就行:
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install openresty
装完之后,你会发现它的目录结构和Nginx差不多,配置文件还是在/usr/local/openresty/nginx/conf/nginx.conf。但是多了很多Lua相关的模块,比如lua-resty-redis、lua-resty-mysql这些,基本上常用的都给你准备好了。
#这是我修改后的文件
[root@webtest ~]# cat /usr/local/openresty/nginx/conf/nginx.conf
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location / {
default_type text/html;
content_by_lua_block {
ngx.say("<p>hello, world</p>")
}
}
}
}
Tengine
官网:https://tengine.taobao.org/
Tengine是阿里巴巴开源的Web服务器,基于Nginx开发。说到阿里的技术,那肯定是在高并发场景下被虐过千百遍才开源出来的,所以在性能和稳定性方面确实有两把刷子。
安装
官网下载编译安装包,上传到服务器
[root@webtest ~]# tar -xf tengine-3.1.0.tar.gz
[root@webtest ~]# cd tengine-3.1.0
[root@webtest ~]# ./configure
[root@webtest ~]# make
[root@webtest ~]# make install
Tengine最让我印象深刻的是它的动态模块加载功能。以前用Nginx,如果要加个模块,必须重新编译整个服务器,这在生产环境简直是噩梦。但Tengine可以动态加载模块,就像这样:
dso {
load ngx_http_lua_module.so;
load ngx_http_geoip_module.so;
}
重启服务就能生效,不用重新编译。这个功能在我们需要快速响应业务需求的时候特别有用。
还有一个让我很喜欢的功能是Tengine的健康检查。原生Nginx的upstream健康检查功能比较弱,基本上就是被动检查,后端服务挂了还要等用户请求失败才知道。但Tengine提供了主动健康检查:
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
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;
}
这样配置后,Tengine会每3秒主动检查一次后端服务器的健康状态,发现问题立即摘除,用户基本感知不到。
实际使用
用OpenResty做API网关,用Tengine做静态资源服务器和负载均衡器。
OpenResty常用模块参考:https://www.cnblogs.com/phpworld/p/10969297.html
用OpenResty做API网关,比如我们需要做接口限流,传统方式要么在应用层做,要么用Redis + Lua脚本。但OpenResty直接内置了限流模块:
location /api/ {
access_by_lua_block {
local limit_req = require "resty.limit.req"
local lim, err = limit_req.new("my_limit_req_store", 200, 100)
if not lim then
ngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)
return ngx.exit(500)
end
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
end
}
proxy_pass http://backend;
}
这样就实现了每个IP每秒最多200个请求,突发100个请求的限流策略。
不过OpenResty也有一些坑,主要是Lua代码的调试比较麻烦。不像应用代码可以打断点单步调试,Lua代码基本上只能靠日志调试。我一般会在关键位置加上这样的日志:
ngx.log(ngx.ERR, "debug: variable value is ", ngx.var.some_variable)
然后在error.log里查看输出。
Tengine的话,我主要用它做七层负载均衡。它的负载均衡算法比Nginx丰富一些,支持一致性哈希、最少连接数等多种算法:
upstream backend {
consistent_hash $request_uri;
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 weight=1;
}
这种一致性哈希在缓存场景下特别有用,可以保证相同的请求总是路由到同一台服务器。
选择建议
选择建议的话,我觉得主要看使用场景:
如果你需要在Web服务器层面做很多业务逻辑处理,比如API网关、动态内容生成、复杂的访问控制等,那OpenResty是首选。它的Lua生态很丰富,基本上你能想到的功能都有现成的库。
如果你主要做负载均衡和静态资源服务,对稳定性和性能要求比较高,那Tengine是个不错的选择。特别是在高并发场景下,Tengine的表现确实比原生Nginx要好一些。
当然,如果你的需求比较简单,就是做个简单的反向代理或者静态文件服务,那原生Nginx也完全够用,没必要为了用新技术而用新技术。
注意细节
部署这两个服务器的时候,有几个地方需要注意。
OpenResty的话,记得要合理设置Lua代码缓存。在开发环境可以关闭缓存方便调试:
lua_code_cache off;
但在生产环境一定要开启,否则性能会很差。
还有就是要注意Lua代码的内存使用。OpenResty使用LuaJIT,内存管理和标准Lua有些不同。如果你的Lua代码里有大量的字符串操作或者表操作,要注意及时释放内存:
-- 及时设置为nil释放内存
local big_table = {}
-- ... 使用big_table
big_table = nil
collectgarbage()
Tengine的话,要注意动态模块的加载顺序。有些模块之间有依赖关系,加载顺序错了会导致启动失败。一般来说,基础模块要先加载,业务模块后加载。
监控方面,两者都支持Nginx的标准监控接口,可以用nginx-module-vts或者stub_status模块。我一般会配置一个内部监控接口:
location /nginx_status {
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
stub_status on;
}
然后用Prometheus + Grafana做监控大盘,效果还不错。
4 comments
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com