09 nginx 中 upstream max_conns 配置为 1, 导致的一部分静态资源请求成功, 一部分静态资源请求失败

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了09 nginx 中 upstream max_conns 配置为 1, 导致的一部分静态资源请求成功, 一部分静态资源请求失败相关的知识,希望对你有一定的参考价值。

前言

呵呵 这是之前搭建一个项目的时候出现的问题 

主要的情况是 一个 nginx, 代理了上游的服务, 设置的 max_conns 为 1, 然后 之后 nginx 来请求上游的服务的时候 一部分请求成功, 一部分请求失败  

这里 我们来从 源码层面上 剖析一下这个问题, 以及 max_conns 的理解 

测试用例

nginx 配置文件如下 

    # upstream list
    upstream api_server 
#        server localhost:18080 max_conns=1;
        server localhost:63344 max_conns=1;
    

    // 省略部分其他配置 
        location / 
            #root   html;
            #index  index.html index.htm;
            proxy_set_header Host $host;
                proxy_pass http://api_server;
        

上游的服务的 html, 这里会级联获取依赖的 100 个 js 文件 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>H5DrawImage.html</title>
</head>
<body>

</body>

<script src="./js/js01.js" type="text/javascript"></script>
<script src="./js/js02.js" type="text/javascript"></script>
<script src="./js/js03.js" type="text/javascript"></script>
<script src="./js/js04.js" type="text/javascript"></script>
<script src="./js/js05.js" type="text/javascript"></script>
<script src="./js/js06.js" type="text/javascript"></script>
<script src="./js/js07.js" type="text/javascript"></script>
<script src="./js/js08.js" type="text/javascript"></script>
<script src="./js/js09.js" type="text/javascript"></script>
<script src="./js/js10.js" type="text/javascript"></script>
<script src="./js/js11.js" type="text/javascript"></script>
<script src="./js/js12.js" type="text/javascript"></script>
<script src="./js/js13.js" type="text/javascript"></script>
<script src="./js/js14.js" type="text/javascript"></script>
<script src="./js/js15.js" type="text/javascript"></script>
<script src="./js/js16.js" type="text/javascript"></script>
<script src="./js/js17.js" type="text/javascript"></script>
<script src="./js/js18.js" type="text/javascript"></script>
<script src="./js/js19.js" type="text/javascript"></script>
<script src="./js/js20.js" type="text/javascript"></script>
<script src="./js/js21.js" type="text/javascript"></script>
<script src="./js/js22.js" type="text/javascript"></script>
<script src="./js/js23.js" type="text/javascript"></script>
<script src="./js/js24.js" type="text/javascript"></script>
<script src="./js/js25.js" type="text/javascript"></script>
<script src="./js/js26.js" type="text/javascript"></script>
<script src="./js/js27.js" type="text/javascript"></script>
<script src="./js/js28.js" type="text/javascript"></script>
<script src="./js/js29.js" type="text/javascript"></script>
<script src="./js/js30.js" type="text/javascript"></script>
<script src="./js/js31.js" type="text/javascript"></script>
<script src="./js/js32.js" type="text/javascript"></script>
<script src="./js/js33.js" type="text/javascript"></script>
<script src="./js/js34.js" type="text/javascript"></script>
<script src="./js/js35.js" type="text/javascript"></script>
<script src="./js/js36.js" type="text/javascript"></script>
<script src="./js/js37.js" type="text/javascript"></script>
<script src="./js/js38.js" type="text/javascript"></script>
<script src="./js/js39.js" type="text/javascript"></script>
<script src="./js/js40.js" type="text/javascript"></script>
<script src="./js/js41.js" type="text/javascript"></script>
<script src="./js/js42.js" type="text/javascript"></script>
<script src="./js/js43.js" type="text/javascript"></script>
<script src="./js/js44.js" type="text/javascript"></script>
<script src="./js/js45.js" type="text/javascript"></script>
<script src="./js/js46.js" type="text/javascript"></script>
<script src="./js/js47.js" type="text/javascript"></script>
<script src="./js/js48.js" type="text/javascript"></script>
<script src="./js/js49.js" type="text/javascript"></script>
<script src="./js/js50.js" type="text/javascript"></script>
<script src="./js/js51.js" type="text/javascript"></script>
<script src="./js/js52.js" type="text/javascript"></script>
<script src="./js/js53.js" type="text/javascript"></script>
<script src="./js/js54.js" type="text/javascript"></script>
<script src="./js/js55.js" type="text/javascript"></script>
<script src="./js/js56.js" type="text/javascript"></script>
<script src="./js/js57.js" type="text/javascript"></script>
<script src="./js/js58.js" type="text/javascript"></script>
<script src="./js/js59.js" type="text/javascript"></script>
<script src="./js/js60.js" type="text/javascript"></script>
<script src="./js/js61.js" type="text/javascript"></script>
<script src="./js/js62.js" type="text/javascript"></script>
<script src="./js/js63.js" type="text/javascript"></script>
<script src="./js/js64.js" type="text/javascript"></script>
<script src="./js/js65.js" type="text/javascript"></script>
<script src="./js/js66.js" type="text/javascript"></script>
<script src="./js/js67.js" type="text/javascript"></script>
<script src="./js/js68.js" type="text/javascript"></script>
<script src="./js/js69.js" type="text/javascript"></script>
<script src="./js/js70.js" type="text/javascript"></script>
<script src="./js/js71.js" type="text/javascript"></script>
<script src="./js/js72.js" type="text/javascript"></script>
<script src="./js/js73.js" type="text/javascript"></script>
<script src="./js/js74.js" type="text/javascript"></script>
<script src="./js/js75.js" type="text/javascript"></script>
<script src="./js/js76.js" type="text/javascript"></script>
<script src="./js/js77.js" type="text/javascript"></script>
<script src="./js/js78.js" type="text/javascript"></script>
<script src="./js/js79.js" type="text/javascript"></script>
<script src="./js/js80.js" type="text/javascript"></script>
<script src="./js/js81.js" type="text/javascript"></script>
<script src="./js/js82.js" type="text/javascript"></script>
<script src="./js/js83.js" type="text/javascript"></script>
<script src="./js/js84.js" type="text/javascript"></script>
<script src="./js/js85.js" type="text/javascript"></script>
<script src="./js/js86.js" type="text/javascript"></script>
<script src="./js/js87.js" type="text/javascript"></script>
<script src="./js/js88.js" type="text/javascript"></script>
<script src="./js/js89.js" type="text/javascript"></script>
<script src="./js/js90.js" type="text/javascript"></script>
<script src="./js/js91.js" type="text/javascript"></script>
<script src="./js/js92.js" type="text/javascript"></script>
<script src="./js/js93.js" type="text/javascript"></script>
<script src="./js/js94.js" type="text/javascript"></script>
<script src="./js/js95.js" type="text/javascript"></script>
<script src="./js/js96.js" type="text/javascript"></script>
<script src="./js/js97.js" type="text/javascript"></script>
<script src="./js/js98.js" type="text/javascript"></script>
<script src="./js/js99.js" type="text/javascript"></script>

