前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学成菜-openrestry(1)

自学成菜-openrestry(1)

作者头像
用户2825413
发布2019-07-16 10:43:37
1.2K0
发布2019-07-16 10:43:37
举报
文章被收录于专栏:呆呆熊的技术路

nginx可以定义日志精选的几个变量

http://www.xxx.com/test/a?a=1&age=1

代码语言:javascript
复制
location /test {
    default_type text/html;
    echo "uri:$document_uri;args:$args;param.age=$arg_age;";
    echo "client ip:$remote_addr";
    echo "status:$status;user:$remote_user;$connection_requests";
}

output

代码语言:javascript
复制
uri:/test/a;args:a=1&age=1;param.age=1; client ip:172.17.0.1 status:200;user:;12

上面是一个很乱的输出,简单说下请求参数, <span class="katex">args是请求的参数,arg_age是后面具体的某个参数值

一些建议

有时候需要判断文件是否存在

代码语言:javascript
复制
server {
    root /var/www/example.com;
    location / {
        if (!-f $request_filename) {
            break;
        } 
    }
}

更好的写法

代码语言:javascript
复制
server {
    root /var/www/example.com;
    location / {
        try_files $uri $uri/ /index.html;
    }
}

请求 http://www.xxx.com/test/ <pre>不能识别此Latex公式: request_filename:/data/www/xxx/pay/test/ </pre>uri: /test/ try_files优先尝试是否存在<pre>不能识别此Latex公式: uri,如果不存在尝试</pre>uri/ 否则转向index.html


下面正式进入主题

hello openrestry

代码语言:javascript
复制
location /test {
    default_type text/html;

   content_by_lua '
        ngx.say("Hello Openrestry")
        ngx.say(ngx.localtime() )
   ';
}

打印字符串 返回当前时间

简单的内部调用

代码语言:javascript
复制
location = /getname {
    #此处表示属于内部调用,外部无法直接访问
    internal;

    default_type text/html;
    content_by_lua '
            local params = ngx.req.get_uri_args();
            ngx.print(params.name);
    ';
}
代码语言:javascript
复制
location = /test {
    default_type text/html;

   content_by_lua '
        local res = ngx.location.capture(
                "/getname", {args={name=ngx.var["arg_name"],age=18}}
                )

        ngx.say(ngx.var["arg_name"]);
        ngx.say("status:", res.status, " response:", res.body)

   ';
}
代码语言:javascript
复制
请求url: http://www.xxx.com/test?name=bbb 
output : bbb status:200 response:bbb

关键词: ngx.location.capture 发起请求, ngx.var["arg_name"]访问uri参数变量, ngx.say和ngx.print都属于输出数据,但ngx.say会自动在后面加\n ngx.location.capture 是非阻塞的,ngx.location.capture也可以用来完成http请求,但是它只能请求到相对于当前nginx服务器的路径,不能使用之前的绝对路径进行访问

方法1

代码语言:javascript
复制
location = /getname {

    internal;

    default_type text/html;
    content_by_lua '
            local params = ngx.req.get_uri_args();
            ngx.print(params.name);
    ';
}

方法2

代码语言:javascript
复制
location = /getage {

    internal;

    default_type text/html;
    content_by_lua '
            local params = ngx.req.get_uri_args();
            ngx.print(params.age);
    ';
}

并行调用并输出返回值

代码语言:javascript
复制
location = /test {
    default_type text/html;

   content_by_lua '
        local res1,res2 = ngx.location.capture_multi{
                {"/getage",{args="age=16&sex=1"}},
                {"/getname",{args={name=ngx.var["arg_name"]}}}
            }

        ngx.say("status:", res1.status, " response:", res1.body)
        ngx.say("status:", res2.status, " response:", res2.body)
    ';
 }

可使用ngx.sleep(0.1) 延迟测试,ngx.now()获取毫秒级时间戳,ngx.time()返回秒级别

代码语言:javascript
复制
location = /getname {
    default_type text/html;
    content_by_lua '
       ngx.say(123)
    ';
}

http重定向302跳转

代码语言:javascript
复制
location = /test {
    default_type text/html;

    rewrite_by_lua '
        return ngx.redirect("/getname")
    ';
 }

内部执行

代码语言:javascript
复制
location = /test {
    default_type text/html;

    rewrite_by_lua '
        return ngx.exec("/getname")
    ';
 }

ngx.exec 方法与 ngx.redirect 是完全不同的,前者是个纯粹的内部跳转并且 没有引入任何额外 HTTP 信号

获取请求参数

获取一个 uri 有两个方法: ngx.req.get_uri_args 、ngx.req.get_post_args

关于指令的优先级问题

代码语言:javascript
复制
location = /test {
    default_type text/html;

    content_by_lua '
        ngx.say("hello")
    ';

    rewrite_by_lua '
        ngx.say("rewirite")
    ';
    access_by_lua '
        ngx.say("access")
    ';
 }

