简介
Spring Cloud 提供了一个部署微服务的平台, 包括了微服务中常见的组件: 配置中心服务, API 网关, 断路器, 服务注册与发现, 分布式追溯, OAuth2, 消费者驱动合约等. 我们不必先知道每个组件有什么作用, 随着教程的深入, 我们会逐渐接触到它们. 一个分布式服务大体结构见下图(图片来自于: https://spring.io/):
使用 Spring Cloud 搭建分布式的系统十分简单, 我们只需要几行简单的配置就能启动一系列的组件, 然后可以在代码中控制, 使用和管理这些组件. Spring Cloud 使用 Spring Boot 作为基础框架, 可以参考我的上一篇博客介绍如何创建一个 Spring Boot 项目, Spring Boot 2.0.1 入门教程 http://www.zxuqian.cn/spring-boot-get-started/ . 本教程将教大家如何配置服务中心服务, 并通过 web 客户端读取配置.
基础环境
- JDK 1.8
- Maven 3.3.9
- IntelliJ 2018.1
- Git
项目源码
Gitee 码云 https://gitee.com/zxuqian/spring-cloud
创建 Web Client
首先用 IntelliJ 创建一个 Maven 项目, 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>cn.zxuqian</groupId>
- <artifactId>web</artifactId>
- <version>1.0-SNAPSHOT</version>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.0.1.RELEASE</version>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-config</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-web</artifactId>
- </dependency>
- </dependencies>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>Finchley.M9</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- <properties>
- <java.version>1.8</java.version>
- </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- <repositories>
- <repository>
- <id>spring-milestones</id>
- <name>Spring Milestones</name>
- <url>https://repo.spring.io/libs-milestone</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
- </project>
- dependencyManagement
可以为所有的依赖指定统一的版本号, 这里的 Spring-cloud 依赖版本均为 Finchley.M9, 然后使用 repository 指定此版本的仓库.
spring-cloud-starter-config
提供了访问配置中心服务的 API 接口.
添加控制器
新建一个控制器类
cn.zxuqian.controllers.HelloController
, 并添加如下代码:
- package cn.zxuqian.controllers;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.cloud.context.config.annotation.RefreshScope;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RefreshScope
- @RestController
- public class HelloController {
- @Value("${message: 本地消息}")
- private String message;
- @RequestMapping("/message")
- public String message() {
- return this.message;
- }
- }
一个简单的控制器, 匹配 / message 路径, 并返回 message 变量的值. 这里先不用管 @RefreshScope 这个注解, 等下会用到时再讲.@Value 会取来自配置中心服务的配置项, 或本地环境变量等等, 此处取了配置中心的 message 的值, 并给了它一个默认值 "本地消息", 即如果远程配置中心不可用时, 此变量将会用默认值初始化.
添加配置文件
bootstrap.xml
我们需要在 web 客户端项目完全启动之前去加载配置中心的配置项, 所以需要在 src/main/resources 下创建 bootstrap.yml 文件, 然后指定此客户端的名字和远程配置中心的 uri:
- spring:
- application:
- name: web-client
- cloud:
- config:
- uri: http://localhost:8888
yml 相比 properties 文件更加简洁, 不用写很多重复的前缀, 上边的内容可以转换为对应的 properties:
- spring.application.name=web-client
- spring.cloud.config.uri=http://localhost:8888
- spring.application.name
指定了此项目的名字, 用来取配置中心相同文件名的配置文件, 即配置中心应有一文件名为 web-client.yml 的配置文件.
spring.cloud.config.uri
指定了远程配置中心服务的 uri 地址, 默认为 http://localhost:8888/
创建配置中心项目
新建一个 Maven 项目, 使用如下 pom 配置:
- <?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>cn.zxuqian</groupId>
- <artifactId>config-server</artifactId>
- <version>1.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.0.1.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <java.version>1.8</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-config-server</artifactId>
- </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>Finchley.M9</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-milestones</id>
- <name>Spring Milestones</name>
- <url>https://repo.spring.io/libs-milestone</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
- </project>
- spring-cloud-config-server
即为配置中心服务的核心依赖.
配置 Application
新建一个 Java 类
cn.zxuqian.Application
, 添加如下代码:
- package cn.zxuqian;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cloud.config.server.EnableConfigServer;
- @EnableConfigServer
- @SpringBootApplication
- public class Application {
- public static void main(String[] args) {
- SpringApplication.run(Application.class, args);
- }
- }
使用 @EnableConfigServer 这一条注解即可把该 Maven 项目作为配置中心服务启动.
新建 Git 仓库
配置中心的文件都是基于版本控制的, 所以需要在本地新建一个 git 仓库来保存配置文件. 或者也可用公共远程 git 仓库, github, 码云等. 在任意位置 (如项目的上级目录) 创建一空白文件夹, 这里叫做 config, 可以使用任何名字. 然后进入此文件夹下, 运行
$ git init
来初始化 git 仓库, 然后新建一个文件, 名为 web-client.yml, 并添加如下内容:
message: 此条消息来自于 cofig server
注意此文件名需要和之前在 web 项目中配置的
spring.application.name
保持一致. 这个文件的内容就是 web 客户端要获取的 message 的值. 创建完成之后, 运行如下 git 命令提交到本地仓库:
$ git add web-client.yml
$ git commit -m "added web-client.yml"
配置 git 仓库位置
我们需要为配置中心指定上述创建的 git 仓库地址. 在 src/main/resources 下创建 applicaiton.yml 文件, 提供如下内容:
- server:
- port: 8888
- spring:
- cloud:
- config:
- server:
- git:
- uri: ${HOME}/development/codes/backend/gitee/config
此文件指定了配置中心服务的端口号, 和保存配置文件的 git 仓库目录, 如果是远程仓库, 可以直接指定 url 地址. 到此, 配置中心服务创建完成.
测试
首先启动配置中心服务, 使用 spring-boot maven 插件: spring-boot:run. 启动成功后再启动 web 客户端, 访问
http://localhost:8080/message
, 如果看到
此条消息来自于 cofig server
即配置成功. 然后关闭配置中心服务, 再重启 web 客户端, 访问
http://localhost:8080/message
, 我们就会看到本地消息.
动态更新配置
那么每次配置更新后都要重启是不是很麻烦? Spring boot 提供了
spring-boot-starter-actuator
组件, 用来进行生产环境的维护, 如检查健康信息等. 还记得上面 HelloController 的 @RefreshScope 注解吗? 使用它我们可以动态的加载配置中心修改后的配置. 然后我们还需要在配置中心的 web-client.yml 添加如下内容用以暴露 acurator 的 / refresh 终端 api.
message: 此条消息来自于 cofig server
- management:
- endpoints:
- web:
- exposure:
- include: "*"
更新完成后提交的 git 仓库, 然后重启配置中心服务和 web 客户端. 修改 message 为
message: 更新: 此条消息来自于 cofig server
然后发送一个空的 post 请求到 / refresh
$ curl http://localhost:8080/actuator/refresh -d {} -H "Content-Type: application/json"
之后刷新页面, 即可看到更新后的消息.
总结
现在我们搭建好了一个配置中心服务, 它是根据每个组件的
spring.application.name
来决定读取哪个配置文件, 然后我们用了 acurator 的 / refreshapi 在运行时刷新配置项. 另外配置项都是基于版本控制的, 可以方便的进行还原和更新. 通过这个教程可以看到 Spring Cloud 的各组件的配置相当简单, 基本就只用一条注解就可以创建一个完整的服务组件.
来源: http://blog.51cto.com/13727459/2110639