Spring Cloud Alibaba提供微服务开发的⼀站式解决⽅案。包含开发分布式应⽤服务的必需组件,⽅便开发者通过Spring Cloud编程模型轻松使⽤这些组件来开发分布式应⽤服务。依托Spring Cloud Alibaba,只需要添加⼀些注解和少量配置,就可以将Spring Cloud应⽤接⼊阿⾥分布式应用解决⽅案,通过阿⾥中间件来迅速搭建分布式应⽤系统。
本课程以微服务分布式架构应用业务场景作为实践案例,阐述Spring Boot、Spring Cloud、Spring Cloud Alibaba、Nacos、Spring Cloud Ribbon、Spring Cloud Feign、Spring Cloud Gateway框架实用技术,讲述企业级Spring Cloud Alibaba开发技术栈知识。
在本课程中,会讲到如下技术栈内容:
一、微服务基础知识
1、微服务架构
2、Spring Cloud简介
3、Spring Cloud Alibaba简介
二、微服务构建Spring Boot
1、框架简介
2、项目构建与解析
3、实现RESTful API
三、服务治理Spring Cloud Alibaba Nacos
1、服务注册与发现
2、安装Nacos Server
3、接入Nacos服务注册与发现
3.1 父工程
3.2 业务微服务
3.3 订单微服务
3.4 库存微服务
四、客户端负载均衡Spring Cloud Ribbon
1、启动两个服务实例
2、业务微服务
五、声明式服务调用Spring Cloud Feign
1、导入依赖
2、Feign的客户端
3、业务逻辑层
4、控制器层
5、开启Feign功能
六、API网关服务Spring Cloud Gateway
1、引入依赖
2、启动类
3、配置文件
七、分布式配置中心Spring Cloud Alibaba Nacos
1、配置管理
2、接入Nacos配置中心
2.1 引入依赖
2.2 配置文件
2.3 nacos中的配置
2.4 业务中读取配置属性
八、微服务实战案例
适合人群: 本课程是来自一线开发者的实战经验总结,对微服务分布式架构开发、设计感兴趣的所有技术人员。
一、微服务基础知识
1、微服务架构
微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的RESTful API进行通信协作。被拆分成的每一个小型服务都围绕着系统中的某一项或一些耦合度较高的业务功能进行构建,并且每个服务都维护着自身的数据存储、业务开发、自动化测试案例以及独立部署机制。由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。
微服务结构图 :
API Gateway网关是一个服务器,是系统的唯一入口。网关提供RESTful/HTTP的方式访问服务。而服务端通过服务注册中心进行服务注册和管理。
微服务中每一个服务都对应唯一的业务能力,做到单一职责;每个服务都要对外暴露服务接口API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供REST的接口即可;每个服务都是一个独立的开发团队;因为是面向服务,提供REST接口,使用什么技术没有别人干涉;采用前后端分离开发,提供统一REST接口,后端不用再为PC、移动端开发不同接口;每个服务都使用自己的数据源。
2、Spring Cloud简介
Spring Cloud是一个基于Spring Boot实现的微服务架构开发工具。它为微服务架构中涉及的配置管理、服务治理、容错管理、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。
Spring Cloud是分布式微服务架构的一站式解决方案,它提供了一套简单易用的编程模型,使我们能在Spring Boot的基础上轻松地实现微服务系统的构建。Spring Cloud提供以微服务为核心的分布式系统构建标准。
Spring Cloud本身并不是一个开箱即用的框架,它是一套微服务规范,共有两代实现。Spring Cloud Netflix是Spring Cloud的第一代实现,主要由Eureka、Ribbon、Feign、Hystrix等组件组成。Spring Cloud Alibaba是Spring Cloud的第二代实现,主要由Nacos、Sentinel、Seata等组件组成。
3、Spring Cloud Alibaba简介
Spring Cloud Alibaba提供的基于Spring Cloud编程模型实现的微服务框架,其所有组件都来自于阿里巴巴微服务技术,无论是解决方案完整性、技术成熟度、社区还是文档资料等都对国内开发者非常友好。是Spring Cloud第二代实现的主要组成部分。吸收了Spring Cloud Netflix微服务框架的核心架构思想,并进行了高性能改进。自Spring Cloud Netflix进入停更维护后,Spring Cloud Alibaba逐渐代替它成为主流的微服务框架。
同时Spring Cloud Alibaba也是国内首个进入Spring社区的开源项目。2018年7月,Spring Cloud Alibaba正式开源,并进入Spring Cloud孵化器中孵化;2019年7月,Spring Cloud官方宣布Spring Cloud Alibaba毕业,并将仓库迁移到 Alibaba Github OSS下。
主要功能
服务限流降级:默认⽀持WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo和RocketMQ限流降级功能的接⼊,可以在运⾏时通过控制台实时修改限流降级规则,还⽀持查看限流降级 Metrics监控。
服务注册与发现:适配Spring Cloud服务注册与发现标准,默认集成了Ribbon的⽀持。
分布式配置管理:⽀持分布式系统中的外部化配置,配置更改时⾃动刷新。
消息驱动能⼒:基于Spring Cloud Stream为微服务应⽤构建消息驱动能⼒。
分布式事务:使⽤@GlobalTransactional注解,⾼效并且对业务零侵⼊地解决分布式事务问题。
主要组件
Sentinel:把流量作为切⼊点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Nacos:⼀个更易于构建云原⽣应⽤的动态服务发现、配置管理和服务管理平台。
Seata:阿⾥巴巴开源产品,⼀个易于使⽤的⾼性能微服务分布式事务解决⽅案。
RocketMQ:⼀款开源的分布式消息系统,基于⾼可⽤分布式集群技术,提供低延时的、⾼可靠的消息发布与订阅服务。
版本说明
组件版本关系
依赖版本关系