会执行rewrite_by_lua,因为它的优先级比 其他要高

指定lua文件运行

代码语言:javascript
复制
location = /test {
    default_type text/html;

    content_by_lua_file /usr/server/openresty/nginx/conf/vhost/content.lua;
 }

content.lua

代码语言:javascript
复制
ngx.say("hello world")

其他access_by_lua_file、access_by_lua_file用法类似

init_by_lua init_by_lua_file

main.conf

代码语言:javascript
复制
init_by_lua '
    cjson = require "cjson"
';

server {
    ....
}

contnet.lua

代码语言:javascript
复制
ngx.say(cjson.encode({dog=5,cat=6}))
--output {"dog":5,"cat":6}

中断执行

代码语言:javascript
复制
ngx.exit(ngx.HTTP_OK)
ngx.exit(404)

value = ngx.HTTP_CONTINUE (100) (first added in the v0.9.20 release)
value = ngx.HTTP_SWITCHING_PROTOCOLS (101) (first added in the v0.9.20 release)
value = ngx.HTTP_OK (200)
value = ngx.HTTP_CREATED (201)
value = ngx.HTTP_ACCEPTED (202) (first added in the v0.9.20 release)
value = ngx.HTTP_NO_CONTENT (204) (first added in the v0.9.20 release)
value = ngx.HTTP_PARTIAL_CONTENT (206) (first added in the v0.9.20 release)
value = ngx.HTTP_SPECIAL_RESPONSE (300)
value = ngx.HTTP_MOVED_PERMANENTLY (301)
value = ngx.HTTP_MOVED_TEMPORARILY (302)
value = ngx.HTTP_SEE_OTHER (303)
value = ngx.HTTP_NOT_MODIFIED (304)
value = ngx.HTTP_TEMPORARY_REDIRECT (307) (first added in the v0.9.20 release)
value = ngx.HTTP_BAD_REQUEST (400)
value = ngx.HTTP_UNAUTHORIZED (401)
value = ngx.HTTP_PAYMENT_REQUIRED (402) (first added in the v0.9.20 release)
value = ngx.HTTP_FORBIDDEN (403)
value = ngx.HTTP_NOT_FOUND (404)
value = ngx.HTTP_NOT_ALLOWED (405)
value = ngx.HTTP_NOT_ACCEPTABLE (406) (first added in the v0.9.20 release)
value = ngx.HTTP_REQUEST_TIMEOUT (408) (first added in the v0.9.20 release)
value = ngx.HTTP_CONFLICT (409) (first added in the v0.9.20 release)
value = ngx.HTTP_GONE (410)
value = ngx.HTTP_UPGRADE_REQUIRED (426) (first added in the v0.9.20 release)
value = ngx.HTTP_TOO_MANY_REQUESTS (429) (first added in the v0.9.20 release)
value = ngx.HTTP_CLOSE (444) (first added in the v0.9.20 release)
value = ngx.HTTP_ILLEGAL (451) (first added in the v0.9.20 release)
value = ngx.HTTP_INTERNAL_SERVER_ERROR (500)
value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501)
value = ngx.HTTP_BAD_GATEWAY (502) (first added in the v0.9.20 release)
value = ngx.HTTP_SERVICE_UNAVAILABLE (503)
value = ngx.HTTP_GATEWAY_TIMEOUT (504) (first added in the v0.3.1rc38 release)
value = ngx.HTTP_VERSION_NOT_SUPPORTED (505) (first added in the v0.9.20 release)
value = ngx.HTTP_INSUFFICIENT_STORAGE (507) (first added in the v0.9.20 release)

记录日志 ngx.log

代码语言:javascript
复制
ngx.log(ngx.ERR,"error!error!error!")
ngx.STDERR
ngx.EMERG
ngx.ALERT
ngx.CRIT
ngx.ERR
ngx.WARN
ngx.NOTICE
ngx.INFO
ngx.DEBUG

查看错误日志 : 2018/07/02 13:52:23 [error] 141#0: *19 [lua] content.lua:2: error!error!error! 在 Nginx 内核中硬编码限制了单条错误信息最长为 2048 字节。这个长度包含了最后的换行符和开始的时间戳。如果信息长度超过这个限制,Nginx 将把信息文本截断

ngx.ctx

这个 Lua 表可以用来存储基于请求的 Lua 环境数据,其生存周期与当前请求相同 (类似 Nginx 变量)。

代码语言:javascript
复制
location /test {
     rewrite_by_lua_block {
         ngx.ctx.foo = 76
     }
     access_by_lua_block {
         ngx.ctx.foo = ngx.ctx.foo + 3
     }
     content_by_lua_block {
         ngx.say(ngx.ctx.foo) --output : 79
     }
 }

一个简单的post内部调用

代码语言:javascript
复制
ocation = /getname {
    default_type text/html;

    content_by_lua '
        ngx.req.read_body()
        ret = ngx.req.get_body_data() --获取body体,包含post数据
        ret = cjson.decode(ret)
        ngx.say(ret.a,ret.b)
    ';
}

