前言
本小节我们将进入学习SpringCloud的预热阶段既学习与理解微服务中的服务提供者和消费者。
我们知道在微服务的架构体系中服务与服务间的通讯可以通过RestTamplate(Spring对RESTful API请求的一种简单封装)和Fegin(SpringCloug集成的声明式客户端,后面我们将学习到)。
此处我们对本节案例中涉及到的一些技术栈或知识点不做细数,学习的基础前提是大家对SpringBoot有比较好的了解并且对SpringCloud有一个整体认识。我们将模拟一个业务场景:微服务中有一个deal模块作为服务的提供者(Provider),有一个broker模块作为服务的消费者(Consumer)。broker通过RestTamplate消费deal即broker模块调用deal模块。
以上业务场景是一个在微服务中常见的服务调用场景。
案例
准备工作
本案包括以后的案例中我们都是使用的:使用STS IED开发。因为STS对Spring生态做了很好的扩展。
服务提供者业务实现
编写一个服务提供者的业务用于服务调用
项目结构
代码解读
使用STS 的Spring Starter Project构建Maven WEB项目(STS的SSP Plugin会将该项目构建成一个基于SpringBoot的web项目然后使用SpringCloud做一次封装)。
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.example</groupId>
<artifactId>microservice.deal</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>microservice-deal</name>
<description>Demo project for Spring Boot</description>
<!-- 引入spring boot的依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<!-- 引入spring cloud的依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 添加spring-boot的maven插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
为方便快速演示本案例将使用h2以及Spring JPA做DB和Persistence. properties.yml配置如下
server:
port: 8080
spring:
jpa:
generate-ddl: false
show-sql: true
hibernate:
ddl-auto: none
datasource: # 指定数据源
platform: h2 # 指定数据源类型
schema: classpath:schema.sql # 指定h2数据库的建表脚本
data: classpath:data.sql # 指定h2数据库的数据脚本
logging: # 配置日志级别,让hibernate打印出执行的SQL
level:
root: INFO
org.hibernate: INFO
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
## INFO
info:
app:
name: @project.artifactId@
encoding: @project.build.sourceEncoding@
java:
source: @java.version@
target: @java.version@
management:
security:
enabled: false
Controler
@RestController
public class DealController {
@Autowired
private DealRepository dealRepository;
@GetMapping("/{id}")
public Deal findById(@PathVariable Long id) {
Deal findOne = this.dealRepository.findOne(id);
return findOne;
}
}
访问 http://localhost:8080/1 获取订单信息
服务消费者业务实现
项目结构
代码解读
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.example</groupId>
<artifactId>microservice.deal.broker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>microservice-deal-broker</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.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>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
properties.yml
server:
port: 8010
controller
@RestController
public class BrokerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/deal/{id}")
public Deal findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://localhost:8080/" + id, Deal.class);
}
}
访问
http://localhost:8010/deal/1 获取订单信息
小结
如上案例是一个在微服务中常用到的业务场景即一个服务消费另一个服务,只是实现地比较简单。同时这样实现也存在一些问题:
缺少服务注册和发现机制,无法保证服务的可用性。
存在着硬编码的问题,服务的可扩展性极低。
我们将在下一章节中学习服务的注册与发现机制。