Nginx 下的 recursive error pages 命令的實(shí)踐(多級錯(cuò)誤重試)

說明

部分的服務(wù)節(jié)點(diǎn)經(jīng)常再經(jīng)過了nginx已經(jīng)進(jìn)入到了上游服務(wù)器服務(wù)內(nèi)部之后,因?yàn)橐恍┪粗脑?,如第三方接口的請求超時(shí)等,也會(huì)引起的服務(wù)的502的響應(yīng)異常,如何再此類的情況解決節(jié)點(diǎn)不直接的響應(yīng)返回的502的狀態(tài)碼和結(jié)果信息,或者重試。
本實(shí)踐主要是嘗試這種方案的可行性。

應(yīng)用場景

此場景僅限于自己業(yè)務(wù)中,比如當(dāng)某個(gè)業(yè)務(wù)進(jìn)行到內(nèi)部服務(wù)器且經(jīng)過第三方接口直充成功的之后,突然的莫名成的程序進(jìn)程崩潰或無響應(yīng)的時(shí)候,此時(shí)重新提交一下相關(guān)的接口進(jìn)行分發(fā)核對一下具體的充值接口情況,避免返回給第三方服務(wù)商的的接口狀態(tài)是502的響應(yīng)。
正常來說充值類的業(yè)務(wù)最好不要進(jìn)行二次的確認(rèn)提交,不過我這邊進(jìn)行加鎖處理,目前暫時(shí)先這樣處理!

環(huán)境

首先配置一下具體的服務(wù)

nginx 的配置環(huán)境
127.0.0.1:5555用于引發(fā)502狀態(tài)碼的服務(wù)測試。
127.0.0.1:6666 用于引發(fā)502狀態(tài)碼引發(fā)之后,Nginx 下的 recursive error pages 之后的代理轉(zhuǎn)發(fā)到的服務(wù)節(jié)點(diǎn)

步驟:

PS:因當(dāng)前服務(wù)已安裝響應(yīng)的模塊bottle.所以直接的使用它來啟動(dòng)一個(gè)簡單的服務(wù)即可
搭建服務(wù)1:

#!/usr/bin/evn python
# coding=utf-8


from bottle import route, run, abort,request
from urllib.parse import quote, unquote
import urllib
def write_request_headers_log():
    """寫客戶端訪問路由的日志記錄"""
    # 記錄客戶端提交的參數(shù)
    request_log = '\nheaders:'
    try:
        request_log = request_log + '\nheaders:' + urllib.parse.unquote(str(request.headers.__dict__))
    except:
        request_log = request_log + '\nheaders:' + urllib.parse.unquote(str(request.headers))
    try:
        pass
        # log_helper.request_log(request_log + '\n')
    except:
        # log_helper.request_log(request_log + '頭部記錄異常')
        pass
    print(request_log)


@route('/')
def index():
    write_request_headers_log()
    print(request.query_string)
    print(request.forms)
    return "你好"

@route('/hello/502')
def index():
    write_request_headers_log()
    write_request_headers_log()
    print(request.query_string)
    print(request.forms)
    abort(502)

run(host='127.0.0.1', port=5555,debug=True,reloader=True)

搭建服務(wù)2:

#!/usr/bin/evn python
# coding=utf-8


from bottle import route, run, abort,request
from urllib.parse import quote, unquote
import urllib
def write_request_headers_log():
    """寫客戶端訪問路由的日志記錄"""
    # 記錄客戶端提交的參數(shù)
    request_log = '\nheaders:'
    try:
        request_log = request_log + '\nheaders:' + urllib.parse.unquote(str(request.headers.__dict__))
    except:
        request_log = request_log + '\nheaders:' + urllib.parse.unquote(str(request.headers))
    try:
        pass
        # log_helper.request_log(request_log + '\n')
    except:
        # log_helper.request_log(request_log + '頭部記錄異常')
        pass
    print(request_log)


@route('/')
def index():
    print('我是服務(wù)2')
    write_request_headers_log()
    print(request.query_string)
    print(request.forms)
    return "你好"

@route('/hello/502')
def index():
    print('我是服務(wù)2')
    write_request_headers_log()
    write_request_headers_log()
    print(request.query_string)
    print(request.forms)


