Сборник методов обработки проблем HTTP 499

MySQL

предисловие

В этой статье я обобщаю проблемы 499 в ежедневном бизнесе, с которыми я имел дело в последнее время, и подробно описываю причины возникновения 499 и процесс позиционирования, надеясь помочь всем.

Код состояния HTTP 499

nginxсерединаsrc/http/ngx_http_special_response.cКод состояния 499 определяется в файле:

    ngx_string(ngx_http_error_494_page), /* 494, request header too large */
    ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
    ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
    ngx_string(ngx_http_error_497_page), /* 497, http to https */
    ngx_string(ngx_http_error_404_page), /* 498, canceled */
    ngx_null_string,                     /* 499, client has closed connection */

Из комментариев видно, что 499 означаетКлиент активно отключается.

На первый взгляд, 499 — это активное отключение клиента, однако в реальном развитии бизнеса появление кода состояния HTTP 499 в большинстве случаев связано с длительным временем запроса сервера, что приводит к «нетерпению» клиента. клиент и т.д., так что подключение подключено.

Теперь давайте поговорим о 4 из 499 проблем, с которыми я сталкивался в повседневной разработке, и соответствующих методах позиционирования проблем.

4 проблемы HTTP 499

1. Тайм-аут запроса интерфейса сервера

Когда клиент запрашивает интерфейс сервера, некоторые запросы интерфейса выполняются очень медленно. Позвольте мне просто привести пример:

select * from test where test_id in (2,4,6,8,10,12,14,16);

Например, у нас естьtestТаблица, в таблице 5 миллионов единиц данных, мы запрашиваем приведенную выше.where inSQL, покаtest_idПоле не индексируется, что приводит к полному сканированию таблицы. Этот SQL очень медленный, и обычно запрашивается несколько секунд.

Если клиент устанавливает тайм-аут, он автоматически отключится по истечении тайм-аута, что вызовет проблему 499. Например, если клиент не установил тайм-аут, этот SQL-запрос занимает 5 секунд, а тайм-аут php-fpm — 3. секунд , это вызовет проблему 502.

Решить эту проблему очень просто, найти соответствующий медленный запрос и оптимизировать его, в общем случае это медленный SQL, например, в приведенном выше примере поле не имеет индекса, просто добавьте индекс.

Конечно, есть также случаи, когда индекс не следует за индексом, например, проблема, с которой я столкнулся раньше,Анализ проблемы выбора MYSQL неправильного индекса, то есть даже если есть индекс, то индекс все равно не берется.

Суммировать

В данном случае интерфейс действительно тормозит, это не случайное явление, тормозит всегда при запросе, это тоже лучшее решение, просто оптимизируйте интерфейс.

2. nginx вызывает отключение

Другой случай — проблема 499, вызванная nginx.

nginx proxy_ignore_client_abort 参数导致的 499 问题

Из приведенного выше рисунка мы можем найти, что,request_timeОчень маленький, это не может быть тайм-аут интерфейса запроса, в чем причина этой проблемы?

На самом деле, некоторая информация не была показана на рисунке, потому что он включает в себя конкретный запрос интерфейса компании, я опишу здесь явление: два запроса на рисунке с очень близким временем запроса на самом деле имеют точно такие же параметры запроса.

решение

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

Решение - настроить в nginx:

proxy_ignore_client_abort   on; 

Этот параметр означает, что прокси-сервер игнорирует прерывание работы клиента и ожидает возврата прокси-сервера.Если ошибки выполнения нет, в журнал записывается журнал 200. Если время выполнения истекает, записываемый журнал представляет собой журнал 504. .

Включив этот параметр, понаблюдав некоторое время в сети, я обнаружил, что с 499 практически нет проблем.

Меры предосторожности

  1. Эта конфигурация работает только на прокси-сервере, например, если есть два сервера nginx, первый сервер является обратным прокси для второго сервера nginx, а второй сервер nginx указывает на службу PHP, то этот параметр можно настроить только на первый сервер nginx Он будет действовать только на сервере, а конфигурация не повлияет на второй сервер nginx.

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

