Bjoern в 4 раза быстрее, чем Nginx - как настроить Nginx для обработки запросов Bjoern proxy_requests без потеря производительности? [закрыто]

Я пытался поставить Bjoern за Nginx для упрощения балансировки нагрузки и предотвращения DoS / DDoS-атак.

К моему ужасу, я не только обнаружил, что он не только сбрасывает соединения, как микросхемы (это значение варьируется от 20% до 50% от общего числа подключений), но и кажется на самом деле быстрее, если его не оставлять позади.

Это было протестировано на машине с 6 ГБ ОЗУ и двухъядерным процессором 2 ГГц.

Мое приложение следующее:

import bjoern,redis

r = redis.StrictRedis(host='localhost', port=6379, db=0)

val = r.get('test:7')

def hello_world(environ, start_response):
    status = '200 OK'
    res = val
    response_headers = [
        ('Content-type','text/plain'),
        ('Content-Length',str(len(res)))]
    start_response(status, response_headers)
    return [res]

# despite the name this is not a hello world as you can see
bjoern.run(hello_world, 'unix:/tmp/bjoern.sock')

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

user www-data;
worker_processes 2;
worker_rlimit_nofile 52000; # worker_connections * 2
pid /run/nginx.pid;

events {
    multi_accept on;
    worker_connections 18000;
    use epoll;
}

http {

    charset                         utf-8;
    client_body_timeout             65;
    client_header_timeout           65;
    client_max_body_size            10m;
    default_type                    application/octet-stream;
    keepalive_timeout               20;
    reset_timedout_connection       on;
    send_timeout                    65;
    server_tokens                   off;
    sendfile                        on;
    server_names_hash_bucket_size   64;
    tcp_nodelay                     off;
    tcp_nopush                      on;


    error_log /var/log/nginx/error.log;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

и виртуальный хост:

upstream backend {
server unix:/tmp/bjoern.sock;
}

server {
    listen 80;

    server_name _;

    error_log  /var/log/nginx/error.log;



    location / {
        proxy_buffering     off;
        proxy_redirect      off;
        proxy_pass         http://backend;
    }
}

Тест Bjoern, установленный за Nginx через сокет unix, который я получил:

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /
Document Length:        148 bytes

Concurrency Level:      1000
Time taken for tests:   0.983 seconds
Complete requests:      10000
Failed requests:        3
   (Connect: 0, Receive: 0, Length: 3, Exceptions: 0)
Non-2xx responses:      3
Total transferred:      3000078 bytes
HTML transferred:       1480054 bytes
Requests per second:    10170.24 [#/sec] (mean)
Time per request:       98.326 [ms] (mean)
Time per request:       0.098 [ms] (mean, across all concurrent requests)
Transfer rate:          2979.64 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   15   4.8     15      35
Processing:    11   28  19.2     19     223
Waiting:        7   24  20.4     16     218
Total:         16   43  20.0     35     225

Percentage of the requests served within a certain time (ms)
  50%     35
  66%     38
  75%     40
  80%     40
  90%     79
  95%     97
  98%    109
  99%    115
 100%    225 (longest request)

10k запросов в секунду, меньшее количество неудачных запросов на этот раз, но все же ..

Когда Бьорн попадает прямо в руки, результаты тестов следующие:

После изменения bjoern.run (hello_world, 'unix: /tmp/bjoern.sock') на bjoern.run (hello_world, "127.0.0.1", 8000)

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /
Document Length:        148 bytes

Concurrency Level:      100
Time taken for tests:   0.193 seconds
Complete requests:      10000
Failed requests:        0
Keep-Alive requests:    10000
Total transferred:      2380000 bytes
HTML transferred:       1480000 bytes
Requests per second:    51904.64 [#/sec] (mean)
Time per request:       1.927 [ms] (mean)
Time per request:       0.019 [ms] (mean, across all concurrent requests)
Transfer rate:          12063.77 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       4
Processing:     1    2   0.4      2       5
Waiting:        0    2   0.4      2       5
Total:          1    2   0.5      2       5

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%      2
  90%      2
  95%      3
  98%      4
  99%      4
 100%      5 (longest request)

50 тыс. Запросов в секунду, и в данном случае даже не ошибочный запрос.

Я сильно изменил системные переменные, такие как somaxconn и т. Д., В противном случае, думаю, я бы все равно не получил столько запросов с одним Бьорном.

Как такое возможно, что Bjoern настолько быстрее, чем Nginx?

Я действительно обеспокоен тем, что не могу использовать Nginx и извлечь выгоду из вещей, описанных в первой строке, и надеюсь, что вы поможете мне найти, где виноват.

Краткий и лаконичный вопрос: как передать прокси-пропуск Bjoern в Nginx без потери производительности? Должен ли я просто остаться с Бьорном и добиться балансировки нагрузки и смягчения DoS / DDoS-атак другим способом?

-3
задан 30 June 2014 в 18:30
1 ответ

Я думаю, что ответ приведен в статье ниже.

https://news.ycombinator.com/item?id=2036661

Например, давайте рассмотрим этот мыслительный эксперимент: Кто-то здесь упомянутый Mongrel2, получающий 4000 реакций в секунду. Заменим имя "Mongrel2" с "Server A", потому что этот мыслительный эксперимент не является ограничивается Mongrel2, но все серверы. Полагаю, он сравнивает приложение "hello world app" на его ноутбуке. Предположим, что гипотетический Сервер Б получает "только" 2000 рекв./сек. Теперь можно (ошибочно) сделать вывод, что:

  • Сервер B намного медленнее.

  • В среде с большим трафиком следует использовать Сервер A вместо Сервера B.

Теперь поставьте Сервер А за HAProxy. HAproxy известный как высокопроизводительный HTTP прокси-сервер с минимальными накладными расходами. Отметьте эту установку и посмотрите, как количество отказов на секунду снижается примерно до 2000-3000 (когда на типичном двухъядерном ноутбуке).

Что только что случилось? Сервер Б, похоже, очень медленно. Но реальность такова, что и Сервер А, и Сервер Б настолько быстр, что делает даже минимальный объем дополнительной работы. окажет значительное влияние на количество реакций на секунду. В этом случае, накладные расходы на дополнительный контекстный переключатель и вызов read()/write() на кернела уже достаточно, чтобы число req/sec уменьшилось наполовину. Любая достаточно сложная логика веб-приложений приведет к тому, что число упадет так сильно. что разница в производительности между разными серверами становится ничтожно мало.

6
ответ дан 5 December 2019 в 21:50

Теги

Похожие вопросы