最近学习了一些Spring Cloud微服务相关的知识,利用一个Spring Cloud微服务的实例demo来练习巩固一下Spring Cloud的相关知识。
1. 微服务模块划分
该微服务系统采用maven的多module工程的结构,一共有 10 个 module 工程。其中有 9 个 module 工程为微服务工程,这 9 个微服务工程构成了一个完整的微服务系统。微服务系统包含了 7 个微服务系统的基础服务,它们分别是配置中心 config-server、注册中心 eureka-server、授权中心 uaa 服务 uaa-service、turbine 聚合监控服务 monitor-service、聚合监控服务 admin-service、路由网关服务 gateway-service、日志服务 log-service。另外还包含了 2 个资源服务 user-service 和 blog-service,对外暴露 API 接口。最后还有一个链路工程,使用 Jar 包的形式启动;一个 common 的 module 工程,为资源服务器提供基本的工具类。
SpringCloudAction工程为父工程,主要负责管理spring cloud版本和spring boot版本之间的关系以及一些公共依赖,此处spring boot选用2.1.0.RELEASE,spring cloud选用Greenwich.RELEASE。
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>top.picacho</groupId>
<artifactId>SpringCloudInAction</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<!-- 此处添加子模块-->
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.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>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- jolokia 是一个利用 JSON 通过 http 实现 JMX 远程管理的开源组件-->
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</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>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
应用名 | 端口 |
---|---|
eureka-server:服务注册中心 | 8761 |
config-server:配置中心 | 8762 |
admin-service:聚合监控服务 | 8763 |
gateway-service:路由网关 | 8764 |
monitor-service:Turbine聚合监控服务 | 8765 |
uaa-service:授权服务 | 8766 |
user-service:user资源服务 | 8767 |
blog-service:blog资源服务 | 8768 |
log-service:日志服务 | 8769 |
zipkin-service:链路追踪服务 | 8770 |
微服务的架构图:
gateway-service 为网关服务,使用的是 Zuul 组件,Zuul 组件可以实现智能路由、负载均衡的功能。gateway-service 作为一个边界服务,对外统一暴露 API 接口,其他的服务 API 接口只提供给内部服务调用,不提供给外界直接调用,这就很方便实现统一鉴权、安全验证的功能。有些同学可能会有疑惑,为什么在自己的电脑上运行微服务系统时可以直接访问内部微服务的 API 端口呢?这需要设置网络环境,例如配置防火墙,只允许外部请求访问微服务系统的 gateway-service 服务端口,其他的端口不对外开放。另外,可以通过 Docker 部署微服务,由于 Docker 采用沙盒原理,可以实现只允许内部服务调用,同时只暴露 gateway-service 服务的端口给外部调用。
turbine-service 聚合了 user-service 和 blog-service 的 Hystrix Dashboard,可以查看这两个服务熔断器的监控状况。
admin-service 是一个 Spring Boot Admin Server 工程,提供了非常强大的服务监控功能,可以查看每个向 eureka-server 注册的服务的健康状态、日志、注册时间线等,并能够集成 Turbine。
uaa-service 集成了 Spring Cloud OAuth2,由这个服务统一鉴权,并返回 Token。其他的应用服务,例如 user-service 和 blog-service 作为资源服务,它们的 API 接口资源是受保护的,需要验证 Token,并鉴权后才能访问。
user-service 和 blog-service 作为资源服务,对外暴露 API 接口资源。
log-service 为日志服务,user-service 和 blog-service 服务通过 RabbitMQ 向 log-service 发送业务操作日志的消息,日志服务统一持久化操作日志。该日志服务只持久化资源操作的日志,如 API 接口的请求。如果有大量的日志需处理,可以使用 ELK 组件进行处理。
2.common模块
添加子模块common模块,提供给其他模块使用的公共类,被其他子模块所依赖,并不作为微服务运行。
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>top.picacho</groupId>
<artifactId>SpringCloudInAction</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>top.picacho</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>common</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- RespDTO:服务端响应的数据包装类。存放请求的响应信息。
com.forezp.exception.CommonException:工程自定义的业务逻辑异常,与 ErrorCode 搭配使用。
com.forezp.exception.ErrorCode:自定义的业务逻辑错误代码枚举类。
本案例采用了 AOP 的方式进行实现。通过自定义注解 @SysLogger,然后写一个 AOP 切面,拦截被 @SysLogger 注解修饰的方法,提取方法中的信息,再通过 log-service 发送,这样做的好处就是业务代码和发送日志的代码进行了松耦合。在 com/forezp/annotation 包下,新建 SysLogger 注解