Многие реальные приложения, написанные на 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.

Badger — это реализация LSM tree на языке Go. Не будет преувеличением сказать, что это как RocksDB, только написанный с нуля на другом языке программирования. Библиотека основана на WiscKey paper [PDF], обмазана кучей всевозможных тестов, неплохо показывает себя на бенчмарках, ну и в целом производит впечатление серьезного проекта. Мне захотелось познакомиться с библиотекой поближе. Поэтому я написал на ней простенькую key-value СУБД с REST-интерфейсом.

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