В рамках поста Работа с PostgreSQL в языке Go при помощи pgx был написан микросервис, использующий SQL-запросы в виде обыкновенных строк. Безусловно, это единственный правильный способ работать с РСУБД, однако в некоторых задачах он может быть не очень удобен. Например, если вам нужно генерировать запросы со сложными WHERE-условиями в зависимости от пользовательского ввода. Одно из возможных решений заключается в использовании библиотеки squirrel.

Допустим, мы разрабатываем микросервис на языке Go. Мы успешно написали модульные тесты. Но также требуется написать и другие тесты, которые проверяли бы, что посылка определенной серии запросов к сервису приводит к получению ожидаемых ответов. Обычно такие тесты называют интеграционными. Существует более одного решения задачи. Можно поднимать стенды со всеми зависимостями микросервиса (или чем-то, что ими притворяется), что практически сводит задачу к системному тестированию. Или наоборот, можно замокать все зависимости, и свести задачу к модульному тестированию. Но в рамках этой заметки мне хотелось бы рассказать о решении, основанном на использовании Docker и библиотеки dockertest.

Многие реальные приложения, написанные на Go, используют ту или иную РСУБД. Притом, последней нередко является PostgreSQL. Для работы с постгресом в мире Go существует больше одной библиотеки, в связи с чем возникает закономерный вопрос — а какую выбрать? Неплохим и достаточно популярным вариантом является jackc/pgx, с которым мы и познакомимся.

Редкая программа обходится без файла конфигурации. Даже если вы пишите простенький REST-сервис, то ему как минимум нужно знать, какой порт и на каком интерфейсе слушать, а также где искать PostgreSQL. Что уж говорить о более сложных приложениях. Для чтения конфигов в проектах на Go часто используют библиотеку spf13/viper.

В этой небольшой заметке мы поговорим о том, как парсить флаги и аргументы командной строки в языке Go. Казалось бы, в стандартной библиотеке есть пакет flag — берешь и используешь. Но он плох тем, что заставляет пользователя указывать флаги в стиле -config, вместо всем привычных -c и --config. То есть, когда два знака минус используются для полного имени флага, и один знак для короткого. Кроме того, pflag не помогает обрабатывать сложные команды вроде тех, что использует утилита kubectlget nodes, describe pods, и так далее.

За последние десять лет подход к управлению зависимостями в Go несколько раз переосмыслялся. Все начиналось с «просто используйте go get и никогда не ломайте обратную совместимость». Как ни странно, это не работало. Потом было «Вы все не так поняли — мы не говорили, что менеджер зависимостей не нужен, мы просто не знали, как его сделать! Попробуйте dep ensure». Dep работал уже почти хорошо. Иногда он сыпал непонятными ошибками, но обычно эти ошибки проходили с удалением файла Gopkg.lock и каталога vendor. Сейчас же на смену dep, носившему статус «официального эксперимента», пришел go mod. Это уже совсем настоящий, не экспериментальный, менеджер зависимостей. Вот о паре нюансов, связанных с использованием go mod, мне и хотелось бы рассказать.

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

Нет такой вещи, как идеальная модель многопоточности. Одни задачи хорошо ложатся на треды и мьютексы, другие на каналы и горутины (a.k.a CSP), третьи на акторную модель, четвертые на Software Transaction Memory. Из этих моделей язык Go предлагает первые две. Но, как мы сейчас убедимся на примере акторов, не представляет труда добавить в язык и другие модели.

Пару дней назад состоялся релиз Grafana 6.0. Из интересного в данной версии добавили встроенную агрегацию логов. Соответствующее хранилище для логов называется Loki, а агент для записи логов в это хранилище — Promtail. Таким образом, теперь в Grafana можно смотреть не только метрики, но также и логи. Удобно, когда и те, и другие доступны в одном месте. В этой заметке мы научимся писать логи в Promtail / Loki из программ на языке Go.

Типичная проблема, возникающая при разработке распределенных систем, состоит в следующем. Допустим, пользователь посылает системе запрос, и запрос этот обрабатывался очень долго. При этом внутри системы запрос распался на запросы к нескольким внутренним микросервисам, которые в свою очередь могли также превратиться в несколько подзапросов, возможно, даже выполняемых параллельно. Как в такой ситуации выяснить, где тормозит система? Метрики не дают ответа на данный вопрос, поскольку в целом вся система работает нормально, затупил только отдельный запрос конкретного пользователя. Логи могут дать ответ, но они разбросаны по множеству машин, время на которых не синхронизировано. На помощь приходит Jaeger.