草庐IT

Nginx作反向代理时超时重试配置

青砖伴瓦 2023-04-17 原文

这里只讨论作反向代理时,当上游服务发生如接口超时、返回指定状态码等状况时而导致nginx超时重试。

这里使用的nginx版本为1.16.1,可通过nginx -V查看版本。

超时重试主要通过配置ngx_http_upstream_modulengx_http_proxy_module模块中字段实现的。

这两个模块的官方文档:

准备的工作:

  1. 准备一个后台服务,向外暴露访问地址,服务收到请求后,处理的时间为5s(当然你可以设置为其它大小),随后返回结果。这是用来模拟nginx访问上游服务接口时超时场景。
  2. 运行两个这样相同的后台服务实例,对外暴露的端口分别为9090和9091,用来模拟nginx作负载均衡的场景。
  3. nginx配置一个server,暴露端口9000,用于接收请求,并把请求分发到9090和9091的两台实例上。

具体配置:

upstream RETRY_TEST_SERVER {
        server 127.0.0.1:9090;
        server 127.0.0.1:9091;
}

server {
        listen 9000;
        server_name localhost;
        location / {
                proxy_pass http://RETRY_TEST_SERVER;
                proxy_next_upstream timeout;
                proxy_read_timeout 3;
        }
}

配置字段解释:

  • proxy_pass

    即分发到哪个upstream上

  • proxy_next_upstream

    用来配置哪些情景下会重试。当nginx收到请求,并把请求转发到RETRY_TEST_SERVER,upstream默认的负载均衡策略为轮询,第一次请求转到9090端口,若9090服务实例响应超时,那么将会将请求转到9091,这个“响应超时”,就是这个字段配置的触发场景。可配置的字段有:

    • timeout
    • error
    • http_500

    默认的配置为 proxy_next_upstream error timeout

    所有的配置列表及含义:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream

  • proxy_read_timeout

    配置从上游服务读取的超时时间。

    官方解释为:

    Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.

运行

由于设置了proxy_read_timeout为3秒,实例的响应时间为5秒,所以当访问地址curl localhost:9000/test/delay(这是实例的接口测试地址)时:

  1. 请求路由到9090端口,9090接收到请求,3秒后请求超时
  2. 由于配置了proxy_next_upstream timeout,即在发生超时时,会路由到下一节点,这时请求会路由到9091
  3. 3秒过后请求再次超时,nginx返回给客户端错误信息:Gateway Timeout;

注意

  1. 由于作测试用,为方便会将多个相同的实例部署到本机通过端口作负载均衡测试,如:

    upstream RETRY_TEST_SERVER {
            server 127.0.0.1:9090;
            server 127.0.0.1:9091;
    }
    

    我在测试时,server 后的 127.0.0.1 一开始是写成localhost,测试9090发生超时时,没有路由到9091,而是又在9090执行了一次,改成127.0.0.1后正常。

  2. upstream 的 server 模块后还可以添加其它属性字段:

    upstream RETRY_TEST_SERVER {
            server 127.0.0.1:9090 max_fails=2 fail_timeout=10s;
            server 127.0.0.1:9091 max_fails=2 fail_timeout=10s;
    }
    

    官方文档:https://nginx.org/en/docs/http/ngx_http_upstream_module.html#server

    • max_failsfail_timeout

      max_failsfail_timeout须结合使用,意为“在多长时间内访问server多少次不可用”时,标记这个server节点不可用,若不可用则在此周期内当该server收到请求后直接返回错误,即nginx会直接返回给客户端 "Bad Gateway",等到下一个 "fail_timeout"周期,才会再次尝试该server是否可用。(至于"如何判断是否可用",则根据字段proxy_next_upstream的配置。)

      这一点相当重要。如实例有两个请求地址,一个耗时较长 /test/slow,一个耗时较短 /test/fast;当接口/test/slow超时时,指定时间(fail_timeout)超过最大尝试次数(max_fails)时,此时9090标记为不可用,此时请求/tset/fast路由到9090上时,nginx 会直接返回错误(Bad Gateway),即超时接口影响了正常接口的调用。

      我建议有两种方式:

      1. 提高检测是否可用的频率

        即使 fail_timeout/max_fails变小。如max_fails=5 fail_timeout=10 要比 max_fails=2 fail_timeout=10可靠

      2. 为耗时长的接口单独配置upstream和server(推荐)


有关Nginx作反向代理时超时重试配置的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  3. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  4. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  5. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  6. 神州数码无线产品(AC+AP)配置 - 2

    注意:本文主要掌握DCN自研无线产品的基本配置方法和注意事项,能够进行一般的项目实施、调试与运维AP基本配置命令AP登录用户名和密码均为:adminAP默认IP地址为:192.168.1.10AP默认情况下DHCP开启AP静态地址配置:setmanagementstatic-ip192.168.10.1AP开启/关闭DHCP功能:setmanagementdhcp-statusup/downAP设置默认网关:setstatic-ip-routegeteway192.168.10.254查看AP基本信息:getsystemgetmanagementgetmanaged-apgetrouteAP配

  7. hadoop安装之保姆级教程(二)之YARN的配置 - 2

    1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模

  8. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

    使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

  9. Ruby 默认将 IRB 配置为 Pretty_Inspect - 2

    我是ruby​​的新手,正在配置IRB。我喜欢pretty-print(需要'pp'),但总是输入pp来漂亮地打印它似乎很麻烦。我想做的是默认情况下让它漂亮地打印出来,所以如果我有一个var,比如说,'myvar',然后键入myvar,它会自动调用pretty_inspect而不是常规检查。我从哪里开始?理想情况下,我将能够向我的.irbrc文件添加一个自动调用的方法。有什么想法吗?谢谢! 最佳答案 irb中默认pretty-print对象正是hirb被迫去做。Theseposts解释hirb如何将几乎所有内容转换为ascii表。虽

  10. Ruby 在 n *milli* 秒后超时一段代码 - 2

    在Ruby中,我需要在n毫秒秒后暂停一段代码的执行。我知道RubyTimeout库支持秒的超时:http://ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html这可能吗? 最佳答案 只需为超时使用十进制值。n毫秒的示例:Timeout::timeout(n/1000.0){sleep(100)} 关于Ruby在n*milli*秒后超时一段代码,我们在StackOverflow上找到一个类似的问题: https:

随机推荐