Eureka
使用步骤
-
添加依赖—>pom.xml文件中
-
配置Eureka相关信息—>application.yml文件中
-
添加注解 —>服务的启动类上添加注解
-
服务器端添加@EnableEurekaServe 服务端的主启动类,可以接受别人的注册
server: port: 7001 eureka: instance: hostname: localhost # Eureka服务端的实例名称 client: register-with-eureka: false # 表示是否向eureka注册中心注册自己 fetch-registry: false # 如果为false,则表示自己为注册中心 service-url: # 监控页面 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
-
客户端添加@EnableEurekaClient
# Eureka的配置,服务注册到哪里 eureka: client: service-url: defaultZone: http://localhost:7001/eureka/ #表示向哪里注册 instance: instance-id: springcloud-provider # 修改eureka上的默认描述信息
-
配置Eureka集群
服务端将defaultZone添加到其他的集群
客户端将defaultZone向全部集群发布
CAP原则
- C (Consistency)强一致性
- A (Availability)可用性
- P (Partition tolerance)分区容错性
CAP的三进二:CA、CP、AP
CAP理论的核心
- 一个分布式系统不可能同时很好的满足一致性、可用性和分区容错性三个需求
- 根据CAP原理,将NoSQL数据库分成了满足CA原则、满足CP原则和满足AP原则三大类
- CA:单点集群,满足一致性、可用性的系统,通常可扩展性较差
- CP:满足一致性、分区容错性的系统,通常性能不是特别高
- AP:满足可用性、分区容错性的系统,通常可能对一致性要求低一些
作为服务注册中心,Eureka比Zookeeper好在哪里?
由于分区容错性P在分布式系统中是必须要保证的,因此我们只能在A和C之间进行权衡。
- Zookeeper保证的是CP
- Eureka保证的是AP
Zookeeper
当向注册中心查询服务列表是,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但zookeeper会出现一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于选举leader的时间太长,30~120s,且选举期间整个zookeeper集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因为网络问题使得zookeeper集群失去master节点是较大概率会发生的事件,虽然服务最终能够恢复,但是漫长的选举事件导致注册长期不可用是不能容忍的。
Eureka
Eureka看明白了这一点,因此在设计时就优先保证可用性,Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余节点依旧可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册时,如果发现连接失败,则会自动切换至其他节点,只要有一台Eureka还在,就能保证注册服务的可用性,只不过查到的信息可能不是最新的,除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现一下几种情况:
1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点仍然可用)
2. 当网络稳定时,当前实例新的注册信息会被同步到其他节点中
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。
Ribbon
Ribbon是什么?
- Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具
- 主要功能是提供客户端的软件负载均衡算法,将NetFlix的中间层服务连接在一起。Ribbon的客户端组件提供一系列完整的配置项如:连接超时、重试等等。简单的说,就是在配置文件中列出LoadBalancer(简称LB:负载均衡)后面的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询、随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。
Ribbon能干什么?
-
负载均衡,在微服务或分布式集群中经常用的一种应用
-
负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的高可用(HA)。
-
常见的负载均衡软件有Nginx、Lvs等
-
dobbo、Spring Cloud中均给我们提供了负载均衡,Spring Cloud的负载均衡算法可以自定义
-
负载均衡简单分类:
-
集中式LB
即在服务的消费方和提供方之间使用独立的LB设施,如Nginx,由该设施负责吧访问请求通过某种策略转发至服务的提供方
-
进程式LB
将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器
Ribbon
就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
-
-
Ribbon实现负载均衡
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>自行查询</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>自行查询</version>
</dependency>
消费者配置eureka
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: # 注册中心地址
启动类配置注解 @EnableEurekaClient
在消费者上加入注解 @LoadBalanced
自定义负载均衡算法
IRule ribbon负载均衡规则
RoundRobinRule 轮询
RandomRule 随机
AvailabilityFilteringRule 会先过滤掉跳闸、访问故障的服务,对剩下的进行轮询
RetryRule 会按照轮询获取服务,如果服务获取失败,则会在指定时间内进行重试
...
自定义 需要在启动类上添加注解RibbonClient(name = "服务注册的名字", configuration = MyRule.class)
// 不能放置在启动类同级目录下
@Configuration
public class MyRule {
@Bean
public IRule myRule() {
return new MyRandomRule();
}
}
public class MyRandomRule extends AbstractLoadBalancerRule {
// 每个服务,访问5次,换下一个服务
private int total = 0; // 总共访问了几次
private int currentIndex = 0; // 提供服务的对象
// Ribbon实现的随机
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers(); // 获取活着的服务
List<Server> allList = lb.getAllServers(); // 获取全部服务
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
// int index = chooseRandomInt(serverCount); // 生成存活的服务中的随机数
// server = upList.get(index); // 获取对应服务
// ====================== 自己修改位置
if (total < 5) {
server = upList.get(currentIndex);
total++;
}else {
total = 0;
currentIndex++;
if (currentIndex > upList.size()) {
currentIndex = 0;
}
server = upList.get(currentIndex);
}
// ======================
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
return server;
}
}
Feign负载均衡
什么是Feign?
feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。
只需要创建一个接口,然后添加注解即可。 @FeignClient
Feign能干什么?
- Feign旨在使编写Java http客户端变得更容易
- 在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。
Hystrix
服务雪崩
多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,即所谓的“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有的服务器上的所有资源都在几秒中内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障,这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
什么是Hystrix?
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个服务预期,可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,这样就可以保证了服务调用方的线程不会被长时间不必要的占用,从而避免了故障在分布式系统中的蔓延乃至雪崩。
能做什么?
- 服务降级
- 服务熔断
- 服务限流
- 接近实时的监控
- …
服务熔断
是什么? 熔断机制是对应雪崩效应的一种微服务链路保护机制。
当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信号
。当检测到该节点微服务调用响应正常后恢复调用链路。在Spring Cloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5s内调用20次调用失败就会启动熔断机制。熔断机制的注解是 @HystrixCommand
。
步骤
-
导入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>自行查询</version> </dependency>
-
使用注解
@RestController public class DeptController { @Autowired private DeptService deptService; @GetMapping("/dept/get/{id}") @HystrixCommand(fallbackMethod = "hystrixGet") // 当方法失败,则调用传入的方法 public Dept get(@PathVariable("id") Long id) { return deptService.queryById(id); } public Dept hystrixGet(@PathVariable("id") Long id) { return new Dept() .setDeptNo(id) .setDname("id=>"+id+"没有找到对应信息, null--@Hystrix"); }
-
需要在启动类上添加注解
@EnableCircuitBreaker
开启断路器
服务降级
在客户端实现。从整体网站请求负载考虑,某些服务请求多,某些服务请求少,当大流量来时可以考虑先将请求少的服务进行降级来将资源给予请求量大的服务。于是当某个服务熔断或关闭之后,服务将不再被调用,此时在客户端可以准备一个fallbackFactory返回一个默认值。虽然整体服务水平下降了但是好歹能用,比直接挂掉强。
- 配置文件中开启降级
feign:
hystrix:
enabled: true
-
在
@FeignClient
中加入fallbackFactory = 下面创建的类 -
创建一个类实现fallbackFactory
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory {
@Override
public DeptClientService create(Throwable throwable) {
return new DeptClientService() {
// 实现接口中的方法
}
}
}
Dashboard流监控
-
导入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> <version>自行查询</version> </dependency>
-
启动类上添加注解
@EnableHystrixDashboard
开启监控 -
服务注册需要添加依赖
<!--actuator完善监控信息--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
向注册实例中的启动类添加一个bean方法
@Bean public ServletRegistrationBean hystrixMetricsStreamServlet() { ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet()); registrationBean.addUrlMappings(/actuator/hystrix.stream); return registrationBean; }
Zuul 路由网关
什么是Zuul?
Zuul包含了对请求的路由和过滤两个主要功能:
其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。而过滤功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,即以后的访问微服务都是通过Zuul跳转后获得的。
==注意:==Zuul服务最终还是会注册进Eureka ==提供:==代理+路由+过滤三大功能
使用步骤
-
导入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> <version>自行查询</version> </dependency>
-
配置信息
# Eureka的配置 eureka: client: service-url: defaultZone: #注册中心的位置 instance: instance-id: zuul # eureka上的描述信息 zuul: routes: mydept.serverId: springcloud-provider-dept mydept.path: /mydept/** # 将上面的Id替换成path中的名称 ignored-services: springcloud-provider-dept # 不能再使用这个路径访问了 prefix: /xxx # 设置公共前缀
-
启动类上添加注解
@EnableZuulProxy
Spring Cloud Config
什么是Spring Cloud Config分布式配置中心?
Spring Cloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环节提供了一个中心化的外部配置。
Spring Cloud Config分为服务端
和客户端
两部分:
服务端也称分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户提供获取配置信息、加密、解密信息等访问接口。
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认采用git来存储配置信息,这样有助于对环境配置进行版本管理。并且可以通过git客户端工具来方便的管理和访问配置信息。
Spring Cloud Config分布式配置中心能干什么?
- 集中管理配置文件
- 不同环境、不同配置、动态化的配置更新,分环境部署,比如/dev /test /prod /beta /release 等等
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启,即可感知到配置的变化,并应用新的配置
- 将配置信息以Rest接口的形式暴露
步骤
-
引入依赖 -->maven仓库搜config-server选择想要的
-
配置config仓库
spring: application: name: # config的名字 cloud: config: server: git: uri: # 远程仓库的地址 https的
-
启动类添加注解
@EnableConfigServer
client
配置bootstrap.yml文件 将uri 绑定到 config服务中心
spring:
cloud:
config:
name: # 需要从git读取的资源名字,不需要后缀
profile: dev # 需要的环境
label: master # 分支名字
uri: # config服务中心地址