So konfigurieren Sie die Fehlerinjektion dynamisch mit OpenNJet

NGINX entwickelt sich zu Cloud Native weiter, alles in  OpenNJet


Durch Ausfälle verursachte Dienstunterbrechungen können schwerwiegende geschäftliche Folgen haben. Daher ist es wichtig, belastbare Systeme aufzubauen, auszuführen und zu testen. Die Widerstandsfähigkeit eines Systems ergibt sich aus der Widerstandsfähigkeit seiner Teile: Jeder Teil des Systems ist in der Lage, eine bestimmte Anzahl von Fehlern oder Ausfällen zu bewältigen. Unabhängig davon, ob es sich um nachfolgende Nichtverfügbarkeit von Diensten, Netzwerklatenz oder Datenverfügbarkeitsprobleme handelt, sind verteilte Systeme mit impliziten nichtfunktionalen Anforderungen für die entsprechende Fehlerbehandlung gefüllt.

Welche Fehlerinjektion?

Fault Injection ist eine ergänzende Technik zum Softwaretest und wird zur Verbesserung der Softwareleistung und -ausfallsicherheit eingesetzt. Während herkömmliche Testmethoden das korrekte Verhalten von Software überprüfen, bewertet die Fehlerinjektion das korrekte Verhalten von Software durch gezielt injizierte Fehler.
Die HTTP-Fehlerinjektion unterstützt das Abbrechen von HTTP-Anfragen von Downstream-Diensten und/oder das Verzögern von Proxy-Anfragen. Eine Fehlerregel muss eine Verzögerung oder einen Abbruch oder beides haben. Bei der Weiterleitung von HTTP-Anfragen an das in der Route angegebene Ziel können ein oder mehrere Fehler eingefügt werden. Fault-Injection-Strategien werden auf den Client-HTTP-Verkehr angewendet.
Verzögerungsspezifikationen werden verwendet, um Verzögerungen in den Anforderungsweiterleitungspfad einzufügen.
Die Abbruchspezifikation wird verwendet, um eine Anfrage vorzeitig abzubrechen und einen vorab festgelegten Fehlercode zurückzugeben.

Typ

Es gibt drei Haupttypen der Fehlerinjektion. An derselben Stelle darf nur ein Typ konfiguriert werden:
  • Verzögerung: Nur Verzögerungsfehler einspeisen. Nach Ablauf der Verzögerungszeit eine Verbindungsanforderung an den Upstream initiieren.
  • Abbruch: Nur Abbruchfehler injizieren, Client-Anfrage empfangen, den injizierten Statuscode direkt an den Client zurückgeben und die Anfrage beenden.
  • Verzögerung + Abbruch: Verzögerungsfehler und Abbruchfehler gleichzeitig injizieren. Zuerst verzögern. Nachdem die Verzögerungszeit abgelaufen ist, geben Sie den durch Abbruch festgelegten Statuscode direkt an den Client zurück, beenden Sie die Anforderung und initiieren Sie keine Verbindungsanforderung mehr zum Upstream .

Anweisung (fault_inject):

Fault_inject- Direktive

Parametereinführung:
Parameter Typ Erforderlich veranschaulichen
Typ={Typ} Zeichenfolge Ja Verzögerung, Abbruch, Verzögerung_Abort eine der drei Verzögerungen: Injektionstyp verzögern, Abort: Injektionstyp abbrechen, Verzögerung_abort: Verzögerung + Injektionstyp abbrechen
delay_duration={duration} Zeichenfolge Ja (Verzögerung und Verzögerung_Abort sind erforderlich) Verzögerungszeit, 1h/1m/1s/1ms, muss >=1ms sein
status_code={code} uint Ja (abort und delay_abort sind erforderlich) Code legt den Injektions-Rückgabecode fest, [200, 600]
delay_percentage={pct} uint Optional, Standard 100 (100 %) Legen Sie den Prozentsatz der eingespeisten verzögerten Anforderungen fest. Der Standardwert ist 100 %, Bereich: [1, 100], z. B.: 1 bedeutet 1 %, 10 bedeutet 10 %
abort_percentage={pct} uint Optional, Standard 100 (100 %) Legen Sie den Prozentsatz der injizierten Abbruchanfragen fest. Der Standardwert ist 100 %, Bereich: [1, 100], z. B.: 1 bedeutet 1 %, 10 bedeutet 10 %

Injektionstyp abbrechen

Funktion: Entsprechend der eingestellten prozentualen Wahrscheinlichkeit gibt die Trefferanforderung direkt den angegebenen Statuscode zurück
Parametereinführung:
 
