前言
公司最近要做一个短信的运营功能,需要短信中有短链接,点击进入微信小程序或者公众号的功能,因此采用nginx采用lua脚本访问Redis,进行短链的重定向
安装准备
环境 centos 7.9、nginx 1.18.0、luajit2-2.0.5、redis 5.0
在centos安装C++,openssl,lua 组件
# 安装C++ 依赖库
yum install -y gcc gcc-c++
# 安装openssl 依赖库
yum -y install openssl openssl-devel make zlib zlib-devel gcc gcc-c++ libtool pcre pcre-devel
下载安装 luajit2-2.0.5
# 下载文件统一放在root目录下
cd /root
访问 https://github.com/openresty/luajit2/releases/tag/v2.0.5
将下载的文件上传到 centos /root目录下
# 解压luajit2-2.0.5.tar.gz
tar zxvf /root/luajit2-2.0.5.tar.gz -C /usr/local/src
# 进入 luajit2-2.0.5解压路径
cd /usr/local/src/luajit2-2.0.5
# 编译并安装luajit2-2.0.5
make PREFIX=/usr/local/luajit2-2.0.5
make install PREFIX=/usr/local/luajit2-2.0.5
配置luajit2-2.0.5 环境变量
# 下面内容写入/etc/profile文件
echo "export LUAJIT_LIB=/usr/local/luajit2-2.0.5/lib" >>/etc/profile
echo "export LUAJIT_INC=/usr/local/luajit2-2.0.5/include/luajit-2.0" >>/etc/profile
# 配置立即生效
source /etc/profile
# 配置 luajit2-2.0.5 软链
ln -s /usr/local/luajit2-2.0.5/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2
下载 pcre (目的是让 nginx 支持 Rewrite 功能)
# 下载 pcre-8.35.tar.gz
wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
# 解压 pcre-8.35.tar.gz
tar zxvf /root/pcre-8.35.tar.gz -C /usr/local
# 配置、编译、安装
cd /usr/local/pcre-8.35
./configure
make
make install
# 查看PCRE版本命令:pcre-config --version 显示版本说明安装成功
下载 ngx_devel_kit和lua-nginx-module
访问 https://github.com/vision5/ngx_devel_kit/releases
访问 https://github.com/openresty/lua-nginx-module/releases/tag/v0.10.13
将上面下载的 ngx_devel_kit-0.3.1.tar.gz lua-nginx-module-0.10.13.tar.gz 上传到centos /root 目录下
# 解压 ngx_devel_kit-0.3.1.tar.gz、lua-nginx-module-0.10.13.tar.gz 到/usr/local/src目录
tar zxvf /root/ngx_devel_kit-0.3.1.tar.gz -C /usr/local/src
tar zxvf /root/lua-nginx-module-0.10.13.tar.gz -C /usr/local/src
下载安装nginx 1.18.0
# 下载 nginx-1.18.0.tar.gz
wget http://nginx.org/download/nginx-1.18.0.tar.gz
# 解压 nginx-1.18.0.tar.gz
tar zxvf /root/nginx-1.18.0.tar.gz -C /usr/local/src
# 进入 解压目录
cd /usr/local/src/nginx-1.18.0
# NGINX配置
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/var/lock/subsys/nginx --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --with-http_v2_module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-ipv6 --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-threads --with-stream --with-stream_ssl_module --add-module=/usr/local/src/ngx_devel_kit-0.3.1 --add-module=/usr/local/src/lua-nginx-module-0.10.13
# 编译、安装nginx
make & make install
# 查看NGINX安装状态,显示版本号说明安装成功
/usr/local/nginx/sbin/nginx -v
下载安装 lua-resty-redis
访问 https://codeload.github.com/agentzh/lua-resty-redis/tar.gz/v0.26下载lua-resty-redis-0.26.tar.gz文件后,上传到服务器 /root目录下
# 解压lua-resty-redis-0.26.tar.gz
tar zxvf /root/lua-resty-redis-0.26.tar.gz -C /usr/local/src
# 进入lua-resty-redis-0.26 解压目录
cd /usr/local/src/lua-resty-redis-0.26/lib/resty
# 将redis.lua拷贝到nginx安装目录
cp redis.lua /usr/local/nginx/redis.lua
# 安装 lua 依赖库
yum -y install lua*
redis 5的安装请参考
https://blog.csdn.net/penganchunyan/article/details/119041820?spm=1001.2014.3001.5502
可以使用java程序将短链的key-valu写入redis
格式如下
key url:yhdfy67
value https://mp.weixin.qq.com/s/DATWREV454GHUHTYHRYUUEEIMCHH
编写lua脚本实现nginx连接redis,完成短链的转发
1.在NGINX安装目录新建lua文件夹,lua文件下创建short-url.lua 赋予此文件执行权限,内容如下
--获取请求的完整URL地址
local url = ngx.var.uri
--判断参数是否小于7位
if string.len(url) < 7 then
ngx.say("抱歉:访问的页面不存在!")
return
end
--redis连接放入连接池
local function close_redis(redis_instance)
if not redis_instance then
return
end
local pool_max_idle_time = 300000 --毫秒
local pool_size = 5 --连接池大小
local cl, err = redis_instance:set_keepalive(pool_max_idle_time, pool_size)
if not cl then
ngx.say("set keepalive error : ", err)
end
end
--获取指定字符串最后出现的索引值
local find = string.find
local function lastIndexOf(haystack, needle)
local i, j
local k = 0
repeat
i = j
j, k = find(haystack, needle, k + 1, true)
until j == nil
return i
end
local redis = require('resty.redis')
--local redis = require "redis"
-- 创建一个redis对象实例。在失败,返回nil和描述错误的字符串的情况下
local redis_instance = redis:new()
--设置后续操作的超时(以毫秒为单位)保护,包括connect方法
redis_instance:set_timeouts(2000,2000,2000)
--尝试连接到redis服务器正在侦听的远程主机和端口
local ok,err = redis_instance:connect("127.0.0.1",6379)
if not ok then
ngx.say("connect redis error : ",err)
return close_redis(redis_instance)
end
--密码和选择的数据库,没有密码可以注释 redis_instance:auth("你的redis密码")
redis_instance:auth("你的redis密码")
redis_instance:select(1)
--调用API进行处理
--local resp,err = redis_instance:set("msg","hello world")
--if not resp then
-- ngx.say("set msg error : ",err)
-- return close_redis(redis_instance)
--end
--1.获取URL中的参数,截取后6位
--local url_key = string.sub(url,-6)
--2.按最后'/'截取后面的字符串
local last=lastIndexOf(url,'/')+1
local url_key = string.sub(url,last,-1)
--调用API获取数据
local resp, err = redis_instance:get("url:"..url_key)
if not resp then
--ngx.say("get msg error : ", err)
resp = "http://www.baidu.com"
end
--默认页面
if resp == ngx.null then
resp="http://www.baidu.com"
end
--跳转页面
ngx.redirect(resp)
--关闭redis连接
return close_redis(redis_instance)
nginx.conf 中http模块 配置访问lua文件
http {
# 此处注意
lua_package_path "/usr/local/nginx/redis.lua;;";
server {
listen 80;
server_name ej.cn;
location / {
default_type text/plain;
# 此处注意
access_by_lua_file /usr/local/nginx/lua/short-url.lua;
root html;
index home.html home.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
#root html;
}
}
}
启动nginx即可 /usr/local/nginx/sbin/nginx