Удивительно, но именно в первый день после окончания моего отпуска, когда я уже вышел на работу, впервые, за без малого два года непрерывной работы, "упало" моё первое "промышленное" решение (сервис) на Go, о котором я уже кратко писал ниже. После падения сервис был перезапущен и благополучно продолжил работу, а последующий анализ логов выявил следующее сообщение об ошибке:
fatal error: concurrent map writes
Падение сервиса с такой ошибкой произошло из-за того, что я не учёл (а точнее пренебрёг из-за малой вероятности) возможность доступа к используемому в программе словарю (map) одновременного из двух потоков (у нас не очень большая интенсивность потока сообщений, суммарным объёмом 12-15 тысяч в день).
Не смотря на то, что за два года это было первое и единственное падение сервиса желание сделать "как надо", заставило меня заняться изучением данного вопроса.
После изучения официальной документации и прочтения нескольких статей (Golang Maps: Not safe for concurrent use, Танцы с мьютексами в Go, Разбираемся с новым sync.Map в Go 1.9) остановился на использовании мьютексов для создания блокировок при записи в словарь. Это позволило минимальными усилиями защититься от подобных падений в будущем. Так что удалось в очередной раз получить удовольствие от работы на Go и немного улучшить свои познания в нём.
Надеюсь, что обновлённый сервис проработает не меньше, а дополнительно обновлённая система логов позволит легче отвечать на возможные вопросы по его работе.
Комментарии