После докеризации нашей существующей инфраструктуры в Sense Health я работал над созданием набора микросервисов для серверной части. Как и для всех микросервисов, основные требования обычно такие же: быстрая связь, простая отладка и масштабируемость.

Чтобы создать этот набор микросервисов, я сделал множество дизайнерских решений и построил структуру и набор библиотек, которые могут быть расширены и будут использоваться всеми будущими сервисами, которые мы создаем собственными силами.

Конфигурация

Я использую файлы TOML для всех наших потребностей в конфигурации с этим пакетом Go. Файлы TOML довольно интуитивно понятны для настройки, но, что более важно, способ, которым пакет Go выполняет демонтаж содержимого TOML из файла, помогает нам иметь легко расширяемые конфигурации. С помощью одного вызова API toml.DecodeFile я могу проанализировать всю структуру данных конфигурации, включая структуры вне моего собственного пакета.

Поскольку пакет использует отражение, чтобы найти имена переменных в файле TOML и сопоставить их непосредственно с самой переменной, у нас могут быть такие структуры, как:

type Config struct {
Строка имени
Redis cachemgr.RedisConfig
}

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

Связь (RPC, REST)

Обмен данными между службами должен быть быстрым, надежным и основан на проверенной технологии. Для всей межсервисной связи в наших микросервисах я использую GRPC от ​​Google. GRPC разработан на основе буферов протоколов (очень эффективная структура обмена двоичными сообщениями), которая позволяет выполнять вызовы RPC между серверами и поставляется с множеством полезных свойств (встроенных в контекст и метаданные для аутентификации, поддержка HTTP / 2, направленная потоковая передача). support) и работает практически на всех доступных языках. GRPC хорош тем, что обеспечивает эффективные, тесно связанные вызовы RPC между службами.

В наших сервисах все еще есть конечные точки REST для связи с внешними сервисами. Все конечные точки HTTP используют встроенную в Go библиотеку net / http в качестве предпочтительной. Я настоятельно рекомендую использовать встроенную службу, если все ваши конечные точки HTTP являются динамическими и не связаны с обслуживанием статического / кэшированного содержимого. Для кэшированного содержимого существуют библиотеки, такие как fasthttp, которые выполняют кэширование в памяти и могут быть значительно быстрее.

Для нашего случая использования, поскольку у нас есть только динамический контент, я выбрал внутреннюю библиотеку net / http, поскольку она поддерживает HTTP / 2, чего fasthttp на данный момент не поддерживает. Для маршрутизации конечных точек к их соответствующим функциям мы использовали Gorilla Mux, что делает процесс разработки довольно безболезненным.

Регистрация и отслеживание

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

Я использовал логрус как основу всех наших лесозаготовок. С красивым цветным выводом на терминале, простыми вызовами API и гораздо лучшим способом работы с трассировкой объектов, чем printf с параметрами. Logrus также поддерживает перехватчики для отправки данных журналов в различные службы и отлично справляется со всеми нашими потребностями в журналах.

Поскольку все выгружается в файлы журнала, мы по-прежнему регистрируем только сам сервис. Когда несколько служб работают вместе, нам нужно больше информации, чем просто отдельный файл журнала каждой службы для отслеживания проблем. Для решения распределенной трассировки я использовал opentracing с Z ipkin в качестве бэкэнда трассировщика.

Opentracing поддерживает несколько языков, не зависит от производителя и имеет солидное сообщество, что упрощает распределенную трассировку. Я прикрепил хуки ко всем нашим вызовам GRPC и HTTP и сделал вспомогательные функции, чтобы сделать функции трассировки и профилирования более безболезненными и автоматизированными во время разработки.

Эти распределенные журналы настроены для хранения данных только за последние 2 недели. Я настроил Zipkin на высокую частоту дискретизации только во время разработки. Для наших конечных производственных серверов у нас будет небольшое количество выборок для Zipkin и сервера Logstash & Kibana для показателей производительности и ElastAlert или аналогичного для уведомления об ошибках.

В целом я очень доволен этим стеком для Go и тем, что он позволяет нам выполнять очень быстрые циклы разработки, особенно с распределенной трассировкой и журналированием ошибок, мы получаем достаточную гибкость, чтобы агрессивно кодировать и быстро двигаться, поскольку обнаружить медленный и подверженный ошибкам код так же просто, как открыть веб-панель Zipkin.