Давайте изучим основы микросервисов и микросервисных архитектур. Мы также начнем рассматривать базовую реализацию микросервиса с помощью Spring Boot. Мы создадим пару микросервисов и заставим их общаться друг с другом, используя Eureka Naming Server и Ribbon для балансировки нагрузки на стороне клиента.

Вот краткое описание серии микросервисов: микросервисы с загрузкой Spring

Это третья часть этой серии статей. В этой части мы сосредоточимся на создании микросервиса конвертации валют.

Ты выучишь

  • Как создать микросервис с помощью Spring Boot?
  • Как использовать RestTemplate для выполнения службы REST?
  • Как использовать Feign для выполнения службы REST?
  • В чем преимущества Feign перед RestTemplate?

Бесплатные курсы - 10 шагов обучения

Если вам нужно больше возможностей, вы можете проверить эти бесплатные курсы Spring и Spring Boot:



Обзор ресурсов

Служба конвертации валют (CCS) может конвертировать большое количество валют в другую валюту. Он использует сервис Forex для получения текущих курсов валют. CCS - это Потребитель услуг.

Пример запроса и ответа показан ниже:

ПОЛУЧИТЬ на http: // localhost: 8100 / currency-converter / from / EUR / to / INR / amount / 10000

{
  id: 10002,
  from: "EUR",
  to: "INR",
  conversionMultiple: 75,
  quantity: 10000,
  totalCalculatedAmount: 750000,
  port: 8000,
}

Вышеуказанный запрос предназначен для определения стоимости 10 000 евро в индийских рупиях. TotalCalculatedAmount составляет 750000 индийских рупий.

На схеме ниже показана связь между CCS и FS.

Структура кода проекта

На следующем снимке экрана показана структура проекта, который мы создадим.

Несколько деталей:

  • SpringBootMicroserviceCurrencyConversionApplication.java - Класс Spring Boot Application, созданный с помощью Spring Initializer. Этот класс действует как точка запуска приложения.
  • pom.xml - Он содержит все зависимости, необходимые для сборки этого проекта. Мы будем использовать Spring Boot Starter Web.
  • CurrencyConversionBean.java - Бин для хранения ответа, который мы хотим отправить.
  • CurrencyExchangeServiceProxy.java - Это будет прокси-сервер Feign для вызова службы Forex.
  • CurrencyConversionController.java - Spring Rest Controller, предоставляющий сервис конвертации валют. Это будет использовать CurrencyExchangeServiceProxy для вызова службы Forex.

Инструменты, которые вам понадобятся

  • Maven 3.0+ - ваш инструмент для сборки
  • Ваша любимая IDE. Мы используем Eclipse.
  • JDK 1.8+

Если вам нужно узнать больше о некоторых важных инструментах для Java-разработчика, вы можете проверить здесь:



Полный проект Maven с примерами кода

В нашем репозитории Github есть все примеры кода - https://github.com/in28minutes/spring-boot-examples/tree/master/spring-boot-basic-microservice

Загрузка с помощью Spring Initializr

Создание микросервиса с помощью Spring Initializr - простая прогулка.

Spring Initializr http://start.spring.io/ - отличный инструмент для начальной загрузки ваших проектов Spring Boot.

Используя Spring Initializr, вы можете создавать самые разные проекты.

Для проекта веб-служб необходимо выполнить следующие шаги.

  • Запустите Spring Initializr и выберите следующее
  • Выберите com.in28minutes.springboot.microservice.example.currencyconversion в качестве группы
  • Выберите spring-boot-microservice-currency-conversion в качестве артефакта
  • Выберите следующие зависимости
  • Интернет
  • DevTools
  • Притворяться
  • Щелкните "Создать проект".
  • Импортируйте проект в Eclipse. Файл - ›Импорт -› Существующий проект Maven.

Не забываем в зависимостях выбрать Feign

Создание CurrencyConversionBean

Это простой компонент для создания ответа.

public class CurrencyConversionBean {
  private Long id;
  private String from;
  private String to;
  private BigDecimal conversionMultiple;
  private BigDecimal quantity;
  private BigDecimal totalCalculatedAmount;
  private int port;
  public CurrencyConversionBean() {
  }
  public CurrencyConversionBean(Long id, String from, String to, BigDecimal conversionMultiple, BigDecimal quantity,
      BigDecimal totalCalculatedAmount, int port) {
    super();
    this.id = id;
    this.from = from;
    this.to = to;
    this.conversionMultiple = conversionMultiple;
    this.quantity = quantity;
    this.totalCalculatedAmount = totalCalculatedAmount;
    this.port = port;
  }

Реализуйте клиент REST с помощью RestTemplate

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

@RestController
public class CurrencyConversionController {
  private Logger logger = LoggerFactory.getLogger(this.getClass());
  @GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}")
  public CurrencyConversionBean convertCurrency(@PathVariable String from, @PathVariable String to,
      @PathVariable BigDecimal quantity) {
    Map<String, String> uriVariables = new HashMap<>();
    uriVariables.put("from", from);
    uriVariables.put("to", to);
    ResponseEntity<CurrencyConversionBean> responseEntity = new RestTemplate().getForEntity(
        "http://localhost:8000/currency-exchange/from/{from}/to/{to}", CurrencyConversionBean.class,
        uriVariables);
    CurrencyConversionBean response = responseEntity.getBody();
    return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity,
        quantity.multiply(response.getConversionMultiple()), response.getPort());
  }