3. 499 проблем возникают в фиксированное время

Также бывает ситуация, когда проблема 499 возникает в фиксированное время.

固定时间出现 499 问题

Видно, что вышеуказанные случаи 499 относительно зафиксированы, все в течение десяти минут после 2 часов ночи.

В это время мы обычно быстро думаем, есть ли какие-то временные задачи, занимающие ресурсы.На самом деле это так, но найти эту проблему непросто.Позвольте мне рассказать о том, как я нахожу эту проблему.

Шаги позиционирования

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

  2. машина: Потом я заподозрил, что с этими машинами что-то не так, а потом проверил схему мониторинга машины (с помощью falcon) и обнаружил, что в 2 часа ночи ничего ненормального не было. (На самом деле, можно также сделать вывод, что служба имеет 499 на нескольких машинах, невозможно, чтобы на всех машинах были проблемы, и на этой машине развернуты другие проекты, и у других проектов нет проблем, что указывает на то, что вряд ли быть эта машина. есть проблема с машиной.)

  3. база данных: Поскольку с этим сервисом есть проблема, я проверил схему мониторинга основной базы данных, подключенной этим сервисом (тоже falcon), и не обнаружил никаких проблем. (На самом деле проблема есть, но я ее не заметил)

  4. nginx: Раз с вышеперечисленным проблем нет, то есть ли проблемы с верхним nginx? так какupstream_response_timeЗначение вообще никакое.Возможно запрос вообще не дошел до PHP сервиса на бекенде.Есть проблема с nginx в два часа ночи? В конце концов, я обнаружил, что на самом деле понял это неправильно, и это также касается вышеуказанных параметров.proxy_ignore_client_abort, если этот параметр не установлен вonЕсли это так, запрос к серверу больше не будет выполняться.upstream_response_timeзаписывается-, это не проблема. Это означает, что с nginx все в порядке.

  5. ненормальный запрос: Так неужели в два часа ночи была волна ненормальных запросов. Запрос post request.Бывает, что nginx включил post log.По параметрам запроса, записанным nginx, я пересобрал запрос и обнаружил, что проблемы нет. Описание не имеет ничего общего с параметрами запроса.

  6. база данных:

    1. По сути, все решения, которые можно здесь придумать, в основном продуманы. Просто поищите, что общего у этих запросов.
    2. Я обнаружил, что все эти запросы запрашивали базу данных, а затем нашел интерфейс с наибольшим количеством запросов, распечатал время выполнения запросов к базе данных и обнаружил, что простой интерфейс выполнялся за 2 секунды, а их было более дюжины. более 2 секунд за одну ночь запрос. И наш тайм-аут составляет 1 секунду, поэтому это вызовет проблему 499.
    3. Независимо от того, является ли это причиной 499 или нет, проблема есть, и с ней нужно бороться.Потом я снова посмотрел на мониторинг falcon и обнаружил, что в два часа ночи произошел ненормальный ввод-вывод и процессор машины. Я вошел в эту машину и посмотрел журнал ошибок.
  7. error.log:

    1. существуетerror.logЯ нашел оператор SQL интерфейса запроса 499 и нашел сообщение об ошибке следующим образом.mycat Waiting for query cache lock.
    2. Из этого журнала мы обнаружили, что этот SQL заблокирован и ожидаетquery cache lock, блокировка — это глобальная блокировка, мы не будем вдаваться в подробности здесь.
    3. query cacheОн устарел в MYSQL 8.0, потому что, если таблица только обновляется, она будет очищена.query cache, для часто обновляемых таблиц это не очень удобно.Если объем данных небольшой и таблицы обновляются нечасто, можно напрямую проверить базу, а это бессмысленно. а если включитьquery cache, приходит запрос запроса, надо пройти первымquery cacheЕсли вы не можете найти его, перейдите в базу данных, чтобы найти его, и после того, как вы его найдете, поместите данные вquery cacheсередина.
    4. Я проверил базу данных, и она включиласьquery cache, я думал в этом причина, просто отключил, а потом проверил другие базы и обнаружил, что он тоже был включенquery cache, можно доказать, чтоquery cacheне причина проблемы. Кстати, проверьтеquery cacheВключить ли командуshow variables like '%query_cache%';.query_cache_typeзначениеONвключено, значение равноOFFзакрыто.
    5. После кучи грязных испытаний, наконец, сосредоточился наЧто занимает кеш запросов. Просматривая журнал ошибок, я нашел следующий SQL (обработанный):select A,B,C from test where id > 1 and id < 2000000. Этот SQL запросит 2 миллиона фрагментов данных, а затем поместит эти данные вquery cache, точно займетquery cache.
  8. slow.log:

    1. существуетerror.logИсточник этого SQL не может быть найден в запросе, это не должен быть SQL бизнеса, и бизнес не будет запрашивать такой SQL.slow.logЗапрос 2 миллионов IP-запросов SQL показал, что запрос исходит от кластерного компьютера Hadoop, на котором есть сценарий для синхронизации онлайн-данных с HIVE, и обнаружил, что IP-адрес базы данных, настроенный сценарием, является рассматриваемым IP-адресом.
    2. Затем я изменил конфигурацию базы данных и заменил IP-адрес на IP-адрес подчиненной библиотеки, которая не используется в Интернете.После наблюдения в течение нескольких дней, то есть последних трех дней на картинке выше, было очевидно, что 499 было меньше. случаи.

