nginx的问题(续)

昨天说了nginx的几个问题,

由于我现在支持的主要是通用CDN,也就是小图片和CSS以及JS这些东西,并没有做大文件的cache。而问了我们视频部门他们也根本不用nginx作为cache使用,所以有些问题还是没考虑周到。

一个问题是之前发现的,在做tmpfs的时候,当你设置的cache大小为tmpfs的90%的时候,一旦要缓存的内容大于这个90%的时候,nginx会自己崩溃掉。这个我明天做个测试再重现一下,现在有点忘记原因了,好像是tmpfs会占用到实际的磁盘才导致的。

另外一个其实是upstream的问题,这个是一个新浪的老兄提的,基本现在是无解。问题是:比如平均一个文件10M,你在磁盘上存3000个文件,然后模拟多个客户端去访问,因为shm一开始是空的,所以都会去后端拽文件,我们放慢这个拽的过程,比如说网络不好吧 呵呵,那么第一个请求发现不在lookup失败,就会去upstream取数据,边取边向downsteam发,并且存在一个临时文件中,这时第二个请求来了也请求这个文件,因为第一个请求没有处理完,所以第二个请求找不到目标文件只好继续去后端拽,又生成临时文件,并发量大的时候,一个大文件会对应N多的临时文件,最终这些文件rename到一个目标文件,大大浪费了磁盘IO。这个rename是内核做的,nginx调完之后就返回了。这种问题往往会导致内部网络流量非常大,而实际却没有根本没有大。

