一、引言
1、什么是SpringCloud
SpringCloud是一套微服务开发一站式解决方案,它提供了微服务开发所需要的很多功能组件,比如服务统一管理、配置统一管理、路由网关、断路器、事件总线、集群状态配置等等。而且SpringCloud与SpringBoot无缝衔接,配合SpringBoot能够更轻松的搭建出一套微服务架构平台。
2、什么是微服务
微服务其实是一种架构的设计风格,并没有明确的技术绑定和架构概念。简单来说,微服务架构风格其实就是将原来的单一架构开发为一组小型服务(微服务)的方法,每个服务都运行在自己独立的进程中(服务间的隔离),服务间采用轻量级的通讯机制(HTTP、RPC - Netty、WebService),这些服务按照业务拆分,并且独立部署(自动化部署)。服务会由一个统一的管理中心管理(Zookeeper、Eureka、Nacos),服务可以采用不同的语言开发,并且使用不同的存储技术(数据库垂直拆分)。
二、服务的注册与发现 - Eureka
问题:为什么需要注册中心?
如果没有注册中心,服务和服务之间会形成硬耦合状态
注册中心的作用就是为了减少服务间的调用耦合
1、Eureka 对比 Zookeeper
2、Eureka服务端的搭建
2.1 配置自定义的父工程(继承SpringBoot、SpringCloud)
pom.xml
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.qf</groupId>
<artifactId>springcloud_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- <name>springcloud_demo</name>
<description>Demo project for Spring Boot</description>-->
<!--
SpringBoot 2.1.x <-> SpringCloud版本 G版
SpringBoot 2.2.x <-> SpringCloud版本 H版
-->
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR5</spring-cloud.version>
</properties>
<!-- 删除
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>-->
<!-- 相当于让当前的工程继承了SpringCloud的父工程,用这种方式可以实现Maven的多继承 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<!-- 导入pom工程,相当于多继承 -->
<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>-->
</project>
2.2 创建Eureka服务
1)创建一个Maven工程(Eureka微服务),继承自定义的父工程(springcloud_demo)
2)修改当前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">
<parent>
<artifactId>springcloud_demo</artifactId>
<groupId>com.qf</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud_eureka</artifactId>
<dependencies>
<!-- 必须到包含starter的依赖包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3)配置当前springboot的启动类
package com.qf.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
//添加注解
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
//run的第一个参数一定是添加了@SpringBootApplication注解的类
//不是当前类
SpringApplication.run(EurekaServerApplication.class, args);
}
}
4)配置application.yml - 没有就手动创建
server:
port: 20000
spring:
application:
#配置微服务的名称,以后所有的微服务,都必须配置这个属性,不然注册中心的名字会变成unable
name: eureka-server
#配置eureka的相关属性
eureka:
client:
service-url:
#配置eureka的注册地址
#defaultZone没有提示,必须手写
defaultZone: http://localhost:20000/eureka
#当前的微服务就是注册中心,注册中心不能从注册中心抓取服务,所以该配置需要配置成false
fetch-registry: false
#使得当前的微服务不注册到注册中心上
register-with-eureka: false
5)启动SpringBoot工程 - 启动Eureka服务端
6)访问注册中心,http://localhost:20000
3、微服务(Eureka客户端)的搭建
3.1 Eureka客户端的搭建
1)创建一个Maven工程,继承springcloud_demo工程
2)配置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">
<parent>
<artifactId>springcloud_demo</artifactId>
<groupId>com.qf</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud_mircoservice_student</artifactId>
<dependencies>
<!-- 微服务需要对外提供功能,所以需要添加web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 同时为了能够让微服务注册到注册中心之上 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
3)配置启动类
@SpringBootApplication
//SpringCloud 2.x之后 该注解可以省略
@EnableEurekaClient
public class StudentApplication {
public static void main(String[] args) {
SpringApplication.run(StudentApplication.class, args);
}
}
4)配置application.yml
server:
port: 8080
#微服务的名字
spring:
application:
#微服务的名字一定不要用下划线
name: micro-student
eureka:
client:
service-url:
#配置注册中心的地址,因为微服务需要注册,也需要抓取服务所以另外两个配置就可以省略了
defaultZone: http://localhost:20000/eureka
5)编写微服务的功能接口(根据微服务本身的业务不同,编写不同的接口)
package com.qf.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/stu")
public class StuController {
/**
* 根据学生id查询学生姓名
*
* @ResponseBody -> 返回json (错误)
*
* @ResponseBody -> 将方法的返回值,放入response响应体中
*
* 响应体 -> 数值、字符串(json)、二进制流....
*
* @param sid
* @return
*/
@RequestMapping("/queryName")
public String getNameById(Integer sid){
switch (sid){
case 1:
return "小明";
case 2:
return "小红";
case 3:
return "小刚";
default:
return "查无此人";
}
}
}
4、Eureka的集群
4.1 eureka集群的工作模式
4.2 Eureka集群的搭建(伪集群)
1)将eureka服务端复制2份
2)修改eureka服务的端口(因为是伪集群,在一台机器上,需要修改端口)
3)找到本机的hosts文件(C:\Windows\System32\drivers\etc\hosts),分别给本机设置3个主机名
注意:第一次修改hosts文件,一般没有权限,所以需要修改下文件权限,如何修改文件权限,自行百度
4)修改3个eureka服务的service-url配置
#配置eureka的相关属性
eureka:
client:
service-url:
#配置eureka的注册地址
#defaultZone没有提示,必须手写
defaultZone: http://eureka1:20000/eureka,http://eureka2:20001/eureka,http://eureka3:20002/eureka
#当前的微服务就是注册中心,注册中心不能从注册中心抓取服务,所以该配置需要配置成false
fetch-registry: false
#使得当前的微服务不注册到注册中心上
register-with-eureka: false
5)启动三台eureka服务
6)所有的微服务的注册地址必须改成eureka集群的地址
eureka:
client:
service-url:
#配置注册中心的地址,因为微服务需要注册,也需要抓取服务所以另外两个配置就可以省略了
defaultZone: http://eureka1:20000/eureka,http://eureka2:20001/eureka,http://eureka3:20002/eureka
5、Eureka的自我保护机制
5.1 什么是Eureka的自我保护机制?
Eureka如果收到的微服务心跳相对于应该收到的微服务心跳来说,如果低于了85%,那么就会触发Eureka的自我保护机制。一旦自我保护机制启动,Eureka会保护所有的微服务,不被移除,哪怕当前微服务已经下线,仍然会保留到Eureka微服务列表中。
5.2 Eureka自我保护机制触发后的表现
5.3 自我保护机制的作用
为什么Eureka要一种看起来如此傻逼的设计?- 自我保护机制是为了保证微服务间的高可用性,避免脑裂的影响
为什么Zookeeper要设计一个过半数存活原则?感觉特别浪费资源? - 为了让整个集群一定只有一个Leader
CAP原则:任何一个分布式系统,都只能满足CAP中的2个原则,因为分区问题不可避免,所以P是必选的,一般的系统,都是从C和A中做选择。Zookeeper是CP设计,而Eureka是AP设计。
C(一致性)
A(可用性)
P(分区容错性)
zookeeper的过半数存活的设计
Eureka的自我保护设计
思考:Eureka的自我保护机制,虽然是为了保证服务的高可用,但是如果服务真的挂掉了?那么也被自我保护起来,是不是有问题呢?
自我保护机制一旦启动,确实会保护那些真的出问题的微服务,所以Eureka设计了一个阈值,当15%的心跳都丢失的时候,才会发生自我保护机制。因为这个时候,相对于15%的机器挂掉来说,发生脑裂的概率大一些。但是有没有可能真的是15%机器挂掉了?这个时候Eureka是不能帮我们判断的,需要客户端本身有一定的容错机制,比如断路器
思考:CP设计好?还是AP设计好? - 取决于业务,对于注册中心来说,偶尔拿到出问题的微服务,其实对于整个架构来讲没有太大问题,微服务架构最害怕整个注册中心服务不可用,因此对于注册中心来说,AP(高可用)设计强于CP(一致性)设计。并不是说一致性不好,对于分布式锁的业务来讲,一定要CP,不然整个集群的业务会混乱
注意:zookeeper可以是偶数台,只是说奇数台,服务器成本更低一些
三、服务的调用-Ribbon + RestTemplate(独立的组件)
1、什么是Ribbon?
Ribbon是一个客户端的负载均衡器,用来进行SpringCloud间的微服务负载均衡调用
2、什么是客户端负载均衡?服务端负载均衡?
负载均衡的方式: 1)客户端负载均衡
2)服务端负载均衡
2.1)网络4层负载
2.2)网络7层负载 - nginx
3、Ribbon+RestTemplate的使用
1)再创建一个微服务(班级服务),用于后续的服务间调用
2)在**主动的调用方(学生服务 -> 班级服务,学生服务就是主动调用方)**添加依赖
<!-- 添加ribbon依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
3)启动类中声明RestTemplate组件
@Bean
@LoadBalanced//负载均衡
public RestTemplate getRest(){
return new RestTemplate();
}
4)编写服务调用代码
//根据班级id,调用班级服务,查询班级信息
//关键 调用地址 MICRO-CLASSES 必须写一个微服务的名称
String classInfo = restTemplate
.getForObject("http://MICRO-CLASSES/cls/queryClsName?cid=1",String.class);
4、Ribbon的负载均衡
思考:Eureka如何知道两个服务是集群的关系?还是两个独立的微服务?
微服务名称相同,那么就是集群关系
spring: application: name: micro-classes
4.1 Ribbon的负载均衡策略
/**
* 切换负载均衡策略
* @return
*/
@Bean
public IRule getRule(){
return new RandomRule();
}
四、服务的调用-Feign(底层其实就是Ribbon)
1、为什么有了Ribbon还有用Feign?
Feign底层也调用了Ribbon,Feign其实本质上是Ribbon + Hystrix(豪猪)的集合体,因为Ribbon本身的写法不够面向对象,很多Java程序员对这种写法会很不习惯。
2、Feign的使用
1)调用方添加feign的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2)编写一个Feign接口(关键)
@FeignClient("MIRCO-TEACHER")
public interface ITeacherFeign {
@RequestMapping("/tea/queryTeaName")
String queryTeaName(@RequestParam("tid") Integer tid);
}
3)在需要调用微服务的地方,注入改接口
@Autowired
private ITeacherFeign teacherFeign;
...
//远程调用教师服务
String s = teacherFeign.queryTeaName(cid);
4)配置启动类注解
@SpringBootApplication(scanBasePackages = "com.qf")
@EnableEurekaClient
//表示启动feign,而且这个注解需要找到Feign接口所在的包,默认去启动类所在包下找
//所有如果Feign接口没有在启动类的包下,就需要手动配置扫描
@EnableFeignClients(basePackages = "com.qf.feign")
public class ClassesApplication {
public static void main(String[] args) {
SpringApplication.run(ClassesApplication.class, args);
}
}
3、Feign的超时与重试
Feign默认超时时间为1S,如果1S内,被调用方没有返回结果,就默认失败,然后重试1次。
有些时候,如果不加干预,可能引起请求的重复发送,导致出现各种问题。
注意:Feign自带超时和重试的功能,但是默认是关闭的。所以我们看到的超时和重试的效果,是底层Ribbon提供的。如果开启了Feign的超时重试就会覆盖掉Ribbon的设置
设置Feign的超时和重试:
#配置ribbon的超时和重试
ribbon:
#配置的是连接超时
ConnectTimeout: 1000
#配置读超时
ReadTimeout: 1000
#配置ribbon的重试次数,默认是0
MaxAutoRetries: 0
#配置ribbon的下个服务的重试次数,默认是1
MaxAutoRetriesNextServer: 0
#MaxAutoRetriesNextServer为m, 表示会重试(m + 1)个实例
#MaxAutoRetries为n,表示单实例重试(n + 1)次
#总的执行次数 (n + 1) * (m + 1)
#配置Feign的超时,一旦配置了Feign的超时,ribbon的重试和超时会全部失效
feign:
client:
config:
MIRCO-TEACHER: #可以针对不同的微服务配置不同的超时时间
connectTimeout: 1000
readTimeout: 6000
MIRCO-STUDENT:
connectTimeout: 1000
readTimeout: 2000
五、Hystrix-断路器
1、 什么是断路器
断路器 - 就是微服务架构的保险丝
2、为什么需要Hystrix(保险丝)?
在微服务架构中,根据业务会拆分成一个一个为微服务,服务于服务之间可以互相调用。为了保证高可用性,单个服务通常会集群部署,但是由于网络等原因,不能保证服务100%可用。如果单个服务出现问题,调用这个服务的服务就有可能出现线程阻塞,刚好这个时候大量的请求在访问当前服务,就会导致当前服务的线程资源不足,从而导致服务瘫痪,形成故障转移,导致**“服务雪崩”**
3、Hystrix是如何解决服务间调用问题的
资源隔离:鸡蛋不要放在一个篮子里(线程池隔离、信号量隔离)
服务降级:当调用目标服务出问题(超时、报错…)时,会自动的调用一个本地的方法,返回一个默认值
请求熔断:一旦确定目标服务出问题(失败比例),Hystrix的熔断器会自动打开,拦截后续的所有请求,立刻判定失败,进行服务降级。过了单位时间之后,熔断器变成半开状态,放行一个请求,如果还是失败,继续全开,拦截请求,否则熔断器关闭。
4、Ribbon整合Hystrix(了解)
1)在Ribbon的工程中,添加Hystrix的依赖
<!-- hystrix 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2)在启动类上添加注解
....
@EnableHystrix
...
3)在使用RestTemplate的地方,通过注解实现资源隔离
//使用注解,隔离其他服务的调用资源,被该注解标记的方法会被Hystrix提供的线程调用(线程池隔离)
//fallbackMethod就是指定降级方法,当资源不足或者服务报错时,会走降级方法
//熔断器默认已经开启
@HystrixCommand(fallbackMethod = "myFallBack")
@RequestMapping("/queryName")
public String getNameById(Integer sid){
......
}
/**
* 降级方法
* @param sid
* @return
*/
public String myFallBack(Integer sid){
return "服务异常,降级方法调用!!!";
}
5、Feign整合Hystrix(常用)
1)直接通过配置,开启Hystrix
#开启Feign的断路器功能
feign:
hystrix:
enabled: true
注意:Feign中已经整合了Hystrix,所以不需要添加任何依赖,Feign中的Hystrix功能默认关闭
2)配置Feign接口,编写降级实现类
@FeignClient(value = "MIRCO-TEACHER", fallback = ITeacherFeign.TeacherFeign.class)
public interface ITeacherFeign {
@RequestMapping("/tea/queryTeaName")
String queryTeaName(@RequestParam("tid") Integer tid);
/**
* Feign接口的实现类
*/
@Component
public static class TeacherFeign implements ITeacherFeign{
//就是对应的降级方法
@Override
public String queryTeaName(Integer tid) {
return "教师服务调用异常,服务进行降级!!!";
}
}
}
6、Hystrix的常用配置
#配置Hystrix的常用属性
hystrix:
command:
default:
execution:
isolation:
#资源隔离的策略,线程池隔离(默认)、信号量隔离(SEMAPHORE)
strategy: THREAD
#hystrix超时时间,默认1秒
thread:
timeoutInMilliseconds: 500
timeout:
#是否开启Hystrix的超时时间, 默认为true,如果设置为false,
#意为不超时,但是Feign的超时仍然起作用
enabled: true
#熔断器的相关配置,默认打开熔断器
circuitBreaker:
enabled: true
#单位时间内,失败的次数,如果达到这个阈值,那么熔断器就会打开,默认20次
requestVolumeThreshold: 5
#多久之后,熔断器进入半开状态,默认5S
sleepWindowInMilliseconds: 5000
注意:实际开发过程中,调用超时,需要结合Feign的超时和Hystrix的超时,哪个超时设置的小,哪个就起作用,默认都是1S。
7、Hystrix的仪表盘(图形化界面监控)
什么是Hystrix的仪表盘?
Hystrix提供了一个组件,可以监控Hystrix的微服务,来动态掌握各个微服务之间的请求调用情况。
配Hystrix的仪表盘
1)单独创建一个SPringBoot项目,作为仪表盘工程
2)该工程添加依赖仪表盘工程
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
3)配置启动注解仪表盘工程
@EnableHystrixDashboard
4)启动该工程
5)去到需要监控的工程,配置监控Servlet
//添加监控依赖
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>1.5.18</version>
<scope>compile</scope>
</dependency>
//启动类配置监控的Servlet
@Bean
public ServletRegistrationBean<HystrixMetricsStreamServlet> getServlet(){
HystrixMetricsStreamServlet hystrixMetricsStreamServlet
= new HystrixMetricsStreamServlet();
ServletRegistrationBean<HystrixMetricsStreamServlet>
servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(hystrixMetricsStreamServlet);
servletRegistrationBean.addUrlMappings("/hystrix.stream");
servletRegistrationBean.setName("HystrixMetricsStreamServlet");
return servletRegistrationBean;
}
6)去到仪表盘工程,配置监控地址即可
注意:Hystrix的仪表盘,不需要注册到注册中心上,是一个独立的工程就可以了
六、路由网关
1、什么是路由网关?
简单来说,路由网关往往是微服务架构的入口组件,外来的所有的请求,都需要通过路由网关进行分发和过滤。路由网关的核心功能:请求的路由、请求的过滤
2、为什么需要路由网关?
路由网关提供了外部请求的访问入口,所有的外部请求都只需要知道路由网关的地址就行了,无需知道每个微服务的访问地址,路由网关可以将外部的请求负载分发给不同的微服务,这样可以对外屏蔽微服务架构内部的结构。因为路由网关往往是外部请求访问微服务架构的入口,所以可以在路由网关做请求过滤的工作。
SpringCloud默认提供了2个路由网关,Zuul和Gateway,Zuul是网飞(netflix)提供的路由组件,而Gateway是SpringCloud团队自己开发的一款路由组件,用来替换Zuul的
3、路由网关的请求路由实现
1)创建一个微服务工程,注意该微服务工程不能添加web依赖
2)添加Gateway依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
3)配置application.yml
server:
port: 18888
spring:
application:
name: gateway-server
#配置路由网关的路由规则
cloud:
gateway:
routes:
#id:规则的标识,是一个合法不重复的字符串即可
- id: guize1
#predicates:路由规则,什么样的请求,匹配当前这个规则
predicates:
# http://localhost:18888/stu/a/b
- Path=/stu/**
#当前的规则,分发给哪个微服务
#http://MICRO-STUDENT/stu/a/b
uri: lb://MICRO-STUDENT
eureka:
client:
service-url:
defaultZone: http://localhost:20000/eureka
七、分布式统一配置中心
1、统一配置中心的搭建(服务端)
1)创建一个工程(可以不是微服务,不用注册到注册中心上)
2)添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
3)启动类添加依赖
@EnableConfigServer
4)配置application.yml
server:
port: 40000
spring:
application:
name: config-server
#读取本地配置文件,强制需要配置该属性
profiles:
active: native
cloud:
config:
server:
#配置文件放到本地
native:
search-locations: classpath:config
#配置文件放到svn上的配置
# svn:
# uri: #svn仓库的地址
#配置文件放到git上的配置
# git:
# uri: xxxxxxxx #配git仓库的地址,git仓库里放的就是各种配置文件
5)在config文件夹中,随便准备一个配置文件
com:
name: zhangsan
6)运行配置中心,测试是否能都读到管理的配置信息
2、微服务配置的统一管理(其他微服务的配置全部交由统一配置中心管理)
1)将所有微服务的application.yml放到统一配置中心的指定目录下(git、svn需要传到指定的仓库中)
2)所有微服务添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
3)所有的微服务,添加一个配置文件bootstrap.yml
注意:bootstrap.yml用法和application.yml的用法完全一致,但是在SpringBoot启动过程中,是先加载bootstrap.yml再加载application.yml
spring:
cloud:
config:
#配置统一配置中心的地址
uri: http://localhost:40000
#配置文件的名字
name: teacher
#配置文件的环境
profile: local
4)启动配置中心、再启动微服务
注意:这里有一个强制的顺序要求,必须先启动配置中心,再启动微服务
3、统一配置需要注意的一些地方
1、如果配置文件是放在Config Server本地管理的,那么每次修改配置文件,都必须重启Config Server才会生效
2、如果配置文件是放在Config Server的git、SVN仓库中管理的,那么每次修改配置文件,不用重启Config Server,会自动生效
3、不管配置文件放在哪里,每次修改配置文件,所有的Config Client(微服务),都必须重启才有效。原因在于Config Client只有在启动的时候会去抓一次配置,然后配置就缓存到本地了,后续所有的代码都是从本地获得配置,因此服务的变化,是无感知的,这也是一种优化的结果
4、关于配置修改,需要重启所有微服务的解决方案(只说方案,不实现)
统一配置中心的管理方案一
统一配置中心的管理方案二 升级方案