关于后端:openresty-http-client工具类luarestyhttp封装

个性

  • 应用连接池

我的项目源码

https://github.com/helloJiu/o…

代码

-- http客户端
-- https://github.com/ledgetech/lua-resty-http
local http = require("resty/http")
local config = {
    max_idle_time = 30000,
    pool_size = 1000,
    timeout = 5000,
    backlog = 1000
}

local _M = {}

function _M.new()
    local instance = {
        timeout = config.timeout or 5000,
        max_idle_time = config.max_idle_time or 60000,
        pool_size = config.pool_size or 1000,
        backlog = config.backlog or 1000,
    }
    setmetatable(instance, { __index = _M })
    return instance
end


function _M:exec(options, func)
    local httpc = http:new()
    -- Sets the socket timeout (in ms) for subsequent operations. 
    httpc:set_timeout(self.timeout)

    -- https://github.com/openresty/lua-nginx-module#tcpsockconnect
    -- pool_size 指定连接池的大小。
    -- 如果省略且未 backlog提供任何选项,则不会创立任何池。如果省略但backlog已提供,
    -- 则将应用等于lua_socket_pool_size 指令的值的默认大小创立池。
    -- 连接池可包容可供pool_size后续调用connect重用的流动连贯,
    -- 但请留神,池外关上的连贯总数没有下限。如果您须要限度关上的连贯总数,
    -- 请指定backlog选项。当连接池超过其大小限度时,
    -- 池中最近起码应用(放弃流动)的连贯将被敞开,认为以后连贯腾出空间。请留神,
    -- cosocket 连接池是每个 Nginx 工作过程而不是每个 Nginx 服务器实例,
    -- 因而此处指定的大小限度也实用于每个 Nginx 工作过程。
    -- 另请留神,连接池的大小一旦创立就无奈更改。此选项首次在v0.10.14发行版中引入。
    options.pool_size = self.pool_size

    -- backlog 如果指定,此模块将限度此池的关上连贯总数。
    -- pool_size任何时候都不能为此池关上更多的连贯。
    -- 如果连接池已满,后续连贯操作将排入与此选项值相等的队列(积压队列)。
    -- 如果排队的连贯操作数等于backlog,后续连贯操作将失败并返回nil谬误字符串"too many waiting connect operations"。
    -- 一旦池中的连接数小于 ,排队的连贯操作将复原pool_size。
    -- 排队的连贯操作将在排队超过 时停止connect_timeout,由 settimeouts管制,并返回nil谬误字符串。
    -- "timeout". 此选项首次在v0.10.14发行版中引入。
    options.backlog = self.backlog
    options.ssl_verify = false
    local ok, err = httpc:connect(options)
    if not ok then
        ngx.log(ngx.ERR, "http connect, err:", err)
        return nil, err
    end

    -- 执行业务逻辑
    local res, err = func(httpc)
    if not res then 
        ngx.log(ngx.ERR, "http request, err:", err)
        return nil, err
    end
    -- 读取响应体
    local res_body = ""
    if res.status == 200 and res.has_body then
        local reader = res.body_reader
        local buffer_size = 4096
        repeat
            local buffer, err = reader(buffer_size)
            if err then 
                ngx.log(ngx.ERR, "reader err", err)
                break
            end

            if buffer then
                res_body = res_body .. buffer
            end
        until not buffer
    end

    -- 将连贯放回连接池
    local ok = httpc:set_keepalive(self.max_idle_time, self.pool_size)
    if not ok then
        httpc:close()
    end
    -- 返回响应体  响应  以及err
    return res_body, res, err
end



return _M

理论应用

local http = require("http")
local path = string.format("/cgi-bin/qrcode/create?access_token=%s", "accessToken")
local httpi = http.new()
local options = {
    scheme = "https",
    host = "api.weixin.qq.com",
    port = "443",
}

local scene_str = "abc"
local body = {
    expire_seconds = 3600*24,
    action_name = "QR_SCENE",
    action_info = {
        scene = {
            scene_str = scene_str
        }
    }
}
local resBody, res, err = httpi:exec(options, function(httpc)
    return httpc:request({
        method = "POST",
        path = path,
        body = json.encode(body),
        headers = {["Content-Type"] = "application/json",},
    })
end)

if not res then
    ngx.log(ngx.ERR, "=============>send message request failed: ", err)
    return nil
end
log.notice(resBody)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理