Pull to refresh

Микросервис на Golang

Reading time4 min
Views31K
image Среди беспорядка найдите простоту; среди раздора найдите гармонию; в трудности найдите возможность...
(С) Альберт Эйнштейн

Статей о микросервисах, их достоинствах и недостатках в последнее время написано немало. Однако как-то редко кто пишет об имплементации микросервисной архитектуры, и прежде всего, именно об микросервисе, как о кирпичике, из которой и строится потом здание такого приложения. Я попытался восполнить этот пробел, и поделиться своим опытом в разработке http-микросервиса, вылившемся в конечном счёте в небольшую библиотеку под не оставляющим места для сомнений названием Microservice. Код написан на прекрасно подходящем для микросервисов, простом и удобном языке программирования Golang.

В последнее время мне довелось поработать над созданием микросервисов на языке Golang. Это был интересный опыт. Однако во многом получается (по крайней мере у меня), что каждый раз новый микросервис создаётся заново и с нуля. Конечно, можно использовать предыдущие наработки, но в таком подходе нет некоей системности, и мне захотелось сделать инструмент, который бы несколько упорядочил такую работу (искренне на это надеюсь). Не сомневаюсь, это не единственная идея в разработке микросервисов, но если вы ими интересуетесь, возможно, вам будет интересно прочитать данную статью.

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

Архитектура микросервиса (тут и дальше речь о http микросервисе) в моей библиотеке включает в себя хэндлер, тюнер (конфигуратор), демонстрационный middleware. Работает всё очень просто: в приложении загружается конфигурация с учётом файла конфигурации, окружения и командной строки. Под нужные роуты формируется из middleware и хэндлера обработчик. Далее запускается сервер и по запросу приложение отрабатывает нужные очереди. По сути, это подходит и может быть использовано как прототип обычного http приложения, но пожалуй, для такого приложения я бы использовал немного другую архитектуру.

Тюнер


Важным моментом для микросервиса является загрузка конфигурации. Я постарался сделать этот функционал максимально гибким. По умолчанию конфигурация загружается из указанного файла (`config.toml`). Адрес файла конфигурации можно изменить из командной строки, например так: вашсервис -confile config.toml Таким образом можно создать несколько разных конфигурационных файла и запускать микросервис с одной из конфигураций по выбору.

Поскольку в конфигурировании микросервиса задействован не только файл, но и переменные окружения и параметры командной строки, то уточню порядок и приоритетность конфигурирования. Самым низким приоритетом обладает конфигурация из файла. Если в операционной системе настроены переменные окружения, то они имеют более высокий приоритет, чем переменные из конфигурационного файла. Параметры командной строки имеют самый важный приоритет. Для изменения параметра в командной строке нужно указывать его название в виде названии раздела и названия параметра (с прописной буквы!). Вот пример изменения порта — вашсервис -Main/Port 85

Ещё немного о конфигурировании: помимо варианта с закидыванием конфигурации в заранее заготовленную структуру, вполне можно было бы использовать вариант импорта данных в обычный map, и потом спокойно использовать значения по ключу. У этого способа есть несомненное достоинство — не нужно добавляя данные в конфигурационный файл дублировать это в конфигурационной структуре. Т.е. всё проще и быстрее. Минусом же будет то, что ошибки неправильного указания ключа переносятся с этапа компиляции на этап выполнения, и кроме того, тут IDE уже не станет нам делать подсказки, что кстати, само по себе очень хорошо в плане защиты от опечаток и как следствие — ошибок.

Middleware


Чтобы не засорять пространство хэндлеров, в микросервисе предусмотрено использование сервисного функционала в стиле middleware (однако не совсем в классическом понимании гоферного миддлваре). К каждому такому сервису предъявляются минимальные требования: он должен принимать в качестве аргумента функцию, принимающую http.ResponseWriter, *http.Request и возвращать такую же функцию. В дистрибутиве продемонстрирован пример с подключением метрики для фиксации времени обработки запроса (duration).

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

Handler


В дистрибутиве handler содержит в себе совсем мало кода. Однако именно его методы и являются теми хэндлерами, которые обработают поступивший запрос, всё остальное по сути обвес микросервиса. Если это так, то почему бы не сделать просто кучу автономных функций, которые и будет вызывать роутер? На это есть причина: благодаря объединению посредством структуры хэндлеры-методы теперь смогут иметь доступ (если потребуется) к полям структуры (общему контексту приложения). На самом деле очень удобно для каждого публичного метода (читай — обработчика) создать отдельный файл, например handle_hello_word.go, что впрочем не мешает организовать всё каким угодно другим образом.

Создание нового хэндлера


Для этого нужно просто создать новый публичный метод в handler, который на вход принимает http.ResponseWriter, *http.Request. Посмотрите созданный для демонстрации метод HelloWorld.

Perfomance


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

  • BenchmarkMain-2 10000000 195 ns/op
  • BenchmarkMainParallel-2 10000000 107 ns/op


Зависимости



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

Заключение


Библиотека Microservice не претендует на лавры единственно верного решения, но при случае, надеюсь, сможет помочь вам сформировать архитектуру собственного http-микросервиса, став прототипом будущего приложения.

Ссылки




UPD


С учётом комментариев немного изменил библиотечку, удалив хранилище и подправив метод организации мидлваре (без очередей), что кстати, даже немного ускорило работу приложения в бенче.
Only registered users can participate in poll. Log in, please.
Используете ли вы микросервисную архитектуру?
43.55% Да, использую125
45.3% Нет, но собираюсь130
11.15% Нет, и не буду32
287 users voted. 78 users abstained.
Tags:
Hubs:
+18
Comments27

Articles