run(host='127.0.0.1', port=6666,debug=True,reloader=True)

nginx 配置(沒啟用recursive error pages 的情況下)

upstream ceshsihii_test {
    server 127.0.0.1:5555 weight=1 max_fails=0 fail_timeout=12s;
}

upstream ceshsihii6666_test {
    server 127.0.0.1:6666 weight=1 max_fails=0 fail_timeout=12s;
}

server {
    listen      5554;
    charset     utf-8;
    server_name 127.0.0.1;
    



    location / {
        proxy_pass    http://ceshsihii_test;
        proxy_set_header   Host    $host;  
        proxy_set_header   X-Real-IP   $remote_addr;   
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout      300; #nginx跟后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí))
        proxy_send_timeout         300; #后端服務(wù)器數(shù)據(jù)回傳時(shí)間(代理發(fā)送超時(shí))
        proxy_read_timeout         300; #連接成功后,后端服務(wù)器響應(yīng)時(shí)間(代理接收超時(shí))
        error_page   502          = @fetch;
    }
    
    location @fetch {
        proxy_pass    http://ceshsihii6666_test;
        proxy_set_header   Host    $host;  
        proxy_set_header   X-Real-IP   $remote_addr;   
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout      300; #nginx跟后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí))
        proxy_send_timeout         300; #后端服務(wù)器數(shù)據(jù)回傳時(shí)間(代理發(fā)送超時(shí))
        proxy_read_timeout         300; #連接成功后,后端服務(wù)器響應(yīng)時(shí)間(代理接收超時(shí))
    }
    
    access_log  /data/logs/nginx/ceshsihii_test.log  main;
}

測試啟動(dòng)

[root@web-1 ceshi]# python server_5555.py 
Bottle v0.12.10 server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:5555/
Hit Ctrl-C to quit.

[root@web-1 ceshi]# python server_6666.py 
Bottle v0.12.10 server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:6666/
Hit Ctrl-C to quit.

測試服務(wù)響應(yīng)正常:

[root@web-1 ~]# curl http://127.0.0.1:5554/
你好[root@web-1 ~]#

測試502響應(yīng)