主程(post请求)

代码语言:javascript
复制
res = ngx.location.capture(
     '/getname',
     { method = ngx.HTTP_POST, body = '{"a":123,"b":345}' }
 )

ngx.say("status:", res.status, " response:", res.body) --输出

output : status:200 response:123345 cjson包 cjson.encode 将table转成json, cjson.decode 将json转成table

重温 : 调用

代码语言:javascript
复制
redis = {ip='127.0.0.1'}

function redis:new()
    ngx.say(self.ip)
end

redis:new()

: 调用会将自己传递赋给self

redis使用实例

代码语言:javascript
复制
local credis = require('resty.redis')

local redis = credis:new()

redis:set_timeout(1000) -- 1 sec

local ok,err = redis:connect('*****',11368)

if not ok then
    ngx.say(err)
    ngx.eof()
end

local res, err = redis:auth('123456');

if not res then
    ngx.say("failed to authenticate: ", err)
    return
end

--redis:setex('name',60,'test'); 

local res, err = redis:get("name")
    if not res then
        ngx.say("failed to get dog: ", err)
        return
    end

ngx.say(res)

- -把它放入大小为100的连接池中
-- 10秒最大空闲时间
local ok, err = red:set_keepalive(10000, 100)
if not ok then
    ngx.say("failed to set keepalive: ", err)
    return
end

-- redis:close()

setex(key,expire_time,value) https://github.com/openresty/lua-resty-redis

mysql操作

代码语言:javascript
复制
local mysql = require "resty.mysql"

local db,err = mysql:new()

if not db then 
    ngx.say('init failed mysql',err)
end

db:set_timeout(1000)

local ok,err,errcode,sqlstate = db:connect({
    host = "******",
    port = 3306,
    database = "edu_large_data",
        user = "**",
        password = "****",
        charset = "utf8",
        max_packet_size = 1024 * 1024,
})

 if not ok then
     ngx.say("failed to connect: ", err, ": ", errcode, " ", sqlstate)
    eturn
 end


res, err, errcode, sqlstate =
                    db:query("select * from flow_user_stat order by id desc limit 2")

if not res then
       ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
       return
end

db:set_keepalive(0, 100)

ngx.say(cjson.encode(res))

[{"uv":1000,"id":4,"one_uv":80,"platform":2,"ip":700,"module":2,"pv":"1500","wait_time":"55555","ymd":20180703},{"uv":800,"id":3,"one_uv":150,"platform":1,"ip":500,"module":2,"pv":"900","wait_time":"66666","ymd":20180703}]

模拟发起远程post请求

发起请求

代码语言:javascript
复制
local res = ngx.location.capture('/getuser',{
    method = ngx.HTTP_POST,
    body = '{1,2,3}'
})

ngx.say(res.status,res.body)

因为ngx.location.capture只能访问本地,本地转发远程地址

代码语言:javascript
复制
location = /getuser {
         proxy_http_version 1.1;
         proxy_set_header Connection "";
         proxy_pass http://www.xxx.com/getpostuser;
}

模拟远程地址,只把传来值传回去

代码语言:javascript
复制
location = /getpostuser {
    content_by_lua '
        ngx.req.read_body()
          ngx.say(ngx.req.get_body_data() ) 
        ';
}

发起请求方输出 ngx.say(res.status,res.body) : 200 {1,2,3}

安装第三方拓展包

  1. 进入到 /usr/server/openresty/lualib/resty目录,
  2. wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http_headers.lua
  3. wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http.lua
  4. local http = require "resty.http"

痛苦使用resty.http发送请求

上面已经安装了resty.http包,下面直接请求远程的接口(实际还是本机)

代码语言:javascript
复制
 local http = require "resty.http"

      local httpc = http.new()
      local res, err = httpc:request_uri("http://XXXX/getpostuser", {
        method = "POST",
        body = "a=1&b=2",
        headers = {
          ["Content-Type"] = "application/x-www-form-urlencoded",
        }
      })

      if not res then
        ngx.say("failed to request: ", err)
        return
      end

  ngx.say(res.body)

但是一直是失败的,需要配置 resolver,查看本机DNS

cat /etc/resolv.conf

代码语言:javascript
复制
resolver 192.168.65.1;

init_by_lua '
    cjson = require "cjson"
';

server {
    ...
}

再去远程请求本机访问就可以了

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 呆呆熊的技术路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • nginx可以定义日志精选的几个变量
  • 一些建议
  • hello openrestry
  • 获取请求参数
  • 关于指令的优先级问题
  • 指定lua文件运行
  • init_by_lua init_by_lua_file
  • 中断执行
  • 记录日志 ngx.log
  • ngx.ctx
  • 一个简单的post内部调用
  • 重温 : 调用
  • redis使用实例
  • mysql操作
  • 模拟发起远程post请求
  • 安装第三方拓展包
  • 痛苦使用resty.http发送请求
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档