Re: 请教:nginx怎么丢弃某个subrequest返回的数据?

463 views
Skip to first unread message

agentzh

unread,
Aug 20, 2012, 1:35:36 AM8/20/12
to Alvin Jiang, openresty
Hello!

2012/8/19 Alvin Jiang wrote:
> 我正在做一个文件共享和多人群聊系统,所有聊天时发送的文件都会存在服务器上。
> 群聊时,当某个人上载一个大文件时,需要将该文件的上传进度广播到所有参与聊天的人的客户端界面上。
> 目前我准备在nginx-upload-progress-module模块上改进,每隔固定的时间(比如1秒)将当前的上传进度通过另外一个消息服务器(基于nginx_push_stream_module实现的)广播给其余的人。
> 该消息服务器和文件上传服务器并不是同一个,而且向该消息服务器发送消息必须采用POST或者websocket。
> 一旦进度消息发出,就不再关心其返回结果;或者当前一个进度消息未返回时就不再发送下一条进度消息。
> 这样我需要丢弃进度消息的响应,不把该消息的响应发送会客户端。
> 我看了您写的echo_nginx_module,但没有和我这个需求相关的东西。
> 请教,这个需求该怎么实现呢?

我的 ngx_srcache 模块中的 srcache_store 指令发起的子请求的响应是被直接忽略的,见

http://wiki.nginx.org/HttpSRCacheModule

你可以参考这个模块的实现。不过对于你的需求本身而言,我觉得或许 ngx_lua 模块更合适一些?见

http://wiki.nginx.org/HttpLuaModule

我同时抄送给了 openresty 邮件列表:https://groups.google.com/group/openresty 那里的
Nginx/OpenResty 用户和开发者或许可以给你更多的意见和建议 :)

Best regards,
-agentzh

agentzh

unread,
Apr 9, 2013, 2:39:55 PM4/9/13
to openresty
Hello!

2013/4/9 li.huang:
>
> 请教怎么让连续多条srcache store指令?
>

你想在一个 location 内部指定多条 srcache_store 指令?这是不行的,你这么做会得到类似下面这条错误消息:

nginx: [emerg] "srcache_store" directive is duplicate in conf/nginx.conf:47

如果你想让把响应存储到多个目标,你可以使用 ngx_lua 模块来服务 srcache_store 对应的子请求,并在 Lua 里自己把数据推送到多个目标。即:

location / {
...
srcache_store PUT /sub $key;
}

location = /sub {
internal;
content_by_lua '
local key = ngx.unescape_uri(ngx.var.arg_key)
local data = ngx.req.get_body_data()
if not data then
ngx.log(ngx.ERR, "no request body data found")
return ngx.exit(500)
end
-- push the data and key to memcached, redis, and/or mysql
-- via lua-resty-memcached, lua-resty-redis, and/or lua-resty-mysql,
-- respecitively
';
}

Best regards,
-agentzh

calio

