1503707472.401523 [0 127.0.0.1:57076] "auth" "123123"
1503707472.439407 [0 127.0.0.1:57076] "hexists" "sync_pla
1503707473.057015 [0 127.0.0.1:57082] "auth" "123123"
1503707473.094836 [0 127.0.0.1:57082] "hexists" "sync_pla
1503707473.694647 [0 127.0.0.1:57086] "auth" "123123"
1503707473.732524 [0 127.0.0.1:57086] "hexists" "sync_pla
1503707474.308147 [0 127.0.0.1:57092] "auth" "123123"
1503707474.346172 [0 127.0.0.1:57092] "hexists" "sync_pla
追踪openresty工作进程worker的系统调用:
connect(5, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(5, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(5, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(5, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
connect(5, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)

系统调用统计:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 57.54    0.001000           6       174           epoll_wait
 24.22    0.000421          19        22           writev
  8.75    0.000152           7        22        22 connect
  6.44    0.000112           3        44           close
  1.50    0.000026           0        88           sendto
  1.09    0.000019           0       133           write
  0.46    0.000008           0       175           gettimeofday
  0.00    0.000000           0        22           ioctl
  0.00    0.000000           0        22           socket
  0.00    0.000000           0       174        20 recvfrom
openresty 2976 nobody    3w   REG              202,1  4148486  1338754 /usr/local/openresty/nginx/logs/error.log
openresty 2976 nobody    6u  IPv4           39140146      0t0      TCP *:88 (LISTEN)
openresty 2976 nobody    7w   REG              202,1   313582  1338761 /usr/local/openresty/nginx/logs/access.log
openresty 2976 nobody    8u  IPv4           40715012      0t0      TCP xxxxx:42815->xxxxx:80 (ESTABLISHED)
openresty 2976 nobody    9u  unix 0xffff880108fb63c0      0t0 40681448 socket
openresty 2976 nobody   10u   REG                0,9        0     3919 [eventpoll]
openresty 2976 nobody   11u   REG                0,9        0     3919 [eventfd]
openresty 2976 nobody   12u  IPv4           40681475      0t0      UDP xxxx:15451->xxxx:53
openresty 2976 nobody   13u  IPv4           40715040      0t0      TCP xxxx:21521->xxxx:80 (ESTABLISHED)
按照openresty lua-resty-redis模块文档说明,代码中其实使用了长连接的配置。 但事实,当一个协程使用完连接后,没有塞回连接队列.  对的,没有归还连接? 既然没有还回去,其他的请求必然找不到可用的,只能重建新连接。  一开始虽然调用了 redis_conn:set_keepalive 方法,但是没有放对地方,set_keepalive应该放在return前面。。。 也就是说,你每次new的时候,他其实是从全局队列里获取可用的连接. set_keepalive用法:
syntax: ok, err = httpc:set_keepalive(max_idle_timeout, pool_size)
-- 设定 redis 连接信息 local redis_ip = config["redis"]["conn"]["host"] -- ip 地址 local redis_port = config["redis"]["conn"]["port"] -- 端口号 local redis_auth = config["redis"]["conn"]["auth"] -- 密码 -- 获取 Redis 连接 local ok, err = redis_conn:connect(redis_ip, redis_port) if not ok then utils.error(string.format("Redis 连接失败: %s", err)) return ok, err -- 如果密码为空则不需要进行密码验证 if redis_auth ~= "" then -- 如果连接来自于连接池中,get_reused_times() 永远返回一个非零的值 -- 只有新的连接才会进行授权 count, err = redis_conn:get_reused_times() if count == 0 then ok, err = redis_conn:auth(redis_auth) if not ok then utils.error(string.format("redis 授权失败: %s", err)) return ok, err return redis_conn, err
openresty 16499 nobody  291u  IPv4           40783314      0t0      TCP localhost:35450->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  292u  IPv4           40783317      0t0      TCP localhost:39414->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  294u  IPv4           40783319      0t0      TCP localhost:35454->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  295u  IPv4           40783322      0t0      TCP localhost:39418->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  297u  IPv4           40783324      0t0      TCP localhost:35458->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  298u  IPv4           40783327      0t0      TCP localhost:39422->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  300u  IPv4           40783329      0t0      TCP localhost:35462->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  301u  IPv4           40783332      0t0      TCP localhost:39426->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  303u  IPv4           40783334      0t0      TCP localhost:35466->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  304u  IPv4           40783337      0t0      TCP localhost:39430->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  305u  IPv4           40783338      0t0      TCP localhost:35470->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  306u  IPv4           40783341      0t0      TCP localhost:39434->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  307u  IPv4           40783342      0t0      TCP localhost:39436->localhost:8001 (ESTABLISHED)
openresty 16499 nobody  308u  IPv4           40783343      0t0      TCP localhost:39438->localhost:8001 (ESTABLISHED)

虽然这么多在线连接,但对方这么多的连接一点业务数据都没有吐回来,造成了client一直占用该连接,其他人拿不到可用的连接,另外你就算把连接池放大,本地的发起端口也只有理论的65535。

gettimeofday({1503711999, 568024}, NULL) = 0
write(4, "2017/08/26 09:46:39 [info] 16499"..., 85) = 85
epoll_wait(10,
怎么解决? 针对我这个需求, 可以加 timeout 超时 中断请求的。 if task_type == "refresh" then local uri_batch_str = "" for _, urls in pairs(tasks["task_body"]["url_list"]) do -- 获取该URL中域名 domain_name = utils.get_domain_name(urls["url"]) uri = vars.request_uri -- if not uri_batch_str then 以前的代码 if uri_batch_str == "" then -- 修复后的代码 uri_batch_str = ngx.md5(domain_name..uri) uri_batch_str = uri_batch_str..","..ngx.md5(domain_name..uri) utils.info("refresh params is "..uri_batch_str) local p2p_refresh_url = config["api"]["p2p_refresh_api"]..uri_batch_str local status, body = utils.requests(p2p_refresh_url, 'GET', "") if status then local js = json.decode(body) if js["state"]["code"] ~= 0 then -- 0: 成功, -1: 参数不全, -2: 执行失败