一、简介
Spring Cloud是一个含概多个子项目的开发工具集,集合了众多的开源框架,他利用了Spring Boot开发的便利性实现了很多功能,如服务注册,服务注册发现,负载均衡等.Spring Cloud在整合过程中主要是针对Netflix(耐非)开源组件的封装. Spring Cloud的出现真正的简化了分布式架构的开发
微服务: 微服务体系结构样式是一种将单个应用程序开发为一组小服务的方法,每个小服务都能够独立运行在自己的进程中,并与轻量级机制(通常指 HTTP 资源API) 进行通信。这些服务围绕业务功能构建,并且可以由全自动部署机制独立部署。还可以使用不同的编程语言编写并使用不同的数据存储技术。
微服务特点:
- 每个服务可以独立运行在自己的进程
- 一系列独立运行的微服务共同构建起整个系统
- 每个服务独立的业务开发,一个服务只关注某个特定的功能。
- 微服务之间通过一些轻量的通信机制进行通信,如:Restful API (Http)进行调用
- 可以使用不同的语言与数据存储机制。
二、架构的演变![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/96b8facd66ff91c38ebc31fabdb6e07b.png)
转载:架构的演变详解
微服务的的解决方案:
三、SpringCloud的服务架构:
相关组件:
Eureka: 服务注册和发现,基于Rest 的服务,包含Client 和 Server两部分
Zuul: 路由 用于路由转发和过滤器,默认和Ribbon结合实现了负载均衡
Feign: 微服务之间的通信 Feign 是一个声明式的伪HTTP客户端,支持可插拔的编码器和解码器,并默认集成了Ribbon
Ribbon: 负载均衡器 用户可以自定义负载均衡算法
Hystrix: 断路器 是NetFilx 开源的延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性和容错性。
四、Eureka组件
1.eureka中的server和client的介绍及特点
- Eureka Server:提供服务发现的能力,各个微服务启动时,会向Eureka Server注册自己的信息例如(IP,端口号,服务名称等),Eureka会存储这些信息
- Eureka Client:是一个java的客户端用来简化Eureka Server的交互
- 微服务启动后会周期性的(默认30秒)向Eureka Server发送心跳,如果Eureka在规定的时间没有收到心跳,则会注销该实例(默认90秒)
- Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势首先可以降低Eureka Server的压力,其次当所有的Eureka Server宕机服务调用方依然可以完成调用
2.服务注册与服务发现
- 服务注册:当微服务client启动时,向Eureka Server发起注册,并上报该节点的相关信息
- 服务发现:client从Eureka Server获取注册信息,然后发起调用
3.Eureka Server开发
1.引入相关依赖
<dependencies>
<!-- 第三个引入 -->
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<!-- 第二个引入 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 第一个引入 -->
<!-- SpringCloud依赖下载镜像 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
2.入口类开发
//代表Server
@EnableEurekaServer
//代表Client
@EnableEurekaClient
@SpringBootApplication
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class,args);
}
}
3.配置文件
//设置eureka server 的交互地址,之后的服务获取和服务注册都需要依赖于这个地址
# 注册中心的位置 注册 发现
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
register-with-eureka: false #关闭注册自己
fetch-registry: false #关闭发现自己
#声明当前节点的名字
spring:
application:
name: eureka-server1
server:
port: 8761
4.Eureka Client开发
1.引入相关依赖
<dependencies>
<!-- 第三个引入 -->
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!--
feign
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--
统一配置中心
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<!-- 第二个引入 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 第一个引入 -->
<!-- SpringCloud依赖下载镜像 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
2.入口类开发
@EnableDiscoveryClient //既支持zooKeeper 又支持eureka
@EnableEurekaClient //eureka
@EnableFeignClients //开启Feign支持
@EnableConfigServer //开启统一配置中心
@SpringBootApplication
public class HiApplication {
public static void main(String[] args) {
SpringApplication.run(HiApplication.class, args);
}
}
3.配置文件
#注册中心位置 注册 发现
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
instance:
lease-renewal-interval-in-seconds: 10 #发送心跳间隔 s
lease-expiration-duration-in-seconds: 20 #心跳超时时间 s
server:
enable-self-preservation: false #关闭自我保护机制
#查看监控详细信息
management:
endpoint:
health:
show-details: always
#声明当前节点名
spring:
application:
name: eureka-client1
#统一配置中心远程仓库员
cloud:
config:
server:
git:
uri: https://gitee.com/xusan_java/springcloud-clien2.git
server:
port: 8888 # 远程配置中心 默认端口 8888
servlet:
context-path: /
5.Eureka client之间的相互调用
1.java配置RestTemplate
@Bean
RestTemplate getRestTemplate(){
return new RestTemplate();
}
2.调用
@Autowired
RestTemplate restTemplate;
@RequestMapping("/hi")
public String hi(String name) {
String restTemplateForObject = restTemplate.getForObject("http://服务名/test/test?name=" + name, String.class);
return restTemplateForObject;
}
6.Eureka的自我保护机制
Eureka进入自我保护机制的最直接体现,是Eureka首页输出警告如图:
默认情况下,如果Eureka Server在一定时间内没有接受到服务实例的心跳,Eureka将会注销该实例(默认90秒).但是当网络分区发生故障时(大面积网络故障),微服务和Eureka Server 无法正常通信.以上行为可能变得特别危险了-因为微服务本身是健康的,此时不能注销该服务实例.
Eureka通过自我保护机制来解决这个问题,当Eureka Server在短时间丢失过多的服务实例(可能发生了网络分区的故障,那么这个节点进入自我保护模式,一旦进入此模式,Eureka Server将会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不再注销任何的服务实例),当网络故障恢复后,Eureka会自动退出自我保护模式。
综上,自我保护模式是一种应对网络故障的安全保护措施,它的架构哲学是宁可同时保留所有的微服务,也不盲目注销任何健康的微服务,使用自我保护模式可以让Eureka,更加健壮,稳定。
自定义关闭自我保护机制:
#Eureka-Server 设置
#关闭自我保护机制 默认开启
eureka.server.enable-self-preservation=false
如果想及时剔除eureka的服务除了关闭自我保护机制外,可以调低eureka的心跳值
#eureka-server服务端
#配置文件中我们添加如下配置
eureka:
server:
#关闭保护机制,以确保注册中心将不可用的实例正确剔除
enable-self-preservation: false
#(代表是5秒,单位是毫秒,清理失效服务的间隔 )
eviction-interval-timer-in-ms: 1000
客户端
配置文件中我们添加如下配置
# 心跳检测与续约时间
# 测试时将值设置设置小些,保证服务关闭后注册中心能及时剔除为服务实例
# 配置说明
# lease-renewal-interval-in-seconds 每间隔10s,向服务端发送一次心跳,证明自己依然”存活“
# lease-expiration-duration-in-seconds 告诉服务端,如果我20s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
eureka:
instance:
lease-renewal-interval-in-seconds: 10
lease-expiration-duration-in-seconds: 20
7.client的高可用(client 集群)
保证端口号不一致(测试环境)
保证实例名一致
配置如下
eureka.client.service-url.defaultZone=http://peer:8761/eureka
spring.application.name=eureka-producter
server.port=8764
eureka.client.service-url.defaultZone=http://peer:8761/eureka
spring.application.name=eureka-producter
server.port=8763
8.Eureka Server的高可用
单节点的Eureka Server 不适合线上的生产环境,Eureka Client会定时连接Eureka Server,获取服务注册表中的信息并缓存在本地,微服务消费远程API总是使用本地缓存的数据,因此一般来说既是Eureka Server发生宕机,也不会影响到服务的调用,但是如果Eureka Server宕机时某些微服务也出现了不可用的情况,Eurek Client中的缓存若不被更新,可能会影响到服务的调用,甚至影响到整个系统的高可用性,因此在生产环境会部署一个高可用的Eureka Server集群。
Eureka可以通过运行多个实例并互相注册实现高可用部署,Eureka Server实例会彼此同步信息。
server.port=8761
eureka.client.service-url.defaultZone=http://peer2:8762/eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
server.port=8762
eureka.client.service-url.defaultZone=http://peer1:8761/eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
注意:在client注册eureka server时 需要填写所有eureka的地址
eureka.client.service-url.defaultZone=http://peer:8761/eureka,http://peer1:8765/eureka
9.Eureka的健康监测
人会生病,服务有时候也会出现异常情况,我们也需要知道某个服务的健康状况。我们可以通过添加如下依赖,开启某个服务的健康检查。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
访问http://localhost:9000/actuator/health,看到了一个很简短的健康报告:
{"status":"UP"}
查看详细信息
management:
endpoint:
health:
show-details: always
9.http VS rpc(tcp)
应用间通信方式主要是HTTP和RPC,在微服务架构中两大配方的主角分别是:
- Dubbo RPC框架
基于dubbo开发的应用还是要依赖周边的平台生态, 相比其它的RPC框架, dubbo在服务治理与服务集成上可谓是非常完善, 不仅提供了服务注册,发现还提供了负载均衡,集群容错等基础能力同时,还提供了面向开发测试节点的Mock和泛化调用等机制。 在spring cloud 出现之前dubbo在国内应用十分广泛,但dubbo定位始终是一个RPC框架。
- SpringCloud 微服务框架(HTTP通信)(应用范围广泛)
Spring Cloud 的目标是微服务架构下的一栈式解决方案,自dubbo复活后dubbo官方表示要积极适配到spring cloud的生态方式,比如作为springcloud的二进制通信方案来发挥dubbo的性能优势,或者通过dubbo的模块化以及对http的支持适配到Spring Cloud,但是到目前为止dubbo与spring cloud 还是不怎么兼容,spring cloud 微服务架构下微服务之间使用http的RestFul方式进行通信,Http RestFul 本身轻量易用适用性强,可以很容易跨语言,跨平台,或者与已有的系统集成。
五.使用Ribbon完成负载均衡
1.Ribbon简介
ribbon是Netflix发布的负载均衡器,有助于控制http和tcp客户端的行为,为ribbon配置服务提供者列表后,ribbon就可以基于某种负载均衡算法,自动的帮助服务消费者去请求。ribbon提供了很多的负载均衡算法例如
- RoundRobinRule(): 轮询算法
- RandomRule(): 随机算法
- AvailabilityFilteringRule():会先过滤由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问
- WeightedResponseTimeRule():根据平均响应的时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高,刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够会切换到WeightedResponseTimeRule
- RetryRule():先按照RoundRobinRule的策略获取服务,如果获取失败则在制定时间内进行重试,获取可用的服务。
- BestAviableRule():会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
在springCloud中,当ribbon和Eureka配和使用时ribbon可以自动获取服务注册列表,并基于负载均衡算法,请求其中的一个服务提供实例
2.为服务消费者整合ribbon
1.ribbon和springcloud的启动器
**注意:**如果已经引入了spring-cloud-starter-netflix-eureka-server该依赖已经包含了spring-cloud-starter-ribbon,所以不需要再次引入
2.ribbon整合RestTemplate
@Bean
@LoadBalanced
RestTemplate getRestTemplate(){
return new RestTemplate();
}
3.使用
@Autowired
RestTemplate restTemplate;
@RequestMapping("/hi")
public String hi(String name) {
String restTemplateForObject = restTemplate.getForObject("http://HI-SERVICE/test/test?name=" + name, String.class);
return restTemplateForObject;
}
4.验证负载均衡
@RequestMapping("/test")
public void test() {
ServiceInstance serviceInstance = loadBalancerClient.choose("HI-SERVICE");
int port = serviceInstance.getPort();
String host = serviceInstance.getHost();
String serviceId = serviceInstance.getServiceId();
}
3.自定义负载均衡的策略
3.1 配置文件形式
EUREKA-CLIENT2:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
3.2java配置形式
@Configuration
public class conf {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
public IRule rule(){
//随机
RandomRule randomRule = new RandomRule();
return randomRule;
}
}
六.使用feign实现声明式的调用
使用RestTemplate+ribbon已经可以完成对端的调用,为什么还要使用feign?
@RequestMapping("/hi")
public String hi(String name) {
String restTemplateForObject = restTemplate.getForObject("http://HI-SERVICE/test/test?name=" + name, String.class);
return restTemplateForObject;
}
上述代码采用url拼接参数的形式发送请求,如果要发送多个请求参数那么代码就会变得很低效并且难以维护。例如
http://localhost:8989/hi/hi?name=zhangsan&password=123456&age=18
如果使用字符串拼接的方式,那么代码可以编排为:
@RequestMapping("/hi")
public String hi(String name, String password, Integer age) {
String restTemplateForObject = restTemplate.getForObject("http://HI-SERVICE/test/test?name="+name+"&password="+password+"&age="+age, String.class);
return restTemplateForObject;
}
@RequestMapping("/hi")
public String hi(String name, String password, Integer age) {
Map<Object, Object> map = new HashMap<>();
map.put("name", name);
map.put("password", password);
map.put("age", age);
String restTemplateForObject = restTemplate.getForObject("http://HI-SERVICE/test/test?name={name}&password={password}&age={age}", String.class, map);
return restTemplateForObject;
}
在这里url仅仅包含三个参数,如果url为10个参数那么代码会变的更加难以维护。
1.feign简介
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果并且springcloud为feign添加了springmvc注解的支持。
2.为服务消费者整合feign
1.引入feign的相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.入口类开启feign支持
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class HiApplication {
public static void main(String[] args) {
SpringApplication.run(HiApplication.class, args);
}
}
3.创建feign接口
//指定的是为服务实例注册中心的名字
@FeignClient(name = "EUREKA-CLIENT2")
public interface feignTest {
//调用的 namespace 和 方法名
@RequestMapping("/test/test")
public String sayHi(@RequestParam("name") String aa);
}
4.测试
//Controller
@Autowired
private FeignTest feignTest;
@RequestMapping("/hi")
public String hi(String name) {
final String s = feignTest.sayHi(name);
System.out.println(s);
return s;
}
3.feign日志
很多的场景下,需要了解feign处理请求的具体细节,如何满足这种需求呢?
feign对日志的处理非常灵活可为每个feign客户端指定日志记录策略,每个客户端都会创建一个logger默认情况下logger的名称是feign的全限定名需要注意的是,feign日志的打印只会DEBUG级别做出响应。
我们可以为feign客户端配置各自的logger.lever对象,告诉feign记录那些日志logger.lever有以下的几种值
- NONE 不记录任何日志
- BASIC 仅仅记录请求方法,url,响应状态代码及执行时间
- HEAdERS 记录Basic级别的基础上,记录请求和响应的header
- FULL 记录请求和响应的header,body和元数据
1.java配置核心日志类
@Configuration
public class feignConf {
@Bean
public Logger.Level feignConfiguration() {
return Logger.Level.FULL;
}
}
2.配置feign客户端的日志级别
logging.level.com.baizhi.feign.feignTest=debug
4.feign构造多参数请求
1.错误方式
feign的注意事项
1.多参数传输的时候 必须要在feign接口上进行参数的绑定
public String testFeign(@RequestParam("name") String name, @RequestParam("password") String password, @RequestParam("age") Integer age);
2.以对象格式为参数进行数据传输时 必须设置feign的请求形式为post
3.在服务方接收对象参数时需在形参上加入@RequestBody的注解
public interface feignPost {
@RequestMapping(value = "/test/test1", method = RequestMethod.GET)
public User sayHi(User user);
}
错误日志信息
feign.FeignException: status 405 reading feignPost#sayHi(User); content:
{"timestamp":1546852876890,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/test/test1"}
由异常信息可知,尽管指定了get的方法,feign依然会使用post发送请求(对象传输时)。正确的方式如下:
2.get
@RequestMapping("/test/test",method = RequestMethod.GET)
public String sayHi(@RequestParam("name") String name,@RequestParam("password")String password);
3.post
feign配置
@FeignClient(serviceId = "HI-SERVICE")
public interface feignPost {
@RequestMapping(value = "/test/test1", method = RequestMethod.POST)
public User sayHi(User user);
}
服务提供方 client1 调用 client2 client2属于提供方
@RequestMapping("/test1")
public User test1(@RequestBody User user) {
return user;
}
七.使用Hystrix实现微服务的容错处理
1.实现容错的手段
如果服务提供者响应的速度特别慢,那么消费者对提供者的请求就会强制等待,直到提供者响应或者超时。在高负载的情况下,如果不做任何处理,此类问题可能会导致服务消费者的资源耗尽甚至整个系统的崩溃。例如曾经发生的一个案例,某个电子商务网站在某个星期五发生过载,过多的并法请求,导致用户支付请求延迟很久没有响应,在等待很长时间后最终失败,支付失败又导致用户重新刷新页面再次尝试支付,进一步增加了服务器的负载,最终整个系统崩溃了。
1.1雪崩效应
我们常把基础服务故障导致级联服务故障的现象称为雪崩效应。雪崩效应描述的是提供方不可用导致消费方不可用并将不可用逐渐放大的过程。
1.2.如何容错
想要避免雪崩效应,必须有强大的容错机制,该容错机制需要实现以下两点
-
为网络请求设置超时
-
使用断路器模式
正常情况下断路器关闭,可正常请求服务,当一定时间内请求达到了一定的阈(yu)值(错误率达到百分之50或者100次/分钟 5秒内的20次),断路器就会打开,此时不会再去请求依赖服务,断路器打开一段时间之后,会自动进入半开的状态。此时断路器允许一个请求请求服务实例,如果该服务可以调用成功,则关闭断路器,否则继续保持打开状态。
2.使用hystrix实现容错
hystrix是Netfilx开源的延迟和容错库,用于隔离访问远程系统,服务或者第三方库,防止级联失败,从而提升系统的可用性和容错性
3.通用方式整合Hystrix (restTempale feign)
1.为项目添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.在消费者的入口类上添加注解
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class HiApplication {
public static void main(String[] args) {
SpringApplication.run(HiApplication.class, args);
}
3.让当前方法具备容错的能力
@Autowired
LoadBalancerClient loadBalancerClient;
@HystrixCommand(failbackMethod = "testFallback")
@RequestMapping("/hi")
public User hi(String name) {
User restTemplateForObject = restTemplate.getForObject("http://HI-SERVICE/test/test?name=" + name, User.class);
return restTemplateForObject;
}
public User testFallback(String name){
User user=new User();
user.setName(name);
user.setAge(-1);
return user;
}
4.测试
1.启动eureka服务
2.启动生产者
3.启动消费者
4.访问消费者
结果
{"name":"xiaohei","password":null,"age":null}
5.关闭生产者
6.访问消费者
结果
{"name":"xiaohei","password":null,"age":-1}
我们知道,当请求失败,被拒绝超时或者短路器打开时都会进入到回退方法,但是进入回退方法并不是意味着断路器被打开,那怎样才算断路器打开呢?
5.实验 进行健康监测实时查看断路器是否打开
1.启动eureka服务
2.启动生产者
3.启动消费者
4.访问消费者
结果
{"name":"xiaohei","password":null,"age":null}
5.访问 http://ip:port/health
{
status:"up",
hystrix:{
status:"up"
}
}
6.关闭生产者
7.访问消费者
结果
{"name":"xiaohei","password":null,"age":-1}
8.访问 http://ip:port/health
{
status:"up",
hystrix:{
status:"up" (熔断器正常的状态)
}
}
通过这里我们可以发现,尽管执行了fallback方法,但此时hystrix状态依然是up,这是因为咱们的失败率还没有达到阀值(默认5秒20次失败),这里再次强调,执行回退的逻辑并不代表断路器已经打开,请求超时,失败,被拒绝以及断路器打开都会执行回退逻辑
9.5秒请求20次
{
status:"up",
hystrix:{
status:"CIRCUIT_OPEN"(断路器打开的标识)
}
}
4.feign整合Hystrix
很显然@HystrixCommand是添加到方法上的,那么对于feign来说一定不适用,如何让Hystrix整合feign
1.feign方法上添加相关注解
@FeignClient(name = "HI-SERVICE",fallback = FeignClientFallBack.class)
public interface feignPost {
@RequestMapping(value = "/test/test1", method = RequestMethod.POST)
public User sayHi(User user);
}
2.实现Feign接口
@Component
public class FeignClientFallBack implements feignPost {
@Override
public User sayHi(User user) {
System.out.println("Hystrix method is invoke");
return null;
}
}
3.添加feign的配置文件
为feign开启断路器
feign.hystrix.enabled=true
八.统一配置中心
为什么需要统一配置中心?
统一配置中心顾名思义,就是将配置统一管理,配置统一管理的好处是在日后大规模集群部署服务应用时相同的服务配置一致,日后再修改配置只需要统一修改全部同步,不需要一个一个服务手动维护
统一配置中心的架构图:
1.配置中心服务器的开发
1.添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
2.添加注解支持
@EnableEurekaClient
@EnableConfigServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
3.在远程的仓库创建配置文件(yml,properties,yaml)
4.配置相关的配置文件
#注册到注册中心
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
#默认端口号 8888
server.port=8888
# 实例名
spring.application.name=config
#配置git的远程仓库 https 暂时不支持ssh
spring.cloud.config.server.git.uri=https://gitee.com/my_os_do_you_know/springcloud-config.git
5.启动配置中心服务
http://localhost:8888/order-a.yml
http://localhost:8888/order-a.yaml
http://localhost:8888/order-a.properties
http://localhost:8888/order-a.json
以上四种访问方式都可以
6.服务的配置的访问规则
{name}-{profiles}.yml
{name}/{profiles:.[^-].}
{name}-{profiles}.json
{label}/{name}-{profiles}.yml
{name}/{profiles}/{label:.*}
{label}/{name}-{profiles}.properties
{label}/{name}-{profiles}.json
{name}/{profile}/{label}/**
{name}/{profile}/{label}/**
说明:
label: 分支名称 默认是master分支
name:文件的服务的名称(自定义的名称)
profiles:不同环境
2.创建配置中心客户端
1.导入相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
2.添加配置
spring:
cloud:
config:
enabled: true #是否使用配置中心
discovery:
service-id: CONFIGSERVER #配置中心 实例的名字
name: client #配置文件文件的名字
profile: test #环境
label: master #分支
uri: http://localhost:9999 #指定配置中心的uri
3.注意将配置文件名修改为 bootstrap.yml
#注册中心位置 注册 发现
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
instance:
lease-renewal-interval-in-seconds: 10 #发送心跳间隔 s
lease-expiration-duration-in-seconds: 20 #心跳超时时间 s
server:
enable-self-preservation: false #关闭自我保护机制
#查看监控详细信息
management:
endpoint:
health:
show-details: always
#声明当前节点名
spring:
application:
name: eureka-client2
cloud:
config:
enabled: true #开启配置中心
discovery:
service-id: EUREKA-CLIENT1 #配置中心实例名
name: clien #指定配置文件名字
profile: test #环境
label: master #分支
uri: https://gitee.com/xusan_java/springcloud-clien2.git
#客户端端口号
server:
servlet:
context-path: /client2
九 路由网关(zuul)
在微服务架构中,需要多个基础的服务治理组件,包括服务注册与发现、服务消费、负载均衡、断路器、智能
路由、配置管理等,由这个基础组件相互协作,共同组建了一个简单的微服务系统。一个简单的微服务系统如下
图
注意:A服务和B服务是可以相互调用的,并且配置服务也是注册到服务注册中心的。
总结:在Spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求先先经过负载均衡(
Ngnix),再到达服务网关(zuul集群),然后再到具体的服务。服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务(统一配置中心)管理,配置服务的配置文件仓库,方便开发人员随时改配置。
1.Zuul 简介
Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服
务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能
1.搭建Zuul
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2.编写Zuul的入口类
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class ServiceZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceZuulApplication.class, args);
}
}
3.编写application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8080/eureka/
server:
port: 8769
spring:
application:
name: service-zuul
zuul:
routes:
products:
path: /product/**
serviceId: client-product
#关闭安全认证
management.security.enabled=false
#设置断路时间(zuul默认是1秒 如果1秒之后没有响应会报错)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 9000
ribbon:
ReadTimeout: 9000
ConnectTimeout: 9000