基于《spring boot 实战》的微服务架构 三.建立一个提供项目配置信息的微服务项目
为了确保提供的每个新服务实例与生产环境的所有其他服务实例具有相同的配置和代码库即微服务项目的可重复性.
1.项目的配置管理
将应用的配置数据直接写入代码中会导致每次修改配置,都必须重新编译项目并部署.为了避免这种情况,我们将配置信息与应用程序分离.这样就可以很容易地在不进行重新编译的情况下对配置进行更改,也可以方便地看到项目的所有配置. 但是这样也会引起项目的复杂性,因为会存在另一个需要与应用程序一起管理和部署的配置信息.
一般地,我们将配置信息保存在xml,json,yml,properties(由java提供的一种文件格式) 等属性文件来存储配置信息.将这份属性文件保存在服务器上,通常包含数据库和中间件连接信息,以及驱动应用程序行为的相应元数据.
对于拆分成少量微服务项目的应用程序使用如下方案即可方便地管理配置信息(要求parent与common添加到本地maven库中)

但是在处理包含数百个微服务的基于云的应用程序时,其中每个微服务可能会运行多个服务实例时,就比较困难了.在微服务项目中配置管理就变成了一个重大的事情,因为在基于云的环境中,应用程序和运维团队必须与配置文件的"鼠潮"进行斗争.基于云的微服务开发强调以下几点.
a. 应用程序的配置与正在运行的实际代码完全分离.
b.构建服务器,应用程序以及一个不可点的镜像,它们在任何环境中进行提升时永远不会发生变化.
c.在服务器启动时通过环境变量注入配置信息,或者在微服务项目启动时通过集中式存储库读取应用程序配置信息.
2.管理配置
通过建立要遵循的4条原则:
(1) 分离----服务配置信息与服务的实际物理部署完全分开.在服务器启动时通过环境变量注入配置信息,或者在微服务项目启动时通过集中式存储库读取应用程序配置信息.
(2) 抽象----将访问配置数据的功能抽象到一个服务接口中,应用程序基于REST的JSON服务来检索配置数据,而不是编写直接访问服务存储库的代码(也就是使用JDBC从数据库读取数据).
(3) 集中----因为基于云的应用程序可能会有数百个服务,所以最小化用于保存配置信息的不同存储库的数量至关重要.将应用程序配置集中在尽可能少的存储库中.
(4) 稳定----因为应用程序的配置信息与部署的服务完全隔离并集中存放,所以不管采用何种方案实现,至关重要的一点就是保证其高可用和冗余.
要记住一个关键点,降配置信息与实际代码分开后,开发人员将创建一个需要管理和版本控制的外部依赖项.
3.可以实现的技术
a.Etcd 由go开发的开源项目,用于服务发现和键值管理,使用raft协议作为它的分布式计算模型
特点: 非常快和可伸缩 可分布式 命令行驱动 易于搭建和使用
b.Erueka 有Netflix开发.久经测试,用于服务发现和键值管理
特点: 分布式键值存储 灵活,需要费些功夫去设置 提供开箱即用的动态客户端刷新
c.Consul 由Hashicop开发,特征上类似于Etcd和Eureka,它的分布式计算模型使用了不同的算法(SWIM协议)
特点: 快速 提供本地服务发现功能,可直接与DNS集成 没有提供开箱即用的动态客户端刷新
d.ZooKeeper 提供分布式锁定功能的Apache项目,经常用作访问键值数据的配置管理解决方案
特点: 最古老,最久经测试的解决方案 使用最为负责 可用作配置管理,但只有在其他框架中已使用了ZooKeeper的时候才考虑使用
e.Spring Cloud Config 一个开源项目,提供不同后端支持的通用配置管理解决方案.它可以将Git,Eureka和Consul作为后端进行整合
特点: 非分布式键值存储 提供了对Spring和Spring服务的紧密集成 可以使用多个后端来存储配置数据,包括共享文件系统,Eureka,Consul和Git
4.选择使用 Spring Cloud Config 服务器原因
(1) Spring Cloud Config 服务器易于搭建和使用
(2) Spring Cloud Config 和 spring Boot 紧密集成. 可以使用一些简单易用的注解来读取应用程序的配置数据.
(3) Spring Cloud Config 服务器提供多个后端用于存储配置数据.适配的情况下,可以直接插入Spring Cloud Config 服务器中.
(4) 其他工具不提供任何类型的原生版本控制,如果想要版本控制的话,就必须自己去建立它. 如果我们使用Git,那么使用 Spring Cloud Config 与 Git 的继承消除了解决方案的额外依赖,并可以实现版本化应用程序配置数据
5.构建 Spring Cloud config 微服务项目
(1), 为 Spring Cloud config 微服务项目创建 pom.xml
其中 微服务通用的依赖项: spring-boot-starter-parent,spring-cloud-dependencies
Spring Cloud 配置服务器专用的依赖项: spring-cloud-starter-config,spring-cloud-config-server
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <project xmlns="http://maven.apache.org/POM/4.0.0" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 6 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 7 <modelVersion>4.0.0</modelVersion> 8 9 <groupId>com.throughtmechanix</groupId> 10 <artifactId>configurationserver</artifactId> 11 <version>1.0.0</version> 12 <packaging>jar</packaging> 13 14 <name>configurationserver</name> 15 <description>Config Server demo project</description> 16 17 <parent> 18 <!-- spring boot 项目版本 --> 19 <groupId>org.springframework.boot</groupId> 20 <artifactId>spring-boot-starter-parent</artifactId> 21 <version>2.3.12.RELEASE</version> 22 </parent> 23 24 <properties> 25 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 26 <maven.compiler.source>1.8</maven.compiler.source> 27 <maven.compiler.target>1.8</maven.compiler.target> 28 29 <!-- Spring Cloud Config 信息 --> 30 <start-class>com.throughtmechanix.confsvr.ConfigServerApplication</start-class> 31 <java.version>1.8</java.version> 32 <docker.image.name>johncarnell/tmx-confsvr</docker.image.name> 33 <docker.image.tag>chapter3</docker.image.tag> 34 35 <!-- 依赖版本信息 --> 36 <!-- spring cloud 版本应该在spring cloud 官网确认与 spring boot 版本适配 --> 37 <spring.cloud-version>Hoxton.SR12</spring.cloud-version> 38 </properties> 39 40 <dependencies> 41 <!-- 在这个特定项目中将要使用的 Spring Cloud 项目 --> 42 <dependency> 43 <groupId>org.springframework.cloud</groupId> 44 <artifactId>spring-cloud-starter-config</artifactId> 45 <!-- 使用这个项目配置的项目都需要这个依赖项 --> 46 </dependency> 47 48 <dependency> 49 <groupId>org.springframework.cloud</groupId> 50 <artifactId>spring-cloud-config-server</artifactId> 51 </dependency> 52 </dependencies> 53 54 <!-- 55 spring cloud 依赖项,用于架构微服务项目.版本需要在 spring cloud 官网确认与 spring boot 的版本相适配 56 <scope></scope>中import 作用是添加的其他 spring cloud 相关依赖版本可不自行指定,由spring cloud自动添加 57 --> 58 <dependencyManagement> 59 <dependencies> 60 <dependency> 61 <groupId>org.springframework.cloud</groupId> 62 <artifactId>spring-cloud-dependencies</artifactId> 63 <version>${spring.cloud-version}</version> 64 <type>pom</type> 65 <scope>import</scope> 66 </dependency> 67 </dependencies> 68 </dependencyManagement> 69 70 <build> 71 <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> 72 <plugins> 73 <!-- 配置 Spring Boot Maven Plugin 依赖用于打包 [BEGIN] --> 74 <plugin> 75 <groupId>org.springframework.boot</groupId> 76 <artifactId>spring-boot-maven-plugin</artifactId> 85 <executions> 86 <execution> 87 <goals> 88 <goal>repackage</goal> 89 </goals> 90 </execution> 91 </executions> 92 </plugin> 93 <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --> 94 <plugin> 95 <artifactId>maven-clean-plugin</artifactId> 96 <version>3.1.0</version> 97 </plugin> 98 <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> 99 <plugin> 100 <artifactId>maven-resources-plugin</artifactId> 101 <version>3.0.2</version> 102 </plugin> 103 <plugin> 104 <artifactId>maven-compiler-plugin</artifactId> 105 <version>3.8.0</version> 106 </plugin> 107 <plugin> 108 <artifactId>maven-surefire-plugin</artifactId> 109 <version>2.22.1</version> 110 </plugin> 111 <plugin> 112 <artifactId>maven-jar-plugin</artifactId> 113 <version>3.0.2</version> 114 </plugin> 115 <plugin> 116 <artifactId>maven-install-plugin</artifactId> 117 <version>2.5.2</version> 118 </plugin> 119 <plugin> 120 <artifactId>maven-deploy-plugin</artifactId> 121 <version>2.8.2</version> 122 </plugin> 123 <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --> 124 <plugin> 125 <artifactId>maven-site-plugin</artifactId> 126 <version>3.7.1</version> 127 </plugin> 128 <plugin> 129 <artifactId>maven-project-info-reports-plugin</artifactId> 130 <version>3.0.0</version> 131 </plugin> 132 </plugins> 133 </pluginManagement> 134 </build> 135 </project>
(2),配置 application.yml.使用带有本地文件系统的Spring Cloud Config 微服务项目
1 server: 2 #### Spring Cloud 配置服务器将要监听的端口 3 port: 6666 4 spring: 5 profiles: 6 #### 因为我们正在使用文件系统来储存应用配置信息,所以告诉Spring Cloud 配置服务器 我们将以"native" profile 运行 7 active: native 8 cloud: 9 config: 10 #### 为 Spring Cloud 配置提供应用数据所在的文件目录: 11 server: 12 native: 13 #### git方式 spring 不要配置 spring.profiles.active:native 14 #### server.git.uri: https://gitee.com/bugzeroman/spring-cloud-config.git 15 #### 本地类路径策略 classpath:com/throughtmechanix/confsvr 16 search-locations: classpath:/config/licensingservice 17 #### 本地文件策略 file:///(widonws下前有一个转义字符,所以是三个. linux下 不需要转义字符一个即可) 18 ##search-locations: file:///F:/newplace/configurationserver/src/main/resources/config/licensingservice,file:///F:/newplace/configurationserver/src/main/resources/config/myserver
a.具体请参考:https://www.cnblogs.com/zh9311/p/14246816.html
由 不可、结缘 所写的配置信息说明较为详细
b.要设置 spring.profiles.active:native 让这个config项目以 "native" profiles 运行, 读取本地文件. 可以在文件策略中写多个文件位置.
因为我的项目使用的类路径 classpath:/config/licensingservice,所以要创建对应的文件结构