unread,
Apr 10, 2013, 10:52:10 AM4/10/13
to open...@googlegroups.com
�� 2013/4/10 20:44, li.h...@unlun.com �:
> On Wednesday, April 10, 2013 6:28:55 PM UTC+8, li.h...@unlun.com wrote:
>> On Wednesday, April 10, 2013 2:39:55 AM UTC+8, agentzh wrote:
>>
>>> Hello!
>>> 2013/4/9 li.huang:
>>>> �����ô���������srcache storeָ�
>>> ������һ�� location �ڲ�ָ������ srcache_store ָ����Dz��еģ�����ô����õ�������������������Ϣ��
>>> nginx: [emerg] "srcache_store" directive is duplicate in conf/nginx.conf:47
>>> ��������ð���Ӧ�洢�����Ŀ�꣬�����ʹ�� ngx_lua ģ�������� srcache_store ��Ӧ�������󣬲��� Lua ���Լ���������͵����Ŀ�ꡣ����
>>> location / {
>>> ...
>>> srcache_store PUT /sub $key;
>>> }
>>> location = /sub {
>>> internal;
>>> content_by_lua '
>>> local key = ngx.unescape_uri(ngx.var.arg_key)
>>> local data = ngx.req.get_body_data()
>>> if not data then
>>> ngx.log(ngx.ERR, "no request body data found")
>>> return ngx.exit(500)
>>> end
>>> -- push the data and key to memcached, redis, and/or mysql
>>> -- via lua-resty-memcached, lua-resty-redis, and/or lua-resty-mysql,
>>> -- respecitively
>>> ';
>>> }
>>> Best regards,
>>> -agentzh
>>
>>
>> �dz���л�����ڿ�������˵�ķ������Ͷ��srcache_storeָ���ˡ�����ngx.var.arg_key���ֵ��nil����־���?ngx.var.key�������?����ֵΪ�գ���֪����Ǻá�
>>
>> ����srcache_fetch��Ҳʹ����lua�����ǻ������к���Ȼִ���˺����srcache_store���������������ngx.exit�ĸ���ֵ����̫���룬��������access_by_luaҲ���С�
>>
>> �����ұ���srcache_store��lua resty.memcached��srcache_fetchʹ��memc_nginx_moudle����������к�store�Dz�ִ�еģ���֪��memc get�����к󷵻���ʲô����ʹ�����store��ִ���ˡ�
>>
>> ����store��fetch��ʹ��resty.memcached����Ϊ��2��ģ�鶼����д�ģ�������˵resty.memcached��Ч�ʺ��ڴ��á�
> ��lua_shared_dict�����fetch���к�ִ��store�����⣬����ngx.var.arg_key���ֵʼ����nil���������ú���д��һ������var[key]������ʽ�Ķ��Թ��ˣ�Ҳ���У�����
>
�ܷ�����Nginx�����������û�����õĻ���̫�÷������⡣

srcache_store��Ŀ��location��Ҫ����HTTP status 201����ʾ����Ѿ�д�뻺�档

agentzh

unread,
Apr 10, 2013, 6:27:28 PM4/10/13
to openresty
Hello!