当有多个连接来获取同一个文件的时候,squid中却没有跟nginx cache一样的问题。我们看看squid是怎么解决的吧。我们在squid有这样一个参数collapsed_forwarding on(http://wiki.squid-cache.org/Features/CollapsedForwarding),一旦设置了参数了,当发现有连接请求同一个文件的时候,squid会合并多个连接,但是它会以最慢速的那个连接去取,然后同步地传送给客户端。这样就不会重复请求后端了。但是squid也有问题,因为首先它是同步的。当用户请求的是动态的内容的话会导致客户端错误。而且当一个用户连接速度很快,一个用户连接速度很慢,那就会以最慢的速度进行获取和传输。所以在squid3.0以后取消了这个参数。

这个问题的解决办法暂时看起来只能在nginx cache前充一下热点的大文件。还好一般内网都是千兆连接,这个速度往往大于用户的连接速度。只有当文件特别大,并且热点文件特别多的情况下才会发生。而且nginx这种处理方式也有一定的好处。

nginx upstream流程我们可以参考http://bollaxu.javaeye.com/blog/900424http://bollaxu.javaeye.com/blog/900357这2篇文章。基本是由于nginx upstream为了防止锁所以进程间是不共享的。

###########################################

Best regards
Timo Seven
blog:http://www.timoseven.com
twitter: http://twitter.com/zauc
Linux System Admin  & MySQL DBA

关于 Timo
XNIX SA & MYSQL DBA

12 Responses to nginx的问题(续)

  1. zealer说道:

    请教个问题:我用apache的ab压 nginx.只是访问一个nginx上面的一个大小只有2字节的静态文件。qps到头了 也就2万多就再也上不去了。nginx那台服务器是双cpu,每个cpu是4核的。然后 应该是用了超线程技术。系统中看到的是16核的。我nginx的worker起了16个。压它的时候, 网卡带宽没有跑满。cpu使用率也很低。但就是 上不去了。这是为何?我nginx的配置文件里 设置了 worker_cpu_affinity, 但是我看网络中断还是只集中在一个cpu 核上。 是这个原因吗?

    • timo说道:

      worker_cpu_affinity 0000000000000001 0000000000000010 0000000000000100 0000000000001000 0000000000010000 0000000000100000 0000000001000 0000000000010000000 0000000100000000 0000001000000000 0000010000000000 0000100000000000 0001000000000000 0010000000000000 010000000000 00001000000000000000; 是这样的? 我用mpstat很平均阿各个cpu负载

      • zealer说道:

        我又看了一下 当时网卡收发数据包的速度,发现到了10万多每秒,而且 我感觉那个网卡 发送 或者 接受到了10万packets/s 就再也上不去了。 我不知道,nginx的qps是卡在网卡收发数据包的处理能力上了,还是cpu响应硬中断的能力,或者是执行软中断处理程序上面出现瓶颈了。用mpstat看 ,中断集中在一个物理cpu上,达到了10万的中断每秒了。 我不知道 mpstat 中的这个最后一列的中断速度,指的是硬中断还是软中断。不清楚。你有何见解?你现在在去哪干得怎么样?:)

      • zealer说道:

        我又看了一下 当时网卡收发数据包的速度,发现到了10万多每秒,而且 我感觉那个网卡 发送 或者 接受到了10万

        packets/s 就再也上不去了。 我不知道,nginx的qps是卡在网卡收发数据包的处理能力上了,还是cpu响应硬中断的能

        力,或者是执行软中断处理程序上面出现瓶颈了。用mpstat看 ,中断集中在一个物理cpu上,达到了10万的中断每秒了

        。 我不知道 mpstat 中的这个最后一列的中断速度,指的是硬中断还是软中断。不清楚。你有何见解?你现在在去哪干

        得怎么样?:)

      • Timo说道:

        硬中断和软中断区别大吗? 我觉得导致的结果都是一样的。 你不是都加了worker_cpu_affinit, 怎么可能还都集中在一个CPU上?

  2. laneovcc说道:

    没记错的话 网卡的中断确实只有CPU0来处理.

    time的第二个问题, 我觉得说的是 proxy_cache_use_stale update可以解决的

  3. sun说道:

    问个问题,我在使用healthcheck模块的时候,用nginx的 0.8.50,1.0.4,1.0.5三种版本编译时都出现以下错误,求解。
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_mark_finished’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:287: 错误:‘struct ’ 没有名为 ‘onumber’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:303: 错误:‘struct ’ 没有名为 ‘onumber’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:308: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_failcount’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:316: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_delay’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_send_request’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:348: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:349: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:365: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:367: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:368: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:371: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_read_handler’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:395: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_timeout’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_process_recv’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:461: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_expected’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_begin_healthcheck’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:590: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_delay’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:614: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_timeout’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_try_for_ownership’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:640: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_delay’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:640: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_timeout’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_procinit’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:690: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘healthcheck_enabled’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:708: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_delay’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_init’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:753: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_buffersize’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_is_down’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:823: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘healthcheck_enabled’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_enabled’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1003: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘healthcheck_enabled’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_delay’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1014: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_delay’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1015: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_delay’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_timeout’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1027: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_timeout’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1028: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_timeout’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_failcount’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1040: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_failcount’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1041: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_failcount’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_send’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1055: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1060: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1062: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1064: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1065: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1065: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1066: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1072: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1075: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1078: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1080: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1081: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_send’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_expected’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1095: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_expected’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1096: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_expected’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_buffer’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1108: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_buffersize’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:1109: 错误:‘ngx_http_upstream_srv_conf_t’ 没有名为 ‘health_buffersi

    • Timo说道:

      cd nginx-0.7.62 # or whatever
      patch -p1 < /path/to/this/directory/nginx.patch
      ./configure –add-module=/path/to/this/directory
      make
      make install

      你是这样安装的吗? 得先打补丁

  4. sun说道:

    不好意思,刚才那个是没有打上补丁的,这次我打上了,还是有个错误:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c: In function ‘ngx_http_healthcheck_mark_finished’:
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:287: 错误:‘struct ’ 没有名为 ‘onumber’ 的成员
    /opt/nginx/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.c:303: 错误:‘struct ’ 没有名为 ‘onumber’ 的成员
    make[1]: *** [objs/addon/healthcheck_nginx_upstreams/ngx_http_healthcheck_module.o] 错误 1
    make[1]: Leaving directory `/opt/nginx/nginx-0.8.50′
    make: *** [build] 错误 2

  5. sun说道:

    我的QQ:89151524。

  6. sun说道:

    –add-module=/opt/nginx/ngx_supervisord –add-module=/opt/nginx/gnosek-nginx-upstream-fair –add-module=/opt/nginx/healthcheck_nginx_upstreams 这三个模块我是在编译时一起添加的。

    • Timo说道:

      这个我前面特地在centos5.6上测试下没有问题
      patch -p1 < ../healthcheck_nginx_upstreams/nginx.patch
      ./configure –add-module=../healthcheck_nginx_upstreams/
      make
      make install
      都没有问题。

      你这种情况最好把现在的nginx源代码目录给删除了,重新解压一样和再打一下补丁

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: