项目集·Java-分布式
- 一、Dubbo
- 1、项目背景
- 2、Dubbo特性
- 2.1 负载均衡
- 2.2 异步应用
- 2.3 结果缓存
- 2.4 并发、连接控制(结合Hystrix)
- 二、SpringCloud
- 1、技术栈
- 2、基于Hystrix的多级缓存服务降级
- 3、分布式事务
- 4、Zookeeper分布式锁
- 三、Dubbo·分布式架构
- 1、 分布式理论
- 1.1 C(一致性)A(可用性)P(分区容错性)
- 1.2 BA(基本可用)S(软状态)E(最终一致性)
- 1.3 Dubbo
- 1.3.1 服务提供者能实现失效踢出是什么原理
- 1.3.2 服务上线怎么不影响旧版本
- 1.3.3 如何解决服务调用链过长的问题
- 1.3.4 Dubbo.xml的核心的配置有哪些
- 1.3.5 Dubbo 集群容错
- 1.4 Spring Cloud
- 1.4.1 微服务的好处
- 2、分布式配置中心
- 2.1 Spring Cloud Config & Bus
- 2.1.1 服务调用
- 2.1.2 动态刷新
- 2.1.3 Config 高可用
- 2.2 Apollo
- 2.3 Spring Cloud Alibaba Nacos
- 3、服务注册中心
- 3.1 Zookeeper
- 3.1.1 Zookeeper应用场景
- 3.1.2 ZAB (原子广播协议)
- 3.1.3 Zookeeper选举流程
- 3.1.4 Zookeeper顺序一致性
- 3.1.5 Zookeeper集群为什么采用一主多从架构
- 3.2 Spring Cloud Eureka
- 3.2.1 Eureka 高可用
- 3.2.2 服务续约 & 自我保护
- 3.2.3 Eureka 安全认证(外网情况下使用)
- 3.3 Spring Cloud Feign
- 3.4 Spring Cloud Alibaba Nacos
- 4、网关流控
- 4.1 Spring Cloud GateWay
- 5、集群容错
- 5.1 Spring Cloud Hystrix
- 5.1.1 Hystrix 原理
- 5.1.2 RestTemplate + Ribbon 使用 Hystrix
- 5.1.3 Feign 使用 Hystrix
- 5.1.4 Turbine 聚合多个 Hystrix Dashboard
- 5.2 Spring Cloud Alibaba Sentinel
- 6、分布式事务
- 6.1 基于定时
- 6.2 基于MQ
一、Dubbo
1、项目背景
服务聚合、熔断降级、身份安全
2、Dubbo特性
2.1 负载均衡
- 随机(按权重随机访问)、轮询、最少活跃和一致性Hash(相同参数的请求,都发给同一台)
2.2 异步应用
Future barFuture = RpcContext.getContext().getFuture();
barService.findBar(barId);
Bar bar = barFuture.get();
2.3 结果缓存
@Reference cache=“lru”
2.4 并发、连接控制(结合Hystrix)
executor、conn
二、SpringCloud
1、技术栈
Spring Cloud Eureka(注册中心)、OpenFegin(服务调用)、Hystrix(服务降级)、GateWay(网关)、SkyWalking(链路追踪)
2、基于Hystrix的多级缓存服务降级
3、分布式事务
4、Zookeeper分布式锁
三、Dubbo·分布式架构
1、 分布式理论
1.1 C(一致性)A(可用性)P(分区容错性)
- 强一致性
- 最终一致性
1.2 BA(基本可用)S(软状态)E(最终一致性)
1.3 Dubbo
Dubbo框架可以分为10层,而这10层又可以归为Business、RPC、Remoting这三层。
Business
Service业务层:业务代码的接口和实现。我们实际使用的Dubbo的业务层级。该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
RPC
Config配置层: 对外的配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。主要是dubbo的一些配置。
Proxy服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 扩展接口为ProxyFactory 。不论是Consumer还是Provider,Dubbo都会对其生成代理,在代理之间进行通信。
Registry注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService。进行服务的注册与发现。
Cluster路由层:封装多个Provider的路由以及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance。就是将多个服务组合起来形成一个大服务。
Monitor监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService。
Remoting
Protocol 远程调用层:封装 RPC 调用,以 Invocation, Result 为中心,扩展接口为 Protocol, Invoker, Exporter。
Exchange 信息交换层:封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer。
Transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec。
Serialize 数据序列化层:可复用的一些工具,扩展接口为 Serialization, ObjectInput, ObjectOutput, ThreadPool。
1.3.1 服务提供者能实现失效踢出是什么原理
服务失效踢出基于 Zookeeper 的临时节点原理。
1.3.2 服务上线怎么不影响旧版本
采用多版本开发, 不影响旧版本。
1.3.3 如何解决服务调用链过长的问题
可以结合 Zipkin 实现分布式服务追踪。
1.3.4 Dubbo.xml的核心的配置有哪些
配置 配置说明
dubbo:service 服务配置
dubbo:reference 引用配置
dubbo:protocol 协议配置
dubbo:application 应用配置
dubbo:module 模块配置
dubbo:registry 注册中心配置
dubbo:monitor 监控中心配置
dubbo:provider 提供方配置
dubbo:consumer 消费方配置
dubbo:method 方法配置
dubbo:argument 参数配置
1.3.5 Dubbo 集群容错
集群容错方案 说明
Failover Cluster 失败自动切换,自动重试其它服务器(默认)
Failfast Cluster 快速失败,立即报错,只发起一次调用
Failsafe Cluster 失败安全,出现异常时,直接忽略
Failback Cluster 失败自动恢复,记录失败请求,定时重发
Forking Cluster 并行调用多个服务器,只要一个成功即返回
Broadcast Cluster 广播逐个调用所有提供者,任意一个报错则报错
1.4 Spring Cloud
1.4.1 微服务的好处
- 独立开发、独立部署、故障隔离
- 身份认证 – 验证用户或客户身份并颁发安全令牌
- API 网关 – 处理客户端请求
Spring Boot版本号 | Spring Cloud版本号 |
1.2.x | Angel版本 |
1.3.x | Brixton版本 |
1.4.x | Camden版本 |
1.5.x | Dalston版本、Edgware版本 |
2.0.x(Java8) | Finchley版本 |
2.1.x | Greenwich版本 |
2.2.x | Hoxton版本 |
2、分布式配置中心
- 安全性、动态修改、即时刷新(不需重启服务)
2.1 Spring Cloud Config & Bus
2.1.1 服务调用
- Server:
启动类上加@EnableEurekaServer注解
配置文件上加spring.cloud.config.server.git.uri 用户名、密码
- Client:
配置文件上加spring.cloud.config.label=master 分支、策略、文件名
2.1.2 动态刷新
- 局部刷新:Actuator Refresh
- 全局刷新:
2.1.3 Config 高可用
- 注册到Eureka
2.2 Apollo
2.3 Spring Cloud Alibaba Nacos
3、服务注册中心
3.1 Zookeeper
Zookeeper是基于CP来设计的,即任何时刻对Zookeeper的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是它不能保证每次服务请求的可用性。从实际情况来分析,在使用Zookeeper获取服务列表时,如果zookeeper正在选主,或者Zookeeper集群中半数以上机器不可用,那么将无法获得数据。所以说,Zookeeper不能保证服务可用性。
3.1.1 Zookeeper应用场景
分布式应用程序可以基于 Zookeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
Zookeeper 保证了如下分布式一致性特性:
1、顺序一致性
2、原子性
3、单一视图
4、可靠性
5、实时性( 最终一致性)
3.1.2 ZAB (原子广播协议)
ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持崩溃恢复的原子广播协议。
ZAB 协议包含两种模式:崩溃恢复和消息广播。
Zookeeper 集群刚刚启动或者 Leader 服务器宕机(需要重新选举时)、重启或者网络故障导致不存在过半的服务器与 Leader 服务器保持正常通信时,所有进程( 服务器)进入崩溃恢复模式,
首先选举产生新的 Leader 服务器, 然后集群中 Follower 服务器开始与新的 Leader 服务器进行数据同步, 当集群中超过半数机器与该 Leader 服务器完成数据同步之后, 退出恢复模式进入消息广播模式。
3.1.3 Zookeeper选举流程
Leader(分布式协调)、Follower(参与 Leader 选举投票)、Observer(不参与任何形式的投票)
服务器有四种状态,LOOKING、FOLLOWING、LEADING、OBSERVING。
1、LOOKING:寻找 Leader 状态。当服务器处于该状态时,它会认为当前集群中没有 Leader, 因此需要进入 Leader 选举状态。
2、FOLLOWING: 跟随者状态。表明当前服务器角色是 Follower。
3、LEADING: 领导者状态。表明当前服务器角色是 Leader。
4、OBSERVING: 观察者状态。表明当前服务器角色是 Observer。
3.1.4 Zookeeper顺序一致性
Zookeeper 根据全局递增的事务 Id(zxid)来保证事务的顺序一致性的
3.1.5 Zookeeper集群为什么采用一主多从架构
一台执行、多台共享、减少重复计算, 提高性能。
3.2 Spring Cloud Eureka
而Spring Cloud Netflix在设计Eureka时遵守的就是AP原则。Eureka Server也可以运行多个实例来构建集群,解决单点问题,但不同于ZooKeeper的选举leader的过程,Eureka Server采用的是Peer to Peer对等通信。这是一种去中心化的架构,无master/slave区分,每一个Peer都是对等的。在这种架构中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的serviceUrl指向其他节点。每个节点都可被视为其他节点的副本。
如果某台Eureka Server宕机,Eureka Client的请求会自动切换到新的Eureka Server节点,当宕机的服务器重新恢复后,Eureka会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会进行replicateToPeer(节点间复制)操作,将请求复制到其他Eureka Server当前所知的所有节点中。
3.2.1 Eureka 高可用
注册中心间的相互注册、同步服务清单
3.2.2 服务续约 & 自我保护
一个新的Eureka Server节点启动后,会首先尝试从邻近节点获取所有实例注册表信息,完成初始化。Eureka Server通过getEurekaServiceUrls()方法获取所有的节点,并且会通过心跳续约的方式定期更新。默认配置下,如果Eureka Server在一定时间内没有接收到某个服务实例的心跳,Eureka Server将会注销该实例(默认为90秒,通过eureka.instance.lease-expiration-duration-in-seconds配置)。当Eureka Server节点在短时间内丢失过多的心跳时(比如发生了网络分区故障),那么这个节点就会进入自我保护模式
3.2.3 Eureka 安全认证(外网情况下使用)
- 引入Spring Security依赖
- 在配置文件里添加spring.security.user的用户名和密码
- 关闭Spring Security的CSRF验证
package com.wind.eurekaserver;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
1. 如果eurekaServer设置了登录密码 就必须关闭Spring Security的CSRF验证
*/
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); //关闭csrf
super.configure(http);
}
}
- 客户端调用时,在eureka.client.serviceurl.defaultzone中加上用户名:密码@
3.3 Spring Cloud Feign
- 在Service接口上加@FeignClient
- 在程序启动类上加@EnableFeignClients,当程序启动时,就会扫描所有带@FeignClient的类,加载到Spring IOC容器中
3.4 Spring Cloud Alibaba Nacos
4、网关流控
- 流量分发、权限认证、服务降级
4.1 Spring Cloud GateWay
5、集群容错
- 故障隔离、服务熔断、快速失败、Fallback失败回退、Dashboard监控
5.1 Spring Cloud Hystrix
5.1.1 Hystrix 原理
- Hystrix断路器一共有三种状态:关、开、半开
- 请求失败阈值决定断路器的开关状态
- 请求数量 < 请求失败阈值 => {断路器状态关闭}
- 请求数量 > 请求失败阈值 => {断路器状态开启,走Fallback失败回退逻辑}
- 熔断器的自我恢复 => {断路器状态半开,开启限流模式,前限流数个请求成功,其余失败}
5.1.2 RestTemplate + Ribbon 使用 Hystrix
- 启动类添加@EnableHystrix注解
- 需要限流的方法上加@HystrixCommed(fallbackMethod=“xxx”)指向写有失败回退逻辑的方法
5.1.3 Feign 使用 Hystrix
5.1.4 Turbine 聚合多个 Hystrix Dashboard
- 启动类添加@EnableHystrixDashboard
- 8764/hystrix.stream
5.2 Spring Cloud Alibaba Sentinel
6、分布式事务
6.1 基于定时
6.2 基于MQ
-- ----------------------------
-- Table structure for broker_message_log
-- ----------------------------
DROP TABLE IF EXISTS `broker_message_log`;
CREATE TABLE `broker_message_log` (
`message_id` varchar(255) NOT NULL COMMENT '消息唯一ID',
`message` varchar(4000) NOT NULL COMMENT '消息内容',
`try_count` int(4) DEFAULT '0' COMMENT '重试次数',
`status` varchar(10) DEFAULT '' COMMENT '消息投递状态 0投递中,1投递成功,2投递失败',
`next_retry` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP COMMENT '下一次重试时间',
`create_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
`update_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`message_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_order
-- ----------------------------
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`message_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2018091102 DEFAULT CHARSET=utf8;