On Tue, Apr 9, 2013 at 11:39 AM, agentzh wrote:
> location / {
> ...
> srcache_store PUT /sub $key;
> }
>
> location = /sub {
> internal;
> content_by_lua '
> local key = ngx.unescape_uri(ngx.var.arg_key)

不好意思,这里有一处笔误。应当把这一行

local key = ngx.unescape_uri(ngx.var.arg_key)

替换为

local key = ngx.var.args

毕竟,在 srcache_store 配置指令中,key 是直接作为 URL querystring 这个整体来传递给子请求的。

Best regards,
-agentzh

agentzh

unread,
Apr 10, 2013, 6:32:39 PM4/10/13
to openresty
Hello!

2013/4/10 li.huang:
> 非常感谢,现在可以用你说的方法发送多个srcache_store指令了。但是ngx.var.arg_key这个值是nil

在我的例子中,应当使用 ngx.var.args 而不是 ngx.var.arg_key.

> 还有srcache_fetch我也使用了lua,但是缓存命中后仍然执行了后续的srcache_store,我在里面加入了ngx.exit的各种值都不太理想,后来改用access_by_lua也不行。

如果真的 srcache_fetch 真的成功命中的话,srcache_store 是不会被执行的。 否则就是 bug.
请提供问题请求对应的 Nginx 的调试日志,见这里:

http://wiki.nginx.org/Debugging#Debugging_log

另外,提供一个最小化的可以复现问题的用例也会对定位问题很有帮助。

最后值得一提的是,access_by_lua 在子请求中根本不会执行的,因为整个 access 请求处理阶段都不会在子请求中执行。

Best regards,
-agentzh

agentzh

unread,
Apr 11, 2013, 3:02:59 PM4/11/13
to openresty
Hello!

2013/4/10 li.huang:
>
> 嗯,按照您说的方法ngx.var.args可以工作了。现在手动使用shared dict让store在fetch命中后不执行,但是抓包看nginx还是回源了。
> 附件是我的配置文件和error.log,请大神修复。
>

你在 nginx 配置文件里面配置了

srcache_fetch GET /acq $key;

但是你的 location /acq 的实现并不符合 srcache_fetch 对子请求的要求。其中存在的两个重要问题是:

1. 你只是简单地访问了一个 memcached 却并没有使用 ngx.print 把 memcached 返回的结果作为子请求的响应体输出。

2. 同时 srcache_fetch 是根据子请求的响应状态码来判断子请求是否成功的,所以你在 location /acq
中进行错误处理时,应当使用 ngx.exit() 返回 500 这样的响应状态码。另外,当 key 在 memcached
中找不到时,应返回 404 状态码。

正因为你没有在 location /acq 中输出 key 对应的值,所以 srcache_fetch 才在你的 nginx 错误日志文件中如是抱怨:

[error] 783#0: *1 srcache_fetch: cache sent truncated status line or headers

srcache_fetch 期望子请求 /acq 返回类似下面这样格式的响应体:

HTTP/1.1 200 OK
Content-Type: text/css

hello world

但是你的 /acq 在成功时返回空响应体,在失败时又返回出错消息(通过 ngx.say)。

你的 location /acq 正确的写法应当是

location = /acq {
internal;
content_by_lua '
local memcached = require "resty.memcached"

local memc, err = memcached:new()
if not memc then
ngx.log(ngx.ERR, "failed to instantiate memc: ", err)
return ngx.exit(500)
end

memc:set_timeout(1000) -- 1 sec

local ok, err = memc:connect("127.0.0.1", 11216)
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return ngx.exit(500)
end

local key = ngx.var.args
local res, flags, err = memc:get(key)
if err then
ngx.log(ngx.ERR, "failed to get www.sina.com.cn_80/: ", err)
return ngx.exit(500)
end
if not res then
print("key not found in memcached: ", key)
return ngx.exit(404)
end

local ok, err = memc:set_keepalive(0, 100)
if not ok then
ngx.log(ngx.ERR, "failed to set keepalive: ", err)
-- here we do not abort the current request because we
-- already have the result.
end

ngx.print(res)
';
}

Best regards,
-agentzh

黄力

unread,
Apr 12, 2013, 2:09:01 AM4/12/13
to open...@googlegroups.com
不好意思,又发现了一个问题,用附件中的配置,在/sub中同时写2个memcached,测试了一段时间后,本地memcached写入了22G,外网的memcahced写入了12G,配置中首先写入的那个memcached是本地的。不知道这是什么原因?2个memcached的数据差异越来越大,最早是差4G现在差10G的数据了,而且在error.log中只发现了连接本地memcached的日志。
而且如果配置本地memcached的ip为127.0.0.1,在error.log中会报错:can't assign address
www.sina.com.cn_80

黄力

unread,
Apr 12, 2013, 2:15:56 AM4/12/13
to open...@googlegroups.com
现在连接本地memcached的真实ip也会报错了,2013/04/12 14:12:51 [crit] 15559#0: *7704979 connect() to 122.225.36.179:11216 failed (99: Cannot assign requested address), client: 122.225.36.178, server: www.sina.com.cn, request: "GET http://www.sina.com.cn/link/bg3626424.jpg HTTP/1.1", subrequest: "/acq", host: "www.sina.com.cn"
不过还是没有发现连接外网memcached的日志。

黄力

unread,
Apr 12, 2013, 2:26:12 AM4/12/13
to open...@googlegroups.com
外网memcached连接抽样
未完全关闭
root@debian:/etc/nginx/proxy# ss -t -a | grep 112.253.18.179:11216 | grep -c TIME
13
连接中
root@debian:/etc/nginx/proxy# ss -t -a | grep 112.253.18.179:11216 | grep -c EST
21
本地memcached连接统计
未完全关闭
root@debian:/etc/nginx/proxy# ss -t -a | grep 122.225.36.179:11216 | grep -c TIME
26095
连接中
root@debian:/etc/nginx/proxy# ss -t -a | grep 122.225.36.179:11216 | grep -c EST
0
总的来说,对外网memcached的连接数量大于TIME-WAIT数量,对本地memcached的TIME-WAIT数量远远大于连接数量。难道还是该用回close?或者set_keepalive的idle time不该设为0?还是其它什么原因?

黄力

unread,
Apr 12, 2013, 4:29:28 AM4/12/13
to open...@googlegroups.com
目前使用附件中的配置,本地memcached可以每秒150个左右的set,而外网memcached每秒只有20个左右的set。
另外就是,每隔一段时间,只有本地memcached有get请求,set请求在本地和外网memcached都没有,但是抓包看的话,nginx回原了,就是说get没有命中,不知道这是怎么回事?
www.sina.com.cn_80

黄力

unread,
Apr 12, 2013, 4:35:14 AM4/12/13
to open...@googlegroups.com
使用以上配置,在sysctl中加入
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
timewait明显减少。

黄力

unread,
Apr 12, 2013, 6:32:42 AM4/12/13
to open...@googlegroups.com
增加set请求可以在/sub里把2个都置为memc:set_timeout(2000),这样set请求会有所增加,但是本地和远程还是2倍的差距。那我要是同时store50个memcached岂不是要memc:set_timeout(50000)?

黄力

unread,
Apr 12, 2013, 6:46:24 AM4/12/13
to open...@googlegroups.com
压力一段时间后,set在2个memcached都消失的原因是,error.log和access.log太大,导致nginx cpu  100%,echo > 以后,set指令在2个memcached又重现了,nginx cpu降到50%左右。
这应该是nginx的缺陷吧,春哥一并修复了吧,呵呵。

黄力

unread,
Apr 12, 2013, 6:57:16 AM4/12/13
to open...@googlegroups.com
我把error_log和access_log都关闭后,set请求数在2个memcached中都翻倍了,这时本地的请求数的区间是0-700,远程是0-600,不再是2倍的差距了。
但是,显然线上必须有日志的,顺便说一下,之前一直是把你的dd函数打开的,:)