[root@web-1 ~]# curl http://127.0.0.1:5554/hello/502

    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html>
        <head>
            <title>Error: 502 Bad Gateway</title>
            <style type="text/css">
              html {background-color: #eee; font-family: sans;}
              body {background-color: #fff; border: 1px solid #ddd;
                    padding: 15px; margin: 15px;}
              pre {background-color: #eee; border: 1px solid #ddd; padding: 5px;}
            </style>
        </head>
        <body>
            <h1>Error: 502 Bad Gateway</h1>
            <p>Sorry, the requested URL <tt>&#039;http://127.0.0.1/hello/502&#039;</tt>
               caused an error:</p>
            <pre>Unknown Error.</pre>
        </body>
    </html>
[root@web-1 ~]# 

此時(shí)5555端口的服務(wù)節(jié)點(diǎn)的響應(yīng)也是502:

<bottle.FormsDict object at 0x7f39e0279e80>
127.0.0.1 - - [29/Oct/2020 13:27:27] "GET /hello/502 HTTP/1.0" 502 718

6666服務(wù)節(jié)點(diǎn)沒任何的響應(yīng):

查看ngin日志:
127.0.0.1 - 127.0.0.1:5555  [29/Oct/2020:13:27:27 +0800-1603949247.669] "GET /hello/502 HTTP/1.1" [0.006] [0.005]502 718 "" "curl/7.29.0" "" ""

修改Nginx配置信息:(啟用recursive error pages 的情況下)

修改Nginx配置信息:

upstream ceshsihii_test {
    server 127.0.0.1:5555 weight=1 max_fails=0 fail_timeout=12s;
}

upstream ceshsihii6666_test {
    server 127.0.0.1:6666 weight=1 max_fails=0 fail_timeout=12s;
}

server {
    listen      5554;
    charset     utf-8;
    server_name 120.77.63.115;
    
    proxy_intercept_errors on; 
    recursive_error_pages on; 

    location / {
        proxy_pass    http://ceshsihii_test;
        proxy_set_header   Host    $host;  
        proxy_set_header   X-Real-IP   $remote_addr;   
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout      300; #nginx跟后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí))
        proxy_send_timeout         300; #后端服務(wù)器數(shù)據(jù)回傳時(shí)間(代理發(fā)送超時(shí))
        proxy_read_timeout         300; #連接成功后,后端服務(wù)器響應(yīng)時(shí)間(代理接收超時(shí))
        error_page   502          = @fetch;
    }
    
    location @fetch {
        proxy_pass    http://ceshsihii6666_test;
        proxy_set_header   Host    $host;  
        proxy_set_header   X-Real-IP   $remote_addr;   
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout      300; #nginx跟后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí))
        proxy_send_timeout         300; #后端服務(wù)器數(shù)據(jù)回傳時(shí)間(代理發(fā)送超時(shí))
        proxy_read_timeout         300; #連接成功后,后端服務(wù)器響應(yīng)時(shí)間(代理接收超時(shí))
    }
    
    access_log  /data/logs/nginx/ceshsihii_test.log  main;
}



關(guān)鍵修改點(diǎn),新增:

    proxy_intercept_errors on; 
    recursive_error_pages on; 


說明: proxy_intercept_errors on; 當(dāng)上游服務(wù)器響應(yīng)頭回來后,可以根據(jù)響應(yīng)狀態(tài)碼的值進(jìn)行攔截錯(cuò)誤處理,
通常是結(jié)合error_page 指令進(jìn)行使用。用在訪問上游服務(wù)器出現(xiàn)錯(cuò)誤的情況下。

recursive_error_pages on; 可以讓下面的location @fetch生效

再進(jìn)行服務(wù)的測試:

訪問的經(jīng)過的Nginx的路由節(jié)點(diǎn):
[root@web-1 ~]# curl http://127.0.0.1:5554/hello/502?5467456=345345
[root@web-1 ~]# 
此時(shí):5555服務(wù)的節(jié)點(diǎn)響應(yīng)的是502的信息

<bottle.FormsDict object at 0x7fcfb9a88c50>
127.0.0.1 - - [29/Oct/2020 13:35:53] "GET /hello/502?5467456=345345 HTTP/1.0" 502 733
此時(shí):6666服務(wù)的節(jié)點(diǎn)響應(yīng)的是200的響應(yīng)信息
<bottle.FormsDict object at 0x7f9a54317400>
127.0.0.1 - - [29/Oct/2020 13:35:53] "GET /hello/502?5467456=345345 HTTP/1.0" 200 0
查看的最終的nginx日志信息為:
27.0.0.1 - 127.0.0.1:5555  [29/Oct/2020:13:27:27 +0800-1603949247.669] "GET /hello/502 HTTP/1.1" [0.006] [0.005]502 718 "" "curl/7.29.0" "" ""
127.0.0.1 - 127.0.0.1:5555 : 127.0.0.1:6666  [29/Oct/2020:13:31:24 +0800-1603949484.675] "GET /hello/502 HTTP/1.1" [0.005] [0.002 : 0.003]200 0 "" "curl/7.29.0" "" ""
127.0.0.1 - 127.0.0.1:5555 : 127.0.0.1:6666  [29/Oct/2020:13:32:31 +0800-1603949551.442] "GET /hello/502 HTTP/1.1" [0.004] [0.003 : 0.001]200 0 "" "curl/7.29.0" "" ""
127.0.0.1 - 127.0.0.1:5555 : 127.0.0.1:6666  [29/Oct/2020:13:33:26 +0800-1603949606.396] "GET /hello/502?5467456=345345 HTTP/1.1" [0.005] [0.003 : 0.001]200 0 "" "curl/7.29.0" "" ""
127.0.0.1 - 127.0.0.1:5555 : 127.0.0.1:6666  [29/Oct/2020:13:35:53 +0800-1603949753.523] "GET /hello/502?5467456=345345 HTTP/1.1" [0.009] [0.008 : 0.001]200 0 "" "curl/7.29.0" ""

實(shí)踐結(jié)果

說明,錯(cuò)誤的響應(yīng)的時(shí)候,可以進(jìn)行再次的轉(zhuǎn)發(fā)了!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容