什么是OpenResty
以下内容来自OpenResty官网
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® 中包含了多少软件。
安装OpenResty
-
本次安装采用yum方式安装,离线安装请参考OpenResty中文官网的安装教程,离线方式安装
-
在yum 仓库中添加openresty的安装源
sudo yum install yum-utils sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
-
安装openresty
sudo yum install openresty
-
安装命令行工具
sudo yum install openresty-resty
-
查看
openresty
仓库中的软件包sudo yum --disablerepo="*" --enablerepo="openresty" list available
到此安装就完成了。默认安装位置在 /usr/local/openresty,该目录下包含了 luajit, lualib, nginx, openssl, pcre, zlib 这些组件。
- 使用脚本启动,OpenResty安装时, 已经把路径加入了/usr/bin, 并且添加了服务 /etc/init.d/openresty, 可以通过服务脚本启动
systemctl start/stop/status openresty #启动、停止、查看状态
- 可以通过-p参数设置工作目录,后续将会把nginx、openresty的conf、log、html都存放在该目录下
openresty -p /data/openresty-conf/
防火墙端口开放,我这边就先关闭防火墙了,在生产环境上只开放openresty的互联网端口如80、443。
然后通过访问对应openresty服务的地址或域名就看访问到欢迎页
Lua Demo
后续更新Lua语法相关文章......
1、创建lua server文件夹
mkdir lua-learn
- 创建lua脚本
vim test.lua
ngx.say("hello world");
3、配置nginx.conf
在server段中添加以下代码
lua_code_cache off; #关闭lua缓存,在不用重启nginx也可以实时访问lua脚本
location /lua {
default_type 'text/html';
content_by_lua_file /usr/example/lua/test.lua;
}
通过访问nginx中配置lua路径即可访问到有lua编写的脚本内容
Centos7 下OpenResty ab性能测试
1.服务器说明
我这边使用另一台虚拟机向openresty服务器发起请求,以减少对openresty服务器的影响。
服务器版本 | CPU | 内存 |
---|---|---|
Centos7.9 OpenResty | 1 | 2 |
Centos7.9 Httpd(ab) | 1 | 2 |
2.压力测试
安装ab工具
yum -y install httpd-tools
测试前对服务器进行配置
net.ipv4.tcp_syncookies= 1 //打开TIME-WAIT套接字重用功能,对于存在大量连接的Web服务器非常有效。
net.ipv4.tcp_tw_reuse= 1 //减少处于FIN-WAIT-2连接状态的时间,使系统可以处理更多的连接。
net.ipv4.tcp_fin_timeout=30 //减少TCP KeepAlive连接侦测的时间,使系统可以处理更多的连接。
net.ipv4.tcp_tw_recycle= 1 //快速回收,慎用!慎用!慎用!
net.ipv4.neigh.default.gc_stale_time=120 //决定检查过期多久邻居条目
net.ipv4.conf.lo.arp_announce=2 //避免arp放大攻击
net.ipv4.icmp_echo_ignore_broadcasts = 1 //表示开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0。
net.ipv4.icmp_ignore_bogus_error_responses = 1 //开启恶意icmp错误消息保护
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0 //避免无源路由包
net.ipv4.tcp_keepalive_time = 1200 //如果对方不予应答,探测包的发送次数
net.ipv4.tcp_max_syn_backlog = 65536 //个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_tw_buckets = 6000 //参数设置为 1 ,表示允许将TIME_WAIT状态的socket重新用于新的TCP链接,该参数默认为180000,过多的TIME_WAIT套接字会使Web服务器变慢。
#使配置生效
sysctl -p
测试命令
ab -r -c 10000 -n 100000 http://192.168.62.127/lua
测试结果
测试指标 | 请求次数 | 用时 | 错误请求 |
---|---|---|---|
1W并发 | 10W | 347S | 0 |
1.5W并发 | 15W | 438S | 6 |
2W并发 | 20W | 517S | 12 |
OpenResty + Redis实现灰度发布
主机描述
IP | 描述 |
---|---|
192.168.62.127 | 虚拟机:OpenResty服务,Tomcat1 |
192.168.62.128 | 虚拟机:Tomcat2 |
192.168.62.1 | 宿主机: Redis |
实现思路:
用户发起请求到openresty代理的网关,由openresty获取请求ip,然后向redis获取白名单地址,如果该请求ip为白名单ip则将流量转发到代理相对应的后端服务器上。可在redis中动态设置白名单,实现服务切换。
实现代码
local redis=require "resty.redis";
local red=redis:new();
red:set_timeout(1000);
--redis连接ip 端口
local ok,err=red:connect("10.18.63.44", 6379);
--redis 密码
ok,err=red:auth("******");
if not ok then
ngx.say("redis 连接失败",err);
return;
end
--请求ip
local client_ip = ngx.req.get_headers()["X-Real-IP"];
if client_ip == nil then
client_ip = ngx.req.get_headers()["x_forwarded_for"];
end
if client_ip == nil then
client_ip = ngx.var.remote_addr;
end
client_ip=ngx.var.remote_addr;
--redis中获取白名单
local ip_lists=red:get("grayIp");
--判断是否在白名单然后转到对应服务
if string.find(ip_lists,client_ip) == nil then
ngx.log(ngx.INFO, "client_ip",client_ip);
//对应的负载服务器
ngx.exec("@server1");
else
ngx.log(ngx.INFO, "client_ip",client_ip);
ngx.exec("@server2");
end
local ok,err=red:close();
测试
此时redis中的ip不是客户端ip
访问openresty时获取到的白名单ip与请求ip不符,则将请求转发到127的后端应用。
然后将redis中的ip换为宿主机的ip
然后重新发起请求,请求ip与白名单ip匹配,则将流量转发到128的后端应用
至此就完成了简单的灰度发布功能。
openresty还有其他的应用场景,如:高并发的首页,可以由redis存储预加载数据,由openresty进行页面渲染。还有秒杀类功能、网关限流等。
总结
OpenResty有了nginx高并发和lua丰富的一方库和可以由开发者自定义的lua库的加持能让前端代理服务器也实现一些简单、高性能的需求,在之前的开发中需要由后端网关完成的功能,现在在openresty中就可以完成。由于lua脚本的特性支持热更新,不用频繁重启服务而影响业务。