首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164...
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca...
一 . 前言
以前也简单涉及过 OpenResty , 但是未深入的思考 , 这个组件应该扮演什么角色 , 这一篇就以架构的角度来想一想 , OpenResty 可以解决什么问题
文章目标 :
- OpenResty 入门上手
宏观观念
- OpenResty 是使用 C 语言编写的
- OpenResty 是一个基于Nginx 的高性能Web 平台
- OpenResty 能够方便地使用动态脚本语言Lua搭建高并发、高扩展性的Web 应用和动态网关。
有没有必要学 ?
- 你能想象这个组件在 哔哩哔哩 有自己的官方号吗 ?? space.bilibili.com/457424101
- 从 2011 年发布,到2023 年官方论坛还保持活跃
二. 宏观
2.1 宏观图
从这个图里面可以看出来,整个框架中有几个核心的组件:
- Nginx : 主角,底层基石,高性能的 Web 服务器
- LuaJIT : 一个 Lua 语言的解释器和编译器 , 这个组件可以在运行时动态生成和编译机器码(可以看成 LUA 虚拟机)
- ngx_lua :这是一个 OpenResty 的模块,允许在 Nginx 服务器中嵌入 Lua 脚本
2.2 性能
这里直接引用 《OpenResty完全开发指南》 里面的结果 :
- Transferred : 传输数据量
- Transfer rate :数据传输的速率,通常以每秒传输的数据量来表示 ,越高表示越快
从这个结果上看, OpenResty 的性能很高。毕竟底层使用的是 Nginx , 外层使用的是轻量级的 LUA 脚本,还慢就不合理了。
2.3 使用优势
- Spring 类型的业务网关性能不够,需要的硬件资源更多
- Nginx 性能足够,但是业务属性低,无法实现复杂的功能
= 需要一个既能实现业务功能, 性能又强劲的网关 = OpenResty
三. OpenResty 基础操作
3.1 OpenResty 的安装方式
@ blog.csdn.net/u013697959/...
java
// Step 1 : 依赖库下载
yum install readline-devel pcre-devel openssl-devel
// Step 2 : OpenResty 下载
wget https://openresty.org/download/openresty-1.19.9.1.tar.gz
tar -zxvf openresty-1.19.9.1.tar.gz
cd openresty-1.19.9.1
// Step 3 : OpenResty 安装
判断是否安装 gcc : which gcc
未安装 : yum -y install gcc automake autoconf libtool make
./configure
make
make install
// Step 4 : 查看文件 , 并且创建访问权限
ll /usr/local/openresty/
mkdir /home/www
cd /home/www/
mkdir openresty/ openresty/logs openresty/conf
3.2 怎么把代码写到 Nginx 里面的
OpenResty 支持3种集成 Lua 脚本的方式 :
- 方式一 : 通过配置项 content_by_lua , 通过该配置项可以直接把 Lua 代码集成到 Nginx 配置红
- 方式二 : 引用外部 Lua 文件 ,直接调用文件内的内容
- 方式三 : 引用外部 Lua 模块,这一类的功能功能会更加复杂
OpenResty 支持多种阶段执行 :
- rewrite_by_lua : 用于在 Nginx 的 "rewrite" 阶段执行 Lua 代码,例如重写 URL 、参数等
- content_by_lua : content 阶段,用于处理请求的内容生成和响应 ,生成响应内容等
- header_filter_by_lua : header_filter 阶段,处理请求头
- body_filter : 修改响应体 body 内容
- log_by_lua : 用于记录响应日志
- access_by_lua : 引用认证阶段进行处理 , 用于身份认证和验证等
方式一 : 直接嵌入 Lua 代码到 Nginx 配置文件中
java
// Step 1 : 配置 nginx (/home/www/openresty/conf/nginx.conf)
vim 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>")
}
}
}
}
// Step 2 : 启动openresty (PS : 此处注意和前文地址对应)
/usr/local/openresty/nginx/sbin/nginx -p /home/www/openresty -c /home/www/openresty/conf/nginx.conf
// Step 3 : 测试访问
本机 -> ps -ef | grep nginx
http://192.168.158.30:8080/
-> Hello, World!
>>>> 打印Log
java
http {
log_format log_format_2 '$remote_addr - - $time_local - - $request_method - - $request_uri - - $status - - $request_time - - "$request_body" - - "$resp_body"';
log_escape_non_ascii off;
server {
# ........
body_filter_by_lua_file /home/www/lua/lua_log.lua;
access_log /home/www/openresty/logs/access_test.log log_format_2;
location / {
default_type text/html;
content_by_lua '
ngx.say("<p>Hello, World!V2</p>")
';
}
}
}
方式二 : 集成外部的 LUA 文件
JAVA
// Step 1 : 准备 lua 脚本 (lua_request.lua)
local arg = ngx.req.get_uri_args()
for k,v in pairs(arg) do
ngx.say("[GET ] key:", k, " v:", v)
end
ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) do
ngx.say("[POST] key:", k, " v:", v)
end
// Step 2 : 修改
location /lua_request{
default_type 'text/html';
lua_code_cache off;
content_by_lua_file /home/www/lua/lua_request.lua;
}
// Step : 重启
/usr/local/openresty/nginx/sbin/nginx -t -p /home/www/openresty -c /home/www/openresty/conf/nginx.conf
方式三 : 引用外部模块
java
http {
lua_package_path "/path/to/lua_modules/?.lua;;";
lua_package_cpath "/path/to/lua_modules/?.so;;";
server {
location /use_lua_module {
default_type 'text/plain';
content_by_lua '
local my_module = require("my_module")
ngx.say(my_module.hello())
';
}
}
}
3.3 不同的集成阶段及复杂功能
通过 Redis 对请求进行校验。
java
worker_processes 1;
error_log logs/error.log info;
events {
worker_connections 1024;
}
http {
upstream apache.org {
server apache.org;
}
upstream nginx.org {
server nginx.org;
}
server {
listen 8082;
// 配置 Redis 路径
location = /redis {
internal;
// 在 Lua 代码中对 URI 进行解码,并将解码后的结果设置为请求 URI
set_unescape_uri $key $arg_key;
//发送一个 GET 请求到 Redis,获取 "$key" 的值
redis2_query get $key;
// 将请求代理到 Redis 数据存储
redis2_pass 127.0.0.1:6379;
}
location / {
set $target '';
access_by_lua '
local key = ngx.var.http_user_agent
// 发起一个子请求并捕获子请求的响应内容
local res = ngx.location.capture(
"/redis", { args = { key = key } }
)
// 对结果进行解析
print("key: ", key)
if res.status ~= 200 then
ngx.log(ngx.ERR, "redis server returned bad status: ",
res.status)
ngx.exit(res.status)
end
if not res.body then
ngx.log(ngx.ERR, "redis returned empty body")
ngx.exit(500)
end
local parser = require "redis.parser"
local server, typ = parser.parse_reply(res.body)
if typ ~= parser.BULK_REPLY or not server then
ngx.log(ngx.ERR, "bad redis response: ", res.body)
ngx.exit(500)
end
print("server: ", server)
ngx.var.target = server
';
proxy_pass http://$target;
}
}
}
// 重启 Nginx
/usr/local/openresty/nginx/sbin/nginx -t -p /home/www/openresty -c /home/www/openresty/conf/nginx.conf
总结
简单的入门记录,文档记得比较早了,有些东西应该是验证过的,但是之前的服务器已经丢失了,不清楚和现在的版本是不是匹配的.
基于这个文档,就可以详细说说秒杀体系了。
补充知识点
Nginx 补充命令
java
// 启动 Nigx
/usr/local/openresty/nginx/sbin/nginx -p /home/www/openresty -c /home/www/openresty/conf/nginx.conf
> nginx -s stop : 快速关闭服务
> nginx -s quit : 正常关闭服务
> nginx -s reload : 重新加载配置文件
> nginx -s reopen : 重新打开日志文件
Nginx 多配置
java
// S1 : 准备一个 主 Config 用于启动
// S2 : 在主 Config 下添加 include
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>")
}
}
}
include module-config/*.conf;
}
// S3 : 子module 中创建 config(此处直接以 Server 为根就行)
server {
listen 8080;
location / {
default_type text/html;
content_by_lua_block {
ngx.say("<p>hello, world</p>")
}
}
}
// 如果不行需要注意 :
- 端口是否打开 ,防火墙
- 配置是否刷新
参考文档
- OpenResty完全开发指南