The problem background

Symptom 502 Bad Gateway exception occurs on an online Web application page. The online environment is a back-end service combination of Nginx reverse proxy and SpringBoot. For this problem, document the resolution process.

Environment to prepare

If the environment is Mac and Homebrew is already installed, Nginx installation is very convenient.

brew install nginx
Copy the code

Mac Homebrew installation guide www.jianshu.com/p/ebd854196…

If you have already installed the Docker environment, it is more convenient to run an Nginx image.

After Homebrew is installed, you can use the following command to operate Nginx.

Brew services restart nginxCopy the code

The log path of nginx after installation is

/usr/local/var/log/nginx
Copy the code

The Nginx configuration file path is

/usr/local/etc/nginx
Copy the code
Problem location and resolution

We went online and retrieved the Nginx logs corresponding to the time of the exception and found such exception information.

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

This exception is caused by too much Header information in the response. We need to write a simple server-side code to verify this.


@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"; }}Copy the code

The code above is simple: increment the number of headers to the response based on a headCount parameter of the input parameter.

Let’s first validate the service without going through an Nginx reverse proxy. Set headCount to 3000 and check whether the headCount is normal.

😓, how the server first reported the error, or look at the log.

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.
Copy the code

SpringBoot also limits the size of the Header. The exception also provides a solution: increase the size of maxHttpHeaderSize.

We find this property in ServerProperties automatically loaded by SpringBoot by looking for the maxHttpHeaderSize keyword, and you can see that the default size is 8K.

We can increase this size to 128K and restart the service via application.properties.

server.maxHttpHeaderSize=128KB
Copy the code

It is normal to access the server alone at this point. So what does Nginx load balancing look like?

We find the Nginx configuration files, the path/usr/local/etc/Nginx/Nginx. Conf, find the corresponding HTTP port 80 server configuration, configuration SpringBoot service routing information to the machine.

Location / {proxy_pass http://127.0.0.1:8080; }Copy the code

After the changes are made, start the Nginx service and request the same backend service through the browser.

Wow, 502 Bad Gateway, take a look at Ngxin’s logs.

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

You can see that the Header is too large in the response, so what is the solution? Ma.ttias.be /nginx-proxy…

As you can see from this article, Nginx caches response headers and reports this error if the Header exceeds the size of the cache. So the next step is to modify the Nginx configuration as described in this article.

Location / {proxy_pass http://127.0.0.1:8080; proxy_buffer_size 128K; proxy_buffers 4 256K; proxy_busy_buffers_size 256K; }Copy the code

Restart the service validation and you can now see that the request has returned normally.