agentzh

unread,
Apr 12, 2013, 2:05:08 PM4/12/13
to openresty
Hello!

2013/4/11 li.huang:
> 在我的/sub中连续store多个不同的memcached的方式是不是最有效率的?

我其实并不太明白为什么你要向多个 memcached 写入 :)

> set_keepalive和close哪个效率更好?如果是set_keepalive的话,超时和长连接数量的值应该根据什么设置才能有最好的性能?
>

应当总是使用 set_keepalive,同时连接池的大小应当设置得足够大。否则短连接很容易将你系统的临时端口用尽。

另外,在进行压力测试时,应当禁掉 DDEBUG 和 --with-debug,同时使用 warn 以上的 error_log
日志过滤级别。否则你的 nginx
都忙着刷不带缓冲的错误日志了。另外,你也应设置访问日志的缓冲区或者完全禁掉访问日志(如果你不需要的话),见

http://wiki.nginx.org/HttpLogModule#access_log

最后,如果你的 nginx 进程的 CPU 占用比较高,可以使用“火焰图”(flamegraph)对内部的执行热点进行分析:

https://github.com/agentzh/nginx-systemtap-toolkit#ngx-sample-bt

Regards,
-agentzh

agentzh

unread,
Apr 12, 2013, 2:07:51 PM4/12/13
to openresty
Hello!

2013/4/12 黄力:
> 压力一段时间后,set在2个memcached都消失的原因是,error.log和access.log太大,导致nginx cpu 100%,echo
>> 以后,set指令在2个memcached又重现了,nginx cpu降到50%左右。
> 这应该是nginx的缺陷吧,春哥一并修复了吧,呵呵。
>

这不是 nginx 的缺陷,而是你的配置和编码上的缺陷 :) 你就不应该让 nginx 狂刷错误日志,不慢才怪呢。。。

Regards,
-agentzh

agentzh

unread,
Apr 12, 2013, 2:18:40 PM4/12/13
to openresty
Hello!

2013/4/11 黄力:
> 本地memcached连接统计
> 未完全关闭
> root@debian:/etc/nginx/proxy# ss -t -a | grep 122.225.36.179:11216 | grep -c
> TIME
> 26095
> 连接中
> root@debian:/etc/nginx/proxy# ss -t -a | grep 122.225.36.179:11216 | grep -c
> EST
> 0
> 总的来说,对外网memcached的连接数量大于TIME-WAIT数量,对本地memcached的TIME-WAIT数量远远大于连接数量。

