Назад | Перейти на главную страницу

nginx - самая странная проблема - некоторые из полученных запросов имеют неправильный формат

Эта проблема для меня загадка, и я буду очень рад найти решение. Я предоставлю подробности о моей среде, которые я считаю актуальными, но если что-то еще требуется, прокомментируйте, и я добавлю.

Инфраструктура:

хост - цифровая капля океана

Операционные системы - Ubuntu 17.04

обратный прокси - nginx 1.12.0 (проблема возникла и в nginx 1.10.0)

сервер приложений - узел-js 7.10.0 (тоже было на 7.9.0)

клиенты - Android (бывает в нескольких версиях, включая 5.0, 6.0.1, 7.1.1, поэтому, скорее всего, не связаны) с использованием OkHttp 3.8.0

Таким образом, nginx перенаправляет трафик на nodejs, а nodejs обрабатывает запросы от клиентов Android.

Проблема:

Для некоторых клиентов время от времени для определенного запроса json, полученный nodejs, искажается. в частности, несколько байтов записываются в начало json тела,

Вот один пример:

2017-05-24 15:42:14.899 (+0300) - error: Error summary:
name: SyntaxError
status: 400
request: POST /api/v1/user_details
body: 
 J      ount_id":"217627","user":{"email": "abc@def.com" ....<rest of json is ok>

обратите внимание на начало тела - похоже, несколько искаженных байтов перезаписывают начало исходного json. иногда нет странных байтов, только оригинальный json вырезан, например. ser ": {" email ":" abc@def.com "... Это становится еще более странным - это случается только время от времени (может быть, один из 100 вызовов), только для некоторых клиентов, в определенной конечной точке (хотя я не имеют много конечных точек, и этот используется много) и даже в этих клиентах - только один раз во многих запросах. Он не относится к определенному устройству (по крайней мере, на LG, Samsung, OnePlus), и из журналов Я вхожу в клиенты, используя перехватчик OkHttp, чтобы увидеть, какие данные отправляются, он кажется правильным. Я даже пытался отправить тот же точный запрос, который не удался в журналах клиента, на моем устройстве, и это удалось. Я попытался восстановить это ошибка безуспешно - я засыпал сервер запросами с нескольких устройств, чтобы узнать, не было ли это большого количества данных, но ни один из них не вызвал этой проблемы. В ходе расследования я попытался выяснить, где находятся данные точно искажается - я заметил, что до всех промежуточных программ nodejs получает искаженное тело. Я добавил ведение журнала тел в nginx и заметил, что nginx сам получает искаженные данные.

Это одна из самых странных проблем, с которыми я когда-либо сталкивался, и я очень надеюсь, что кто-нибудь сможет сказать мне, что именно происходит.

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

/ и т.д. / nginx / сайты-включен / по умолчанию

# HTTP - redirect all requests to HTTPS:
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name my-service.com, app.my-service.com, www.my-service.com;
    # letsencrypt auto-renew
    location ~ /.well-known {
        root /var/www/html;
    }
    location / {
        return         301 https://$server_name$request_uri;
    }
    #return 301 https://$server_name$request_uri;
}

#log_format postdata '[$time_local] "$request" $status '
#                    '$request_body';

server {
    # SSL configuration

    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    include snippets/ssl-my-service.com.conf;
    include snippets/ssl-params.conf;

    # Pass requests for / to localhost:3000:
    location / {
            #  used to log traffic's post body data when uncommented:
            #  access_log  /var/log/nginx/postdata.log  postdata;
            #  echo_read_request_body;

            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;

            proxy_pass https://localhost:3000/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;

    }
}

сниппеты / ssl-params.conf

ssl_certificate /etc/letsencrypt/live/my-service.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-service.com/privkey.pem;

сниппеты / ssl-my-service.com.conf

server_tokens off;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/my-service.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=86400;
resolver_timeout 10s;

ОБНОВЛЕНИЕ 1:

Вот заголовки запросов, отправленные клиентом Android:

Тип содержимого: приложение / json; charset = UTF-8, Content-Length: 5689, авторизация: Bearer, User-Agent: MyServiceApp / 1.0.0 (Android 7.1.2)