Как динамически настроить внесение ошибок с помощью OpenNJet

NGINX становится облачным, все в  OpenNJet


Перебои в обслуживании, вызванные сбоями, могут иметь серьезные последствия для бизнеса, поэтому важно создавать, запускать и тестировать отказоустойчивые системы. Устойчивость системы зависит от устойчивости ее частей: каждая часть системы способна обрабатывать определенное количество ошибок или сбоев. Будь то последующая недоступность службы, задержка в сети или проблемы с доступностью данных, распределенные системы наполнены неявными нефункциональными требованиями для соответствующей обработки ошибок.

Какая неисправность впрыска?

Внедрение ошибок — это дополнительный метод тестирования программного обеспечения, который используется для повышения производительности и устойчивости программного обеспечения. В то время как обычные методы тестирования проверяют правильное поведение программного обеспечения, внедрение ошибок оценивает правильное поведение программного обеспечения посредством намеренно введенных ошибок.
Внедрение сбоев HTTP поддерживает прерывание HTTP-запросов от нижестоящих служб и/или задержку запросов прокси-сервера. Правило сбоя должно иметь задержку или прерывание, или и то, и другое. При пересылке HTTP-запросов в пункт назначения, указанный в маршруте, может возникнуть одна или несколько ошибок. Стратегии внедрения ошибок применяются к клиентскому HTTP-трафику.
Спецификации задержки используются для внесения задержек в путь пересылки запроса.
Спецификация прерывания используется для досрочного прерывания запроса и возврата заранее заданного кода ошибки.

тип

Существует три основных типа внесения ошибок. В одном месте можно настроить только один тип:
  • Задержка: вводит только ошибки задержки.После истечения времени задержки инициирует запрос на подключение к восходящему каналу.
  • Прерывание: вводить только ошибки прерывания, получать запрос клиента, напрямую возвращать введенный код состояния клиенту и завершать запрос.
  • Задержка+Прерывание: одновременно ввести ошибку задержки и ошибку прерывания. Сначала задержка. По истечении времени задержки напрямую вернуть код состояния, установленный при прерывании, клиенту, завершить запрос и больше не инициировать запрос на соединение с восходящим потоком. .

Инструкция (fault_inject):

директива error_inject

Введение параметров:
параметр тип Необходимый иллюстрировать
тип={тип} нить да задержка, прервать, задержка_аборт один из трех задержка: тип инъекции задержки abort: тип инъекции прерывания задержки_abort: задержка + тип инъекции прерывания
Delay_duration={длительность} нить Да (обязательны Delay и Delay_abort) время задержки, 1ч/1м/1с/1мс, должно быть >=1мс
status_code={код} uint Да (требуются abort и Delay_abort) code устанавливает код возврата инъекции, [200, 600]
Delay_percentage={процент} uint Необязательно, по умолчанию 100 (100 %) Установите процент введенных отложенных запросов, значение по умолчанию — 100%, диапазон: [1, 100], например: 1 означает 1%, 10 означает 10%
abort_percentage={pct} uint Необязательно, по умолчанию 100 (100 %) Установите процент введенных запросов на прерывание, значение по умолчанию — 100%, диапазон: [1, 100], например: 1 означает 1%, 10 означает 10%

Прерывание типа инъекции

Функция: в соответствии с установленной процентной вероятностью запрос на попадание напрямую возвращает указанный код статуса.
Введение параметров:
 
параметр тип Необходимый иллюстрировать
status_code={код} uint да code устанавливает код возврата инъекции, [200, 600]
abort_percentage={pct} uint Необязательно, по умолчанию 100 (100 %) Установите процент введенных запросов на прерывание, значение по умолчанию — 100%, диапазон: [1, 100], например: 1 означает 1%, 10 означает 10%

1.3.2 Тип задержки задержки

Функция: В соответствии с установленной процентной вероятностью запрос на попадание будет задержан на установленное время, чтобы инициировать запрос к восходящему потоку.
Введение параметров:
параметр тип Необходимый иллюстрировать
Delay_duration={длительность} нить да время задержки, 1ч/1м/1с/1мс, должно быть >=1мс
Delay_percentage={процент} uint Необязательно, по умолчанию 100 (100 %) Установите процент введенных отложенных запросов, значение по умолчанию — 100%, диапазон: [1, 100], например: 1 означает 1%, 10 означает 10%

Тип инъекции «Задержка+Прерывание»

Функция: В соответствии с установленной процентной вероятностью запрос на попадание будет задержан на установленное время, чтобы инициировать запрос к восходящему потоку.
Введение параметров:
параметр тип Необходимый иллюстрировать
Delay_duration={длительность} нить да время задержки, 1ч/1м/1с/1мс, должно быть >=1мс
status_code={код} uint да code устанавливает код возврата инъекции, [200, 600]
Delay_percentage={процент} uint Необязательно, по умолчанию 100 (100 %) Установите процент введенных отложенных запросов, значение по умолчанию — 100, диапазон: [1, 100], например: 1 означает 1%, 100 означает 100%
abort_percentage={pct} uint Необязательно, по умолчанию 100 (100 %) Установите процент введенных запросов на прерывание, значение по умолчанию — 100, диапазон: [1, 100], например: 1 означает 1%, 100 означает 100%

