一次Nginx 502问题解决

10 篇文章 0 订阅
1 篇文章 0 订阅
问题背景

线上某个web应用页面,偶发性的报502 Bad Gateway异常。线上环境是Nginx反向代理和SpringBoot的后端服务组合。针对这个问题,记录一下解决过程。

环境准备

如果环境是Mac并且已经安装了Homebrew的话,安装Nginx还是非常方便的。

brew install nginx

Mac Homebrew安装指导https://www.jianshu.com/p/ebd854196c4c

如果已经安装过了Docker环境,则更为便利,直接运行一个Nginx镜像即可。

Homebrew安装完后,可以通过以下命令操作Nginx。

#启动
brew services start nginx

# 停止
brew services stop nginx

# 重启
brew services restart nginx

安装后nginx的日志路径为

/usr/local/var/log/nginx

Nginx配置文件路径为

/usr/local/etc/nginx
问题定位和解决

我们到线上捞取了对应异常时间点的Nginx日志,在其中发现了这样的异常信息。

 61112#0: *1 upstream sent too big header while reading response header from upstream

这个异常是由于响应中Header信息过大导致的。为此我们需要写一个简单的服务端代码验证一下。


@RestController
public class HomeController {
  @RequestMapping(value = "/home")
  public String home(HttpServletRequest request, HttpServletResponse response) {
    String headCount = request.getParameter("headCount");
    if (!StringUtils.hasText(headCount)) {
      headCount = "300";
    }
    for (int i = 0; i < Integer.parseInt(headCount); i++) {
      response.setHeader(String.valueOf(i), String.valueOf(i));
    }
    return "success";
  }
}

上述代码比较简单,就是根据入参的一个headCount参数,向响应中增加Header的数量。

我们先让服务不经过Nginx反向代理来验证一下。headCount设置为3000,看是否正常。

image-20220305143953949😓,怎么服务端自己先报错了呢,还是看看日志吧。

An attempt was made to write more data to the response headers than there was room available in the buffer. Increase maxHttpHeaderSize on the connector or write less data into the response headers.

根据异常信息判断,是SpringBoot自身对Header也有限制大小,异常也给出了解决方案,那就是增加maxHttpHeaderSize的大小。

image-20220305143047461

通过找寻maxHttpHeaderSize关键词,我们找到了SpringBoot自动加载的ServerProperties中的这个属性,可以看到默认大小是8K。

我们可以通过application.properties将该大小增加到128K后重启服务。

server.maxHttpHeaderSize=128KB

image-20220305143911901

此时单独访问服务端是正常的了。那再加上Nginx的负载均衡会是什么样子呢?

我们找到Nginx的配置文件,在路径/usr/local/etc/nginx/nginx.conf中,找到http 80端口对应的server配置,配置路由信息到本机的SpringBoot服务。

location / {
  proxy_pass  http://127.0.0.1:8080;
}

修改完后启动Nginx服务,然后通过浏览器请求同样的后端服务。

image-20220305144121467

哇哦,502 Bad Gateway啦,抓紧时间取看一下Ngxin的日志。

2022/03/05 14:42:35 [error] 63112#0: *14 upstream sent too big header while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET /home?headCount=3000 HTTP/1.1", upstream: "http://127.0.0.1:8080/home?headCount=3000", host: "localhost"

可以看到的确是因为响应中Header过大导致的,那么有什么解决办法呢。感谢万能的谷歌-> https://ma.ttias.be/nginx-proxy-upstream-sent-big-header-reading-response-header-upstream/。

从这篇文章中可以看到,Nginx对于响应Header会进行缓存,如果Header超过了缓存的大小就会报这样的错误。所以接下来那就是按照文章中给的设置修改Nginx配置。

location / {
  proxy_pass  http://127.0.0.1:8080;
  proxy_buffer_size     128K;
  proxy_buffers         4 256K;
  proxy_busy_buffers_size  256K;
}

重新启动服务验证,现在可以看到请求已经可以正常返回了。

image-20220305144741205

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

51iwowo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值