502错误是什么、应该怎么排查?(2)
502错误是什么、应该怎么排查

也不是不行,但就是麻烦。
但这时候如果能有个中间层挡在它们中间就好了,这样客户端只需要跟中间层连接,中间层再和服务器建立连接。
于是,这个中间层就成了这帮服务器的一个代理人一样,客户端有啥事都找代理人,只管发出自己的请求,再由代理人去找某个服务器去完成响应。
整个过程下来,客户端只知道自己的请求被代理人帮忙搞定了,但代理人具体找了那个服务器去完成,客户端并不知道,也不需要知道。
像这种,屏蔽掉具体有哪些服务器的代理方式就是所谓的反向代理。

反过来,屏蔽掉具体有哪些客户端的代理方式,就是所谓的正向代理。
而这个中间层的角色,一般由nginx这类网关来充当。
另外,由于背后的服务器可能性能配置各不相同,有些4核8G,有些2核4G,nginx能为它们加上不同的访问权重,权重高的多转发点请求,通过这个方式实现不同的负载均衡策略。
nginx返回5xx状态码
有了nginx这一中间层后,客户端从直连服务端,变成客户端直连nginx,再由nginx直连服务端。从一个TCP连接变成两个TCP连接。
于是,当服务器发生异常时,nginx发送给服务器的那条TCP连接就不能正常响应,nginx在得到这一信息后,就会返回5xx错误码给客户端,也就是说5xx的报错,其实是由nginx识别出来,并返回给客户端的,服务端本身,并不会有5xx的日志信息。
所以才会出现文章开头的一幕,上游收到了我服务的502报错,但我在自己的服务日志里却搜索不到这一信息。
产生502的常见原因
在rfc7231中有关于502错误码的官方解释是
502 Bad Gateway
The 502 (Bad Gateway) status code indicates that the server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request.
翻译一下就是,502 (Bad Gateway) 状态代码表示服务器在充当网关或代理时,在尝试满足请求时从它访问的入站服务器接收到无效响应。
汝听,人言否?
这对于大部分编程小白来说,不仅没解释到问题,反而只会冒出更多的问号。比如,这上面提到的无效响应到底指的是什么?
我来解释下,它其实是说,502其实是由网关代理(nginx)发出的,是因为网关代理把客户端的请求转发给了服务端,但服务端却发出了无效响应,而这里的无效响应,一般是指TCP的RST报文或四次挥手的FIN报文。
四次挥手估计大家背的很熟了,所以略过,我们来重点说下RST报文是什么。
RST是什么?
我们都知道TCP正常情况下断开连接是用四次挥手,那是正常时候的优雅做法。
但异常情况下,收发双方都不一定正常,连挥手这件事本身都可能做不到,所以就需要一个机制去强行关闭连接。
RST就是用于这种情况,一般用来异常地关闭一个连接。它是TCP包头中的一个标志位,在收到置这个标志位的数据包后,连接就会被关闭,此时接收到 RST的一方,在应用层会看到一个connection reset或 connection refused的报错。

而之所以发出RST报文,一般有两个常见原因。
服务端过早断开连接
nginx与服务端之间有一条TCP连接,在nginx将客户端请求转发给服务端时,他两之间按道理会一直保持这条连接,直到服务端将结果正常返回后,再断开连接。
但如果服务端过早断开连接,而nginx却还继续发消息过去,nginx就会收到服务端内核返回的RST报文或四次挥手的FIN报文,迫使nginx那边的连接结束。
过早断开连接的原因常见的有两个。
第一个是,服务端设置的超时时间过短。不管是用的哪种编程语言,一般都有现成的HTTP库,服务端一般都会有几个timeout参数,比如golang的HTTP服务框架里有个写超时(WriteTimeout),假设设置了2s,那它的含义就是,服务端在收到请求后需要在2s内处理完并将结果写到响应中,如果等不到,就会将连接给断掉。
比如你的接口处理时间是5s,而你的WriteTimeout却只有2s,在没等到响应写完之前,HTTP框架就会主动将连接给断开。nginx此时就有可能收到四次挥手的FIN报文(有些框架也可能发RST报文),然后断开连接,于是客户端就会收到一个502报错。
遇到这种问题,将WriteTimeout的时间调大一些就好了。
相关阅读
-
kafka是什么 主要特点有哪些?
IT袋网网为你介绍kafka是什么的IT知识,一定能解决您的问题的,一起来了解吧! Kafka 是一个开源的分布式流式平台,它可以处理大量的实时数据,并提供高吞吐量,低延迟,高可靠性和高可扩
-
access数据库入门教程 数据库零基础入门教学
今天小编详解access数据库入门教程和数据库零基础入门教学的相关介绍,继续往下看吧! Access数据库除了选择查询,还有操作查询,它们有: 更新查询 生成表查询 追加查询 删除查询 来看看
-
c语言怎么输出语句 C#中怎样快速输出{get;set;}
对于c#初学者来说,可能是受教程的影响,看到老师在Visual Studio中瞬间就可以快速敲出{get;set;},但是自己却不知道怎么敲?老师也不告诉,其实老师这样做是有目的的,让你自己多动手去熟悉
-
使用双异步后 如何保证数据一致性?
小编为大家说一说使用双异步后的相关知识,下面小编为您详细解答 很简单,通过对比Excel文件行数和入库数量是否相等即可。 那么,如何获取异步线程的返回值呢? 一、通过Future获取异步返


