当前位置: 首页 > 科技观察

这些常见的Nginx异常可以帮助你快速定位故障

时间:2023-03-21 20:41:54 科技观察

提示:文章前半部分是关于nginx下HTTPS连接curl请求被重置的处理心得。问题描述网站上线后,添加https证书,浏览器访问正常,通过curl请求重置请求,如上图。路难走。首先curl请求同域名下的httpurl,返回正常,说明至少两边80端口是正常的。然后curl在网站上请求同一台服务器下的其他https域名,返回正常,说明443两个端口网络正常。是证书问题吗?查看证书没有过期,通过myssl.com查看证书的详细信息,没有问题。怀疑密码套件配置文件,尝试添加更兼容的密码套件,仍然没有结果附上兼容的密码套件:“ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!后MD5:!PSK:!RC4”还是失败,我决定在tcpdump两边都抓包,用wireshark分析了从发起请求到reset一共16个包。看到两端的握手完成了。发起数据传输后,开始数据传输。第一个确认包被重置。我想不通。会不会是客户端发送的数据太大,nginx的缓冲区不够?客户端nginx相关设置修改如下:client_header_buffer_size64k;large_client_header_buffers464k;client_body_buffer_size20m;keepalive_timeout120;因为从抓包来看,还没有到fastcgi的部分,所以不修改fastcgi的buffer部分的配置,结果还是一样的,有点方便,虽然我知道应该和没有太大关系证书,但是我决定换成别的证书,因为之前是RSA证书,所以我再试试别的ECC证书(推荐七牛云SSL证书申请,可以选择ECC证书)换完之后,又有新的了curl的发现:(35)CannotcommunicateseCurelywithpeer:没有通用的加密算法。无法与对等方安全通信:没有通用加密算法的问题没有解决,又出现了新的问题。猜测ECC算法兼容性问题。经过一番google,了解到如下信息:原来在Redhat/CentOS服务器上,curl默认使用NSS库,而在这两个系统上,curl默认禁用了ECC加密。服务端加密套件虽然支持ECC,但是客户端不支持,所以请求失败,客户端curl需要通过指定的密码套件来请求curl--ciphersecdhe_rsa_aes_128_gcm_sha_256...指定后ciphersuite,回到起点,原来的错误还在。好像跟证书没关系。没有别的办法。仔细对比了其他网站的nginx配置,没有区别。只是没有配置ssl_session_cache。根据我对这个参数的理解,这个参数只是作为SSL优化的配置,起到缓存的作用,减少握手次数。嗯,压下想吃羊肉的心情,去nginx官网查看ssl_session_cache参数的解释。总结如下:ssl_session_cache有4个可选参数。off严禁使用session缓存:nginx明确告诉客户端session不能被重用nonesession禁止使用缓存:nginx告诉客户端session可以被重用,但实际上并没有把session参数存储在OpenSSL内置的缓存;只有一个工作进程使用会话中指定的缓存大小。如果未指定大小,则等于20480个会话。使用内置缓存会导致内存碎片,共享缓存在所有工作进程之间共享。缓存大小以字节为单位指定;一兆字节可以存储大约4000个会话。每个共享缓存都应该有一个任意名称。具有相同名称的缓存可用于多个虚拟服务器。反正如果要缓存,只有两个参数,builtin和shared,而且这两个参数可以同时开启,不过建议只用shared,性能更高但是看完之后,我还是不明白为什么curl加了这个参数后不报reset,于是又抓包和之前的对比了一下。在数据传输之前,除了没有ServerKeyExchange外,没有任何区别。(在resetconnection过程中,多了一个ServerKeyExchange),通过google查询,看了大神的文章《Winreshark抓包理解HTTPS请求流程》,了解到keyexchange阶段,这一步是可选步骤,补充到Certificate阶段只在这里存在几种情况:协商使用RSA加密,但服务器证书不提供RSA公钥。协商使用DH(ECDiffie-Hellman)加密,但服务器证书不提供DH参数。协商使用fortezza_kea加密,但是服务器证书没有提供任何参数,从包中可以看出。它使用Diffie-Hellman算法进行协商和分析。还是不知道为什么ssl_session_cache这个参数会影响curl请求。但这是唯一的方法。这里有人明白,请留言让我们知道我很感激。以下是nginx日志中常见的错误日志列表。1.请求uri时出现“upstreampremature(过早)关闭连接”异常,是由于upstream未向用户返回响应,用户断开连接造成的,对系统没有影响,可以忽略2."recv()failed(104:Connectionresetbypeer)”(1)服务器的并发连接数超过了它的能力,服务器将关闭部分连接;(2)客户端关闭(3)浏览器按Stop3."(111:Connectionrefused)whileconnectingtoupstream"用户在连接时,如果后端upstream挂了或者失败了,就会收到这个error4."(111:Connectionrefused)whilereadingresponseheaderfromupstream"当用户连接成功后读取数据时,如果后端upstream挂了或者失败,就会收到这个错误5."(111:Connectionrefused)while向upstream发送请求”当Nginx和upstream成功连接发送数据时,如果后端upstream挂了或者失败,你会收到这个错误6。”(110:连接超时)连接upstream时“nginx超时7。”(110:Connectiontimedout)whilereadingupstream"nginxtimedout8."(110:Connectiontimedout)whilereadingresponseheaderfromupstream"nginxtimedoutwhenreadingtheresponseheaderfromupstream9."读取上游响应标头时(110:连接超时)。(110:连接超时t)在读取上游时“nginx在读取来自上游10的响应时超时。”(104:Connectionresetbypeer)whileconnectingtoupstream“upstreamsentRST,resettheconnection11.”上游从上游读取响应标头时发送了无效标头“上游发送的响应标头无效12.”上游从上游读取响应标头时未发送有效的HTTP/1.0标头“上游发送的响应标头无效13.”客户端预期tosendtoolargebody”用于设置允许接受客户端请求内容的最大值,默认值为1M,客户端发送的body超过设置值14。“reopeninglogs”用户发送kill-USR1命令15。“正常关闭”用户发送kill-WINCH命令16。上游没有服务器“上游未配置服务器17”。连接到上游时没有实时上游“上游下的所有服务器都挂起18.”SSL_do_handshake()失败“SSL握手失败19.”ngx_slab_alloc()失败:没有内存SSL会话共享缓存“ssl_session_cachesizeisnotenoughandotherreasonscause20.”SSL握手时无法将新的SSL会话添加到会话缓存ing”ssl_session_cache大小不够等原因