<script>
</script>

</html>

从浏览器访问该服务如下, 确保 服务正常  

nginx 代理访问该服务状态如下, 可以看到 绝大多数的请求 502 请求失败了 

但是 依然存在一部分请求, 正常响应 

参数 max_conns    

以下截图来自于官方文档 Module ngx_http_upstream_module

可以看到 其实就是对于 upstream 的一个保护, 做了一个 并发量 控制  

但是 我们这里只有一个 worker ! 

但是我们考虑另外一个问题, 在之前的调试过程中我们能够发现的是 worker process 是只有一个线程, 那么 即使是客户端这边发送了一百多个请求过来, 那么这个 worker process 也应该是一个请求一个请求的处理呀? 怎么会出现这种情况 ??

nginx 的请求处理方式

nginx 的请求处理调试可以参考文章 nginx 的一次请求处理调试 

是根据事件来处理 

也就是 接受请求, 和向上游发送代理请求, 接受上游的代理响应 这三者 不是串行的 

那么可能是 接受了请求1, 接受了请求2, 处理请求1 处理成功, 接着处理请求2, 因为请求1还没有处理完成, 因此处理请求2 的时候会造成超过 max_conns 的限制, 导致处理失败 

正常情况应该是走如下 peers->single 下面的 max_conns 的校验, 然后返回 NGX_BUSY 