二、微服务构建Spring Boot
1、框架简介
Spring Boot的宗旨并非要重写Spring或是替代Spring, 而是希望通过设计大量的自动化配置等方式来简化Spring原有样板化的配置,使得开发者可以快速构建应用。
除了解决配置问题之外,Spring Boot还通过一系列Starter POMs的定义,让我们整合各项功能的时候,不需要在 Maven的pom.xml中维护那些错综复杂的依赖关系,而是通过类似模块化的Starter模块定义来引用,使得依赖管理工作变得更为简单。
Spring Boot除了可以很好融入Docker之外, 其自身就支持嵌入式的Tomcat、Jetty等容器。所以,通过Spring Boot构建的应用不再需要安装Tomcat, 将应用打包成war, 再部署到Tomcat这样复杂的构建与部署动作,只需将Spring Boot应用打成jar包,并通过java -jar命令直接运行就能启动一个标准化的Web应用,这使得Spring Boot应用变得非常轻便。
构建微服务的基础框架Spring Boot,由于Spring Cloud的构建基于Spring Boot实现。使用Spring Boot的目的除了它是Spring Cloud的基础之外,也由于其自身的各项优点,如自动化配置、快速开发、轻松部署等,非常适合用作微服务架构中各项具体微服务的开发框架。
2、项目构建与解析
1)系统及工具版本要求
• Java 7及以上版本
• Spring Framework 5.2.8及以上版本
• Maven 3.5及以上版本
本视频课程内容均采用Java 1.8、Spring Boot 2.3.2调试通过。
2)构建Maven项目
在IDE中创建一个Maven工程,名称定义为bjwykj-springboot,工程结构如下图所示。
3)工程结构解析
Spring Boot的基础结构有三大块(具体路径根据用户生成项目时填写的Group和Artifact有所差异)。src/main/java: 主程序入口SBApplication, 可以通过直接运行该类来启动Spring Boot应用。
src/main/resources: 配置目录,该目录用来存放应用的一些配置信息,比如应用名、服务端口、数据库链接等。由于我们引入了Web模块,因此产生了static目录与templates目录,前者用于存放静态资源,如图片、css、JavaScript等;后者用于存放Web页面的模板文件,这里我们主要演示提供RESTful API所以这两个目录并不会用到。
src/test/:单元测试目录,生成的SBApplicationTests通过JUnit 4实现,可以直接用运行Spring Boot应用的测试。后文中,我们会演示如何在该类中测试RESTful API。
4)Maven配置分析
打开当前工程下的pom.xml文件, 看看生成的项目都引入了哪些依赖来构建Spring Boot工程, 内容大致如下所示。
java
<?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.bjwykj</groupId>
<artifactId>bjwykj-springboot</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>l.8</java.version>
<mybatisplus.version>3.3.2</mybatisplus.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入Spring Boot依赖构件spring-boot-starter-jdbc,自动帮我们配置JDBC-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--引入数据库mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--引入mybatis plus启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!--引入简化实体类开发的lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</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>
在基础信息部分,groupId和artifactId对应生成项目时页面上输入的内容。另外,我们还可以注意到,打包形式为 jar:<packaging>jar</packaging>, 正如我们之前所介绍的,Spring Boot默认将该Web应用打包为jar的形式, 而非war的形式,因为默认的Web模块依赖会包含嵌入式的Tomcat , 这样使得我们的应用jar自身就具备了提供Web服务的能力。
父项目parent配置指定为spring-boot-starter-parent的2.3.2.RELEASE版本,该父项目中定义了Spring Boot版本的基础依赖以及 一 些默认配置内容 ,比如,配置文件application.properties的位置等。
在项目依赖dependencies配置中,包含了下面两项。
• spring-boot-starter-web: 全栈Web开发模块,包含嵌入式Tomcat、Spring MVC。
• spring-boot-starter-test: 通用测试模块,包含JUnit、Hamcrest、Mockito。
这里所引用的web和test模块,在Spring Boot生态中被称为Starter POMs。Starter POMs是一系列轻便的依赖 包,是一套一站式的Spring相关技术的解决方案。开发者在使用和整合模块时,不必再去搜寻样例代码中的依赖配置来复制使用,只需要引入对应的模块包即可 。比如,开发Web应用的时候,就引入spring-boot-starter-web, 希望应用具备访问数据库能力的时候,那就再引入spring-boot-starter-jdbc或是更好用的spring-boot-starter-data-jpa。在使用Spring Boot构建应用的时候,各项功能模块的整合不再像传统Spring应用的开发方式那样,需要在 pom.xml中做大量的依赖配置,而是通过使用Starter POMs定义的依赖包,使得功能模块整合变得非常轻巧,易于理解与使用。
项目构建的build部分,引入了Spring Boot的Maven插件,该插件非常实用,可以帮助我们方便地启停应用,这样在开发时就不用每次去找主类或是打包成jar来运行微服务,只需要通过mvn spring-boot:run命令就可以快速启动Spring Boot应用。
3、实现RESTful API
在Spring Boot中创建一个RESTful API的实现代码同Spring MVC应用一样,只是不需要像Spring MVC那样先做很多配置,因为现在前后端分离,所以使用JSON作为前后端交互已经十分普遍。Spring MVC在支持REST风格中还存在一个注解@RestController,通过它将控制器返回的对象转化为JSON数据集。
配置文件:
java
spring:
datasource:
url: jdbc:mysql://localhost:3306/bjwykjssm?useUnicode=true&characterEncoding=utf8
username: root
password:
driver-class-name: com.mysql.jdbc.Driver
hikari:
idle-timeout:60000
maximum-pool-size:30
minimum-idle:10
创建启动类:
java
@SpringBootApplication
@MapperScan("com.bjwykj.mapper")
public class SBApplication {
public static void main(String[] args) {
SpringApplication.run(SBApplication.class, args);
}
}
创建实体类:
java
@Data
@TableName("t_product")
public class Product {
@TableId(type = IdType.AUTO)
private Long id;
private String productname;
private double price;
private String picture;
}
创建DAO层接口ProductMapper:
java
public interface ProductMapper extends BaseMapper<Product> {
}
业务逻辑层:
java
@Service
public class ProductService {
@Autowired
private ProductMapper productMapper;
public Product getProductById(Integer id) {
Product product = productMapper.selectById(id);
return product;
}
}
这里采用注解@GetMapping声明HTTP的GET请求,并且把参数编号(id)以URI的形式传递,这符合REST风格要求。在getProductById方法中使用了注解@PathVariable从URI中获取参数,而控制器标注@RestController则REST的表现层则为JSON数据集。
控制器层:
java
@RestController
public class SpringBootDemoController {
@Autowired
private ProductService productService;
@RequestMapping("/restful")
public String getResult(){
return "SpingBoot RestController";
}
@GetMapping(value = "/product/{id}")
public Product getProductById(@PathVariable("id") Integer id){
Product product = productService.getProductById(id);
return product;
}
}
启动该应用,通过浏览器访问http://localhost:8080/product/6, 我们可以看到返回了预期结果。
编写单元测试:功能实现之后,我们要养成随手写配套单元测试的习惯,这在微服务架构中尤为重要。通常,我们实施微服务架构的时候,已经实现了前后端分离的项目与架构部署。那么在实现后端服务的时候,单元测试是在开发过程中用来验证代码正确性非常好的手段,并且这些单元测试将会很好地支持我们未来可能会进行的重构。
java
//设置SpringBoot测试启动器
@RunWith(SpringRunner.class)
//加载SpringBoot测试环境
@SpringBootTest
public class SBApplicationTests {
@Autowired
private ProductMapper productMapper;
@Test
public void testRestful(){
Product product = productMapper.selectById("6");
System.out.println(product);
}
}
注解@Test定义测试用例testRestful。
三、服务治理Nacos
Nacos⼀个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。是阿里巴巴中间件部门开发的新⼀代集服务注册发现中心和配置中心为⼀体的中间件。它是构建以"服务"为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施,支持几乎所有主流类型的"服务"的发现、配置和管理,更敏捷和容易地构建、交付和管理微服务平台。