美文网首页Nginx/Lua
nginx lua socket timeout 问题处理

nginx lua socket timeout 问题处理

作者: 飞将军 | 来源:发表于2015-01-14 21:24 被阅读6721次

    2015/1/14日, 在192.168.2.209环境, web端进行大文件(300-500M)上传时, nginx经常报错. 错误信息如下:

    2015/01/15 03:53:29 [error] 4065#0: *3604 lua tcp socket write timed out while sending to client, client: 192.168.2.24, server: private.com, request: "POST /upload/single HTTP/1.1", host: "192.168.2.209", referrer: "http://192.168.2.209/os/home.html"

    2015/01/15 03:53:29 [error] 4065#0: *3604 [lua] single_upload.lua:7: fail to invoke storage append_by_buff() ! err: storage send request error:timeout while sending to client, client: 192.168.2.24, server: private.com, request: "POST /upload/single HTTP/1.1", host: "192.168.2.209", referrer: "http://192.168.2.209/os/home.html"

    经过分析, 错误可能是一下原因导致的:

    1. nginx.conf中配置的proxy_connect_timeout, proxy_read_timeout, proxy_send_tiemout
    2. upload.lua文件中指定大文件分块上传到fastdfs, 默认是20M一块, 是否太小了
    3. fastdfs.lua, fdfs storage lua socket在使用完成后, 会默认放到socket pool中, 通过调用set_keepalive(timeout, size)函数实现, 是否timeout时间设置太小了. 导致在使用该lua socket时, timeout过期了, 报lua tcp socket write timed out
    4. 查看nginx lua的API 文档, 分析那些配置会影响到lua socket的timeout.

    经过排查, 1,2,3这几个配置确实有问题, 可以优化的. 但改完后, 上传大文件还是报错. 以下是上面几点的优化配置:

    • nginx.conf

    proxy_connect_timeout 5;
    proxy_read_timeout 60;
    proxy_send_timeout 60;

    • uploader.lua中分块修改:

    默认最新分块是60M, 超过60M的文件, 按照60M一块上传到Fastdfs中

    • fastdfs.lua set_keepalive(timeout, size)修改:

    tracker:set_keepalive(0, 3)
    storage:set_keepalive(0, 5)

    1. 根据官方文档说明, socket:set_keepalive(timeout, size)中参数timeout是指定该socket在socket pool中缓存的时间, size则是指定每一个nginx worker中该类socket pool的大小. 配置timeout为0则表示该socket永不过期, 减少因为timeout到期时, 如果该socket正在使用时出错的概率. > 在上传文件到fastdfs的应用中, 每次新创建的socket都会有如下提示:
      Success to query storage! option: {host: 127.0.0.1, port: 22122}
    2. 如果使用的是socket pool中的storage socket, 则不会有上面的日志提示.
    3. 如果使用的是缓存中的socket, 调用socket:connect()函数会使set_keepalive(timeout, size)中配置的timeout不起作用, 因为此时会将调用socket:close(), 然后重新建立连接

    优化了这几点后, 大文件上传成功的概率更高了, 但还不是100%. 经过更加仔细的研究nginx lua关于socket的文档, 我推断问题是上面的第4点. 即lua socket的tcpsock:send() 报了超时错误(也就是write timeout了). 这一点我是从文档中看出来的, 以下是我修改后的fastdfs.lua和uploader.lua

    tracker:set_timeout(60000) # 原来的是300
    storage:set_timeout(60000) # 原来的3000
    

    即现在connect, send, receive的timeout都是60s, 上传大文件全部成功了!

    参考NGINX LUA文档

    tcpsock:connect
    tcpsock:send
    tcpsock:set_timeout
    tcpsock:set_keepalive

    更新记录

    1. 2015/1/14, 问题发生, 解决, 记录

    相关文章

      网友评论

      本文标题:nginx lua socket timeout 问题处理

      本文链接:https://www.haomeiwen.com/subject/pwhcxttx.html