Динамическое внесение ошибок декларативного API в OpenNJet

URL-адрес интерфейса

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

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

Формат Json выглядит следующим образом:

{
    "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

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

Компиляция модуля

Модуль внедрения ошибок компилируется статически и включается с помощью макроса NJT_HTTP_FAULT_INJECT.
Модуль динамического внесения ошибок декларативного API использует динамическую компиляцию, и его необходимо загружать с помощью инструкции loadmodule.

функциональный тест

Тест протокола HTTP1.1

прервать тест с внесением ошибок

Конфигурация:
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/;
        }
     }

Результаты теста:

Доступ браузера по http1.1 немедленно вернет 405, а именно:
 
Журнал OpenNJet:  
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"

задержка теста на внесение ошибок

Конфигурация:
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/;
        }
     }

Результаты теста:

Доступ через браузер http1.1, подождите 10 секунд и вернитесь на страницу успешного доступа, выполнив следующие действия:
 
 
Журнал OpenNJet:
#等待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"

тест задержки_abort с внесением ошибки

Конфигурация:
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/;
        }
     }
Результаты теста:
Когда браузер обращается к http1.1, он возвращает 405 сразу после ожидания в течение 10 секунд, как показано ниже:
Журнал OpenNJet:
# 先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"

Тестирование протокола HTTP2

прервать тест с внесением ошибок

Конфигурация:

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/;
        }
     }
Результаты теста:
 
Когда браузер обращается к http2, он немедленно возвращает 405, а именно:
 
Журнал OpenNJet:
#直接返回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"

задержка теста на внесение ошибок

Конфигурация:
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/;
        }
     }
Результаты теста:
 
Доступ к браузеру по http2, подождите 10 секунд и успешно получите доступ к странице, выполнив следующие действия:
 
Журнал OpenNJet:
#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"

тест задержки_abort с внесением ошибки

Конфигурация:
 
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/;
        }
     }
Результаты теста:
 
Браузер обращается к http2 и возвращает 405 после ожидания в течение 10 секунд, как показано ниже:
 
Журнал OpenNJet:
#先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"

Динамическое тестирование с внесением ошибок декларативного API в OpenNJet

Статическая конфигурация OpenNJet

...
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/;
                }
     }
...
}

Выполнить запрос на получение

локон 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": ""
        }
      ]
    }
  ]
}

Доступ через браузер

Без задержек, немедленно вернитесь на страницу результатов

Выполнить запрос на размещение и изменить

Curl -X PUT http://192.168.40.136:8081/config/2/config/http_dyn_fault_inject -d '@json.txt'
json.txt выглядит следующим образом:
{
  "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": ""
        }
      ]
    }
  ]
}

получить снова

локон 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": ""
        }
      ]
    }
  ]
}

Фактический доступ через браузер

Фактический эффект состоит в том, чтобы подождать 5 секунд и вернуть 405, что соответствует ожиданиям.

Фоновый журнал


#日志也显示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"=

Более практические примеры можно найти на njet.org.cn.


OpenNJet   был впервые основан на базовой версии NGINX1.19 и развивался независимо. OpenNJet обладает характеристиками высокой производительности, стабильности и простоты расширения. Он также решает давние проблемы NGINX, такие как трудности динамической настройки и функции управления, влияющие на бизнес. В качестве базового механизма OpenNJet использует механизм динамической загрузки для реализации различных форм продукта, таких как шлюз API, прокси-сервер сообщений, входящий и исходящий прокси-сервер, балансировка нагрузки, WAF и т. д. В облачной архитектуре OpenNJet не только обеспечивает функции шлюза связи север-юг, но также предоставляет новые функции, такие как связь восток-запад в сервисной сети, прозрачный перехват трафика, автоматический выключатель, телеметрия и внесение сбоев.

    Почтовая группа
Gitee приглашает вас открыть исходный код и работать вместе: https://njet.org.cn/

Оштрафован на 200 юаней и конфисковано более 1 миллиона юаней Ю Юйси: важность высококачественных китайских документов Жесткий сервер миграции Маска Solon для JDK 21, виртуальные потоки невероятны! ! ! Контроль перегрузки TCP спасает Интернет Flutter для OpenHarmony уже здесь Срок LTS ядра Linux будет восстановлен с 6 до 2 лет Go 1.22 исправит ошибку переменной цикла for Svelte построила «новое колесо» — руны Google отмечает свое 25-летие
{{o.name}}
{{м.имя}}

рекомендация

отmy.oschina.net/u/6606114/blog/10114624
рекомендация