Parameter Typ Erforderlich veranschaulichen
status_code={code} uint Ja Code legt den Injektions-Rückgabecode fest, [200, 600]
abort_percentage={pct} uint Optional, Standard 100 (100 %) Legen Sie den Prozentsatz der injizierten Abbruchanfragen fest. Der Standardwert ist 100 %, Bereich: [1, 100], z. B.: 1 bedeutet 1 %, 10 bedeutet 10 %

1.3.2 Art der verzögerten Einspritzung

Funktion: Entsprechend der eingestellten prozentualen Wahrscheinlichkeit wird die Trefferanforderung um die eingestellte Dauer verzögert, um eine Anfrage an den Upstream-Upstream zu initiieren.
Parametereinführung:
Parameter Typ Erforderlich veranschaulichen
delay_duration={duration} Zeichenfolge Ja Verzögerungszeit, 1h/1m/1s/1ms, muss >=1ms sein
delay_percentage={pct} uint Optional, Standard 100 (100 %) Legen Sie den Prozentsatz der eingespeisten verzögerten Anforderungen fest. Der Standardwert ist 100 %, Bereich: [1, 100], z. B.: 1 bedeutet 1 %, 10 bedeutet 10 %

Injektionstyp „Verzögerung+Abbruch“.

Funktion: Entsprechend der eingestellten prozentualen Wahrscheinlichkeit wird die Trefferanforderung um die eingestellte Dauer verzögert, um eine Anfrage an den Upstream-Upstream zu initiieren.
Parametereinführung:
Parameter Typ Erforderlich veranschaulichen
delay_duration={duration} Zeichenfolge Ja Verzögerungszeit, 1h/1m/1s/1ms, muss >=1ms sein
status_code={code} uint Ja Code legt den Injektions-Rückgabecode fest, [200, 600]
delay_percentage={pct} uint Optional, Standard 100 (100 %) Legen Sie den Prozentsatz der eingespeisten verzögerten Anforderungen fest. Der Standardwert ist 100, Bereich: [1, 100], z. B.: 1 bedeutet 1 %, 100 bedeutet 100 %
abort_percentage={pct} uint Optional, Standard 100 (100 %) Legen Sie den Prozentsatz der injizierten Abbruchanfragen fest. Der Standardwert ist 100, Bereich: [1, 100], z. B.: 1 bedeutet 1 %, 100 bedeutet 100 %

Deklarative dynamische API- Fehlerinjektion in OpenNJet

Schnittstellen -URL

 GET  http://{ip:port}/config/2/config/http_dyn_fault_inject

 PUT  http://{ip:port}/config/2/config/http_dyn_fault_inject

Das Json- Format lautet wie folgt:

{
    "servers": [
        {
            "listens": [
                "0.0.0.0:92"
            ],
            "serverNames": [
                ""
            ],
            "locations": [
                {
                    "location": "/",
                    #此处type可为下面四种
                    #abort   这个表示中止注入
                    #delay   这个表示延迟注入
                    #delay_abort  这个表示延迟+中止注入
                    #none    这个表示取消故障注入或者不设置故障注入
                    
                    "fault_inject_type": "delay_abort", #如果该值为none,则其他参数取值无意义
                    
                    "delay_percentage": 100,      #延迟故障注入百分比,如果是abort类型,该值无意义
                    "abort_percentage": 100,      #中止故障注入百分比,如果是delay类型,该值无意义
                    "status_code": 405,         #故障注入状态码,如果是delay类型,该值无意义
                    "delay_duration": "5s",     #故障注入延迟时间,如果是abort类型,该值无意义
                    "locations": [
                        {
                            "location": "/demo",
                            "fault_inject_type": "none", #子location /demo 故障注入类型
                        }
                    ]
                }
            ]
        }
    ]
}

OpenNJet-Konfigurationsdatei

load_module modules/njt_http_dyn_fault_inject_module.so; #使用动态故障注入功能需要load该模块

Modulzusammenstellung

Das Fault-Injection-Modul wird statisch kompiliert und über die Makrosteuerung NJT_HTTP_FAULT_INJECT aktiviert.
Das deklarative API-Modul zur dynamischen Fehlerinjektion übernimmt die dynamische Kompilierung und muss über die Loadmodule-Anweisung geladen werden.

Funktionstest

HTTP1.1- Protokolltest

Fehlerinjektionstest abbrechen _