貌似你的连接池未能生效,很可能是因为有连接超时等错误出现。连接上的错误会导致连接被强行关闭。

建议从错误日志中过滤出 [error] 级别的消息查看(当然,首先你等禁掉调试日志)。

同时你应当总是对 set_keepalive() 调用的返回值进行检查,并总是将错误写入日志,通过 ngx.log(ngx.ERR, ...) 这样的调用。

> 难道还是该用回close?

你每调用一次 close(),便必产生一个 TIME_WAIT 状态的连接 :)

> 或者set_keepalive的idle
> time不该设为0?还是其它什么原因?
>

引用一下 ngx_lua 文档中对此参数的描述:

“The first optional argument, timeout, can be used to specify the
maximal idle timeout (in milliseconds) for the current connection. If
omitted, the default setting in the lua_socket_keepalive_timeout
config directive will be used. If the 0 value is given, then the
timeout interval is unlimited.”

所以 0 便是无限制。见 http://wiki.nginx.org/HttpLuaModule#tcpsock:setkeepalive

Best regards,
-agentzh

黄力

unread,
Apr 13, 2013, 3:17:11 AM4/13/13
to open...@googlegroups.com


On Saturday, April 13, 2013 2:05:08 AM UTC+8, agentzh wrote:
Hello!

2013/4/11  li.huang:
> 在我的/sub中连续store多个不同的memcached的方式是不是最有效率的?

我其实并不太明白为什么你要向多个 memcached 写入 :)
我们这个系统大概有这么多的节点,需要缓存同步,50个是下限。 

> set_keepalive和close哪个效率更好?如果是set_keepalive的话,超时和长连接数量的值应该根据什么设置才能有最好的性能?
>

应当总是使用 set_keepalive,同时连接池的大小应当设置得足够大。否则短连接很容易将你系统的临时端口用尽。

另外,在进行压力测试时,应当禁掉 DDEBUG 和 --with-debug,同时使用 warn 以上的 error_log
日志过滤级别。否则你的 nginx
都忙着刷不带缓冲的错误日志了。另外,你也应设置访问日志的缓冲区或者完全禁掉访问日志(如果你不需要的话),见  

http://wiki.nginx.org/HttpLogModule#access_log
按照上述方法做了以后,压力测试 < 2 hours,貌似性能还可以,我的access_log的buffer是文档里描述的32k不知道合不合理,文档里描述的原子写入记录长度好像不是1行日志的长度 。

最后,如果你的 nginx 进程的 CPU 占用比较高,可以使用“火焰图”(flamegraph)对内部的执行热点进行分析:

https://github.com/agentzh/nginx-systemtap-toolkit#ngx-sample-bt
我们这边都是清一色的debian啊,kernel都是2.6的,这么好的工具, 不用确实可惜,用的话,一个一个patch kernel也很麻烦啊。最难受的是,线上的系统还是debian的裁剪版本。

Regards,
-agentzh

黄力

unread,
Apr 13, 2013, 3:19:57 AM4/13/13
to open...@googlegroups.com


On Saturday, April 13, 2013 3:17:11 PM UTC+8, 黄力 wrote:


On Saturday, April 13, 2013 2:05:08 AM UTC+8, agentzh wrote:
Hello!

2013/4/11  li.huang:
> 在我的/sub中连续store多个不同的memcached的方式是不是最有效率的?

我其实并不太明白为什么你要向多个 memcached 写入 :)
我们这个系统大概有这么多的节点,需要缓存同步,50个是下限。 

> set_keepalive和close哪个效率更好?如果是set_keepalive的话,超时和长连接数量的值应该根据什么设置才能有最好的性能?
>

应当总是使用 set_keepalive,同时连接池的大小应当设置得足够大。否则短连接很容易将你系统的临时端口用尽。
我现在连接池设的是512,如果是50个点的话就是512*50,这好像也太大了吧,有没有什么计算公式来算这个值,还是凭经验? 