Суммировать

Эту проблему очень сложно обнаружить. Это заняло много времени. В общем, я протестировал все ситуации, которые только мог придумать. Если с MYSQL проблем нет, я могу продолжить поиск проблемы на машинном уровне. Давайте изучим некоторые идеи. .

4. Случайные проблемы 499

Обычно мы видим один или два случая 499, но если мы повторно выполняем запрос, скорость ответа очень высока и вообще не может быть воспроизведена, мы можем вообще игнорировать эту случайную ситуацию. Здесь позвольте мне кратко рассказать о причинах, которые могут привести к этой проблеме.

В MYSQL будет операция сброса данных грязных страниц на диск, о чем мы расскажем в отдельной статье. Когда MYSQL выполняет грязные страницы, это занимает системные ресурсы.В это время наши запросы могут выполняться медленнее, чем обычно.

Кроме того, в MYSQL также есть механизм, который может сделать ваш запрос медленнее, то есть при подготовке к сбросу грязной страницы, если страница данных рядом со страницей данных окажется грязной страницей, он принесет с собой этого «соседа». И дальше будет распространяться логика перетаскивания "соседей" в воду, то есть для каждой страницы данных соседа, если соседние страницы данных все еще являются грязными страницами, они также будут сброшены вместе.

Механизм оптимизации поиска «соседей» имеет большое значение в эпоху механических жестких дисков. Он сокращает время поиска и может уменьшить количество случайных операций ввода-вывода. Случайные операции ввода-вывода механических жестких дисков обычно составляют всего несколько сотен. операция уменьшает случайный ввод-вывод, а это означает, что система значительно улучшает производительность. Но теперь IOPS больше не является узким местом: если «просто сбросить сам», то можно быстрее выполнять необходимые операции сбрасывания грязных страниц и сократить время отклика SQL.

Интересно, что этот механизм также отключен в MYSQL 8.0, который предоставляетсяinnodb_flush_neighborsконтроль параметров,1Указывает, что имеется непрерывный механизм чистки,0Указывает, что вы только чистите себя. МСУБЛ 8.0innodb_flush_neighborsПо умолчанию 0.

Давайте посмотрим на нашу онлайн-конфигурацию:

mysql> show variables like "%innodb_flush_neighbors%";
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_flush_neighbors | 1     |
+------------------------+-------+
1 row in set (0.00 sec)

К сожалению, у нас включен онлайн, поэтому очень велика вероятность, что вдруг запрос будет 499.

Суммировать

Выше мы представили 499 случаев ежедневного развития бизнеса, а также методы обнаружения и решения проблем, надеясь оказать вам некоторую помощь.