Aufbau:
server {
        listen       80 ;
        server_name  localhost;

        location / {
          fault_inject type=abort  status_code=405 abort_percentage=100;
          proxy_next_upstream_tries 0;      #关闭重试
          proxy_next_upstream_timeout 0;    #关闭超时
          proxy_pass http://back/;
        }
     }

Testergebnisse:

Der Browser-http1.1-Zugriff gibt sofort 405 zurück, wie folgt:
 
OpenNJet-Protokoll:  
2023/07/17 17:04:51 [debug] 13179#0: *35  fault injet abort 405, client: 192.168.40.205, server: localhost, request: "GET / HTTP/1.1", host: "192.168.40.136"

Fehlerinjektionstest verzögern _

Aufbau:
server {
        listen       80 ;
        server_name  localhost;

        location / {
          fault_inject type=delay  delay_duration=10s delay_percentage=100;
          proxy_next_upstream_tries 0;      #关闭重试
          proxy_next_upstream_timeout 0;    #关闭超时
          proxy_pass http://back/;
        }
     }

Testergebnisse:

Browser http1.1-Zugriff, warten Sie 10 Sekunden und kehren Sie wie folgt zur Zugriffserfolgsseite zurück:
 
 
OpenNJet-Protokoll:
#等待10s 后正常处理并成功返回页面
2023/07/17 17:02:04 [debug] 13015#0: *28  fault inject start deleay, client: 192.168.40.205, server: localhost, request: "GET / HTTP/1.1", host: "192.168.40.136"
2023/07/17 17:02:14 [debug] 13015#0: *28  fault njet delay success, client: 192.168.40.205, server: localhost, request: "GET / HTTP/1.1", host: "192.168.40.136"
2023/07/17 17:02:14 [debug] 13015#0: *28  fault inject delay timer clean while closing request, client: 192.168.40.205, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8008/", host: "192.168.40.136"

„delay_abort “ -Fehlerinjektionstest

Aufbau:
server {
        listen       80 ;
        server_name  localhost;

        location / {
          fault_inject type=delay_abort  delay_duration=10s status_code=405 delay_percentage=100;
          proxy_next_upstream_tries 0;      #关闭重试
          proxy_next_upstream_timeout 0;    #关闭超时
          proxy_pass http://back/;
        }
     }
Testergebnisse:
Wenn der Browser auf http1.1 zugreift, gibt er nach 10 Sekunden Wartezeit direkt 405 zurück, wie folgt:
OpenNJet-Protokoll:
# 先delay等待10s
2023/07/17 16:57:48 [debug] 11894#0: *26  fault inject start deleay, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/1.1", host: "192.168.40.136"
2023/07/17 16:57:58 [debug] 11894#0: *26  fault njet delay success, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/1.1", host: "192.168.40.136"

#直接返回 405 abort
2023/07/17 16:57:58 [debug] 11894#0: *26  fault injet abort 405, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/1.1", host: "192.168.40.136"
2023/07/17 16:57:58 [debug] 11894#0: *26  fault inject delay timer clean while closing request, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/1.1", host: "192.168.40.136"

Testen des HTTP2-Protokolls

Fehlerinjektionstest abbrechen _

Aufbau:

server {
        listen       81 ssl http2;
        server_name  192.168.40.136;
        ssl_certificate                 /root/bug/njet1.0/mycert/www.tmlake.xn--com-7m0aa+3.pem;
        ssl_certificate_key             /root/bug/njet1.0/mycert/www.tmlake.xn--com-7m0aa+3-key.pem;

        location / {
          fault_inject type=abort  status_code=405 abort_percentage=100;
          proxy_next_upstream_tries 0;      #关闭重试
          proxy_next_upstream_timeout 0;    #关闭超时
          proxy_pass http://back/;
        }
     }
Testergebnisse:
 
Wenn der Browser auf http2 zugreift, gibt er sofort 405 wie folgt zurück:
 
OpenNJet-Protokoll:
#直接返回405
2023/07/17 16:43:54 [debug] 11894#0: *8  fault injet abort 405, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", host: "192.168.40.136:81"

Fehlerinjektionstest verzögern

Aufbau:
server {
        listen       81 ssl http2;
        server_name  192.168.40.136;
        ssl_certificate                 /root/bug/njet1.0/mycert/www.tmlake.xn--com-7m0aa+3.pem;
        ssl_certificate_key             /root/bug/njet1.0/mycert/www.tmlake.xn--com-7m0aa+3-key.pem;

        location / {
          fault_inject type=delay  delay_duration=10s delay_percentage=100;
          proxy_next_upstream_tries 0;      #关闭重试
          proxy_next_upstream_timeout 0;    #关闭超时
          proxy_pass http://back/;
        }
     }