黄力

unread,
Apr 13, 2013, 5:24:00 AM4/13/13
to open...@googlegroups.com


On Saturday, April 13, 2013 2:18:40 AM UTC+8, agentzh wrote:
Hello!

2013/4/11 黄力:
> 本地memcached连接统计
> 未完全关闭
> root@debian:/etc/nginx/proxy# ss -t -a | grep 122.225.36.179:11216 | grep -c
> TIME
> 26095
> 连接中
> root@debian:/etc/nginx/proxy# ss -t -a | grep 122.225.36.179:11216 | grep -c
> EST
> 0
> 总的来说,对外网memcached的连接数量大于TIME-WAIT数量,对本地memcached的TIME-WAIT数量远远大于连接数量。

 貌似你的连接池未能生效,很可能是因为有连接超时等错误出现。连接上的错误会导致连接被强行关闭。
现在发现对于外网memcached存在不少connect timeout和set timeout,我现在已经memc:set_timeout(600000) ,十分钟,但是好像不到一分钟就timeout了,有没有什么好的解决办法?我现在已经把不同机器的set请求放到corountine里了,见附件,不过这样改的话,更容易把网络带宽耗尽吧?那时timeout就更多了。
set.lua

agentzh

unread,
Apr 13, 2013, 11:42:00 AM4/13/13
to openresty
Hello!

2013/4/13 黄力:
>
>>>
>>> 应当总是使用 set_keepalive,同时连接池的大小应当设置得足够大。否则短连接很容易将你系统的临时端口用尽。
>
> 我现在连接池设的是512,如果是50个点的话就是512*50,这好像也太大了吧,有没有什么计算公式来算这个值,还是凭经验?

对于单个 memcached 后端节点来说,如果 nginx 有 m 个 worker 进程,同时这个 nginx 访问 memcached
的并发度是 N,则应把这个节点的连接池的大小置为 N/m.

Best regards,
-agentzh

agentzh

unread,
Apr 13, 2013, 11:51:41 AM4/13/13
to openresty
Hello!

2013/4/13 黄力li.huang:
>> 貌似你的连接池未能生效,很可能是因为有连接超时等错误出现。连接上的错误会导致连接被强行关闭。
>
> 现在发现对于外网memcached存在不少connect timeout和set
> timeout,

请提供原始的错误日志,而不是自然语言描述,因为后者丢失了很多重要信息 :)

另外,你从运行 nginx 的机器测试过你的外网 memcached
的性能极限么?特别是整体的吞吐量上限。当超过这个服务的负载能力时,自然会看到很多超时。同时由于外网的网络不确定因素多,出现超时的机会本来就大,仔细把你的外网带宽耗尽。

> 我现在已经memc:set_timeout(600000)
> ,十分钟,但是好像不到一分钟就timeout了,有没有什么好的解决办法?

1. 你说超时设置提前触发,你的根据是什么?
2. 使用过大的超时是应绝对避免的,因这这个时间会加进你的请求服务时间中去。
3. 我觉得像这种涉及外网的缓存同步操作还是放在 nginx 外部来做更合适一些。比如换用 redis 作为缓存存储,并使用它的
master-slave replication 机制自己进行数据同步。

> 我现在已经把不同机器的set请求放到corountine里了,见附件,不过这样改的话,

使用 Lua 标准的 coroutine API 并不能让串行请求并行化,只是徒增额外的开销罢了。或许你这里需要的是 ngx.thread.* API?

http://wiki.nginx.org/HttpLuaModule#ngx.thread.spawn

提高后端访问的并发度可以减少单个请求的响应延时,但不会增加系统整体的吞吐量(事实上,整体吞吐量反而会略有下降)。

> 更容易把网络带宽耗尽吧?那时timeout就更多了。

你为什么不直接对你的网络带宽本身进行测试和计量?猜测是得不出结论的 :)

Best regards,
-agentzh

黄力

unread,
Apr 13, 2013, 11:39:57 PM4/13/13
to open...@googlegroups.com


