OpenResty安装使用

OpenResty安装使用

在Nginx新版本中没有直接提供Lua模块的集成,Lua脚本模块已经作为第三方集成模块中去了,查看Nginx博客地址可知,集成到OpenResty中,OpenResty由主要国人章亦春维护的项目。

OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

充分利用 Nginx的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。

安装OpenResty

有二进制安装包、源码构建两种方式来安装OpenResty

安装OpenResty

官网提供二进制安装包,以CentOS为例,通过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
# 安装命令行工具 resty
sudo yum install openresty-resty

构建OpenResty

下载解压

# 安装依赖工具
yum install -y pcre-devel openssl-devel gcc curl
# 下载源码包
wget https://openresty.org/download/openresty-1.15.8.1.tar.gz
# 解压构建并安装
tar -xzvf openresty-1.15.8.1.tar.gz
sudo mv openresty-1.15.8.1 openresty
sudo mv openresty /usr/local
cd openresty/

编译选项

可以通过./configure --help来了解,编译的各种选项,例如

......
--without-http_srcache_module      disable ngx_http_srcache_module
--without-http_lua_module          disable ngx_http_lua_module
--without-http_lua_upstream_module disable ngx_http_lua_upstream_module
--without-http_headers_more_module disable ngx_http_headers_more_module
--without-http_array_var_module    disable ngx_http_array_var_module
--without-http_memc_module         disable ngx_http_memc_module
--without-http_redis2_module       disable ngx_http_redis2_module
--without-http_redis_module        disable ngx_http_redis_module
--without-http_rds_json_module     disable ngx_http_rds_json_module
--without-http_rds_csv_module      disable ngx_http_rds_csv_module
--without-stream_lua_module        disable ngx_stream_lua_module
--without-ngx_devel_kit_module     disable ngx_devel_kit_module
--without-http_ssl_module          disable ngx_http_ssl_module
--without-stream_ssl_module        disable ngx_stream_ssl_module
......

你可以这样来添加和去除你想要选择的模块。

./configure --prefix=/opt/openresty \ #指定编译目录,默认为/usr/local/openresty--with-luajit \--without-http_redis2_module \--with-http_iconv_module \--with-http_postgres_module

你也可以使用默认配置

sudo ./configure

编译安装

sudo make
sudo make install

启动OpenResty

实际上openresty使用的是nginx,openresty文件通过链接的形式,连到/usr/local/openresty/nginx/sbin/nginx文件,所以使用openresty与使用nginx并无太大区别。

启动

sudo bin/openresty

关闭

sudo bin/openresty -s stop

测试Lua脚本

编写Lua脚本

cd /usr/local/openresty/
sudo mkdir lua_scripts
cd lua_scripts
sudo vim mydata.lua

往mydata.lua中输入内容

local _M = {}local data = {dog = 5,cat = 3,pig = 1,
}function _M.get_age(name)return data[name]
end
return _M

调整配置

sudo vim /usr/local/openresty/nginx/conf/nginx_lua.conf

配置内容

worker_processes  1;
events {worker_connections 1024;
}http {lua_package_path "/usr/local/openresty/lua_scripts/?.lua;;";server {listen 8080;location /lua {default_type text/html;content_by_lua_block {local mydata = require "mydata"ngx.say(mydata.get_age("dog"))}}}
}

启动测试

sudo bin/openresty -c conf/nginx_lua.conf

有人可能在奇怪,为什么配置文件不是nginx/conf/nginx_lua.conf。那是因为使用nginx/conf/nginx_lua.conf路径,发现报错,错误内容告诉我们找不到配置文件,错误信息里面的路径上多了一个nginx目录。

输出内容

curl http://localhost:8080/lua
5

看到输出内容,表示已经安装成功,并且成功的访问了,实现的一个小小的lua脚本。

使用Redis

《nginx_lua_redis.conf》文件:

worker_processes  1;
events {worker_connections 1024;
}http {# 设置由set_by_lua, content_by_lua等指定的脚本使用的Lua模块搜索路径。类似java的classPath# 路径字符串采用标准的Lua路径形式,;; 可用于代表原始搜索路径。lua_package_path "/usr/local/openresty/lua_scripts/?.lua;;";# 申请一个名为dogs的10m字典内存,共享在所有工作进程中lua_shared_dict dogs 10m;server {listen 8080;location /lua {default_type text/html;lua_code_cache on;# mysql只需要替换成mysql_demo.lua脚本即可content_by_lua_file redis_demo.lua;}}
}

《redis_demo.lua》文件:

local function close_redis(red)  if not red then  return  end  --释放连接(Redis连接池实现)local pool_max_idle_time = 10000 --毫秒  local pool_size = 100 --连接池大小  local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)  if not ok thenngx.say("set keepalive error : ", err)end 
end  local redis = require("resty.redis")  --创建实例  
local red = redis:new()  
--设置超时(毫秒)  
red:set_timeout(1000)  
--建立连接  
local ip = "127.0.0.1"  
local port = 6379  
local ok, err = red:connect(ip, port)  
if not ok then  ngx.say("connect to redis error : ", err)  return close_redis(red)  
end  
--调用API进行处理  
ok, err = red:set("msg", "hello world")  
if not ok then  ngx.say("set msg error : ", err)  return close_redis(red)  
end  --调用API获取数据  
local resp, err = red:get("msg")  
if not resp then  ngx.say("get msg error : ", err)  return close_redis(red)  
end  
--得到的数据为空处理  
if resp == ngx.null then  resp = ''  --比如默认值
end  
ngx.say("msg : ", resp)  close_redis(red) 

