Кто открыл и не закрыл: схемы асинхронных вызовов как инструмент аудита
Привет, %username%! Одногруппник спросил, какими диаграммами описывать сервисы с асинхронными вызовами: UML или C4, sequence или activity. Я спросил в ответ, какая там модель — события через очереди или поток данных. Ответ уложился в два слова: «Не знаю».
Настоящая задача оказалась другой: код достался чужой, единого клиента нет, за открытыми соединениями никто не следит. Схема тут нужна для поиска, и рисовать её надо под один вопрос: кто открыл соединение и кто его закроет. Нотация при этом вторична.
Хватает двух диаграмм: sequence самого нагруженного сценария и state жизненного цикла соединения. А начинается всё с rg по точкам выхода в сеть. В синтетическом примере к одному сервису ведут четыре разных клиента: у двух таймаута нет вовсе, у двух других он разный.
Типовые утечки я воспроизвёл на Go и Python. Двадцать ответов без Close() через http.DefaultClient дают двадцать сокетов в CLOSE_WAIT и 43 горутины, и через полминуты картина та же. Пул HTTP на каждый вызов не поймал ни один линтер из тех, что я прогнал.
Тебе тоже доставался код, где каждый ходит в сеть по-своему?
Развернул на 74k знаков, с чек-листом из восьми вопросов и сверкой через ss и lsof:
https://jtprog.ru/posts/async-calls-connection-audit/
Код лабы, чтобы повторить у себя: https://github.com/jtprogru/lab-async-calls-connection-audit
#SRE #DevOps #Golang #Python #Observability #Troubleshooting
Мишка на сервере — про надёжность, инциденты и инженерную практику
В этом посте были ссылки, но мы их удалили по правилам Сетки