On Saturday, April 13, 2013 11:51:41 PM UTC+8, agentzh wrote:
Hello!

2013/4/13 黄力li.huang:
>>  貌似你的连接池未能生效,很可能是因为有连接超时等错误出现。连接上的错误会导致连接被强行关闭。
>
> 现在发现对于外网memcached存在不少connect timeout和set
> timeout,

请提供原始的错误日志,而不是自然语言描述,因为后者丢失了很多重要信息 :)
好的,今天在家无法登陆server,明天去公司拷贝上来。春哥,这里悄悄的问一句 :CF哪些模块用了lua?

另外,你从运行 nginx 的机器测试过你的外网 memcached
的性能极限么?特别是整体的吞吐量上限。当超过这个服务的负载能力时,自然会看到很多超时。同时由于外网的网络不确定因素多,出现超时的机会本来就大,仔细把你的外网带宽耗尽。
说的是,我到没有测试过从nginx测试机打外网memcached的性能,明天试试。 

> 我现在已经memc:set_timeout(600000)
> ,十分钟,但是好像不到一分钟就timeout了,有没有什么好的解决办法?

1. 你说超时设置提前触发,你的根据是什么?
因为当时我只起了10个并发,从压力开始没多久,error.log里就出了failed to connect......time out和 failed to set .......timedout。之前我以为起100个并发压力太大把带宽耗尽了才会出现这些timeout,没想到起10个并发的压力也一样。
2. 使用过大的超时是应绝对避免的,因这这个时间会加进你的请求服务时间中去。
是啊,我也怕这样,那就不能用了。 
3. 我觉得像这种涉及外网的缓存同步操作还是放在 nginx 外部来做更合适一些。比如换用 redis 作为缓存存储,并使用它的
master-slave replication 机制自己进行数据同步。
这个我们也评估过,但是,我们每个节点的网站缓存数据不一样,再加上往一个redis node写入,让它自己同步到其它node这个有些慢,不得已才想到在srcache里发多条store指令来满足实时同步缓存的目的。 

> 我现在已经把不同机器的set请求放到corountine里了,见附件,不过这样改的话,

使用 Lua 标准的 coroutine API 并不能让串行请求并行化,只是徒增额外的开销罢了。或许你这里需要的是 ngx.thread.* API?

http://wiki.nginx.org/HttpLuaModule#ngx.thread.spawn

提高后端访问的并发度可以减少单个请求的响应延时,但不会增加系统整体的吞吐量(事实上,整体吞吐量反而会略有下降)。
这么好啊!我又激动了,呵呵。 

> 更容易把网络带宽耗尽吧?那时timeout就更多了。

你为什么不直接对你的网络带宽本身进行测试和计量?猜测是得不出结论的 :)
您说的是,明天去仔细测测。 

Best regards,
-agentzh

黄力

unread,
Apr 13, 2013, 11:40:39 PM4/13/13
to open...@googlegroups.com
真好,以后有依据了。 

Best regards,
-agentzh

黄力

unread,
Apr 15, 2013, 2:29:25 AM4/15/13
to open...@googlegroups.com


On Sunday, April 14, 2013 11:39:57 AM UTC+8, 黄力 wrote:


On Saturday, April 13, 2013 11:51:41 PM UTC+8, agentzh wrote:
Hello!

2013/4/13 黄力li.huang:
>>  貌似你的连接池未能生效,很可能是因为有连接超时等错误出现。连接上的错误会导致连接被强行关闭。
>
> 现在发现对于外网memcached存在不少connect timeout和set
> timeout,

请提供原始的错误日志,而不是自然语言描述,因为后者丢失了很多重要信息 :)
好的,今天在家无法登陆server,明天去公司拷贝上来。春哥,这里悄悄的问一句 :CF哪些模块用了lua?
附件是timeout日志, 当时我这台nginx机器上光标都无法移动了,压力程序也报一堆timeout,只有10个并发压力,现在网络怎么这么差啊。
error.log

黄力

unread,
Apr 15, 2013, 2:38:02 AM4/15/13
to open...@googlegroups.com


