[转帖]nginx的重试机制 proxy_next_upstream

nginx,重试,机制,proxy,next,upstream · 浏览次数 : 0

小编点评

**Nginx的反向代理配置中 `proxy_next_upstream`选项** `proxy_next_upstream`选项用于指定在什么情况下Nginx会将请求转移到其他服务器上。默认情况下,`proxy_next_upstream error timeout`选项用于当发生网络错误以及超时时才重试其他服务器。 **配置示例:** ```nginx server { listen 9039; location / { proxy_pass http://nginxretry; proxy_next_upstream error timeout http_500; } } upstream nginxretry { server 127.0.0.1:9030 weight=10; server 127.0.0.1:9031 weight=10; } ``` **配置说明:** * `proxy_pass`将请求转发到 `nginxretry` server。 * `proxy_next_upstream`选项指定在 `error timeout` 和 `http_500` 错误时重试其他服务器。 * `error timeout` 指的是当发生网络错误或者超时时重试下一个服务器的等待时间。 * `http_500` 指的是当请求返回状态码 `500` 时重试下一个服务器。 **注意事项:** * `proxy_next_upstream`选项只适用于 `proxy_pass` 指向其他服务器的请求。 * `non_idempotent`选项仅适用于 `proxy_pass` 指向其他服务器的 POST 请求。 * 在生产环境中,不建议添加 `non_idempotent`选项,因为可能导致非幂等方法重复执行,导致业务问题。

正文

https://blog.csdn.net/xiao__gui/article/details/89441162

https://zhuanlan.zhihu.com/p/35803906

https://www.cnblogs.com/powerwu/articles/9791295.html

https://pandaychen.github.io/2019/12/15/NGINX-SMOOTH-WEIGHT-ROUNDROBIN-ANALYSIS/

 

Nginx通过反向代理做负载均衡时,如果被代理的其中一个服务发生错误或者超时的时候,通常希望Nginx自动重试其他的服务,从而实现服务的高可用性。实际上Nginx本身默认会有错误重试机制,并且可以通过proxy_next_upstream来自定义配置。

如果不了解HTTP协议以及Nginx的机制,就可能在使用过程中遇到各种各样的坑。例如服务出现了错误或超时却未重试,或者一些例如创建订单或发送短信这类的HTTP接口,客户端只发送一次请求,后台却由于Nginx重试导致创建了多个订单,或者收到多条短信,导致一些业务上的问题。

在Nginx配置文件中,proxy_next_upstream用于指定在什么情况下Nginx会将请求转移到其他服务器上。其默认值是proxy_next_upstream error timeout,即发生网络错误以及超时,才会重试其他服务器。默认情况下服务返回500状态码是不会重试的,如果想在响应500状态码时也进行重试,可以配置:
 

proxy_next_upstream error timeout http_500;

当然还有http_502http_503http_404等可以指定在出现哪些状态码的情况下需要重试。具体配置项可以参考官方文档: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream 。 

  1. upstream nginxretry {
  2. server 127.0.0.1:9030 weight=10;
  3. server 127.0.0.1:9031 weight=10;
  4. }
  5. server {
  6. listen 9039;
  7. location / {
  8. proxy_pass http://nginxretry;
  9. proxy_next_upstream error timeout http_500;
  10. }
  11. }

配置完成后重启Nginx,使用GET方式请求 http://localhost:9039/ ,再分别查看9030和9031两个端口号对应的服务日志,可以发现两个服务都收到请求,也就是Nginx在访问其中一个服务收到500错误状态码后,又尝试去访问另一个服务。

再次使用POST方式请求 http://localhost:9039/ ,再分别查看9030和9031两个端口号对应的服务日志,可以发现只有一个服务收到请求。也就是当请求类型是POST时,Nginx默认不会失败重试。如果想让POST请求也会失败重试,可以继续向下阅读。

non_idempotent

Nginx文档中可以看到proxy_next_upstream有一个选项non_idempotent:

normally, requests with a non-idempotent method (POST, LOCK, PATCH) are not passed to the next server if a request has been sent to an upstream server (1.9.13); enabling this option explicitly allows retrying such requests;

通常情况下,如果请求使用非等幂方法(POST、LOCK、PATCH),请求失败后不会再到其他服务器进行重试。加上non_idempotent选项后,即使是非幂等请求类型(例如POST请求),发生错误后也会重试。

如果想让POST请求也会失败重试,需要配置non_idempotent

  1. upstream nginxretry {
  2. server 127.0.0.1:9030 weight=10;
  3. server 127.0.0.1:9031 weight=10;
  4. }
  5. server {
  6. listen 9039;
  7. location / {
  8. proxy_pass http://nginxretry;
  9. proxy_next_upstream error timeout http_500 non_idempotent;;
  10. }
  11. }

