Статьи

Изучение Spring-Cloud — Написание микросервиса

Продолжая мой учебный курс по Spring-Cloud, ранее я рассмотрел, как писать компоненты инфраструктуры типичной среды микросервисов на основе Spring-Cloud и Netflix OSS — в данном конкретном случае два важнейших компонента: Eureka для регистрации и обнаружения сервисов и Spring Cloud Конфигурация для поддержки централизованного хранилища конфигурации для службы. Здесь я покажу, как я разработал два фиктивных микро-сервиса, один простой сервис «pong» и сервис «ping», который использует сервис «pong».

Sample-пинг-понг

Sample-Pong microservice

Конечная точка, обрабатывающая запросы «ping», является типичной конечной точкой на основе Spring MVC:

01
02
03
04
05
06
07
08
09
10
11
12
13
@RestController
public 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-CONFIG
 
eureka:
  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
@EnableDiscoveryClient
public class PongApplication {
    public static void main(String[] args) {
        SpringApplication.run(PongApplication.class, args);
    }
}

и это завершает код для службы «понг».

Пробный пинг микро-сервис

Так что теперь на потребителя микросервиса «pong», очень образно названного микросервисом «ping». Spring-Cloud и Netflix OSS предлагают множество опций для вызова конечных точек в зарегистрированных сервисах Eureka, чтобы обобщить имеющиеся у меня варианты:

  1. Используйте необработанный Eureka DiscoveryClient для поиска экземпляров, на которых размещается служба, и выполнения вызовов с помощью Spring RestTemplate .
  2. Используйте Ribbon , клиентское решение для балансировки нагрузки, которое может использовать Eureka для поиска экземпляров сервисов.
  3. Используйте 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 —

EurekaConsole-fullping

Пользовательский интерфейс приложения ping должен быть доступен по адресу http: // dockerhost: 8080 url —

SampleSpringCloudView

Кроме того, панель мониторинга Hystrix должна быть доступна для мониторинга запросов к приложению «pong» по этому адресу http: // dockerhost: 8989 / hystrix / monitor? Stream = http% 3A% 2F% 2Fsampleping% 3A8080% 2Fhystrix.stream:

SpringCloud-Hystrix

использованная литература

  1. Код доступен на моем сайте github — https://github.com/bijukunjummen/spring-cloud-ping-pong-sample
  2. Большая часть кода заимствована из репозитория spring-cloud-samples — https://github.com/spring-cloud-samples
Ссылка: Изучение Spring-Cloud — Написание микросервиса от нашего партнера JCG Биджу Кунджуммен в блоге all and sundry.