Testergebnisse:
 
Browser-HTTP2-Zugriff, warten Sie 10 Sekunden und greifen Sie wie folgt erfolgreich auf die Seite zu:
 
OpenNJet-Protokoll:
#delay 10s后成功访问到页面
2023/07/17 16:42:03 [debug] 11783#0: *4  fault inject start deleay, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", host: "192.168.40.136:81"
2023/07/17 16:42:13 [debug] 11783#0: *4  fault njet delay success, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", host: "192.168.40.136:81"
2023/07/17 16:42:13 [debug] 11783#0: *4  fault inject delay timer clean while sending to client, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", upstream: "http://127.0.0.1:8008/", host: "192.168.40.136:81"

„delay_abort -Fehlerinjektionstest

Aufbau:
 
server {
        listen       81 ssl http2;
        server_name  192.168.40.136;
        ssl_certificate                 /root/bug/njet1.0/mycert/www.tmlake.xn--com-7m0aa+3.pem;
        ssl_certificate_key             /root/bug/njet1.0/mycert/www.tmlake.xn--com-7m0aa+3-key.pem;

        location / {
          fault_inject type=delay_abort  delay_duration=10s status_code=405 delay_percentage=100;
          proxy_next_upstream_tries 0;      #关闭重试
          proxy_next_upstream_timeout 0;    #关闭超时
          proxy_pass http://back/;
        }
     }
Testergebnisse:
 
Der Browser greift auf http2 zu und gibt 405 zurück, nachdem er 10 Sekunden gewartet hat, wie folgt:
 
OpenNJet-Protokoll:
#先delay 10s
2023/07/17 16:39:10 [debug] 11598#0: *2  fault inject start deleay, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", host: "192.168.40.136:81"
2023/07/17 16:39:20 [debug] 11598#0: *2  fault njet delay success, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", host: "192.168.40.136:81"

#再直接返回405 abort
2023/07/17 16:39:20 [debug] 11598#0: *2  fault injet abort 405, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", host: "192.168.40.136:81"
2023/07/17 16:39:20 [debug] 11598#0: *2  fault inject delay timer clean, client: 192.168.40.205, server: 192.168.40.136, request: "GET / HTTP/2.0", host: "192.168.40.136:81"

Dynamischer Fehlerinjektionstest der deklarativen API in OpenNJet

Statische OpenNJet-Konfiguration

...
load_module modules/njt_http_dyn_fault_inject_module.so;     #load 动态模块so
...

http{
...

    upstream back{
       server 127.0.0.1:8008;
    }

     server{
                listen 8008;
                location / {
                        index 8008.html;
                        add_header Set-Cookie route=8008;
                }
     }

     #8009 为普通server, 返回8008.html文件
     server{
                listen 8009;
                location / {
                        proxy_pass http://back/;
                }
     }
...
}

Get-Anfrage ausführen

curl http://192.168.40.136:8081/config/2/config/http_dyn_fault_inject | jq
{
  "servers": [
    {
      "listens": [
        "0.0.0.0:8009"
      ],
      "serverNames": [
        ""
      ],
      "locations": [
        {
          "location": "/",
          "fault_inject_type": "none",         #8009 静态默认为none,即没有设置故障注入,
                                               #相关参数没有意义
          "delay_percentage": 100,
          "abort_percentage": 100,
          "status_code": 200,
          "delay_duration": ""
        }
      ]
    },
    {
      "listens": [
        "0.0.0.0:8008"
      ],
      "serverNames": [
        ""
      ],
      "locations": [
        {
          "location": "/",
          "fault_inject_type": "none",
          "delay_percentage": 100,
          "abort_percentage": 100,
          "status_code": 200,
          "delay_duration": ""
        }
      ]
    }
  ]
}

Browserzugriff

Keine Verzögerung, kehren Sie sofort zur Ergebnisseite zurück

Put-Anfrage ausführen und ändern

