Давайте изучим основы микросервисов и микросервисных архитектур. Мы также начнем рассматривать базовую реализацию микросервиса с помощью Spring Boot. Мы создадим пару микросервисов и заставим их общаться друг с другом, используя Eureka Naming Server и Ribbon для балансировки нагрузки на стороне клиента.
Вот краткое описание серии микросервисов: микросервисы с загрузкой Spring
- Часть 1 - Начало работы с архитектурой микросервисов
- Часть 2 - Создание микросервиса Forex
- Текущая часть - Часть 3 - Создание микросервиса конвертации валют
- Часть 4 - Использование ленты для балансировки нагрузки
- Часть 5 - Использование сервера имен Eureka
Это третья часть этой серии статей. В этой части мы сосредоточимся на создании микросервиса конвертации валют.
Ты выучишь
- Как создать микросервис с помощью Spring Boot?
- Как использовать RestTemplate для выполнения службы REST?
- Как использовать Feign для выполнения службы REST?
- В чем преимущества Feign перед RestTemplate?
Бесплатные курсы - 10 шагов обучения
- БЕСПЛАТНЫЙ 5-ДНЕВНЫЙ ВЫЗОВ - Изучите Spring и Spring Boot
- Изучите Spring Boot за 10 шагов
- Изучите Docker за 10 шагов
- Изучите Kubernetes за 10 шагов
- Изучите AWS за 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
- Часть 1 - Начало работы с архитектурой микросервисов
- Часть 2 - Создание микросервиса Forex
- Текущая часть - Часть 3 - Создание микросервиса конвертации валют
- Часть 4 - Использование ленты для балансировки нагрузки
- Часть 5 - Использование сервера имен Eureka
Если вы не можете ждать и хотите узнать больше о микросервисах, посмотрите этот список лучших курсов по изучению микросервисов с 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-программистов (вопросы)