但是 mac 这里似乎我 api_servers 只配置了一个 后台服务, 这里 peers 中却有两个节点?? 呵呵 这个多久看一下 

然后 在上层 NGX_BUSY, 响应给了客户端 502 

我们在接受请求的地方, 发送代理请求的地方, 接受上游的代理响应的地方 加上日志输出 

可以看到的是 如下几个特征

1. recv 之后的 下一个请求应该就是下一次发送成功的请求

2. recv 之后的下一个 accept 到这个 accept 的 recv 之间所有接受的请求都是 502 处理失败 

accept http - /HelloWorld/getMultiResource/GetMultiResource.html HTTP/1.1
send - /HelloWorld/getMultiResource/GetMultiResource.html HTTP/1.1
recv - /HelloWorld/getMultiResource/GetMultiResource.html HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js01.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js02.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js01.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js03.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js04.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js05.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js06.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js07.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js01.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js08.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js09.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js10.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js11.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js12.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js13.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js14.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js08.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js15.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js16.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js17.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js18.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js19.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js08.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js20.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js21.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js22.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js23.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js24.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js25.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js26.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js27.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js20.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js28.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js29.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js30.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js31.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js32.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js20.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js33.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js34.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js35.js HTTP/1.1
accept http - /50x.html
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js36.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js37.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js38.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js39.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js33.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js40.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js41.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js42.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js43.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js44.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js33.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js45.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js46.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js47.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js48.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js49.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js50.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js51.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js52.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js45.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js53.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js54.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js55.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js56.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js57.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js45.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js58.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js59.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js60.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js61.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js62.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js63.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js64.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js65.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js58.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js66.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js67.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js68.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js69.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js70.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js58.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js71.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js72.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js73.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js74.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js75.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js76.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js77.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js78.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js71.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js79.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js80.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js81.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js82.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js83.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js71.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js84.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js85.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js86.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js87.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js88.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js89.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js90.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js91.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js84.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js92.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js93.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js94.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js95.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js96.js HTTP/1.1
accept http - /50x.html
recv - /HelloWorld/getMultiResource/js/js84.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js97.js HTTP/1.1
accept http - /HelloWorld/getMultiResource/js/js98.js HTTP/1.1
accept http - /50x.html
accept http - /HelloWorld/getMultiResource/js/js99.js HTTP/1.1
accept http - /50x.html
send - /HelloWorld/getMultiResource/js/js97.js HTTP/1.1
recv - /HelloWorld/getMultiResource/js/js97.js HTTP/1.1
accept http - /favicon.ico HTTP/1.1
send - /favicon.ico HTTP/1.1
recv - /favicon.ico HTTP/1.1

我们来看一下 这里请求成功的这一部分请求

以上是关于09 nginx 中 upstream max_conns 配置为 1, 导致的一部分静态资源请求成功, 一部分静态资源请求失败的主要内容,如果未能解决你的问题,请参考以下文章

09 nginx 中 upstream max_conns 配置为 1, 导致的一部分静态资源请求成功, 一部分静态资源请求失败

Nginx upstream DNS 解析缓存问题

Nginx upstream DNS 解析缓存问题

Nginx#upstream指令参数

Nginx错误:(13: Permission denied) while reading upstream

Nginx错误:(13: Permission denied) while reading upstream