重启Nginx后再次使用POST请求访问 http://localhost:9039/ ,再分别查看9030和9031两个端口号对应的服务日志,可以看到两个服务都收到请求,也就是POST请求也会重试了。不过实际上在生产环境中,不建议加上non_idempotent选项,具体原因可以继续往下阅读。

什么是幂等方法

HTTP协议规范中,对幂等方法(Idempotent Method)做了以下定义:

A request method is considered “idempotent” if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.

如果使用该方法的多个相同请求对服务器的预期效果与单个请求的效果相同,则认为请求方法是幂等的。常见的HTTP请求方法中,GET是幂等的,而POST是非幂等的。如果在回答面试题"GET和POST区别"时能答出这一点,才能说明对HTTP协议有一定的理解。

在做业务开发是如何理解幂等性,举个最简单的例子:GET方法一般用于获取数据,如果获取的是数据库数据,对应的是SELECT语句。同样的SELECT语句执行一次还是多次,都不会影响数据。而POST一般对应INSERT,如果执行多次后,可能会造成数据重复插入的问题。所以不要使用GET方法做一些INSERT操作,在业务开发时要遵循HTTP协议规范。

生产环境中为什么不建议加上non_idempotent选项?因为无论是发生500错误还是timeout,服务器上的业务可能都已经执行过了,而重试会导致非幂等方法重复执行,从而导致业务问题,例如一个请求会创建了多个订单,或者收到多条短信的问题。

</article>

与[转帖]nginx的重试机制 proxy_next_upstream相似的内容:

[转帖]nginx的重试机制 proxy_next_upstream

https://blog.csdn.net/xiao__gui/article/details/89441162 https://zhuanlan.zhihu.com/p/35803906 https://www.cnblogs.com/powerwu/articles/9791295.html h

[转帖]nginx的重试机制 proxy_next_upstream

https://blog.csdn.net/xiao__gui/article/details/89441162 https://zhuanlan.zhihu.com/p/35803906 https://www.cnblogs.com/powerwu/articles/9791295.html h

[转帖]nginx的proxy_next_upstream使用中的一个坑

https://zhuanlan.zhihu.com/p/35803906 今天线上系统出了点问题,机房的电信出口突然不通了,原本以为能自动切换的nginx配置,居然没有生效,导致了业务告警,手工紧急处理了才解决了。 当时的设想是,如果这个服务的访问,出现了500或者超时的情况,会自动重试到下一个服

[转帖]nginx http超时重试幂等问题

https://blog.csdn.net/wangtingting_100/article/details/89842557 nginx做反向代理时,作为负载均衡器,对执行失败的任务默认会调度到其他节点执行。 默认设置:proxy_next_upstream error timeout #发生网络

[转帖]Nginx:地址重写(return和rewrite)

https://www.cnblogs.com/testopsfeng/p/15294660.html Nginx的重写指令用于改变客户端的URL请求。主要有return和rewrite。两个指令都有重写URL的能力,但rewrite支持更复杂的功能。 Return指令 在server中返回 301

[转帖]Nginx中的Rewrite的重定向配置与实践

https://www.cnblogs.com/tugenhua0707/p/10798762.html 阅读目录 一:理解地址重写 与 地址转发的含义。 二:理解 Rewrite指令 使用 三:理解if指令 四:理解防盗链及nginx配置 简介:Rewrite是Nginx服务器提供的一个重要的功能

[转帖]详解nginx的rewrite应用,Nginx高级之Rewrite规则

https://zhuanlan.zhihu.com/p/359801091 Rewrite主要的功能是实现URL重写,Nginx 的 Rewrite 规则采用 PCRE Perl 兼容正则表达式的语法进行规则匹配,如相使用 Nginx 的 Rewrite 功能,在编译 Nginx 前要编译安装 P

[转帖]Nginx优化与防盗链

目录 一、配置Nginx隐藏版本号1、第一种方法修改配置文件2、第二种方法修改源码文件,重新编译安装 二、修改Nginx用户与组三、配置Nginx网页缓存时间四、实现Nginx的日志分割五、配置Nginx实现连接超时六、更改Nginx运行进程数七、配置Nginx实现网页压缩功能八、配置Nginx防盗

[转帖]Nginx Rewrite重写功能

目录 一、rewrite的概述1.1、概述1.2 跳转场景1.3 跳转实现1.4 Rewrite实际场景 二、常用的nginx正则表达式三、rewrite命令3.1 rewrite的语法格式3.2 fiag标记说明 四、location4.1 location大致分为三类4.2 location 常

[转帖]nginx(三十二)rewrite模块

一 官方rewrite模块 ① 模块涉及的指令 ② 基本简介 rewrite模块会根据'PCRE正则'匹配'重写URI' pcre下载地址 pcretest测试正则表达式 ③ break 疑惑点: 结束'该作用域'下剩余的指令,还是'只是该rewrite模块的'指令? 1)配置demo 2)不带参数