https://github.com/Tinywan/lua_project_v0.01/wiki
.
├── application -- 业务代码
│ ├── api
│ │ ├── live
│ │ └── users.lua
│ ├── controller -- 业务控制器
│ │ ├── live_redis_cache.lua
│ │ ├── upstream_backend.lua
│ │ └── web_socket_redis.lua
│ ├── model
│ │ └── Products.lua
│ ├── swoole
│ │ └── websocket-server.php
│ ├── waf
│ │ ├── init.lua
│ │ ├── install.sh
│ │ ├── wafconf
│ │ └── waf.lua
│ └── zabbix
│ └── install-record01.conf
├── bin -- 启动脚本
│ ├── doc2unix.sh
│ └── start.sh
├── conf -- 配置文件
│ ├── domains
│ │ └── nginx_live.conf
│ ├── fastcgi_params
│ ├── nginx.conf
│ ├── nginx.conf.default
│ └── nginx_lua_upstream.conf
├── logs -- 日志文件
│ ├── 123.txt
│ ├── error.log
│ └── nginx.pid
├── lualib -- 官方Lua库
│ ├── cjson.so
│ ├── item
│ │ ├── common.lua
│ │ └── items.lua
│ ├── live -- 自定义公共部分Lua文件
│ │ └── common.lua
│ ├── ngx
│ │ ├── ssl
│ │ └── ssl.lua
│ ├── rds
│ │ └── parser.so
│ ├── redis
│ │ └── parser.so
│ ├── resty
│ │ ├── http_headers.lua
│ │ ├── http.lua
│ │ ├── upstream
│ │ └── websocket
│ └── vendor -- 第三方Lua库
│ ├── config.lua
│ ├── dkjson.lua
│ ├── helper.lua
│ ├── ip_check.lua
│ ├── ip_location.lua
│ └── mysql_fun.lua
├── public -- 公共静态文件
│ ├── bootstrap
│ │ ├── css
│ │ ├── fonts
│ │ ├── images
│ │ └── js
│ ├── data
│ │ └── location_ip_db.dat
│ ├── images
│ │ ├── github
│ │ ├── tinywan_title.png
│ │ └── yinzhang.png
│ ├── video-js
│ │ ├── videodemo.png
│ │ ├── video.js
│ │ └── video-js.swf
│ └── websocket
│ └── public
├── README.md
└── template -- 静态模板
├── index
│ └── index.html
├── live
│ ├── 404.html
│ ├── crossdomain.xml
│ ├── index.html
│ ├── videodemo.png
│ └── wesocket.html
├── product
│ ├── footer.html
│ ├── header.html
│ ├── index2.html
│ ├── index.html
│ ├── item.html
│ └── product_list.html
├── waf
│ ├── index.html
│ └── waf.php
└── websocket
├── index.html
├── index.php
├── js
└── websocket.html
- 如何编译一个高性能 OpenResty
- Prerequisites:
apt-get install libreadline-dev libncurses5-dev libpcre3-dev \ libssl-dev perl make build-essential
- Building:
wget https://openresty.org/download/openresty-1.11.2.3.tar.gz tar xvf openresty-1.11.2.1.tar.gz cd openresty-1.11.2.1 ./configure --prefix=/opt/openresty \ --with-luajit \ --without-http_redis2_module \ --with-http_iconv_module \ --with-http_postgres_module make -j2 sudo make install
- error
- 错误1:
you need to have ldconfig in your PATH env when enabling luajit.
- 解决办法:
sudo apt-get install luajit whereis luajit luajit: /usr/bin/luajit /usr/share/man/man1/luajit.1.gz ./configure --prefix=/opt/openresty \ --with-luajit=/usr/bin/luajit \ --without-http_redis2_module \ --with-http_iconv_module \ --with-http_postgres_module make -j2 sudo make install
- 错误1:
user www www;
worker_processes 8;
pid logs/nginx.pid;
error_log log/error.log error;
worker_rlimit_nofile 204800;
events {
use epoll;
worker_connections 204800;
}
http {
include /opt/openresty/nginx/conf/mime.types;
default_type text/html;
charset utf-8;
lua_package_path "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/lualib/?.lua;;"; #lua 模块
lua_package_cpath "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/lualib/?.so;;"; #c模块
include "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/conf/domains/*";
}
- 新建文件夹同时下载项目:
# 切换到 该目录,如果没有请重新建立 www@iZ238xopqw6Z:~$ pwd /home/www git clone -b v0.03 https://github.com/Tinywan/lua_project_v0.01.git
- 修改主配置文件:
lua_project_v0.01/conf/nginx.conf
的路径,以下的/home/
修改为项目所在路径lua_package_path "/home/lua_project_v0.01/lualib/?.lua;/home/lua_project_v0.01/application/controller/?.lua";#lua 模块 lua_package_cpath "/home/lua_project_v0.01/lualib/?.so;;"; # c模块 include "/home/lua_project_v0.01/conf/domains/*";
- 测试配置文件:
test.conf
- 修改项目路径变量:
set $project_path /home/;
- 日志文件路径不支持变量(暂时需要修改,以后直接做跨域保存就可以了):
access_log "/home/lua_project_v0.01/logs/demo_access.log";
- 日志文件路径不支持变量(暂时需要修改,以后直接做跨域保存就可以了):
- 启动脚本
- 赋予权限(655):
chmod +x /start.sh
, - 配置成功运行结果如下:
/home/lua_project_v0.01/conf# ../bin/start.sh start [ Stop OK ] nginx: the configuration file /home/lua_project_v0.01/conf/nginx.conf syntax is ok nginx: configuration file /home/lua_project_v0.01/conf/nginx.conf test is successful [ Start OK ]
- 赋予权限(655):
- 测试流程是否跑通:
curl http://127.0.0.1/
,输出:Hello! lua_project_v0.01
,表示环境配置成功
- master分支已经很稳定了,将不再提交代码,以后将从以下分支提交
- 公司
company
分支 - 家里
home
分支
- API接口专用(8686):
api.conf
- Demo测试专用(8080):
nginx_demo.conf
- 活动直播专用(8088):
nginx_live.conf
- Waf防火墙专用(8082):
waf.conf
- 商品列表专用(8083):
nginx_product.conf
- 解决nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
- 错误日志:
[crit] 3478#0: *5 connect() to unix:/var/run/php7.0.9-fpm.sock failed (13: Permission denied)
- 修改php-fpm.conf配置文件
listen.owner = nginx listen.group = nginx listen.mode = 0660
- 跑nginx的用户是nginx,而/var/run/php7.0.9-fpm.sock 这个文件。监听的nginx用户没有该权限,导致nginx无法访问/var/run/php5-fpm.sock这个文件,自然监听就失去了效果。
- 获取http get/post 请求参数:
helper.http_args()
- 字符串分割:
helper.split()
- 删除空格:
helper.ltrim() / rtrim() / trim()
- json 解析的异常:
helper.cjson_decode(str2)
- 错误返回nil,成功返回解析后的json字符串
- 如何调用
local helper = require 'vendor.helper' local str1 = '{"hobby":{"name":"tinywan","age":24},"is_male":false}' -- 写法1 local str2 = [[ {"hobby":{"name":"tinywan","age":24},"is_male:false} ]] -- 写法2 local obj_obj = helper.cjson_decode(str2) if not json_str then ngx.say('cjson_decode error') else ngx.say(helper.format_table(json_str)) end
- ✅ 添加
local mysql = require 'vendor.mysql_fun' local cjson = require 'cjson' data = { name = "TinyWAN", address = "HeilongJiang", age = "26" } local result = mysql.add(data.name,data.address,data.age) ngx.print(cjson.encode(result))
- ✅ 查询
local result = mysql.select(3) ngx.print(cjson.encode(result))
- ✅ 修改
local result = mysql.update(3,"TinTinAIAI") ngx.print(cjson.encode(result))
- ✅ 删除
local result = mysql.delete(3) ngx.print(cjson.encode(result))
- ✅ 数据返回结果:
- ✔️ 成功
{ "error_code": 200, "message": "add successfully" }
- ✖️ 失败
{ "error_code": 504, "message": "failed to delete" }
- ✔️ 成功
- mysql_fun.lua
- 封装遇到的问题:
- nginx 错误日志总是出现这个:
lua entry thread aborted: runtime error: attempt to yield across C-call boundary
- 解决办法:ngx_lua 连接mysql
- 封装好的文件:
/vendor/mysql_fun.lua
- 封装好调用的时候一直出现这个:
curl: (52) Empty reply from server
- 解决办法,在每次增删改查的时候都要调用数据库连接的这个方法数据库连接
connect_db()
方法就可以了function _M.update(id, name) connect_db() end
- nginx 错误日志总是出现这个:
- 创建项目、项目架构搭建、目录结构调整
- 添加新功能
- 简单的Redis数据库操作
- 根据IP地址获取具体城市信息(@icowan)
- lua-resty-shell库的使用
- 添加功能:lua-resty-websocket 官方测试案例
- 添加功能:WebSocket系统负载统计
- Mysql 数据库添加
- 错误提示:
bad result: Data too long for column 'name' at row 1: 1406: 22001.
,插入字段超过表定义大小
- 错误提示:
- Swoole WebSocket 测试
- 开启服务:
php /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/swoole/websocket-server.php
- 客户端测试:
http://127.0.0.1/clinet.html
- 开启服务:
- 添加Nginx 启动脚本:
start.sh
- 开启Nginx:
/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/bin/start.sh
- 如果已经开始Nginx,则执行
start.sh
可以重新加载配置文件
- 开启Nginx:
- 添加Nginx 停止脚本:
stop.sh
- 停止Nginx:
/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/bin/stop.sh
- 停止Nginx:
- 脚本运行错误:
- 提示错误:
/bin/bash^M: 解释器错误: 没有那个文件或目录
- 解决办法:
sed -i 's/\r$//' ../lua_project_v0.01/bin/start.sh
- 解决 linux下编译make文件报错“/bin/bash^M: 坏的解释器:没有那个文件或目录” 问题
- 提示错误:
-
ngx_lua_waf 安装使用(ngx_lua_waf是一个基于lua-nginx-module(openresty)的web应用防火墙)
- ngx_lua_waf github 地址
- 安装步骤
- 下载源码到某一目录:复制目录到
application
下面,同时重命名waf
- 命令:
cp -R ngx_lua_waf /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/waf
- 移动源文件目录中的
config.lua
文件到../lualib/vendor
下 - 修改waf 目录下的
init.lua
文件的第一行:require 'config'
修改为require 'vendor.config'
- 在
domains
目录下,新建文件waf.conf
,添加以下内容lua_shared_dict limit 10m; init_by_lua_file "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/waf/init.lua"; access_by_lua_file "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/waf/waf.lua"; server { listen 8082; server_name localhost; index index.php index.html index.htm; access_log /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/logs/waf_access.log; error_log /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/logs/waf_error.log error; set $web_root /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/template/waf; root $web_root; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { fastcgi_pass unix:/var/run/php7.0.9-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
- 重启Nginx即可
tinywan@tinywan:~$ /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/bin/start.sh [ Nginx running ] nginx: the configuration file /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/conf/nginx.conf syntax is ok nginx: configuration file /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/conf/nginx.conf test is successful [ Nginx has reload ]
- 可能会遇到的错误
- [1]
nginx: [emerg] open() "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/conf/fastcgi_params" failed
解决:
cp fastcgi_params /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/conf/fastcgi_params
- [2]
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
解决:查看
waf.conf
配置信息是否正确
- [1]
- 下载源码到某一目录:复制目录到
-
修改文件:
config.lua
black_fileExt={"php","jsp"} ipWhitelist={"127.0.0.1"} --ipBlocklist={"1.0.0.1"} ipBlocklist={"192.168.127.133"}
-
测试一:
http://127.0.0.1:8082/waf.php?id=../etc/passwd&name=Tinywan
-
测试二:
http://192.168.127.133:8082/waf.php?id=../etc/passwd&name=Tinywan
-
💩 坑 💩 在提交代码的时候
waf
目录一直提交不了,提示:modified: xxx(modified content, untracked content)
, 原来在waf
目录下有个.git 目录,删除.git目录,重新git add 就可以了
- 第一版采用单模块设计
- 简单的MVC模式,目录、命名约定(Phalcon MVC)
- Model(模型)负责在数据库中存取数据
- View(视图)是应用程序中处理数据显示的部分
- Controller(控制器)通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据
- 第一个简单的 mvc 模式的文件路径访问
-
配置文件:
nginx_product.conf
#upstream upstream item_http_upstream { server 192.168.1.1 max_fails=2 fail_timeout=30s weight=5; server 192.168.1.2 max_fails=2 fail_timeout=30s weight=5; } #缓存 共享字典配置 lua_shared_dict item_local_shop_cache 600m; # server product server { listen 8082; server_name 127.0.0.1; charset gbk; index index.html index.htm; access_log /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/logs/product_access.log; error_log /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/logs/product_error.log error; #加载模板文件 set $template_root /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/template; #url映射 location ~* "^/product/(\d+)\.html$" { rewrite /product/(.*) http://127.0.0.1:8082/$1 permanent; } # chapter location ~* "^/(\d{6,12})\.html$" { default_type text/html; lua_code_cache on; content_by_lua_file "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/controller/ProductController.lua"; } }
-
当我们访问页面:
http://127.0.0.1:8082/13669361192.html
将交给lua_project_v0.01/application/controller/ProductController.lua
处理curl -k http://127.0.0.1:8082/13669361192.html Hello ProductController.lua uri = /13669361192.html
-
项目入口搞定 🌺 🌺 🌺 🌺
-
💐 lua-resty-template 的使用
#加载模板文件 set $template_root "/mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/template/product"; location /template_test { default_type 'text/html'; content_by_lua ' local template = require "resty.template" template.render(chatroom.html, { message = "Hello, World!" }) '; }
-
🌼
resty.template
渲染模板,通过ngx API
输出内容到指定的html
页面
- ✅ helper类的封装
- Example
local helper = require 'vendor.helper' local array = helper.split('a,b,v,b',',') for key,value in ipairs(array) do ngx.say(key, value) end
- Example
- ✅ dkjson 库的加入 👏 👏 👏
- 常用Lua开发库2-JSON库、编码转换、字符串处理
- Example
local dkjson = require 'vendor.dkjson' --lua对象到字符串 local obj = { id = 110, name = "Tinywan", age = 24, is_male = false, hobby = {"film", "music", "read"} } local str = dkjson.encode(obj, {indent = true}) ngx.say(str, "<br/>")
- ✅ 获取Redis数据库数据渲染到html模板页面显示
- 数据显示、文件加载都合适
- ❌ 问题:JS、CSS样式文件路径不合适
- ✅ Nginx+Lua逻辑开发 Redis 做为页面缓存
- Nginx 配置文件:
nginx_live.conf
- Lua 文件:
LiveRedisCacheController.lua
http://127.0.0.1:8088/ad/133456
有缓存返回:{"content":"Redis Cache Data"}
http://127.0.0.1:8088/ad/13345
没有缓存返回:{"content":"MYSQL DATA \n"}
- Nginx 配置文件:
- ✔️ 发布一个V0.01 版本 ✏️ ✏️ ✏️ ✏️
- ✅ 历史遗留问题解决:模板页面的JS、CSS样式文件加载不合适,忘记了Nginx处理静态资源的配置,添加以下代码OK
#配置Nginx动静分离,定义的静态页面直接从Nginx发布目录读取。 location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ { root /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/template/info; #expires定义用户浏览器缓存的时间为7天,如果静态页面不常更新,可以设置更长,这样可以节省带宽和缓解服务器的压力 expires 7d; }
- 访问页面:
http://192.168.127.133:8083/2017TinywanInfo
可以得到响应内容
- 标准os库,待补充 ❎ ❎ ❎
os.rename(oldname, newname)
:文件重命名os.remove(filename)
:删除一个文件os.execute(cmd)
:os.execute可运行一条系统命令,类似于C语言的system函数,os.execute("mkdir /tmp/cq")
os.exit(code)
:中止当前程序的执行,code参数默认值为true。os.getenv(variable)
:返回环境变量的值,如果不存在,返回nil,print(os.getenv('HOME')) -- /root
os.time(tb)
:返回一个指定时间点的UNIX时间戳,如不带参数调用的话,就返回当前时间点的UNIX时间戳
- API 的设计
- 版本:
0.1
- 专用端口:
8686
- 配置文件
location ~ ^/app/([-_a-zA-Z0-9/]+)$ { set $id $1; content_by_lua_file /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/api/${id}.lua; }
- curl访问地址:
curl http://127.0.0.1:8686/0.1/app/web文件名
- 访问案例:
curl http://127.0.0.1:8686/0.1/app/web
,将会执行web.lua
文件
- 版本:
- 如何使用API接口
- ✅ 创建对象:
curl -X POST \ -H "X-LC-Id: 558e20cbe4b060308e3eb36c" \ -H "X-LC-Key: cbe4b06030558e208e3eb36c20cbe4b060308e3eb36c" \ -H "Content-Type: application/json" \ -d '{"name": "Tinywan","age": "26","tel": 13669361192}' \ http://127.0.0.1:8686/0.1/users
- ✅ 查询信息:
curl -X GET \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -G \ --data-urlencode 'id=9090' http://127.0.0.1:8686/0.1/users
- ✅ 更新对象:
curl -X PUT \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{appkey}}" \ -H "Content-Type: application/json" \ -d "name=tinywan&age=26" \ http://127.0.0.1:8686/0.1/users
- ✅ 删除对象:
curl -X DELETE \ -H "X-LC-Id: {{appid}}" \ -H "X-LC-Key: {{masterkey}},master" \ -G \ --data-urlencode 'id=10' \ http://127.0.0.1:8686/0.1/users
- ✅ 创建对象:
- 活动直播接口 API 数据访问Redis,如果没有则回源到后端Mysql数据库
- nginx.conf配置
# 直播接口数据 location ~ ^/0.1/live/([-_a-zA-Z0-9/]+) { content_by_lua_file /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/api/$1.lua; } # Redis 没有缓存数据则后端Mysql查询数据 location /sub { internal; proxy_pass http://127.0.0.1:8686/backend/mysql; } # Backend Mysql Data location /backend/mysql { content_by_lua_block { ngx.say("backend post: Mysql ") } }
- 请求Example:
- 访问如:
http://127.0.0.1:8686/0.1/live/live_redis_mysql?id=1122334
即可得到结果。而且注意观察日志,第一次访问时不命中Redis,回源到Mysql;第二次请求时就会命中Redis了。 - 第一次访问时将看到../logs/api_error.log输出类似如下的内容,而第二次请求相同的url不再有如下内容
live_redis_mysql.lua:122: redis not cache content, Content comes from mysql , id : 1122334, live_redis_mysql.lua:125: Content comes from Redis, id = 1122334,
- live_redis_mysql.lua
- 访问如:
- nginx+lua+redis实现反向代理
- 端口:
8687
- UpstreamBackendController.lua
- 参考文档:利用nginx+lua+redis实现反向代理方法教程
- 虚拟主机的项目根目录自定义,方便灵活修改
- 配置案例:
server { listen 8080; # 定义项目根目录,在此本项目目录为虚拟机目录,你可以自定义为 /home/www/ set $project_path /mnt/hgfs/Linux-Share/Lua/; location /cjson_decode_pcall { content_by_lua_file "${project_path}lua_project_v0.01/application/demo/cjson.lua"; }
- API接口先查询Redis缓存数据,如果没有则到Mysql数据库查询获取,同时缓存数据到Redis中
- 访问地址返回数据:
tinywan@tinywan:~$ curl http://127.0.0.1:8686/0.1/live/live_redis_to_mysql?id=3
{"1":{"age":"24","name":"tinywan","address":"China","id":"3"},"Data_Sources":"Redis Cache Content"}
- 获取Get 参数查询Mysql数据同时把数据在模板页面显示出来
- 参考代码:
local template = require "resty.template" local mysql = require 'vendor.mysql_fun' local helper = require "vendor.helper" local arg = helper.http_args() local live_id = arg.live_id local res = mysql.select(live_id) local address = "" if res.error_code == 200 then address = res.result.address end template.render(chatroom.html, { hls_address = address })
- 商品的详情页页面数据显示(数据存储(Redis)的时候使用json格式存储,键约定:
ITEM:${Product_Id}
) - 配置文件:
nginx_product.conf
- 控制器文件:
ItemController.lua
- 访问路径:
http://127.0.0.1:8087/item/13669361192
即可把Redis的缓存数据渲染到html页面 - 所有的静态文件罗列在一个地方:
- Nginx配置:
root /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/public;
- Html页面加载:
<script src="/video-js/videojs-contrib-hls.min.js"></script>
- Nginx配置:
- 下来要做的就是动态加载模板和数据、缓存处理...
- 一个简单的http请求获取数据,先Redis,再后台数据API,然后缓存在Redis(待优化,现在只是跑通一个DEMO)
- 访问地址:
curl http://127.0.0.1:8088/live/1108
,请注意查看Log日志文件的变化 - 主要代码
# 入口Lua文件的调用 location ~ ^/live/(\d+)$ { set $id $1; content_by_lua_file "lua_project_v0.01/application/controller/LiveRedisCacheController.lua"; } # 请求后端服务器的API接口查询数据,接口返回数据格式为Json格式 location ~ /openapi/(.*) { internal; proxy_pass http://www.baidu.com; }
- 做个压力测试(主要是Redis连接数,并发太多将会出现超时问题,
netstat
查看Redis连接数,好多"TIME OUT"),测试很糟糕的,QPS好低哦! - ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ ❌ 这块一定要优化!80%就大工搞成了 ❌ ❌ ❌ ❌
- 修改后端API请求方式,由
ngx.location.capture
转换为:resty.http
- 可能出现的错误:
resty.http API request error :no resolver defined to resolve "sewise.baidu.com"
- 解决办法,nginx.conf server节增加dns解析
resolver 8.8.8.8 114.114.114.114 valid=3600s;
- 可能出现的错误:
- 别人的建议:
- 添加二级缓存(ngx.cache)
- 访问地址:
http://127.0.0.1:8088/live/1063
- 缓存记录表
+-------------+ +-------------+ +-------------+ +-------------+ | 第一次访问 |--->| ngx_cache |--->| redis_cache |--->| backend API | +-------------+ +-------------+ +-------------+ +-------------+ | +-------------+ +-------------+ +-------------+ | | 第二次访问 |--->| ngx_cache |--->| redis_cache |<---------+ +-------------+ +-------------+ +-------------+ | +-------------+ +-------------+ | | 第三次访问 |--->| ngx_cache |<----------+ +-------------+ +-------------+
- 第一次访问日志记录
[lua] CacheController.lua:145: ngx_cache not found content, request redis db , id : 1066, [lua] CacheController.lua:61: read_redis(): get redis content error : LIVE_TABLE : 1066 [lua] CacheController.lua:151: redis not found content, back to backend API , id : 1066 [lua] CacheController.lua:133: read_http(): content from backend API id : 1066
- 第二次访问日志记录
[lua] CacheController.lua:145: ngx_cache not found content, request redis db , id : 1066 [lua] CacheController.lua:70: read_redis(): content from redis LIVE_TABLE:1066
- 第三次到第N次访问日志记
[lua] CacheController.lua:39: get_cache(): content from ngx.cache id : LIVE_TABLE:1066 [lua] CacheController.lua:39: get_cache(): content from ngx.cache id : LIVE_TABLE:1066 [lua] CacheController.lua:39: get_cache(): content from ngx.cache id : LIVE_TABLE:1066
- 解决缓存失效风暴 lua-resty-lock [二级缓存]
- 缓存时间问题:ngx.cache目前默认为1s
- 访问地址:
- redis使用连接池、锁机制、二级缓存,全部为官方代码,第三方封装好的
redis_iresty
没有使用
resty.websocket.server
和resty.redis
实现聊天室功能- 请求访问地址:
http://192.168.18.180:8088/live/1138
- WebSocketRedisController.lua 文件
- ❌❌❌❌❌❌待解决
lua tcp socket read timed out
问题, - 需要深入研究的API
ngx.thread.spawn
轻线程知识的学习,
set_by_lua
: 流程分支判断,判断变量初始哈rewrite_by_lua
: 用lua脚本实现nginx rewriteaccess_by_lua
: ip准入,是否能合法性访问,防火墙content_by_lua
: 内存生成header_filter_by_lua
:过滤http头信息,增加头信息body_filter_by_lua
: 内容大小写,内容加密log_by_lua
: 本地/远程记录日志- 其实可以只用
content_by_lua
,所有功能都在该阶段完成,也是可以的
- 通过引入已经封装好的Redis类操作Redis数据
- 直接运行curl:
curl http://127.0.0.1/get_redis_iresty
- 官方短连接和长连接测试已通过(本地环境)
- 官方短连接和长连接测试已通过(本地环境)
- 根据IP地址,获取具体IP地址的城市详细信息
- 直接运行curl:
curl http://127.0.0.1/test_ip_location?ip='122.228.95.112'
- 执行shell命令
- 获取Linux的CPU信息:
curl http://127.0.0.1/shell_test
- 服务端文件
lua_websocket_server.lua
,客户端接受文件public/index_default.html
,JS代码public/static/stats_default.js
- 服务端配置location
location /lua_websocket_server { default_type text/html; content_by_lua_file /mnt/hgfs/Linux-Share/Lua/lua_project_v0.01/application/lua_websocket_server.lua; }
- 客户端,通过js
console.log(e.data)
打印接收到的数据,这类我们可以接受到服务端发送的消息
-- 服务端发送文本
bytes, err = wb:send_text("Hello world Tinywan")
--客户端接受数据,通过浏览器Console 可以看到以下数据
Hello world Tinywan
stats_default.js:70 Blob {size: 17, type: ""}
stats_default.js:65 disconnect
stats_default.js:60 connect
- 基于lua-resty-websocket实现系统负载监控
- 使用第三方编写的websocket_shell.lua(原本叫shell.lua) 一个库文件
- 第三方库或者文件引入:
local shell = require 'vendor.websocket_shell'
- 注意:在这里并没有用到
lua-resty-shell
库,有时间整合到一起去 - 效果预览图:
- 配置代理
- 访问8082 服务器代理到8083 服务器代理缓存已经 🆗
- 测试访问:
http://192.168.127.133:8082/2017TinywanInfo
- ❌ 清理缓存配置 ,由于清除模块没有安装,没有进行测试
- 参考文献
- 画图
+-------------+
| uplink |
+-------------+
|
+
MASTER keep|alived BACKUP
172.29.88.224 172.29.88.222 172.29.88.225
+-------------+ +-------------+ +-------------+
| nginx01 |----| virtualIP |----| nginx02 |
+-------------+ +-------------+ +-------------+
|
+------------------+------------------+
| | |
+-------------+ +-------------+ +-------------+
| web01 | | web02 | | web03 |
+-------------+ +-------------+ +-------------+
+-------------+ +-------------+ +-------------+ +-------------+
| 第一次访问 |--->| ngx_cache |--->| redis |--->| backend API |
+-------------+ +-------------+ +-------------+ +-------------+
+-------------+ +-------------+ +-------------+
| 第二次访问 |--->| ngx_cache |--->| redis |
+-------------+ +-------------+ +-------------+
+-------------+ +-------------+
| 第三次访问 |--->| ngx_cache |
+-------------+ +-------------+