4 Spring Boot/Spring Cloud实践
4.1 SpringCloud实践
4.1.1 SoringCloud技术栈总览
- 服务治理:注册中心Eureka、断路器Hystrix、调用端负载均衡Ribbon、Rest客户端Feign、API网关Zuul、监控:Spectator,Servo,Atlas;配置读取Archaius和响应式编程RxJava;
- 配置中心:Spring Cloud Config
- 消息组件:SpringCloud Stream、SpringCloud Bus
- 分布式链路监控:Sleuth、Zipkin
- 安全控制:SpringCloud Security
- 数据处理:SpringCloud Task、SpringCloud Batch
4.1.2 常见项目脚手架
- XX-project-dependencies:maven版本管理
- XX-project-common:自定义错误码;自定义异常类、常量类;自定义结果对象;自定义注解;
- XX-project-logger:配置和扩展日志(MDC增加错误码等信息),Sleuth的调用链信息;
- XX-project-cache:
- XX-project-session:
- XX-project-minio:
- XX-project-feign-jars:自动化装配;支持JAX-RS;异常拦截和转换(ErrorDecoder.Default);权限传递(拦截器实现);
- XX-project-resteasy:支持springboot starter;发布接口实现为REST服务;接口权限控制;
- XX-project-exception:
- XX-project-swagger-ui:swagger文档
5 微服务稳定性保证的常用手段
5.1 微服务的稳定性
- 技术实践:高可用、高并发
- 流程管理和支持
5.2 微服务高可用
5.2.1 限流实践
限流常用实现算法
- 计数器:计数阈值不灵活
- 漏桶算法:消费速度恒定,队列和拒绝策略,类似线程池原理;
- 令牌桶:消费速度可以通过控制令牌的发放进行控制;
限流算法代码实现:
- guava包的RateLimiter实现:代码侵入性比较强;
5.2.2 断路器实现
- NetFix开源的Hystrix:默认选择:断路器、隔离机制(线程池、信号量)、请求聚合、请求缓存
- Alibaba开源的Sentinel:主要概念包括资源和规则;主要功能包括:熔断降级(限制并发线程数、通过响应时间来对资源访问进行降级);流量控制;系统负载保护(保证入口流量和系统负载能力的匹配);集成简单,并且具有DashBoard,还能和Nacos集成进行配置持久化。
5.2.3 超时与重试
- 中间件的超时配置:Dubbo、数据库连接池、Hbase等都支持;
- 重试代码实现:(1)手动通过循环和异常控制重试;(2)通过重试组件(guava-retrying和spring-retrying)等组件进行重试;
5.3 微服务高并发
高并发解决思路的两个指导性原理,
- 阿姆达尔定律:在并行计算中用多处理器的应用加速受限于程序所需的串行时间百分比;
- 局部性原理:时间局部性和空间局部性;
由此衍生出的常见高并发策略:异步、缓存和池化。
5.3.1 线程池-JVM内部异步
自定线程池实现并可用调度线城池实现线程池的定时监控;
5.3.2 异步回调机制-JVM内部异步
HTTP调用可以使用async-http client组件;
5.3.4 消息队列-JVM外部
Kafka、RocketMQ等;
5.3.5 缓存
基本使用思路是CacheAcide模式,
- 读数据:先读取缓存,有直接返回,没有读取DB并存入缓存;
- 写数据:先更新DB,让缓存失效,触发读数据缓存策略;
常见的缓存问题:
- 缓存穿透:同时大并发请求KEY不存在的缓存,请求会全部穿透到DB;
- 缓存雪崩:服务器重启或者缓存集中失效导致的DB压力增加;
- 大Value缓存监测:缓存value值过大会影响读取性能;
- 热点Key缓存:大量热点KEY聚集在某一单机服务器造成的服务器压力增大,采用本机缓存或者热点缓存KEY列表维护和监控;
6 微服务下如何保证事务的一致性
6.1 本地事务VS分布式事务
本地事务的ACID特性,
- A原子性:Atomic,全部成功或者全部失败(回滚)的非中间状态;
- C一致性:Consistency事务执行前后一致性状态;
- I隔离性:Isolation,多事务之间互不影响;
- D持久性:事务的结果会持久化保存;
导致分布式事务的背景原因:分库分表、服务间调用等;
分布式事务的基本特性(平衡理论):
- C一致性:Consistency,最终一致性
- A可用性:Availability,尽量保证
- P分区容错性:Partition-tolerance,必须保证
分布式理论实践准则和原理:BASAE.BASE(Basically Available-基本可用、Soft-state-软状态、Eventually Consistent-最终一致性),基本思路是允许损失部分可用性达到最终一致性。
常见的分布式事务解决方案包括:两阶段提交协议、三阶段提交协议、最终一致性的可靠事件模式、补偿模式、阿里的TCC模式。
6.2 二阶段提交协议-强一致性协议
两阶段包括:
- 准备:通过准备命令预提交;
- 提交:正式提交;
实现主要包括XA协议,XA协议主要包括事务协调者和资源管理者两个角色。
缺点包括:
- 同步阻塞:等待每个资源管理者的响应容易导致同步阻塞问题;
- 单点故障:事务协调者和资源管理者本身的宕机不可用问题;
6.3 三阶段提交协议-强一致性协议
相对于二阶段提交协议主要增加了以下特性:
- 超时机制解决同步阻塞问题;
- 预备阶段提前发现无法执行的资源管理者;
- 三阶段主要包括:预备、准备和提交;
6.4 TCC模式-最终一致性协议
TCC将一个任务拆分成三个操作:Try、Confirm和Cancel。本质上面也是一个2阶段提交协议。
TCC模式主要包括:主业务、从业务(TCC拆分)和事务管理器等角色实现。
TCC模式的开源框架实现:tcc-tranction。
TCC模式包含的事务恢复机制:给予Quartz实现的最大次数重试机制;
操作的幂等性:保证资源唯一性,重复提交和重试机制产生一致性结果;
保证操作幂等性的方案:
- 唯一索引方案:识别和判断重复操作;
- 状态机方案:业务流程化执行保证数据幂等性;
6.5 补偿模式-最终一致性协议
包括以下方案思路:
- 重试机制:尽最大努力重试,保证数据操作一致性。主要分为固定次数和固定时间的重试策略,RocketMQ自带消息重试机制。
- 更新时修复:点赞数、收藏数等在每次更新时进行异常数据修复;
- 定时校对:基于Quartz、Elastic-JOB、XXL-JOB或者SchedulerX等定时框架实现定时校对;
6.6 可靠事件模式-最终一致性协议
针对消息队列保证消息投递和消费的一致性。
- 手动ACK机制,消费方自动控制消息队列消息消费进度;
- 正反向消息机制:处理主要包括主业务先存当前业务快照到数据库,然后发送消息队列,发送成功则处理后续业务,消费者监听消息并保证幂等处理,处理成功则发送消息队列消息,结合定时任务补偿机制,确保数据库中的业务快照信息的成功投递。
6.8 开源项目的分布式事务实现解读
6.8.1 Apache RocketMQ
分布式事务消息:先发送预执行消息,然后执行本地事务,根据本地事务执行结果决定是正式投递MQ消息还是回滚预执行消息。
6.8.2 HUAWEI ServiceComb
Saga:Sega引擎负责协调多个本地事务,如果出现失败,则调用补偿操作,两种补偿操作策略包括向前恢复[重试]和向后恢复[回滚]。
Saga主要包括Alpha和Omega两个组件:
Alpha:协调服务,针对事务的时间进行持久化存储;
Omega:agent,拦截网络请求并上报alpha事务事件,异常情况下根据Alpha的指令进行补偿操作;
7 百亿流量微服务网关的设计与实现
7.1 API网关概述
7.1.1 API网关的智能
MSA(微服务架构)下的API网关类似于SOA(基于服务的架构)下的ESB,主要职责包括:
- 请求接入:API服务请求的接入点;
- 业务聚合:所有厚度按业务的聚合点
- 中介策略:实现安全、验证、路由、过滤和流控等策略;
- 统一管理:API服务和策略进行统一管理
7.1.2 开源API网关选型
- SpringCloud Gateway:Java技术栈新秀,推荐使用;
- ZULL/ZULL2:社区不够活跃;
- Kong:需要结合Lua脚本使用,适合做流量网关;
- OpenResty: 需要结合Lua脚本使用,适合做流量网关;
性能对比上看:
SCG~ZULL系列 < OpenResty < Kong < 直连。性能的问题可以用机器的水平扩容来解决,不直接决定网关的选型。
7.1.3 百亿级流量API网关实现思路
OpenResty(流量网关)—》业务网关(基于Vert.X实现或者其他开源实现)。
8 微服务编排
常用为服务编排框架:Netfix Conductor
与相对应的有Camunda Zeebe框架。
IMPORTANT TODO:微服务编排和传统BPM框架的有啥区别???
9 微服务数据抽取与统计
数据仓库:ODS临时数据存储层—>DW层数据仓库层---->DM层数据集市层。
- Hive:基于HDFS的分布式文件数据库,支持HiveSQL语法,将SQL转换成底层的MapReduce任务;
- Sqoop:从关系型数据库抽取数据导HDFS、Hive和Hbase中。
10 微服务双活体系建设
双机房双活数据中心建设思路,
双机房部署,首先主要在网络层面打通双机房的相互访问;
双活包括:主备切换模式和双活同时服务模式;其中后者需要在入口网关或者Nginx+Lua做请求路由。
常用第三方组件的双活保障:
- ZooKeeper:统一配置中心、分布式锁、命名服务(分布式ID)、分布式协调/通知、集群服务、服务的注册中心等。针对配置中心的数据同步可以采用ZooKeeper Curator的TreeCache来实现
- Redis:主从机制实现数据同步;
- Mysql:主主同步方案、使用Canel+Otter实现数据同步;
支付场景下面常见的双活架构:
- 基于应用的主备架构:(1)应用层面的Slave机房通过专线访问主机房的Mysql数据库;(2)Redis通过主从实现数据同步;(3)ZooKeeper和Duboo等主备机房单独部署并实现隔离;(4)Mysql数据库采用Canel实现主备同步;(5)切换过程需要几十分钟,短暂服务不可用;
- 双活架构:(1)入口网关流量层面采用Nginx+Lua等方式实现根据业务ID的固定分流策略;(2)Redis通过主从实现数据同步;(3)ZooKeeper和Duboo等主备机房单独部署并实现隔离;(4)Mysql数据库采用Otter Binlog实现主住同步;