0. 为了适应不同版本的差异,没少踩坑…
该随笔作为我第一次搭建分布式工程的踩坑记录,因此引用、缝合了一些大佬的内容 以及 一些自己实操过程遇到的问题。
springcloud组件关系:
1. eureka
引入
注册中心
配置
默认端口8761
localhost:8761 -> UI
localhost:8761/eureka -> 服务注册地址
register-with-eureka 非集群的eureka服务端需要置false
fetch-registry 非集群的eureka服务端需要置false
service-url.defaultZone
这一块不能写错,IDE不会提示的,因为这里将作为Map的key
https://blog.csdn.net/shine_guo_star/article/details/103418188
prefer-ip-address
ip/hostname 注册方式
https://juejin.cn/post/6844903993261441031
还可以配置拉取服务的间隔、心跳上报的间隔...
服务发现
推荐使用@EnableDiscoveryClient替代@EnableEurekaClient
SpringCLoud中的“Discovery Service”有多种实现,比如:eureka, consul, zookeeper
spring-cloud eureka (2.x版本) 密码认证
https://blog.csdn.net/qq_37054881/article/details/86608151
依赖于spring-boot-starter-security
不同于1.x的是
spring.security.basic.enabled=true(1.x并没有"spring"前缀)
CSRF 攻击防御
重写WebSecurityConfigurerAdapter的configure方法,因为 Spring Security 默认开启了所有 CSRF 攻击防御,需要禁用 /eureka 的防御。
高可用集群
service-url.defaultZone eureka服务端节点互相注册
优雅停服
何时?
满足自我保护条件
微服务向Eureka服务注册之后,通过判断是否定时有心跳来判断微服务是否健康
如果一段时间内微服务心跳失败的比例超过Eureka服务配置的阈值
可能造成Eureka服务接受不到心跳的原因
微服务本身的原因
通常是个别服务出现
微服务与Eureka服务之间的网络存在故障
可能导致短时间内没有接受到大批量的心跳
为什么需要自我保证机制
即便是保留一些"坏数据"也比丢数据强
防止微服务的提供者、调用者不经过Eureka,而是直接通信
即便是Eureka服务端节点全部宕机,微服务的提供者、调用者仍然可以相互访问
这是因为:Eureka的客户端有缓存功能(微服务的缓存功能)
微服务的负载均衡策略会自动剔除死亡的微服务节点
咋做?
需要依赖模块 spring-boot-actuator
修改Eureka的服务配置
不要 关闭自我保护机制(默认true)
eureka.server.enableSelfPreservation
启用 actuator 的配置
endpoints.shutdown.enabled=true #启用
endpoints.shutdown.sensitive=false #禁用密码校验
可以是Eureka自己停服、也可以是在另一个服务中通过url来远程停服(post:/actuator/shutdown)
如果配置了密码验证的话,可以放行/actuator
自我保护机制
Eureka UI警告:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NO
https://blog.csdn.net/weixin_30632089/article/details/94968244
2. ribbon
负载均衡的类型:
feign&ribbon&hystrix:
引入
负载均衡
支持通过服务名调用提供者(具体调度由注册中心完成)
很多netflix组件都集成了ribbon(zuul、feign等等),这些组件的重试多采用ribbon的方案
底层由拦截器实现
配置
支持配置调用超时(连接、读取)、服务客户端预加载、均衡算法、重试参数、并发参数(池大小)、客户端支持(restclient...)
支持配置全局的、指定服务的
有趣的是,http客户端相关的参数可以采用另一种方式配置-->通过new RestTemplate(request factory)中的factory
其中超时等配置项是没有提示的,如果疏忽首字母大写,将导致配置失效
均衡算法
IRule接口支持
默认轮询
默认算法配置类不能放到@ComponentScan注解同级或者子级(或者将其exclued掉)
RibbonLoadBalancerClient
ribbon客户端对象
可以根据均衡算法选中一个服务实例
重试
需要spring-retry
默认false
预加载
防止服务客户端在第一次调用时候的初始化导致的调用超时
默认false
脱离eureka
将serviceId & 实际地址的映射关系直接配置到ribbon
补充阅读
使用样例
https://zhuanlan.zhihu.com/p/360395531
源码走读
https://blog.csdn.net/shuaigeyimei1/article/details/106668431
https://blog.csdn.net/chengkui1990/article/details/80742225
基于Zuul,Feign的请求重试及全局幂等方案
http://events.jianshu.io/p/ef785368d586
3.restTemplate
引入
spring针对Http基于Restful风格的封装
通过RestTemplate类来代理服务端实现类
负载均衡
相比feign,并没有集成ribbon,需要手动引入并开启
通过配置文件配置的ribbon全局超时参数对restTemplate不起作用,可以通过在@Bean注入
4. feign
引入
底层基于restTemplate,面向接口编程的封装
openfeign
集成了spring-boot-web
建议使用,feign已停止维护
使用
@FeignClient将自动注入到ioc
一个服务声明多个@FeignClient,启动将报错
5. hystrix
hystrix状态转换图:
引入
在微服务架构中多层服务之间会相互调用,如果其中有一层服务故障了,可能会导致一层服务或者多层服务故障,从而导致整个系统雪崩。
熔断状态的转换关系
feign、zuul等组件已集成hystrix
抽象
1、熔断模式:熔断模式原理类似于电路熔断器,当电路发生短路时,熔断器熔断,保护电路避免遭受灾难性损失。
当服务异常或者大量延时,满足熔断条件时服务调用方会主动启动熔断,执行fallback逻辑直接返回,不会继续调用服务进一步拖垮系统。熔断器默认配置服务调用错误率阀值为50%,超过阀值将自动启动熔断模式。服务隔离一段时间以后,熔断器会进入半熔断状态,即允许少量请求进行尝试,如果仍然调用失败,则回到熔断状态,如果调用成功,则关闭熔断模式。
2、隔离模式:Hystrix默认采用线程隔离,不同的服务使用不同的线程池,彼此之间不受影响,当一个服务出现故障耗尽它的线程池资源,其他的服务正常运行不受影响,达到隔离的效果。例如我们通过andThreadPoolKey配置某个服务使用命名为TestThreadPool的线程池,实现与其他命名的线程池隔离。
3、回退(fallback):fallback机制其实是一种服务故障时的容错方式,原理类似Java中的异常处理。只需要继承HystixCommand并重写getFallBack()方法,在此方法中编写处理逻辑,比如可以直接抛异常(快速失败),可以返回空值或缺省值,也可以返回备份数据等。当服务调用出现异常时,会转向执行getFallBack()。有以下几种情况会触发fallback:
程序抛出非HystrixBadRequestExcepption异常,当抛出HystrixBadRequestExcepption异常时,调用程序可以捕获异常,没有触发fallback,当抛出其他异常时,会触发fallback;
程序运行超时;
熔断启动;
线程池已满。
4、限流: 限流是指对服务的并发访问量进行限制,设置单位时间内的并发数,超出限制的请求拒绝并fallback,防止后台服务被冲垮。
Hystix使用命令模式HystrixCommand包装依赖调用逻辑,这样相关的调用就自动处于Hystrix的弹性容错保护之下。调用程序需要继承HystrixCommand并将调用逻辑写在run()中,使用execute()(同步阻塞)或queue()(异步非阻塞)来触发执行run()。
配置
Ribbon的超时时间一定要小于Hystix的超时时间。
工作原理
https://blog.csdn.net/weixin_39513166/article/details/106613430 Hystrix进行熔断保护。保护的方法就是使用 Fallback 来实现服务降级
Hystrix 间隔时间会再次检查故障的服务,如果故障服务恢复,将继续使用服务。
使用
在restTemplate中使用断路器
spring-cloud-netflix-hystrix
@EnableHystrix
应用启动类
@HystrixCommand
属性fallbackMethod表示熔断功能的方法名
表达这是一个需要启动熔断的业务调用方法
熔断方法的签名
[远程被调服务返回类型] [熔断方法名(调用远程服务的方法的传参)]
熔断方法的返回值将替代远程被调服务的返回值
参考:https://www.cnblogs.com/duanxz/p/15708773.html
在feign中使用断路器
feign是自带断路器的,故配置中打开feign.hystrix.enabled: true
接口中使用@FeignClient指定熔断方法的实现类名、需要被熔断的被调服务的方法名
hystrix dashboard
https://www.cnblogs.com/johnvwan/p/15666263.html
6. zuul
springcloud带有网关的实例项目关系图:
引入
网关
作用类似Servlet框架中的Filter
springcloud gateway中只集成了zuul 1.x,2.x版本并未开源
配置
超时、重试
路由配置方式
https://blog.csdn.net/m0_50217781/article/details/112974248
stripPrefix
https://blog.csdn.net/u010953880/article/details/102977884
filter
通过extends ZuulFilter来创建自己的过滤器
支持配置过滤链路的执行优先级、过滤的时机等等
重试源码解读
https://blog.csdn.net/liuhuiteng/article/details/107480367
参考
https://www.cnblogs.com/jing99/p/11696192.html
7.config
分布式架构下的VCS和配置中心服务:
引入
配置中心
可以不用注册到注册中心
参考
https://www.jianshu.com/p/e48de30aab76
服务配置读取无效的一些原因:
配置加载的层级
boostrap(系统层级) > application(应用层级)
同一层级下,配置文件加载优先级(即后加载的配置将覆盖前面的配置)
properties > yaml > yml
动态拉取最新配置
借助spring-boot-actuator:refresh
配置中心server启动报错: Authentication is required but no CredentialsProvider has been registered
私人VCS仓库是加密的,需要配置中加上账户密码(当然啦,也可以采用密文的方式)
8.sleuth
为何需要服务间的 链路追踪 ?
引入
链路追踪
为什么需要?
在复杂的微服务架构系统中,各微服务间的调用关系也变得越来越复杂
为什么是sleuth?
链路追踪
分析性能(服务调用耗时)
数据分析(统计服务调用频率、是否并行调用)
可视化(借助zipkpin)
咋用?
为需要追踪的微服务都添加依赖
spring-cloud-sleuth
spring-cloud-zipkpin
怎么个分析?
sleuth日志
Trace [微服务id,Trace id,Span id,是否导出]
这么看来,sleuth已经发挥作用力,但是可读性还是不够
可视化的链路追踪
twitter zipkin
特点
C/S、轻量级、部署简单、基于sleuth
运行方式
zipkin-server.jar单独运行(不推荐)
整合到springcloud
zipkin服务端
引入依赖zipkin-server、zipkin-autoconfigure-ui
@EnableDiscoveryClient/@EnableEurekaClient
@EnableZipkinServer
如果UI出不来 && 控制台报错:alll meters have same set of tag keys ... named 'http_server-requests_seconds'
可能是springboot默认启用了监控web应用的这个key
management.metrics.web.server.auto-time-requests:false
微服务端
引入spring-cloud-zipkin
修改sleuth配置
spring
sleuth
sampler: #采样器
probability:默认0.1 #trace采样率
rate: #每秒采集的trace数据量
zipkin
base-url: #表示给哪个zipkin服务发送信息
UI api:/zipkin
pinpoint
支持多种插件、UI强大、基于字节码注入(是无侵入的)
skywalking
来自华为、字节码注入、已加入apache
cat
大众点评、基于编码和配置、集 监控、分析、日志、报警
阿里鹰眼
...
使用
Spring Cloud 整合 zipkin 报错:org.springframework.boot.actuate.health.CompositeHealthIndicator
官网推荐使用jar包方式运行
ResourceAccessException: I/O error on POST request for
依赖中含有 zipkin 依赖,没有配置 zipkin-server, 默认提交9411