c.这个spring boot config 项目会因为浏览器的安全验证等原因无法访问,所以请使用 postman 等工具测试

d.在uri licensingservice/default 会去配置的文件位置 classpath:/config/licensingservice 中读取 licensingserver.yml
licensingservice/dev 会去配置的文件位置 classpath:/config/licensingservice 中读取 licensingserver-dev.yml 和licensingservice.yml
测试url http://localhost:6666/licensingservice/default
1 { 2 "name": "licensingservice", 3 "profiles": [ 4 "default" 5 ], 6 "label": null, 7 "version": null, 8 "state": null, 9 "propertySources": [ 10 { 11 "name": "classpath:/config/licensingservice/licensingservice.yml", 12 "source": { 13 "tracer.property": "I AM THE DEFAULT", 14 "spring.jpa.database": "POSTGRESQL", 15 "spring.jpa.show-sql": true, 16 "spring.jpa.properties.hibernate.dialect": "org.hibernate.dialect.PostgreSQLDialecte", 17 "spring.datasource.driver-class-name": "com.mysql.cj.jdbc.Driver", 18 "spring.datasource.url": "jdbc:mysql://localhost:3306/postgresql?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true", 19 "spring.datasource.data-username": "root", 20 "spring.datasource.password": "15610570603wh", 21 "spring.datasource.type": "com.alibaba.druid.pool.DruidDataSource", 22 "spring.datasource.druid.min-idle": 3, 23 "spring.datasource.druid.max-active": 15, 24 "spring.datasource.druid.initial-size": 5, 25 "spring.datasource.druid.min-evictable-idle-time-millis": 30000, 26 "spring.datasource.druid.max-evictable-idle-time-millis": 60000, 27 "spring.datasource.druid.web-stat-filter.exclusions": "*.js,*.gif,*.jpg,/*.css,*.ico,/druid/*", 28 "spring.datasource.druid.web-stat-filter.enabled": true, 29 "spring.datasource.druid.web-stat-filter.url-pattern": "/*", 30 "spring.datasource.druid.stat-view-servlet.enabled": true, 31 "spring.datasource.druid.stat-view-servlet.url-pattern": "/druid/*", 32 "spring.datasource.druid.stat-view-servlet.allow": "127.0.0.1", 33 "spring.datasource.druid.stat-view-servlet.login-username": "druid", 34 "spring.datasource.druid.stat-view-servlet.login-password": 123456, 35 "spring.datasource.druid.stat-view-servlet.reset-enable": false 36 } 37 } 38 ] 39 }
测试url http://localhost:6666/licensingservice/dev
获取 licensingservice-dev.yml的同时时, 也会获得 licensingservice.yml
1 { 2 "name": "licensingservice", 3 "profiles": [ 4 "dev" 5 ], 6 "label": null, 7 "version": null, 8 "state": null, 9 "propertySources": [ 10 { 11 "name": "classpath:/config/licensingservice/licensingservice-dev.yml", 12 "source": { 13 "tracer.property": "I AM THE DEV" 14 } 15 }, 16 { 17 "name": "classpath:/config/licensingservice/licensingservice.yml", 18 "source": { 19 "tracer.property": "I AM THE DEFAULT", 20 "spring.jpa.database": "POSTGRESQL", 21 "spring.jpa.show-sql": true, 22 "spring.jpa.properties.hibernate.dialect": "org.hibernate.dialect.PostgreSQLDialecte", 23 "spring.datasource.driver-class-name": "com.mysql.cj.jdbc.Driver", 24 "spring.datasource.url": "jdbc:mysql://localhost:3306/postgresql?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true", 25 "spring.datasource.data-username": "root", 26 "spring.datasource.password": "15610570603wh", 27 "spring.datasource.type": "com.alibaba.druid.pool.DruidDataSource", 28 "spring.datasource.druid.min-idle": 3, 29 "spring.datasource.druid.max-active": 15, 30 "spring.datasource.druid.initial-size": 5, 31 "spring.datasource.druid.min-evictable-idle-time-millis": 30000, 32 "spring.datasource.druid.max-evictable-idle-time-millis": 60000, 33 "spring.datasource.druid.web-stat-filter.exclusions": "*.js,*.gif,*.jpg,/*.css,*.ico,/druid/*", 34 "spring.datasource.druid.web-stat-filter.enabled": true, 35 "spring.datasource.druid.web-stat-filter.url-pattern": "/*", 36 "spring.datasource.druid.stat-view-servlet.enabled": true, 37 "spring.datasource.druid.stat-view-servlet.url-pattern": "/druid/*", 38 "spring.datasource.druid.stat-view-servlet.allow": "127.0.0.1", 39 "spring.datasource.druid.stat-view-servlet.login-username": "druid", 40 "spring.datasource.druid.stat-view-servlet.login-password": 123456, 41 "spring.datasource.druid.stat-view-servlet.reset-enable": false 42 } 43 } 44 ] 45 }
下载代码:
链接:https://pan.baidu.com/s/1_ujFNwtNpzdzGzb112Jw6g?pwd=fb4z
提取码:fb4z
浙公网安备 33010602011771号