Настроить имя и порт приложения

/spring-boot-microservice-currency-conversion-service/src/main/resources/application.properties

spring.application.name=currency-conversion-service
server.port=8100

Мы назначаем имя приложения, а также порт по умолчанию 8100.

Тестирование микросервиса

Запустите приложение Spring Boot, запустив SpringBootMicroserviceCurrencyConversionApplication.java.

ДОБРАТЬСЯ до http://localhost:8100/currency-converter/from/EUR/to/INR/quantity/10000

{
  id: 10002,
  from: "EUR",
  to: "INR",
  conversionMultiple: 75,
  quantity: 10000,
  totalCalculatedAmount: 750000,
  port: 8000,
}

Если вы работаете в Linux, вы также можете использовать команду cURL для тестирования веб-сервисов REST и микросервиса, как показано в этой статье:



Создание фальшивого прокси

Feign предоставляет лучшую альтернативу RestTemplate для вызова REST API.

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyExchangeServiceProxy.java

package com.in28minutes.springboot.microservice.example.currencyconversion;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name="forex-service" url="localhost:8000")
public interface CurrencyExchangeServiceProxy {
  @GetMapping("/currency-exchange/from/{from}/to/{to}")
  public CurrencyConversionBean retrieveExchangeValue
    (@PathVariable("from") String from, @PathVariable("to") String to);
}

Сначала мы определяем простой прокси.

  • @FeignClient(name="forex-service" url="localhost:8100") - Заявляет, что это фальшивый клиент и URL-адрес, по которому присутствует форекс-сервис, localhost:8100
  • @GetMapping("/currency-exchange/from/{from}/to/{to}") - URI сервиса, который мы хотели бы использовать

Использование прокси-сервера Feign из микросервисного контроллера

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

@Autowired
  private CurrencyExchangeServiceProxy proxy;
  @GetMapping("/currency-converter-feign/from/{from}/to/{to}/quantity/{quantity}")
  public CurrencyConversionBean convertCurrencyFeign(@PathVariable String from, @PathVariable String to,
      @PathVariable BigDecimal quantity) {
    CurrencyConversionBean response = proxy.retrieveExchangeValue(from, to);
    logger.info("{}", response);
    return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity,
        quantity.multiply(response.getConversionMultiple()), response.getPort());
  }

Включить клиентов Feign

Прежде чем мы сможем использовать Feign, нам нужно включить его, используя аннотацию @EnableFeignClients в соответствующем пакете, в котором определены клиентские прокси.

@SpringBootApplication
@EnableFeignClients("com.in28minutes.springboot.microservice.example.currencyconversion")
@EnableDiscoveryClient
public class SpringBootMicroserviceCurrencyConversionApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringBootMicroserviceCurrencyConversionApplication.class, args);
  }
}

Тестирование микросервиса с помощью Feign

ПОЛУЧИТЬ на http: // localhost: 8100 / currency-converter-feign / from / EUR / to / INR / amount / 10000

{
  id: 10002,
  from: "EUR",
  to: "INR",
  conversionMultiple: 75,
  quantity: 10000,
  totalCalculatedAmount: 750000,
  port: 8000,
}

Резюме

Теперь мы создали два микросервиса и установили между ними связь.

Однако мы жестко кодируем URL-адрес для FS в CCS. Это означает, что при запуске новых экземпляров FS у нас нет возможности распределить нагрузку между ними.

Следующие шаги

В следующей части мы включим распределение нагрузки на стороне клиента с помощью ленты.

Микросервисы с Spring Boot

Если вы не можете ждать и хотите узнать больше о микросервисах, посмотрите этот список лучших курсов по изучению микросервисов с Spring:



Полный пример кода

/spring-boot-microservice-currency-conversion-service/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.in28minutes.springboot.microservice.example.currency-conversion</groupId>
  <artifactId>spring-boot-microservice-currency-conversion</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>spring-boot-microservice-currency-conversion</name>
  <description>Microservices with Spring Boot and Spring Cloud - Currency Conversion Service</description>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Finchley.M8</spring-cloud.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </pluginRepository>
    <pluginRepository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
  </pluginRepositories>

</project>

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyConversionBean.java