On Sunday, April 14, 2013 11:39:57 AM UTC+8, 黄力 wrote:
附件的程序,帮忙看看,哪里写的不妥。还有下面写法在wait成功时res是nil 
   local threads = {}
   for _, ip in ipairs(iplist) do
      local tf, err = ngx.thread.spawn(store, memcached, key, data, ip)                                                                                                                                                                    
      if not tf then                                                                                                                                                                                                                       
         ngx.say("failed to spawn thread f: ", err)                                                                                                                                                                                        
         return                                                                                                                                                                                                                            
      end                                                                                                                                                                                                                                  
      table.insert(threads, tf)                                                                                                                                                                                                            
                                                                                                                                                                                     
   end
   for i = 1, #threads do
      local ok, res = ngx.thread.wait(threads[i])
      if not ok then
         say(i, ": failed to run: ", res)
      else                                                                                                                                                                                                                                 
         say(i, ": status: ", res.status)                                                                                                                                                                                                  
         say(i, ": body: ", res.body)                                                                                                                                                                                                      
      end
   end
set.lua

agentzh

unread,
Apr 15, 2013, 2:44:14 AM4/15/13
to openresty
Hello!

2013/4/14 黄力:
>
>
> 附件是timeout日志, 当时我这台nginx机器上光标都无法移动了,压力程序也报一堆timeout,只有10个并发压力,现在网络怎么这么差啊。

看到不少 Connection reset by peer
的错误,很有意思,貌似中间有防火墙之类的东西强行重置连接?其中一些超时也有可能是包被防火墙主动丢弃所致。建议对相关的网络链路进行排查。

Regards,
-agentzh

黄力

unread,
Apr 15, 2013, 2:47:53 AM4/15/13
to open...@googlegroups.com
这么晚还没休息呢,还是不在美国?
能推荐什么工具吗? 

Regards,
-agentzh

黄力

unread,
Apr 15, 2013, 2:50:23 AM4/15/13
to open...@googlegroups.com
tcpdump?wireshark? 

Regards,
-agentzh

黄力

unread,
Apr 15, 2013, 2:52:47 AM4/15/13
to open...@googlegroups.com
可能把机房的防火墙触发了,每个机房我们的点都少,是小用户,IDC的防火墙也许吧。这边nginx经常502都和防火墙有关。 

Regards,
-agentzh

黄力

unread,
Apr 15, 2013, 2:54:05 AM4/15/13
to open...@googlegroups.com
之前压力发起机是没有timeout的,现在很多。当然还没有抓包,纯属猜测。 

Regards,
-agentzh

黄力

unread,
Apr 15, 2013, 2:57:56 AM4/15/13
to open...@googlegroups.com
不过nginx这台机器在worker数从1个改成4个后(并且我按照你说的那个公式假设对memcached是100个连接,所有keepalive设成了25),从errorlog里 timeout减少不少。测了一会就出了2行:
2013/04/15 14:50:17 [error] 14811#0: *80284 connect() failed (110: Connection timed out), client: 122.225.36.178, server: www.sina.com.cn, request: "GET http://www.sina.com.cn/link/bg1000833.jpg HTTP/1.1", subrequest: "/sub", host: "www.\
2013/04/15 14:50:17 [error] 14811#0: *80284 [lua] set.lua:16: failed to connect 112.253.18.179: connection timed out, client: 122.225.36.178, server: www.sina.com.cn, request: "GET http://www.sina.com.cn/link/bg1000833.jpg HTTP/1.1", sub\
request: "/sub", host: "www.sina.com.cn"

Regards,
-agentzh

黄力

unread,
Apr 15, 2013, 3:06:11 AM4/15/13
to open...@googlegroups.com
我晕,刚才问了管理员,原来给我限速了,之前带宽消耗太猛,机房老找他。 

Regards,
-agentzh

黄力

unread,
Apr 15, 2013, 6:28:40 AM4/15/13
to open...@googlegroups.com
刚看了http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html,获益匪浅,现在心里好有底啊,以后得节省多少时间啊,对人类的贡献,呵呵,强!
Reply all
Reply to author
Forward
0 new messages