openresty出现错误:lua tcp socket read timed out问题以及lua环境开发的一些小点输出header头、关闭lua缓存、模块Etags

一、openresty出现错误:lua tcp socket read timed out

    最近使用nginx+lua做弹幕服务器搭建及代码部署后,在服务器的日志中偶尔见到报错lua tcp socket,read timed out,报错的数量不多,属于发生,但是我也到网上看了一下相关的东西,也是想解决这个问题,但网上资料相对较少,报错的内容大致如下 publish:November 21, 2018 -Wednesday:

2018/11/20 12:18:27 [error] 30746#0: *3027387 lua tcp socket read timed out, client: 123.11.244.69, server: danmu.test.com, request: "GET
/d?m=view&uid={86572AC1-6F8B-E85F-E298-074F8DBCC3A4}&moid=838965&ation=101 HTTP/1.1", host: "danmu.test.com"
2018/11/20 12:18:34 [error] 30751#0: *3027457 lua tcp socket read timed out, client: 120.239.114.71, server: danmu.test.com, request: "GET
 /d?m=view&uid={8CB4FC78-314F-AD6F-3629-8AB32887569C}&mid=830464&ation=101 HTTP/1.1", host: "danmu.test.com"

        从报错字面来看,显示为lua tcp socket连接超时,从代码来看涉及这一块的就只明lua中连接redis这部分。代码如下:

local tcp = ngx.socket.tcp
#redis的初始化代码部分
function new(self)
    local sock, err = tcp()
    if not sock then
        return nil, err
    end
    return setmetatable({ sock = sock }, mt)
end

     可tcp连接为什么超时呢?今天的这篇文章我也并未能解决问题,只是把我的情况记录下吧,通过服务器上的netstat统计,连接数完全够用,redis上也还有足够的连接可用。应该说redis服务的问题应该不存在,网上有一篇文章介绍此处,提到官网上有相关说明,应该在Lua中处理socket错误,并在nginx.conf中配置下面语句来关闭错误日志。

lua_socket_log_errors off;
lua的github地址:https://github.com/openresty/lua-nginx-module#lua_socket_log_errors
#详细说明部分
lua_socket_log_errors
syntax: lua_socket_log_errors on|off
default: lua_socket_log_errors on
context: http, server, location
This directive can be used to toggle error logging when a failure occurs for the TCP or UDP cosockets. If you are already doing proper error handling and logging in your Lua code, then it is recommended to turn this directive off to prevent data flushing in your nginx error log files (which is usually rather expensive).
This directive was first introduced in the v0.5.13 release.

    但这个看起来只是关闭错误显示,实际连接中确实是发生了错误,如果有重试机制也许可以,但如果没有重试机制,这个错误发生后本次请求就失败了。目前未找到其它解决办法,在WEB服务器上从netsta看有时会有FIN_WAIT2,FIN_WAIT1状态的连接,但其很快就会消失并且同时查看日志,看不到与报错之间有联系,关于FIN_WAIT状态,网上有解释:

    在三次握手中,主动关闭的一方发出FIN,同时进入FIN_WAIT1 状态,被动关闭的一方响应ACK,从而使主动关闭的一方迁移至FIN_WAIT2状态,接着被动关闭的一方同样会发出FIN,主动关闭的一方响应ACK,同时迁移至TIME_WAIT状态。从这里看和这个FIN_WAIT也没有关系。

    还有提出修改 /etc/sysctl.conf的配置,我对比了一下要改的配置,和我的服务器上的配置是一样的。最后推测可能是连接的redis的问题,因为redis可能会在做save操作,从而导致连接失败。先改一下redis配置看看。不要持久化或者变更为定时持久化。基于此想法我在redis服务器上频繁进行save命令,同时监控日志,但并未发现有新的报错,这样来看也许不是redis的bgsave或save导致的。目前也未找到原因,先记在这里吧。

二、nginx+lua环境开发的一些小点-lua输出header头-关闭lua缓存lua_code_cache-模块Etags

 publish:November 6, 2018 -Tuesday

1、lua开发时启动调试模式:lua_code_cache off;

        nginx+lua开发时因为已经加载进内存,修改lua脚本不会起作用,这样不方便调试。nginx配置中将lua_code_cache配置成on/off来控制是否关闭lua 的cache缓存,如果设置为off.则每次修改lua脚本都会重新加载新的lua代码,从而实现快速调试响应。同时状态为off时启动或重启nginx都会提示:nginx: [alert] lua_code_cache is off; this will hurt performance in /path/to/nginx.conf。因为这会影响nginx性能表现。一般开发调试的时候使用off, 线上运行时设置为on。

location / {
    lua_code_cache off;#调试模式(即关闭lua脚本缓存)
    content_by_lua_file '/opt/data/srccode/current/index.lua';
}

2、ngx+lua脚本中添加头信息输出以方便调试

        nginx+lua有时不方便直接在显示页面里呈现内容,特别是在线上,可以采用输出头信息来达到调试数据的目的,可以使用ngx.header来设置头信息输出如下:

#lua脚本示例如下:
ngx.header["Test-return"] = "192.***. nginx work."
ngx.header["Expires"] = ngx.http_time( ngx.time() + 31536000 );
ngx.header["Cache-Control"] = "max-age=31536000";
ngx.header.content_type = "text/plain;charset=utf-8"
#200状态退出
ngx.exit(200)

3、关于nginx的模块Etags:nginx-dynamic-etags

nginx+lua环境搭建的平台本身的目的就是为了快速提供响应,同时如果接口传输的数据量比较大的话,建议添加模块Etags:nginx-dynamic-etags,详见:火车头抓取数据access导入mysql提示错误Incorrect string value.. 及 关于nginx的Etags模块nginx-dynamic-etags_mysql修改配置 火车头报错-CSDN博客 我在安装openresry的时候就添加了这个模板,这个模块的作用就是会对传输数据做一个标记来确认内容是否有变化。从而减少数据传输,经过我的使用分析有以下几个特点:

A,如果接口里有一些常变动数据,比如接口有返回请求ID或者请求时间戳记等变化数据,这个不适合使用Etags。
B,如果接口返回的内容数据不多,也没有必要使用Etags。
C,使用Etags并没有减少服务器端的计算工作,但可以节省网络带宽和资源。
D,客户端请求服务端,服务端依然会对请求进行处理并得到要返回的数据,将数据进行计算得出Etag值例如:2a7093b56217da29835efed487332501,和请求端的ETag比较,如果一样就返回304状态,如果不一样就响应200.

dynamic_etags on;
#expires 5m; #表示5分钟过期
#expires 1h; #表示1小时有效
expires 1d;  #表示1天过期,另外etag默认是可连续刷新的,即5分钟内返回304后,接下来5分钟如果未改变会持续返回304
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林戈的IT生涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值