package com.in28minutes.springboot.microservice.example.currencyconversion;
import java.math.BigDecimal;
public class CurrencyConversionBean {
  private Long id;
  private String from;
  private String to;
  private BigDecimal conversionMultiple;
  private BigDecimal quantity;
  private BigDecimal totalCalculatedAmount;
  private int port;
  public CurrencyConversionBean() {
  }
  public CurrencyConversionBean(Long id, String from, String to, BigDecimal conversionMultiple, BigDecimal quantity,
      BigDecimal totalCalculatedAmount, int port) {
    super();
    this.id = id;
    this.from = from;
    this.to = to;
    this.conversionMultiple = conversionMultiple;
    this.quantity = quantity;
    this.totalCalculatedAmount = totalCalculatedAmount;
    this.port = port;
  }
  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
  public String getFrom() {
    return from;
  }
  public void setFrom(String from) {
    this.from = from;
  }
  public String getTo() {
    return to;
  }
  public void setTo(String to) {
    this.to = to;
  }
  public BigDecimal getConversionMultiple() {
    return conversionMultiple;
  }
  public void setConversionMultiple(BigDecimal conversionMultiple) {
    this.conversionMultiple = conversionMultiple;
  }
  public BigDecimal getQuantity() {
    return quantity;
  }
  public void setQuantity(BigDecimal quantity) {
    this.quantity = quantity;
  }
  public BigDecimal getTotalCalculatedAmount() {
    return totalCalculatedAmount;
  }
  public void setTotalCalculatedAmount(BigDecimal totalCalculatedAmount) {
    this.totalCalculatedAmount = totalCalculatedAmount;
  }
  public int getPort() {
    return port;
  }
  public void setPort(int port) {
    this.port = port;
  }
}

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyConversionController.java

package com.in28minutes.springboot.microservice.example.currencyconversion;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class CurrencyConversionController {
  private Logger logger = LoggerFactory.getLogger(this.getClass());
  @Autowired
  private CurrencyExchangeServiceProxy proxy;
  @GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}")
  public CurrencyConversionBean convertCurrency(@PathVariable String from, @PathVariable String to,
      @PathVariable BigDecimal quantity) {
    Map<String, String> uriVariables = new HashMap<>();
    uriVariables.put("from", from);
    uriVariables.put("to", to);
    ResponseEntity<CurrencyConversionBean> responseEntity = new RestTemplate().getForEntity(
        "http://localhost:8000/currency-exchange/from/{from}/to/{to}", CurrencyConversionBean.class,
        uriVariables);
    CurrencyConversionBean response = responseEntity.getBody();
    return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity,
        quantity.multiply(response.getConversionMultiple()), response.getPort());
  }
  @GetMapping("/currency-converter-feign/from/{from}/to/{to}/quantity/{quantity}")
  public CurrencyConversionBean convertCurrencyFeign(@PathVariable String from, @PathVariable String to,
      @PathVariable BigDecimal quantity) {
    CurrencyConversionBean response = proxy.retrieveExchangeValue(from, to);
    logger.info("{}", response);
    return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity,
        quantity.multiply(response.getConversionMultiple()), response.getPort());
  }
}

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyExchangeServiceProxy.java

package com.in28minutes.springboot.microservice.example.currencyconversion;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name="forex-service" url="localhost:8000")
public interface CurrencyExchangeServiceProxy {
  @GetMapping("/currency-exchange/from/{from}/to/{to}")
  public CurrencyConversionBean retrieveExchangeValue
    (@PathVariable("from") String from, @PathVariable("to") String to);
}

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/SpringBootMicroserviceCurrencyConversionApplication.java

package com.in28minutes.springboot.microservice.example.currencyconversion;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients("com.in28minutes.springboot.microservice.example.currencyconversion")
public class SpringBootMicroserviceCurrencyConversionApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringBootMicroserviceCurrencyConversionApplication.class, args);
  }
}

/spring-boot-microservice-currency-conversion-service/src/main/resources/application.properties

spring.application.name=currency-conversion-service
server.port=8100

/spring-boot-microservice-currency-conversion-service/src/test/java/com/in28minutes/springboot/microservice/example/currencyconversion/SpringBootMicroserviceCurrencyConversionApplicationTests.java

package com.in28minutes.springboot.microservice.example.currencyconversion;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootMicroserviceCurrencyConversionApplicationTests {
  @Test
  public void contextLoads() {
  }
}

Другие статьи о Java и Spring, которые могут вам понравиться

  • 5 функций Spring Boot, которые должен знать каждый Java-разработчик (функции)
  • 5 Курс по освоению Spring Boot онлайн в 2020 году (курсы)
  • 10 вещей, которые Java-разработчик должен усвоить в 2020 году (цели)
  • 10 инструментов, которые Java-разработчики используют в повседневной жизни (инструменты)
  • 10 советов, как стать лучшим Java-разработчиком в 2020 году (советы)
  • 3 передовых метода, которым Java-программисты могут научиться у Spring (лучшие практики)
  • 5 курсов по изучению Spring Boot и Spring Cloud в 2020 году (курсы)
  • 3 способа изменить порт Tomcat в Spring Boot (учебник)
  • 10 аннотаций Spring MVC, которые следует изучить Java-разработчикам (аннотации)
  • 15 вопросов для собеседований по Spring Boot для Java-программистов (вопросы)