• 中文交流区 求助
  • lua redis并发量大的情况下:Cannot assign requested address,来自nginx错误日志

通过jmeter测试
线程数 100,循环次数 1w。一切正常
线程数 1000,循环次数 1w。有1%的异常率
nginx error_log connect() to 172.29.143.79:6379 failed (99: Cannot assign requested address)
线程数 1000,循环次数 100。有0.07%的异常率
nginx error_log connect() to 172.29.143.79:6379 failed (99: Cannot assign requested address)
我想咨询一下 是我的lua脚本有问题,还是并发太大了?

--定义返回结果对象
local resultData = {
    code = 1,
    msg = "",
    data = {}
}
-- json库
local cjson = require("cjson")
-- 连接Redis,身份认证,切换15库
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(6000, 3000, 3000)
local success, err = red:connect("172.29.143.79", 6379,{pool = "point-redis-pool",pool_size=1500,backlog=10000})
if not success then
    resultData.code = 5002
    resultData.msg = err
    ngx.say(cjson.encode(resultData))
    return
end
local res, err = red:auth("5gBdmD4")
if not res then
    resultData.code = 5003
    resultData.msg = err
    ngx.say(cjson.encode(resultData))
    return
end
red:select(15)
-- 用于接收前端数据的对象
local args=nil
-- 获取前端的请求方式,并获取传递的参数
local request_method = ngx.var.request_method
if "GET" == request_method then
        args = ngx.req.get_uri_args()
elseif "POST" == request_method then
        ngx.req.read_body()
        args = ngx.req.get_post_args()
        if (args == nil or args.data == null) then
                args = ngx.req.get_uri_args()
        end
end

-- 获取前端传递的某个参数
local userId = args.userId
local activityId = args.activityId
-- 参数校验
if userId == nil or activityId == nil
then
    resultData.code = 10002
    resultData.msg = "参数为空"
    ngx.say(cjson.encode(resultData))
    return
end

local mqReceiveRecordRedisKey = "skill:mq:1:"..activityId..":"..userId
local mqStatus = red:get(mqReceiveRecordRedisKey)
if (mqStatus ~= nil and mqStatus ~= ngx.null and tonumber(mqStatus) == 1)
then
        resultData.data = tonumber(mqStatus)
else
    local pointAwardHistoryRedisKey = "skill:rec:"..activityId..":"..userId
    local recPointLasted = red:hget(pointAwardHistoryRedisKey,"recPointLasted")
    if(recPointLasted ~=nil and recPointLasted ~= ngx.null and tonumber(recPointLasted) > 0)
    then
        resultData.data = tonumber(recPointLasted)
    else
        resultData.data = 2
    end
end

-- 将其放入一个最大空闲10秒,大小为500的连接池中
local ok, err = red:set_keepalive(60000, 1500)
if not ok then
   resultData.code = 5001
   resultData.msg = err
   ngx.say(cjson.encode(resultData))
   return
end
-- 设置响应头
ngx.header.content_type="application/json;charset=utf8"
--响应结果
ngx.say(cjson.encode(resultData))

    检查下redis的最大连接数设置是多少

    IYism maxclients 10000
    后来我把脚本的set_keepalive(10000,1500)改为set_keepalive(10000,190)
    nginx的wokers改为auto就不会再有这个问题了。

      2 months later

      这是因为本机端口号被耗尽导致的.
      开启 keepalive 后, 会使用长连接, 减少了端口号的使用.

        Write a Reply...