使用MySQL

《mysql_demo.lua》文件:

    local function close_db(db)  if not db then  return  end  db:close()  end  local mysql = require("resty.mysql")  --创建实例  local db, err = mysql:new()  if not db then  ngx.say("new mysql error : ", err)  return  end  --设置超时时间(毫秒)  db:set_timeout(1000)  local props = {  host = "127.0.0.1",  port = 3306,  database = "mysql",  user = "root",  password = "123456"  }  local res, err, errno, sqlstate = db:connect(props)  if not res then  ngx.say("connect to mysql error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)  return close_db(db)  end  --删除表  local drop_table_sql = "drop table if exists test"  res, err, errno, sqlstate = db:query(drop_table_sql)  if not res then  ngx.say("drop table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)  return close_db(db)  end  --创建表  local create_table_sql = "create table test(id int primary key auto_increment, ch varchar(100))"  res, err, errno, sqlstate = db:query(create_table_sql)  if not res then  ngx.say("create table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)  return close_db(db)  end  --插入  local insert_sql = "insert into test (ch) values('hello')"  res, err, errno, sqlstate = db:query(insert_sql)  if not res then  ngx.say("insert error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)  return close_db(db)  end  res, err, errno, sqlstate = db:query(insert_sql)  ngx.say("insert rows : ", res.affected_rows, " , id : ", res.insert_id, "
"
) --更新 local update_sql = "update test set ch = 'hello2' where id =" .. res.insert_id res, err, errno, sqlstate = db:query(update_sql) if not res then ngx.say("update error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end ngx.say("update rows : ", res.affected_rows, "
"
) --查询 local select_sql = "select id, ch from test" res, err, errno, sqlstate = db:query(select_sql) if not res then ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end for i, row in ipairs(res) do for name, value in pairs(row) do ngx.say("select row ", i, " : ", name, " = ", value, "
"
) end end ngx.say("
"
) --防止sql注入 local ch_param = ngx.req.get_uri_args()["ch"] or '' --使用ngx.quote_sql_str防止sql注入 local query_sql = "select id, ch from test where ch = " .. ngx.quote_sql_str(ch_param) res, err, errno, sqlstate = db:query(query_sql) if not res then ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end for i, row in ipairs(res) do for name, value in pairs(row) do ngx.say("select row ", i, " : ", name, " = ", value, "
"
) end end --删除 local delete_sql = "delete from test" res, err, errno, sqlstate = db:query(delete_sql) if not res then ngx.say("delete error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end ngx.say("delete rows : ", res.affected_rows, "
"
) close_db(db)

《nginx_lua_msyql.conf》文件和上面的nginx_lua_redis.conf差不多,就是替换redis_demo.lua替换为mysql_demo.lua

使用HTTP客户端

OpenResty默认没有提供Http客户端,需要使用第三方提供,从github上搜索相应的客户端,比如lua-resty-http

下载插件

​ 下载lua-resty-http客户端到lualib

cd /usr/local/openresty/lua_scripts  
sudo wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http_headers.lua 
sudo wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http.lua

lua脚本

cd /usr/local/openresty/lua_scripts
sudo vim http_demo.lua

输入内容,参考《http_demo.lua》

nginx配置

参考《nginx_lua_redis.conf》文件,在http部分添加谷歌dns解析器,修改对应的lua脚本文件。

resolver 8.8.8.8;

Lua模板渲染器

动态web网页开发是Web开发中一个常见的场景,Lua中也有许多模板引擎,我们通过lua-resty-template来完成动态页面的渲染。

下载lua-resty-template

cd /usr/local/openresty/lua_scripts
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template.lua
mkdir /usr/example/lualib/resty/html  
cd /usr/local/openresty/lua_scripts
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template/html.lua

使用

lua内容,html_template.lua

local template = require("resty.template")  local context = {  title = "lua模板渲染",  name = "hash同学",  description = "",  age = 20,  hobby = {"电影", "音乐", "阅读"},  score = {语文 = 90, 数学 = 80, 英语 = 70},  score2 = {  {name = "语文", score = 90},  {name = "数学", score = 80},  {name = "英语", score = 70},  }  
}
template.render("resty_template.html", context)

resty_template.html文件的html内容

<html><head><title>{* titile *}title>head><body>{# 不转义变量输出 #}  姓名:{* string.upper(name) *}<br/>  {# 转义变量输出 #}  简介:{{description}}<br/>{# 可以做一些运算 #}  年龄: {* age + 1 *}<br/>  {# 循环输出 #}  爱好:  {% for i, v in ipairs(hobby) do %}  {% if i > 1 then %},{% end %}  {* v *}  {% end %}<br/>  成绩:  {% local i = 1; %}  {% for k, v in pairs(score) do %}  {% if i > 1 then %},{% end %}  {* k *} = {* v *}  {% i = i + 1 %}  {% end %}<br/>  成绩2:  {% for i = 1, #score2 do local t = score2[i] %}  {% if i > 1 then %},{% end %}  {* t.name *} = {* t.score *}  {% end %}<br/>  {# 中间内容不解析 #}  {-raw-}{(file)}{-raw-}  body>
html>

{* var *}:变量输出;

{{ var }}:变量转义输出;

{% code %}:代码片段;

{# comment #}:注释;

{-raw-}:中间的内容不会解析,作为纯文本输出;

{(include_file)}:包含另一个模板文件


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部