Продолжая мой учебный курс по Spring-Cloud, ранее я рассмотрел, как писать компоненты инфраструктуры типичной среды микросервисов на основе Spring-Cloud и Netflix OSS — в данном конкретном случае два важнейших компонента: Eureka для регистрации и обнаружения сервисов и Spring Cloud Конфигурация для поддержки централизованного хранилища конфигурации для службы. Здесь я покажу, как я разработал два фиктивных микро-сервиса, один простой сервис «pong» и сервис «ping», который использует сервис «pong».
Sample-Pong microservice
Конечная точка, обрабатывающая запросы «ping», является типичной конечной точкой на основе Spring MVC:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@RestControllerpublic class PongController { @Value("${reply.message}") private String message; @RequestMapping(value = "/message", method = RequestMethod.POST) public Resource<MessageAcknowledgement> pongMessage(@RequestBody Message input) { return new Resource<>( new MessageAcknowledgement(input.getId(), input.getPayload(), message)); }} |
Он получает сообщение и отвечает подтверждением. Здесь служба использует сервер конфигурации при поиске свойства «reply.message» . Итак, как служба «pong» находит сервер конфигурации, возможно, есть два пути — напрямую, указав местоположение сервера конфигурации, или путем поиска сервера конфигурации через Eureka. Я привык к подходу, когда Eureka считается источником правды, поэтому в этом духе я использую Eureka для поиска сервера конфигурации. Spring Cloud делает весь этот поток очень простым, все, что ему требуется, — это файл свойств «bootstrap.yml» с записями по следующим строкам:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
---spring: application: name: sample-pong cloud: config: discovery: enabled: true serviceId: SAMPLE-CONFIGeureka: instance: nonSecurePort: ${server.port:8082} client: serviceUrl: defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/ |
Местоположение Eureka указывается через свойство «eureka.client.serviceUrl», а «spring.cloud.config.discovery.enabled» устанавливается в «true», чтобы указать, что сервер конфигурации обнаружен через указанный сервер Eureka.
Просто отметьте , что это означает, что Eureka и сервер конфигурации должны быть полностью настроены, прежде чем пытаться вызвать фактические сервисы, они являются предварительными условиями, и основное предположение состоит в том, что компоненты инфраструктуры доступны во время загрузки приложения.
Сервер конфигурации имеет свойства для службы «sample-pong», это можно проверить с помощью конечной точки серверов Config — http: // localhost: 8888 / sample-pong / default, 8888 — это порт, который я указал для конечная точка сервера, и должна отвечать содержимым по следующим направлениям:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
"name": "sample-pong", "profiles": [ "default" ], "label": "master", "propertySources": [ { "name": "classpath:/config/sample-pong.yml", "source": { "reply.message": "Pong" } } ]} |
Как можно видеть, свойство «reply.message» с этого сервера центральной конфигурации будет использоваться службой pong в качестве сообщения подтверждения.
Теперь, чтобы настроить эту конечную точку как службу, все, что требуется, это точка входа на основе Spring-boot по следующим направлениям:
|
1
2
3
4
5
6
7
|
@SpringBootApplication@EnableDiscoveryClientpublic class PongApplication { public static void main(String[] args) { SpringApplication.run(PongApplication.class, args); }} |
и это завершает код для службы «понг».
Пробный пинг микро-сервис
Так что теперь на потребителя микросервиса «pong», очень образно названного микросервисом «ping». Spring-Cloud и Netflix OSS предлагают множество опций для вызова конечных точек в зарегистрированных сервисах Eureka, чтобы обобщить имеющиеся у меня варианты:
- Используйте необработанный Eureka DiscoveryClient для поиска экземпляров, на которых размещается служба, и выполнения вызовов с помощью Spring RestTemplate .
- Используйте Ribbon , клиентское решение для балансировки нагрузки, которое может использовать Eureka для поиска экземпляров сервисов.
- Используйте Feign , который обеспечивает декларативный способ вызова сервисного вызова. Он внутренне использует ленту.
Я пошел с Feign. Все, что требуется, это интерфейс, который показывает контракт для вызова сервиса:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
package org.bk.consumer.feign;import org.bk.consumer.domain.Message;import org.bk.consumer.domain.MessageAcknowledgement;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.http.MediaType;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;@FeignClient("samplepong")public interface PongClient { @RequestMapping(method = RequestMethod.POST, value = "/message", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody MessageAcknowledgement sendMessage(@RequestBody Message message);} |
Аннотация @FeignClient («samplepong») внутренне указывает на «именованного» клиента ленты под названием «samplepong». Это означает, что должна быть запись в файлах свойств для этого именованного клиента, в моем случае у меня есть эти записи в моем файле application.yml:
|
1
2
3
4
5
6
|
samplepong: ribbon: DeploymentContextBasedVipAddresses: sample-pong NIWSServerListClassName: com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList ReadTimeout: 5000 MaxAutoRetries: 2 |
Самая важная запись здесь — это «samplepong.ribbon.DeploymentContextBasedVipAddresses», который указывает на адрес регистрации службы Eureka «pong», по которому экземпляр службы будет обнаружен Ribbon.
Остальная часть приложения представляет собой обычное приложение Spring Boot. Я раскрыл этот сервисный вызов за Hystrix, который защищает от сбоев сервисных вызовов и по существу обходит этот FeignClient:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package org.bk.consumer.service;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import org.bk.consumer.domain.Message;import org.bk.consumer.domain.MessageAcknowledgement;import org.bk.consumer.feign.PongClient;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;@Service("hystrixPongClient")public class HystrixWrappedPongClient implements PongClient { @Autowired @Qualifier("pongClient") private PongClient feignPongClient; @Override @HystrixCommand(fallbackMethod = "fallBackCall") public MessageAcknowledgement sendMessage(Message message) { return this.feignPongClient.sendMessage(message); } public MessageAcknowledgement fallBackCall(Message message) { MessageAcknowledgement fallback = new MessageAcknowledgement(message.getId(), message.getPayload(), "FAILED SERVICE CALL! - FALLING BACK"); return fallback; }} |
«Загрузка»
Я установил всю мою настройку, поэтому самый простой способ запустить набор приложений — это сначала создать образы докера для всех артефактов следующим образом:
|
1
|
mvn clean package docker:build -DskipTests |
и вызовите их все с помощью следующей команды, при условии, что и docker, и docker-compose доступны локально:
|
1
|
docker-compose up |
Предполагая, что все идет нормально, Eureka должна показать все зарегистрированные сервисы по адресу http: // dockerhost: 8761 url —
Пользовательский интерфейс приложения ping должен быть доступен по адресу http: // dockerhost: 8080 url —
Кроме того, панель мониторинга Hystrix должна быть доступна для мониторинга запросов к приложению «pong» по этому адресу http: // dockerhost: 8989 / hystrix / monitor? Stream = http% 3A% 2F% 2Fsampleping% 3A8080% 2Fhystrix.stream:
использованная литература
- Код доступен на моем сайте github — https://github.com/bijukunjummen/spring-cloud-ping-pong-sample
- Большая часть кода заимствована из репозитория spring-cloud-samples — https://github.com/spring-cloud-samples
| Ссылка: | Изучение Spring-Cloud — Написание микросервиса от нашего партнера JCG Биджу Кунджуммен в блоге all and sundry. |



