Очередная порция длинных транзакций, кто виноват в сбое P0?

Java MySQL

Оригинал: Miss Sister Taste (идентификатор публичной учетной записи WeChat: xjjdog), добро пожаловать, пожалуйста, сохраните источник для перепечатки.

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

Кто возьмет на себя вину? Конечно архитектор. Поскольку на этот раз все сервисы живы, эксплуатации и обслуживания нет.

Во время собеседования вы можете столкнутьсяделаЧто касается связанных проблем, обновленная версия может быть проблемой распределенной транзакции. В интернет-индустрии неаккуратная компенсационная транзакция может сойти с рук, в конце концов, все они короткие и мощные интерфейсы.

Но во многих корпоративных приложениях это не работает. Мы должны столкнуться с суровой реальностью.

Зачем использовать длинные транзакции?

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

Возьмем в качестве примера простейшую одномашинную транзакцию базы данных.

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

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

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

Несколько крупинок мышиных фекалий испортили кастрюлю с кашей.

какие-то волшебные реакции

Когда вы пытаетесь устранить проблему такого рода, вы можете застрять. jstack показывает, что большинство запросов фактически блокируются в пуле потоков tomcat, а некоторые запросы с очень быстрым доступом блокируются.

Например, 180 из 200 потоков tomcat заблокированы на интерфейсе **/status**, что занимает менее 1 мс.

Многие люди были ошеломлены. Испытайте неудачу.

Вывод jstack на этот раз нас обманул. Что действительно вызвало блокировку, так это дополнительные 20+ потоков.

Какие улучшения?

Сокращение транзакций является важным требованием, включая, помимо прочего:

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

Транзакции не должны содержать вызовов RPC, что снижает детализацию транзакций.. Часто некоторые вызовы RPC, включая вызовы других нетранзакционных ресурсов, занимают очень неконтролируемое время. Если они также будут включены в объем сделки, это неизбежно увеличит занятость ресурсов. Транзакции не должны содержать другие сервисы, которые подвержены тайм-ауту или блокировке на длительное время, такие как HTTP-вызовы и операции ввода-вывода.

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

Кросс-библиотека, кросс-тип (например, Redis) не должны помещаться в одну и ту же транзакцию., чтобы избежать перекрестных эффектов.

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

Все зависит от вашего выбора.

Всегда есть кто-то, кто виноват в дизайне, и всегда есть кому чем-то жертвовать, чтобы компенсировать это.

Решение

так как получилосьБыстрая починкаКак насчет проблем с недоступностью услуг, вызванных крупными транзакциями?

Кроме расширения решения нет. Перезапуск Дафа может не помочь. Потому что заблокированный запрос снова ударит по более жестокой ситуации.

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

Но мы можем защищаться раньше времени.

Взяв в качестве примера Spring, использование транзакций в основном контролируется аннотацией @Transactional или декларативными транзакциями. Я рекомендую профилактику и обнаружение следующими способами:

  1. Повторно отсканируйте или просмотрите бизнес-код, чтобы проверить, есть ли в транзакции какие-либо из вышеупомянутых ситуаций. Затем переместите операции, отличные от операций с БД, из транзакции.

  2. Каждой операции с транзакцией уделяется достаточно внимания.Для транзакций с неопределенной сложностью выполнения и временной сложностью добавлен сигнал тайм-аута для своевременного обнаружения причины.

В то же время также необходимо усилить мониторинг и помочь в устранении неполадок.

  1. Компания может регулярно распечатывать информацию о пуле соединений с базой данных и проводить предварительное расследование, просматривая журнал.

  2. Используйте jstack, чтобы запросить стек выполнения и найти точку блокировки.

  3. Устраните неполадки и свяжитесь с нижестоящими службами, чтобы определить основную причину

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

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

В лучшем случае сервис уже разобрался с кодом, так что причина скорее всего только в медленном запросе. Для медленных запросов пул соединений с базой данных Druid обеспечивает агрегацию SQL, что позволяет вам просматривать конкретное выполнение каждого типа оператора запроса. Как показано на рисунке, SQL-запросы взлетели за короткий промежуток времени, увеличилось максимальное время выполнения, а пул соединений был заполнен:

С первого взгляда понятно, какой SQL вызывается.

End

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

Лучшим решением, конечно же, является улучшение бизнес-модели. Но в первую очередь это связано с затратами на разработку, а уже потом — с межведомственным сотрудничеством.

Босс, который платит деньги, не может понять ваши мечты.

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

Об авторе:Мисс сестра вкус(xjjdog), публичная учетная запись, которая не позволяет программистам идти в обход. Сосредоточьтесь на инфраструктуре и Linux. Десять лет архитектуры, десятки миллиардов ежедневного трафика, обсуждение с вами мира высокой параллелизма, дающие вам другой вкус. Мой личный WeChat xjjdog0, добро пожаловать в друзья для дальнейшего общения.​