spring cloud组件详解
Spring Cloud中,Eureka常见问题总结
一、eureka
Eureka 是一种基于 REST(Representational State Transfer)的服务,主要用于 AWS 云,用于定位服务,以实现中间层服务器的负载平衡和故障转移。
上面的架构图描述了 Eureka 是如何在 Netflix 部署的,这也是 Eureka 集群的运行方式。在每个区域(region)都有一个 eureka 集群,它只知道该区域内的实例信息。每个分区(zone)至少有一个 eureka 服务器来处理本分区故障。
服务注册在 Eureka 上并且每 30 秒发送心跳来续租。如果一个客户端在几次内没有刷新心跳,它将在大约 90 秒内被移出服务器注册表。注册信息和更新信息会在整个 eureka 集群的节点进行复制。任何分区的客户端都可查找注册中心信息(每 30 秒发生一次)来定位他们的服务(可能会在任何分区)并进行远程调用。
Eureka 组件
Zookeeper 和 Eureka 区别
著名的 CAP 理论指出,一个分布式系统不可能同时满足 C (一致性)、A (可用性) 和 P (分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在 A 和 C 之间进行权衡。在此 Zookeeper 保证的是 CP, 而 Eureka 则是 AP。
zookeeper 优先保证 CP,当服务发生故障会进行 leader 的选举,整个期间服务处在不可用状态,如果选举时间过长势必会大幅度降低性能,另外就用途来说 zookeeper 偏向于服务的协调,当然含有注册中心的作用
eureka 优先保证 AP, 即服务的节点各个都是平等的,没有 leader 不 leader 一说, 当服务发生故障时,其余的节点仍然可以提供服务,因此在出现故障时,性能表现优于 zookeeper,但是可能会造成数据不一致的情况。
二、Ribbon
源码地址:https://github.com/Netflix/ribbon
Ribbon是Netflix发布的负载均衡器,它可以帮我们控制HTTP和TCP客户端的行为。只需为Ribbon配置服务提供者地址列表,Ribbon就可基于负载均衡算法计算出要请求的目标服务地址。
Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机、响应时间加权等——当然,为Ribbon自定义负载均衡算法也非常容易,只需实现IRule
接口即可。
内置负载均衡规则
负载均衡规则是Ribbon的核心,下面来看一下Ribbon内置的负载均衡规则。
- AvailabilityFilteringRule:过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个Server的运行状态;
- BestAvailableRule:选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过。
- RandomRule:随机选择一个Server;
- ResponseTimeWeightedRule:作用同WeightedResponseTimeRule,二者作用一样;
- RetryRule:对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的server;
- RoundRobinRule:轮询选择, 轮询index,选择index对应位置的Server;
- WeightedResponseTimeRule:根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低;
- ZoneAvoidanceRule:复合判断Server所在区域的性能和Server的可用性选择Server;
**如需自定义负载均衡规则,只需实现IRule
接口或继承AbstractLoadBalancerRule
、PredicateBasedRule即可
**,读者可参考RandomRule
、RoundRobinRule
、ZoneAvoidanceRule
等内置Rule编写自己的负载均衡规则。
配置案例:
user:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
三、Feign
源码地址:https://github.com/OpenFeign/feign
Feign是Netflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、JAXRS-2.0以及WebSocket。Feign可帮助我们更加便捷、优雅地调用HTTP API。
四、Hystrix
应用容错三板斧
超时机制
超时机制你懂的,配置一下超时时间,例如1秒——每次请求在1秒内必须返回,否则到点就把线程掐死,释放资源!
思路:一旦超时,就释放资源。由于释放资源速度较快,应用就不会那么容易被拖死。
舱壁模式
思路:不把鸡蛋放在一个篮子里。你有你的线程池,我有我的线程池,你的线程池满了和我没关系,你挂了也和我没关系。
断路器
实时监测应用,如果发现在一定时间内失败次数/失败率达到一定阈值,就“跳闸”,断路器打开——此时,请求直接返回,而不去调用原本调用的逻辑。
跳闸一段时间后(例如15秒),断路器会进入半开状态,这是一个瞬间态,此时允许一次请求调用该调的逻辑,如果成功,则断路器关闭,应用正常调用;如果调用依然不成功,断路器继续回到打开状态,过段时间再进入半开状态尝试——通过”跳闸“,应用可以保护自己,而且避免浪费资源;而通过半开的设计,可实现应用的“自我修复“。
Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。
Hystrix主要通过以下几点实现延迟和容错:
- 包裹请求
使用HystrixCommand(或HystrixObservableCommand)包裹对依赖的调用逻辑,每个命令在独立线程中执行。这使用到了设计模式中的“命令模式”。
- 跳闸机制
当某服务的错误率超过一定阈值时,Hystrix可以自动或者手动跳闸,停止请求该服务一段时间。
- 资源隔离
Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定。
- 监控
Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等。
- 回退机制
当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑可由开发人员自行提供,例如返回一个缺省值。
- 自我修复
断路器打开一段时间后,会自动进入“半开”状态。断路器打开、关闭、半开的逻辑转换。
Turbine是一个聚合Hystrix监控数据的可视化工具,它可将所有相关/hystrix.stream端点的数据聚合到一个组合的/turbine.stream中,从而让集群的监控更加方便。
五、Zuul
源码:
https://github.com/Netflix/zuul
Zuul是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用。Zuul的核心是一系列的过滤器,这些过滤器帮助我们完成以下功能:
- 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求;
- 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而为我们带来精确的生产视图;
- 动态路由:动态地将请求路由到不同的后端集群;
- 压力测试:逐渐增加指向集群的流量,以了解性能;
- 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求;
- 静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群;
- 多区域弹性:跨越AWS Region进行请求路由,旨在实现ELB(Elastic Load Balancing)使用的多样化;以及让系统的边缘更贴近系统的使用者。
过滤器详解
Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。
(1) PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
(2) ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
(3) POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
(4) ERROR:在其他阶段发生错误时执行该过滤器。
除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。
各种类型的过滤器的执行顺序:
自定义过滤器:
1)继承抽象类ZuulFilter
2)实现以下几个方法:
filterType
:返回过滤器的类型。有pre、route、post、error等几种取值,分别对应上文的几种过滤器。filterOrder
:返回一个int值来指定过滤器的执行顺序,不同的过滤器允许返回相同的数字。shouldFilter
:返回一个boolean值来判断该过滤器是否要执行,true表示执行,false表示不执行。run
:过滤器的具体逻辑。
禁用Zuul过滤器:
只需设置zuul.<SimpleClassName>.<filterType>.disable=true
,即可禁用SimpleClassName所对应的过滤器。
以过滤器org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter为例,只需设置zuul.SendResponseFilter.post.disable=true
,即可禁用该过滤器。
六、Spring Cloud Config 配置中心
源码:https://github.com/spring-cloud/spring-cloud-config
Spring Cloud Config为分布式系统外部化配置提供了服务器端和客户端的支持,它包括Config Server和Config Client两部分。
架构:
启动时加载配置文件
默认情况下,在配置被首次请求时,Config Server才会clone Git仓库。我们也可让Config Server在启动时就clone Git仓库,例如。
spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo repos: team-a: pattern: microservice-* clone-on-start: true uri: http://git.oschina.net/itmuch/spring-cloud-config-repo
将属性spring.cloud.config.server.git.repos.*.clone-on-start
设为true,即可让Config Server启动时clone指定Git仓库。
当然,也可使用spring.cloud.config.server.git.clone-on-start = true
进行全局配置。
配置clone-on-start = true,可帮助Config Server启动时快速识别错误的配置源(例如无效的Git仓库)。
技巧:
将以下包的日志级别设为DEBUG,即可打印Config Server请求Git仓库的细节。我们可借助日志,更好地理解Config Server的Git仓库配置,同时,也便于我们快速定位问题。
logging:
level:
org.springframework.cloud: DEBUG
org.springframework.boot: DEBUG
配置属性加解密
配置动态刷新
配置刷新三要素
1)依赖中有spring-boot-starter-actuator
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2)添加如下配置,暴露
/actuator/refresh
端点:
management:
endpoints:
web:
exposure:
include: refresh
3)待刷新的配置属性所在的类上添加了@RefreshScope
注解 ,例如:
@RestController @RefreshScope public class ConfigClientController { @Value("${profile}") private String profile; @GetMapping("/profile") public String hello() { return this.profile; } }
这样,修改profile
配置后,只需向应用的/actuator/refresh
端点发送POST请求,即可刷新该属性。例如:
curl -X POST http://localhost:8081/actuator/refresh
gitlib:https://about.gitlab.com/high-availability/
Config Server注册到Eureka Server上
=============================================================================
Spring Cloud Alibaba
Nacos
Nacos 是阿里开源的易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos是一个注册中心Eureka& 配置中心config
安装&启动
下载地址:
https://github.com/alibaba/nacos/releases
应用:
pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR2</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>0.2.1.RELEASE</version> </dependency>
配置:
spring: application: # 注册到Nacos上的服务名称 name: microservice-provider-user cloud: nacos: discovery: server-addr: 127.0.0.1:8848
注解:
@SpringBootApplication @EnableDiscoveryClient public class ProviderUserApplication { public static void main(String[] args) { SpringApplication.run(ProviderUserApplication.class, args); } ... }
启动后,访问 http://127.0.0.1:8848/nacos
输入账号密码:nacos/nacos
Sentinel
Sentinel是一个轻量级的流量控制、熔断降级 Java 库。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
案例:
pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>0.2.1.RELEASE</version> </dependency>
配置:
server: port: 8010 spring: application: # 指定注册到nacos server上的服务名称 name: microservice-consumer-movie cloud: nacos: discovery: server-addr: 127.0.0.1:8848 management: endpoints: web: exposure: include: '*'
controller:
@RequestMapping("/movies") @RestController public class MovieController { @Autowired private RestTemplate restTemplate; @GetMapping("/users/{id}") public User findById(@PathVariable Long id) { // 这里用到了RestTemplate的占位符能力 User user = this.restTemplate.getForObject( "http://microservice-provider-user/users/{id}", User.class, id ); // ...电影微服务的业务... return user; } }
Sentinel starter默认情况下就会为所有的 HTTP服务提供限流埋点
访问 http://localhost:8010/actuator/sentinel
参考文档:
https://www.itmuch.com/spring-cloud/spring-cloud-index/
1,springcloud 1.x版本与2.x版本区别?
配置中心做了比较大的改动
2,SpringCloud和SpringCloudAlibaba的区别?
SpringCloudAlibaba实际上对我们的SpringCloud2.x和1.x实现拓展组件功能.
1)nacos 分布式配置中心+分布式注册中心=Eureka+config
2)使用了SpringCloudAlibaba,最好使用alibaba整个体系产品