curl -X PUT http://192.168.40.136:8081/config/2/config/http_dyn_fault_inject -d '@json.txt'
json.txt lautet wie folgt:
{
  "servers": [
    {
      "listens": [
        "0.0.0.0:8009"
      ],
      "serverNames": [
        ""
      ],
      "locations": [
        {
          "location": "/",
          "fault_inject_type": "delay_abort", #修改为delay_abort, delay 5s, 然后返回405
          "delay_percentage": 100,
          "abort_percentage": 100,
          "status_code": 405,
          "delay_duration": "5s"
        }
      ]
    },
    {
      "listens": [
        "0.0.0.0:8008"
      ],
      "serverNames": [
        ""
      ],
      "locations": [
        {
          "location": "/",
          "fault_inject_type": "none",
          "delay_percentage": 100,
          "abort_percentage": 100,
          "status_code": 200,
          "delay_duration": ""
        }
      ]
    }
  ]
}

wieder bekommen

curl http://192.168.40.136:8081/config/2/config/http_dyn_fault_inject | jq
{
  "servers": [
    {
      "listens": [
        "0.0.0.0:8009"
      ],
      "serverNames": [
        ""
      ],
      "locations": [
        {
          "location": "/",
          "fault_inject_type": "delay_abort",     #与put 修改一致,说明修改成功
          "delay_percentage": 100,
          "abort_percentage": 100,
          "status_code": 405,
          "delay_duration": "5s"
        }
      ]
    },
    {
      "listens": [
        "0.0.0.0:8008"
      ],
      "serverNames": [
        ""
      ],
      "locations": [
        {
          "location": "/",
          "fault_inject_type": "none",
          "delay_percentage": 100,
          "abort_percentage": 100,
          "status_code": 200,
          "delay_duration": ""
        }
      ]
    }
  ]
}

Tatsächlicher Zugriff über Browser

Der tatsächliche Effekt besteht darin, 5 Sekunden zu warten und 405 zurückzugeben, was den Erwartungen entspricht.

Hintergrundprotokoll


#日志也显示delay 5s后,返回abort 405
2023/07/20 15:55:17 [debug] 30305#0: *12  fault inject start deleay,
client: 192.168.40.205, server: , request: "GET / HTTP/1.1", host: "192.168.40.136:8009"
2023/07/20 15:55:22 [debug] 30305#0: *12  fault njet delay success, client: 192.168.40.205,
 server: , request: "GET / HTTP/1.1", host: "192.168.40.136:8009"
2023/07/20 15:55:22 [debug] 30305#0: *12  fault injet abort 405, client: 192.168.40.205, server: , 
request: "GET / HTTP/1.1", host: "192.168.40.136:8009"
2023/07/20 15:55:22 [debug] 30305#0: *12  fault inject delay timer clean while closing request, 
client: 192.168.40.205, server: , request: "GET / HTTP/1.1", host: "192.168.40.136:8009"=

Weitere praktische Fälle finden Sie unter njet.org.cn


OpenNJet   basierte zunächst auf dem Basiszweig von NGINX1.19 und entwickelte sich unabhängig davon. OpenNJet zeichnet sich durch hohe Leistung, Stabilität und einfache Erweiterung aus. Es löst auch die seit langem bestehenden Probleme von NGINX, wie z. B. Schwierigkeiten bei der dynamischen Konfiguration und die Auswirkungen auf Verwaltungsfunktionen Geschäft. Als zugrunde liegende Engine verwendet OpenNJet den dynamischen Lademechanismus, um verschiedene Produktformen zu implementieren, z. B. API-Gateway, Nachrichten-Proxy, eingehender und ausgehender Proxy, Lastausgleich, WAF usw. In der Cloud-nativen Architektur bietet OpenNJet nicht nur Nord-Süd-Kommunikations-Gateway-Funktionen, sondern auch neue Funktionen wie Ost-West-Kommunikation im Service Grid, transparente Verkehrsentführung, Leistungsschalter, Telemetrie und Fehlerinjektion.

Die Gitee-     Mailinggruppe
lädt Sie zum Open Source und gemeinsamen Erstellen ein:
https://njet.org.cn/

200 Yuan Geldstrafe und mehr als 1 Million Yuan beschlagnahmt You Yuxi: Die Bedeutung hochwertiger chinesischer Dokumente Musks Hardcore-Migrationsserver Solon für JDK 21, virtuelle Threads sind unglaublich! ! ! TCP-Überlastungskontrolle rettet das Internet- Flutter für OpenHarmony ist da. Die LTS-Periode des Linux-Kernels wird von 6 auf 2 Jahre wiederhergestellt. Go 1.22 behebt den Variablenfehler der For-Schleife. Svelte hat ein „neues Rad“ gebaut – Runen. Google feiert sein 25-jähriges Jubiläum
{{o.name}}
{{m.name}}

Ich denke du magst

Origin my.oschina.net/u/6606114/blog/10114624
Empfohlen
Rangfolge