今天阅兵真是震撼,一件件装备让人看得心潮澎湃。不说了~点上两根给空天母舰提提速!!!
跑题了~,看完阅兵就想打开b呼看看,b友是如何讨论的。没想到呀,还真让我碰上了。知乎崩了足足10分钟左右。(知乎也没想到阅兵结束以下这么多人来吧哈哈哈)通过报错信息发现知乎用的web服务器是openrensty。这让我想起了淘宝开源的web服务器Tengine,今天就来唠唠他们吧!!!
官网地址: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就行:
image-20250903213442059
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>")
}
}
}
}
更多配置可以参考官网资料。
官网: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做监控大盘,效果还不错。
从社区活跃度来看,OpenResty的生态更丰富一些。毕竟有春哥(章亦春)这样的技术大牛在推动,而且在国外也有不少用户。GitHub上的star数和贡献者数量都比较可观。
Tengine虽然是阿里开源的,但感觉推广力度没有OpenResty那么大。不过在国内的使用量还是很大的,特别是在电商和金融行业。
从技术发展趋势来看,我觉得OpenResty的前景更好一些。现在微服务、API网关这些概念很火,而OpenResty在这方面有天然的优势。而且随着边缘计算的发展,在CDN节点上运行一些轻量级的业务逻辑会越来越常见,这正是OpenResty的强项。
当然,Tengine在传统的Web服务器领域还是很有竞争力的,特别是在需要高性能和高稳定性的场景下。
写了这么多,其实就想说一个观点:工具没有好坏,只有合适不合适。OpenResty和Tengine都是基于Nginx的优秀发行版,各有各的特点和适用场景。
OpenResty适合需要在Web服务器层面做复杂业务逻辑的场景,它的Lua扩展能力让你可以快速响应各种奇葩需求。Tengine适合传统的Web服务器场景,在性能和稳定性方面有一定优势。
我的建议是,如果你现在还在用原生Nginx,不妨试试这两个发行版。特别是OpenResty,学会了Lua编程,你会发现很多以前需要改应用代码才能实现的功能,现在在Web服务器层面就能搞定,这种感觉真的很爽。
当然,学习新技术需要时间和精力投入,要根据自己的实际情况来选择。如果你的业务场景比较简单,原生Nginx也完全够用,没必要为了追新而增加系统复杂度。
最后,不管选择哪种方案,记住一点:技术服务于业务,不要为了技术而技术。适合自己团队和业务场景的,就是最好的。
题外话,还得学网安,都成一个军种了!!!
image-20250903225457562
如果这篇文章对你有帮助,别忘了点赞转发支持一下!想了解更多运维实战经验和技术干货,记得关注微信公众号@运维躬行录,领取学习大礼包!!!我会持续分享更多接地气的运维知识和踩坑经验。让我们一起在运维这条路上互相学习,共同进步!
公众号:运维躬行录
个人博客:躬行笔记