Eureka(服务治理,配置中心):
Client服务启动后向EurekaServer注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。当服务注册中心Eureka Server检测到服务提供者因为宕机、网络原因不可用时,则在服务注册中心将服务置为DOWN状态,并把当前服务提供者状态向订阅者发布,订阅过的服务消费者更新本地缓存。服务提供者在启动后,周期性(默认30秒)向Eureka Server发送心跳,进行服务续约。Eureka Server在一定的时间(默认90秒)未收到客户端的心跳,则认为服务宕机,注销该实例。服务间使用标准的REST方式通讯。
Eureka Server 集群: Eureka通过互相注册的方式来实现高可用的部署,所以我们只需要将Eureke Server配置其他可用的serviceUrl就能实现高可用部署
CAP:一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。
Zookeeper :保证CP(强一致性Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况: 1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务 2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用) 3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中)。在leader出现宕机时zk无法对外提供访问。
Eureka:保证 AP(最终一致性)。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或查询时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:
1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
Ribbon(实现客户端负载均衡):
Ribbon实现的关键点是为ribbon定制的RestTemplate,ribbon利用了RestTemplate的拦截器机制,在拦截器中实现ribbon的负载均衡。负载均衡的基本实现就是利用applicationName从服务注册中心获取可用的服务地址列表,然后通过一定算法负载,决定使用哪一个服务地址来进行http调用。在Ribbon实现中,定义了一个LoadBalancerInterceptor,ribbon就是通过这个拦截器进行拦截请求,然后实现负载均衡调用。
Ribbon 负载均衡类型:
RandomRule:该策略实现了从服务实例清单中随机选择一个服务实例的功能
RoundRobinRule :该策略实现了按照线性轮询的方式的方式一次选择每个服务实例的功能。与RandomRule非常类似。增加了一个count计数变量,该变量会在每次循环之后累加,如果一直选择不到server超过10次,那么就会结束尝试,并打印一个警告信息。
RetryRule :该策略实现了一个具备重试机制的实例选择功能。默认使用了RoudRobinRule实例。
WeightedResponseTimeRule :该策略是对RoundRobinRule的扩展,增加了根据实例等运行情况来计算权重,并根据权重来挑选实例,以达到更优的分配效果,它的实现主要有三个核心内容:定时任务、权重计算、 实例选择 。
ClientConfigEnabledRoundRobinRule :实现功能与 RoundRobinRule相同 。
Hystrix(熔断器,防止服务雪崩 ):
服务隔离:
在微服务架构中,我们实现的一个业务逻辑通常会依赖多个服务Hystrix。例如:A服务依赖B、C服务,A服务在调用B/C时会共享线程池。如果在调用B服务无响应时,所有应用都处于等待状态;此时服务开始雪崩。通过将每个依赖服务分配独立的线程池进行资源隔离, 从而避免服务雪崩。服务隔离会将A服务线程数量分配给各个依赖服务:例如:B40线程,C60线程。
熔断器模式:
服务的健康状况 = 请求失败数 / 请求总数
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的。
当熔断器开关关闭时, 请求被允许通过熔断器.,如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于设定阈值, 开关则切换为打开状态。
当熔断器开关打开时, 请求被禁止通过。当熔断器开关处于打开状态, 经过一段时间后, 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用 成功时, 熔断器恢复到关闭状态.。若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过。 熔断器的开关能保证服务调用者在调用异常服务时, 快速返回结果, 避免大量的同步等待. 并且熔断器能在一段时间后继续侦测请求执行结果, 提供恢复服务调用的可能。
命令模式:
Hystrix使用命令模式(继承HystrixCommand类或者是HystrixObservableCommand类)来包裹具体的服务调用逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback).同时我们在Command的构造方法中可以定义当前服务线程池和熔断器的相关参数 。(也可以使用注解:@HystrixCommand)
Feign(方便各个服务之间调用。也可以实现服务降级):
主程序入口添加了@EnableFeignClients注解开启对FeignClient扫描加载处理。根据Feign Client的开发规范,定义接口并加@FeignClientd注解。当程序启动时,回进行包扫描,扫描所有@FeignClients的注解的类,并且讲这些信息注入Spring IOC容器中,当定义的的Feign接口中的方法呗调用时,通过JDK的代理方式,来生成具体的RequestTemplate.当生成代理时,Feign会为每个接口方法创建一个RequestTemplate。
当生成代理时,Feign会为每个接口方法创建一个RequestTemplate对象,改对象封装可HTTP请求需要的全部信息,如请求参数名,请求方法等信息都是在这个过程中确定的。
然后RequestTemplate生成Request,然后把Request交给Client去处理,这里指的时Client可以时JDK原生的URLConnection,Apache的HttpClient,也可以时OKhttp,最后Client被封装到LoadBalanceClient类,这个类结合Ribbon负载均衡发器服务之间的调用。
Zuul(服务网关):
服务网关,自身包含Ribbon、Hystrix模块:
1.作为系统入口,屏蔽系统内部各个微服务细节。
2.可以与服务治理框架结合,实现自动化的服务实力维护集负载均衡的路由转发。
3.可以实现接口权限校验与微服务的业务逻辑解耦。
4.通过服务网关中的过滤器,在各生命周期中去校验请求的内容,将原本在对外服务层做的校验前移,保证微服务的无状态性,同时降低了微服务的测试难度,让服务本身更关注业务逻辑。
多实例配置:
xxxxxx.ribbon.listOfServers:配置多个实例。
路径匹配:
/?匹配一个字符
/*匹配多个字符
/**匹配任意字符目录
zuul.ignored-patterns 配置希望zuul忽略的url
核心过滤器:
pre过滤器 :主要是在请求路由之前调用,很多验证可以在这里做
route过滤器:在路由请求时候被调用,主要用来转发请求
post过滤器: 主要用来处理响应请求
error过滤器:当错误发生时,会经由这个类型的过滤器处理
zuul与Spring Cloud Config 整合:
须由zuul实例化 zuulproperties 且添加@RefreshScope
Spring Cloud Config:
占位符匹配git仓库:
默认仓库:
spring.cloud.config.server.git.uri=http://git.com/app/config-repo
占位符一(匹配路径:http://localhost:7000/dev/*):
spring.cloud.config.server.git.repos.dev.pattern=dev/* spring.cloud.config.server.git.repos.dev.uri=file://home/git/config-repo
占位符二(匹配路径:http://localhost:70000/prod/pp* 和 http://localhost:70000/online/oo*):
spring.cloud.config.server.git.repos.prod.pattern=prod/pp*,online/oo* spring.cloud.config.server.git.repos.dev.uri=http://git.com/app/config-repo
加密解密:
{cipher} 可以是仓库文件中密码自动加密
encrypt.key=xxxx 指定加密的盐
curl http://localhost:7000/encrypt -d xxx 加密
curl http://localhost:7000/decrypt -d ******** 解密
Client 端:
须指定:label (git分支)、profile(哪个环境的配置文件)、 server端url
失败快速响应:
spring.cloud.config.failFast=true 在项目启动时先连接config server
失败重试:
使用spring-retry 和spring-boot-starter-aop jar不需要其他配置,默认失败重试6次
spring.cloud.config.retry.multiplier:初始重试间隔时间(默认1000毫秒)
spring.cloud.config.retry.initial-interval:下一次间隔乘数 (默认1.1 本次1000毫秒 下次间隔1100毫秒)
spring.cloud.config.retry.-attempts:最大重试次数(默认6次)
动态刷新配置: 在client端引入actuator 通过/refresh 端点刷新配置 或者使用git hook