Feign client что это
Spring Cloud Netflix: Feign по-русски
Jun 4, 2019 · 4 min read
Я хочу продолжить серию из предыдущих статей по Netflix, а именно поговорить про Feign Client.
На русском языке очень мало информации по стеку Netflix.
И правильно, потому что надо читать официальную документацию, там вы найдете больше всего. Но я все же решил рассказать “своими словами” чтобы сложилась более ясная картина при изучении данного стека для тех, кто предпочитает русскоязычную литературу.
Планирую обновлять статьи по мере изучения нового материала. Если у вас есть предложения на этот счет, буду рад выслушать.
Другие реализации Feign Client я рассмотрел в другой статье:
Feign — простой и гибкий http-клиент, который нативно интегрирован с Ribbon (О нем в другой статье).
Feign использует интерфейсы аннотированные @FeignClient чтобы генерировать API запросы и мапить ответ на Java классы.
Он шлет http запросы другим сервисам.
Его особенность в том, что нам не нужно знать где и на каком по р ту находится какой-то сервис.
Мы просто говорим Feign клиенту, иди к “Джон Уику” и получи у него всех пользователей. Далее Feign обращается к Eureka Server и спрашивает где находится “Джон Уик”.
Если “Джон Уик” регистрировался в Eureka Server, то Eureka будет всё знать о “Джон Уик” (где он находится, на каком порту, его URL и т.д.)
Вам нужно только описать, как получить доступ к удаленной службе API, указав такие детали, как URL, тело запроса и ответа, принятые заголовки и т. д. Клиент Feign позаботится о деталях реализации.
Netflix предоставляет Feign в качестве абстракции для вызовов на основе REST, благодаря которым микросервисы могут связываться друг с другом, но разработчикам не нужно беспокоиться о внутренних деталях REST.
Нужно указать аннотацию @EnableFeignClients над основным классом
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class FeignClientApplication <
public static void main(String[] args) <
SpringApplication.run(FeignClientApplication.class, args);
>
На интерфейс ставим аннотацию @FeignClient(name = “Джон Уик”) и указываем имя того сервиса, который нам нужен (в пояснении я описывал сервис под названием “Джон Уик”). В том сервисе будет выполняться некая логика по работе с базой и настройки коннекта к базе, или получение всех пользователей и т.д.
Feign — это первый шаг в реализации архитектуры микросервиса при помощи инструментов Netflix.
В реальности слабо связанных сервисов очень важно чтобы общение между ними было легковесным и простым для отладки.
Поэтому для этой цели зачастую используют REST, хотя для некоторых случаев это может быть не лучшим выбором.
Еще раз: для упрощения связи по REST мы и используем Feign: при помощи него мы будем поглощать сообщения от других сервисов и автоматически превращать их в Java объекты.
Рассмотрим небольшой и в то же время очень простой пример.
У нас есть сервис А и сервис B, которые оба зарегистрированы в Eureka. Мы хотим из сервиса А вызвать сервис B и получить какие-то данные.
Сервис B имеет следующий контроллер:
@RestController
@RequestMapping(“/users//statistic”)
public class StatisticsController <
@Autowired
StatisticsService statisticsService;
public List getStatistic(@PathVariable String id) <
List statisticsList = statisticsService.getAlbums(id);
return statisticsList;
>
>
public class UserStatisticModel <
private Long id;
private String userId;
private String username;
private String title;
Используем Lombok чтобы избавиться от ненужного кода геттеров и сеттеров.
Чтобы из сервиса А вызвать сервис B мы создадим в сервисе А feign client.
В аннотации @FeignClient мы указываем имя того сервиса, который хотим вызвать ( сервис B).
@FeignClient(name = “B”)
public interface ServiceFeignClient <
@GetMapping(“/users/$
public List getStatistic(@PathVariable String id);
Аннотация @GetMapping содержит путь, который отображается на тот же самый путь в аннотации @RequestMapping в микросервисе B и указывает, что это будет GET запрос.
Метод должен иметь такую-же сигнатуру что и метод в сервисе B. Это важно!
public class UserStatisticModel <
private Long id;
private String userId;
private String username;
private String title;
Теперь чтобы создать экземпляр клиента Feign, вам нужно будет автоматически подключить интерфейс клиента feign к вашему классу, в котором вызывается логика.
@Service
public class UsersServiceImpl implements UsersService <
@Autowired
ServiceFeignClient serviceFeignClient;
Теперь когда мы будем дергать URL “/users/$
Также хочу добавить, если вам нужно использовать внешнюю веб-службу, которая не является частью вашей архитектуры микросервисов и не зарегистрирована в вашей службе Eureka, то используйте URL в качестве параметра аннотации @FeignClient.
@FeignClient(name = “B”, url = “http://lalalala»)
public interface ServiceFeignClient <
@GetMapping(“/users/$
public List getStatistic(@PathVariable String id);
Если вы нашли неточности в описании данной статьи, вы можете написать мне на email и я с радостью вам отвечу.
Spring Cloud OpenFeign
This project provides OpenFeign integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms.
1. Declarative REST Client: Feign
Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Eureka, Spring Cloud CircuitBreaker, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.
1.1. How to Include Feign
Example spring boot app
In the @FeignClient annotation the String value («stores» above) is an arbitrary client name, which is used to create a Spring Cloud LoadBalancer client. You can also specify a URL using the url attribute (absolute value or just a hostname). The name of the bean in the application context is the fully qualified name of the interface. To specify your own alias value you can use the qualifiers value of the @FeignClient annotation.
Spring Cloud OpenFeign supports all the features available for the blocking mode of Spring Cloud LoadBalancer. You can read more about them in the project documentation.
1.2. Overriding Feign Defaults
In this case the client is composed from the components already in FeignClientsConfiguration together with any in FooConfiguration (where the latter will override the former).
Using contextId attribute of the @FeignClient annotation in addition to changing the name of the ApplicationContext ensemble, it will override the alias of the client name and it will be used as part of the name of the configuration bean created for that client. |
Previously, using the url attribute, did not require the name attribute. Using name is now required. |
Placeholders are supported in the name and url attributes.
Spring Cloud OpenFeign provides the following beans by default for feign ( BeanType beanName: ClassName ):
Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder )
Encoder feignEncoder: SpringEncoder
Logger feignLogger: Slf4jLogger
MicrometerCapability micrometerCapability: If feign-micrometer is on the classpath and MeterRegistry is available
Contract feignContract: SpringMvcContract
Feign.Builder feignBuilder: FeignCircuitBreaker.Builder
Client feignClient: If Spring Cloud LoadBalancer is on the classpath, FeignBlockingLoadBalancerClient is used. If none of them is on the classpath, the default feign client is used.
Spring Cloud OpenFeign does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:
Русские Блоги
SpringCloud OpenFeign
Что такое притворство
Лента и сравнение Feign
(1) Прежде всего, нижний уровень отличается. Ribbon использует перехватчики для перехвата отправленных методов (RestTemplate.getForEntity и другие методы), а затем выполняет соответствующую обработку; в то время как Feign использует метод динамического прокси для его обработки.
(2) Нижний уровень Feign по-прежнему вызывается с помощью ленты.
(3) Метод вызова Feign проще, используя Интерфейс + аннотация Этот метод позволяет пользователю выполнить вызов HttpRestfulAPI без восприятия.
Построить проект Feign
1. Создайте поставщика услуг
2. Создайте проект API.
(1) Создайте новый проект feeng-api, Функция этого проекта состоит в том, что мы помещаем сюда все сервисы, которые использует feign. В этот раз, когда мы вызываем feign, нам нужно только унаследовать класс и написать к нему комментарии.
(2) Посмотрите на схему архитектуры.
(3) файл pom
(4) Основной стартовый класс
(6) Упакуйте его в форму jar и введите эту зависимость от вызывающего
3. Создайте потребительскую сторону услуги.
(1) Отображение архитектурной схемы.
(2) Зависимость файла POM
(3) Файл конфигурации
(4) Основной стартовый класс
(5) Интерфейс сервисного уровня
Другое использование Feign
Пользовательский уровень журнала Feign
1. Уровень журнала
(1) НЕТ: Лучшая производительность, используется для дней рождения, журналы не записываются.
(2) ЗАГОЛОВКИ: Запишите заголовки запроса и ответа на основе уровня BASIC.
(3) FULL: он больше подходит для заголовка, тела и метаданных среды разработки и тестирования для обнаружения проблем, записи и ответа.
(4) BASIC: Подходит для отслеживания проблем в производственной среде, регистрируя только метод запроса, URL, код состояния ответа и время выполнения.
2. Как реализовать в коде
3. Настроить в yml
Как поддержать аннотации Feign для замены аннотаций SpringMVC
1. Конфигурация кода
2. Конфигурация в файле yml (после конфигурации файла yml конфигурация в коде не нужна)
Создайте перехватчик для установки общедоступных параметров для достижения
1. Напишите перехватчик
2. Добавьте конфигурацию перехватчика.
(1) Реализовано в коде:
Независимо от того, настраиваем ли мы уровни журнала, перехватчики или заменяем аннотации SpringMVC, мы не добавляем @Configuration, чтобы он не вступил в силу глобально, и позволяем всем Feign использовать эту конфигурацию.
(2) Завершите настройку перехватчика в файле yml без написания кода конфигурации.
3. Токен, заключенный в этот перехватчик, можно получить напрямую у поставщика услуг.
Интеллектуальная рекомендация
Улучшение алгоритма обучения Blue Bridge Cup Простое добавление (насильственный подсчет)
описание проблемы Четыре натуральных числа меньше 10 могут делить 3 или 5 (3, 5, 6, 9), а их сумма равна 23. Вычислите сумму всех натуральных чисел меньше 1000, которые могут делить 3 или 5. Затем исп.
Стратегия Стратегия Pattern
совместное использование обучения awk
Простые несколько строк кода написать Sigmoid Function Image
Python Написать сигмовидное изображение функции.
Создание REST-клиента с помощью Spring Cloud OpenFeign и Netflix Ribbon
В Java HTTP-запросы между сервисами реализуются весьма просто. Так как существует ряд известных открытых HTTP-клиентов, таких как OkHttp и RestTemplate в Spring, то сложность представляет не выбор подходящего кандидата, а дальнейшая с ним работа.
Среди растущего числа распределенных облачных сервисов, где сервера постоянно появляются и исчезают, конечные точки сервисов оказываются динамичны и их сложно знать наперед. По этой причине, прежде чем отправлять запрос сервису, REST-клиенту необходимо интегрироваться в реестр сервисов и находить там его конечную точку.
Помимо этого, нужно обработать сериализацию запрос-ответ, а также реализовать балансировку нагрузки, правильно распределив ее между серверами. Плюсом же к этому нужно организовать систему отказоустойчивости. Все перечисленное представляет собой сквозную функциональность распределенных систем.
Именно здесь на помощь приходит Spring Cloud OpenFeign. Это не просто HTTP-клиент, а целостное решение задач, сопутствующих современным REST-клиентам. Spring Cloud OpenFeign обеспечивает интеграцию OpenFeign для Spring Boot путем автоматической настройки и привязки к среде Spring.
Сервис OpenFeign, изначально известный как Feign, является детищем Netflix. Он позволяет разработчикам использовать декларативный способ построения HTTP-клиентов с помощью аннотированных интерфейсов и без шаблонного кода. Spring Cloud OpenFeign обеспечивает балансировку нагрузки с помощью Ribbon и очень удобно интегрируется с другими облачными службами, например с Eureka для обнаружения сервисов и Hystrix для отказоустойчивости. Все это предусмотрено в OpenFeign изначально и не требует прописывания дополнительного кода.
В текущей статье вы узнаете:
Создание Maven-проекта
Для генерации Maven-проекта со Spring Boot 2.x можно использовать Spring Initializr. Добавьте в этот проект зависимости Spring Web, OpenFeign и Ribbon.
Если вы начинаете Maven-проект с нуля, то импортируйте Spring Cloud Dependencies POM, чтобы он наследовал все версии артефактов семейства Spring CLoud.
Далее добавьте к зависимостям проекта модули Spring Boot Starter Web, Spring Cloud Starter OpenFeign и Spring Cloud Starter Netflix Ribbon.
В качестве альтернативы можете загрузить весь проект с GitHub.
Создание класса Application для запуска
Создание интерфейса REST-клиента
Есть несколько способов предоставить RibbonClient конечную точку сервера для балансировки нагрузки, например использовать настройки Java, свойства приложения Spring или интеграцию с Eureka Server для поиска этой конечной точки.
На официальном сайте Postman Echo можно найти всю документацию по конечным точкам вместе с примерами ответов.
Добавление клиентского метода GET-запроса
Тестирование метода GET-запроса с помощью ‘SpringBootTest’
Выполните автоматическое внедрение (autowire) созданного Spring bean-компонента PostmanEchoClient в класс модульного теста. Bean-компонент должен использовать настроенный список серверов Ribbon для балансировки нагрузки на клиентской стороне.
После вызова конечной точки проверьте, совпадает ли возвращаемый ответ EchoGetResponse с переданными аргументами запроса, убедившись, что он правильно десериализован из ожидаемого содержимого JSON.
Добавление клиентского метода POST-запроса
Тестирование метода POST-запроса с помощью ‘SpringBootTest’
После вызова удаленной точки убедитесь, что возвращаемый ответ EchoPostResponse совпадает с переданными аргументами и телом запроса, подтверждающими его верную десериализацию из ожидаемого формата JSON.
Интеграция с Eureka Server
С помощью простой аннотации и некоторой настройки можно быстро активировать в сервисе Spring REST клиента Netflix Eureka Discovery.
Клиент Eureka использует имя приложения для регистрации на Eureka Server. Если это имя не указать, ваш сервис будет отображаться на Eureka Server как неизвестный.
Проделав эти несколько шагов, вы интегрировали сервис Spring REST в Eureka Server.
Теперь, когда ваш REST-сервис готов к подключению к Eureka Server, нужно удалить свойство listOfServers для Ribbon из application.yaml или закомментировать его.
Создание Eureka Server
Создайте с помощью Spring Initializr другой проект — на этот раз для Eureka Server, добавив в него зависимость Eureka Server.
Если вы начинаете новый Maven-проект, импортируйте Spring Cloud Dependencies POM и добавьте зависимость Spring Cloud Starter Netflix Eureka Server.
В качестве альтернативы можно загрузить проект Eureka Server с GitHub.
Наконец, деактивируйте в application.yaml функции саморегистрации и запроса реестра.
Теперь Eureka Server готов, можете запускать!
Поскольку Postman Echo является внешним сервисом, нужно вручную зарегистрировать его на Eureka Server. Список REST-операций, поддерживаемых Eureka, можно найти здесь. Этот API понадобится вам только для регистрации нового приложения.
Отправьте с помощью Postman запрос на Eureka Server.
URL для регистрации Postman Echo на Eureka Server следующий:
Запросите содержимое для регистрации Postman Echo на Eureka Server так:
В результате вы должны получить успешный ответ без содержимого.
Заключение
Мы научились создавать декларативного REST-клиента при помощи Spring Cloud OpenFeign, задействовав Spring Cloud Netflix Ribbon для обеспечения на клиентской стороне балансировки нагрузки и отказоустойчивости. Плюсом к этому мы узнали, как настраивать конечную точку статического сервера для Ribbon и как выполнять интеграцию с Eureka Server для получения списка конечных точек зарегистрированных серверов. Весь исходный код доступен на GitHub.
Благодарю за чтение и надеюсь, что статья оказалась для вас полезна.
Микросервисная архитектура, Spring Cloud и Docker
Привет, Хабр. В этой статье я кратко расскажу о деталях реализации микросервисной архитектуры с использованием инструментов, которые предоставляет Spring Cloud на примере простого концепт-пруф приложения.
Код доступен для ознакомления на гитхабе. Образы опубликованы на докерхабе, весь зоопарк стартует одной командой.
За основу я взял старый забытый проект, бэкенд которого представлял из себя монолит. Приложение позволяет организовать личные финансы: вносить регулярные доходы и расходы, следить за накоплениями, считать статистику и прогнозы.
Функциональные сервисы
Попробуем декомпозировать монолит на несколько основных микросервисов, каждый из которых будет отвечать за определенную бизнес-задачу.
Account service
Реализует логику и валидацию по сохранению доходов, расходов, накоплений и настроек аккаунта.
Метод | Путь | Описание | Пользователь авторизован | Доступно из UI |
---|---|---|---|---|
GET | /accounts/ | Получить данные указанного аккаунта | ||
GET | /accounts/current | Получить данные текущего аккаунта | × | × |
GET | /accounts/demo | Получить данные демо аккаунта | × | |
PUT | /accounts/current | Сохранить данные текущего аккаунта | × | × |
POST | /accounts/ | Зарегистрировать новый аккаунт | × |
Statistics service
Производит расчет основных статистических параметров аккаунта, приводит их значения к базовой валюте и периоду, сохраняет данные в виде, удобном для последующего анализа. Полученный временной ряд будет использован для отображения пользователю статистики и показателей за прошедшее время и экстраполяции для простейших прогнозов на будущее.
Метод | Путь | Описание | Пользователь авторизован | Доступно из UI |
---|---|---|---|---|
GET | /statistics/ | Получить статистику указанного аккаунта | ||
GET | /statistics/current | Получить статистику текущего аккаунта | × | × |
GET | /statistics/demo | Получить статистику демо аккаунта | × | |
PUT | /statistics/ | Создать/обновить дата-поинт для указанного аккаунта |
Notification service
Хранит настройки уведомлений (частоты напоминаний, периодичность бекапов). По расписанию производит рассылку e-mail сообщений, предварительно собирая и агрегируя нужные данные у первых двух сервисов, если требуется.
Метод | Путь | Описание | Пользователь авторизован | Доступно из UI |
---|---|---|---|---|
GET | /notifications/settings/current | Получить настройки нотификаций для текущего аккаунта | × | × |
PUT | /notifications/settings/current | Сохранить настройки нотификаций для текущего аккаунта | × | × |
Примечания
Инфраструктурные сервисы
Для обеспечения совместной работы описанных выше сервисов будем использовать набор основных паттернов и практик Микросервисной архитектуры. Многие из них реализованы в Spring Cloud (в частности, посредством интеграции с продуктами Netflix OSS) — на деле это зависимости, расширяющие возможности Spring Boot в ту или иную сторону. Ниже кратко рассмотрен каждый из компонентов.
Config Server
Spring Cloud Config — это горизонтально масштабируемое хранилище конфигураций для распределенной системы. В качестве источника данных на данный момент поддерживаются Git, Subversion и простые файлы, хранящиеся локально. По умолчанию Spring Cloud Config отдает файлы, соответствующие имени запрашивающего Spring приложения (но можно забирать проперти под конкретный Spring profile и из определенной ветки системы контроля версий).
На стороне клиентского приложения теперь не требуются никаких конфигурационных файлов, кроме bootstrap.yml с именем приложения и адресом Config server:
Для этого следует внести правки в конфигурационный файл Config server, а затем выполнить следующий запрос к Notification service :
Этот процесс можно автоматизировать, если использовать загрузку конфигураций из систем контроля версий, настроив вебхук из Github, Gitlub или Bitbucket.
Auth Server
Обязанности по авторизации полностью вынесены в отдельное приложение, которое выдает OAuth2 токены для доступа к ресурсам бэкенда. Auth server используется как для авторизации пользователей, так и для защищенного общения сервис-сервис внутри периметра.
На самом деле, здесь описан только один из возможных подходов. Spring Cloud и Spring Security позволяют достаточно гибко настраивать конфигурацию под ваши нужды (например, имеет смысл проводить авторизацию на стороне API Gateway, а внутрь инфраструктуры передавать запрос с уже заполненными данными пользователя).
В этом проекте я использую Password credential grant type для авторизации пользователей и Client credentials grant type — для авторизации между сервисами.
Spring Cloud Security предоставляет удобные аннотации и автоконфигурацию, что позволяет достаточно просто реализовать описанный функционал как со стороны клиента, так и со стороны авторизационного сервера.
API Gateway
Все три основных сервиса, которые мы обсудили выше, предоставляют для внешнего пользователя некоторый API. В промышленных системах, построенных на Микросервисной архитектуре, число компонентов растет быстро — поговаривают, что в Амазоне в рендеринг страницы вовлечены порядка 150 сервисов.
Гипотетически, клиентское приложение могло бы запрашивать каждый из сервисов самостоятельно. Но такой подход сразу натыкается на массу ограничений — необходимость знать адрес каждого эндпоинта, делать запрос за каждым куском информации отдельно и самостоятельно мерджить результат. Кроме того, не все приложения не бэкенде могут поддерживать дружественные вебу протоколы, и прочее прочее.
Для решения такого рода проблем применяют API Gateway — единую точку входа. Ее используют для приема внешних запросов и маршрутизации в нужные сервисы внутренней инфраструктуры, отдачи статического контента, аутентификации, стресс тестирования, канареечного развертывания, миграции сервисов, динамического управления трафиком. У Netflix если блог-пост об оптимизации своего API за счет асинхронной аггрегации контента из разных микросервисов.
Netflix заопенсорсила свою имплементацию API Gateway — Zuul. Spring Cloud нативно интегрирован с ним и включается добавлением одной зависимости и аннотациии @EnableZuulProxy в Spring Boot приложение. В этом проекте Zuul используется для самых элементарных задач — отдачи статики (веб-приложение) и роутинга запросов.
Пример префиксной маршрутизации для Notification service:
Service discovery
Еще один широко известный паттерн для распределенных систем. Service discovery позволяет автоматически определять сетевые адреса для доступных инстансов приложений, которые могут динамически изменяться по причинам масштабирования, падений и обновлений.
Ключевым звеном здесь является Registry service. В этом проекте я использую Netflix Eureka (но есть еще Consul, Zookeeper, Etcd и другие). Eureka — пример client-side discovery паттерна, что означает клиент должен запросить адреса доступных инстансов и осуществлять балансировку между ними самостоятельно.
Теперь инстанс приложения при старте будет регистрироваться в Eureka, предоставляя мета-данные (такие как хост, порт и прочее). Eureka будет принимать хартбит-сообщения, и если их нет в течении сконфигурированного времени — инстанс будет удален из реестра. Кроме того, Eureka предоставляет дашборд, на котором видны зарегистрированные приложения с количеством инстансов и другая техническая информация: http://localhost:8761
Клиентский балансировщик, Предохранитель и Http-клиент
Следующий набор инструментов тоже разработан в Netflix и нативно интегрирован в Spring Cloud. Все они работают совместно и используются в микросервисах, которым нужно общаться с внешним миром или внутренней инфраструктурой.
Ribbon
Ribbon — это client-side балансировщик. По сравнению с традиционным, здесь запросы проходят напрямую по нужному адресу, что исключает лишний узел при вызове. Из коробки он интегрирован с механизмом Service Discovery, который предоставляет динамический список доступных инстансов для балансировки между ними.
Hystrix
Hystrix — это имплементация паттерна Circuit Breaker — предохранителя, который дает контроль над задержками и ошибками при вызовах по сети. Основная идея состоит в том, чтобы остановить каскадный отказ в распределенной системе, состоящей из большого числа компонентов. Это позволяет отдавать ошибку как можно быстрее, не задерживаясь при запросе к зависшему сервису, давая ему восстановиться.
Помимо контроля за размыканием цепи, Hystrix позволяет определить fallback-метод, который будет вызван при неуспешном вызове. Тем самым можно отдавать дефолтный ответ, сообщение об ошибке, и др.
На каждый запрос Hystrix генерирует набор метрик (таких как скорость выполнения, результат), что позволяет анализировать общее состоянее системы. Ниже будет рассмотрен мониторинг на основе данных метрик.
Feign
Вот пример из Account Service:
Панель мониторинга
Однако в нашем случае сервисов несколько, и было бы здорово видеть все их метрики в одном месте. Для этого существует специальное решение. Каждый из наших сервисов будет пушить свои стримы в AMQP брокер (RabbitMQ), откуда аггрегатор стримов, Turbine, будет преобразовывать их, выставляя единый эндпоинт для Hystrix Dashboard.
Рассмотрим поведение системы под нагрузкой: Account service вызывает Statistics Service, и тот отвечает с варьируемой имитационной задержкой. Пороговое значение времени запроса установлено в 1 секунду.
задержка 0 мс | задержка 500 мс | задержка 800 мс | задержка 1100 мс |
Система работает без ошибок. Пропускная способность порядка 22 з/с. Небольшое число активных потоков в Statistics service. Среднее время получения ответа — 50 мс. | Число активных потоков увеличивается. Фиолетовая цифра показывает число отклоненных запросов, соответственно порядка 30-40% ошибок, но цепь все еще замкнута. | Полуоткрытое состояние: процент ошибок более 50%, предохранитель размыкает цепь. После определенного таймаута, цепь замыкается, но снова ненадолго. | 100% запросов с ошибками. Цепь разомкнута постоянно, попытки пропустить запрос спустя таймаут ничего не меняют — каждый отдельный запрос слишком медленный. |
Анализ логов
В инфраструктуре, состоящей из большого количества движущихся частей (каждая из которых может иметь по нескольку экземпляров), очень важно использовать систему централизированного сбора, обработки и анализа логов. Elasticsearch, Logstash и Kibana составляют стeк, с помощью которого можно эффективно решать такую задачу.
Готовая к запуску Docker-конфигурация ELK с Куратором и шаблонами для шипперов доступна на гитхабе. Именно такая конфигурация, с небольшой кастомизацией и масштабированием, успешно работает в продакшене на моем текущем проекте для анализа логов, сетевой активности и мониторинга производительности серверов.
Картинка с официального сайта Elastic, просто для примера
Автоматизация инфраструктуры
Развертывание микросервисной системы с большим количеством движущихся частей и взаимосвязанностью — задача очевидно более комплексная, нежели деплой монолитного приложения. Без автоматизированной инфраструктуры вся история превратится в бесконечную боль и трату времени. Это тема для совершенно отдельного разговора, я лишь покажу простейший Сontinuous delivery воркфлоу, реализованный в этом проекте на бесплатных версиях сервисов:
Запуск
Если вы дочитали до этого места, возможно вам будет интересно запустить все это своими руками. Хочу отметить, что инфраструктура состоит из 8 Spring Boot приложений, 4 инстансов MongoDB и одного RabbitMQ. Убедитесь, что в системе доступны 3-4 Гб памяти. Всегда можно запустить ограничиться самым необходимым функционалом — отказаться от Statistics service, Notification Service и Monitoring.
Прежде чем начать
Production mode
Development mode
Примечания
Всем Spring Boot приложениям в этом проекте для старта необходим доступный Config Server. Благодаря опции fail-fast в bootstrap.yml каждого приложения и опции restart: always в докере, контейнеры можно запускать одновременно (они будут автоматически продолжать попытки старта, пока не поднимется Config Server).
Механизм Service Discovery так же требует некоторого времени для начала полноценной работы. Сервис не доступен для вызова, пока он сам, Eureka и клиент не имеют одну и ту же мета-информацию у себя локально — на это требуется 3 хартбита. По умолчанию период времени между хартбитами составляет 30 секунд.