Zookeeper & Dubbo
2020-10-11 本文已影响0人
极速魔法
Zookeeper
概述
开源分布式的(多台服务器干一件事),为分布式应用提供协调服务Apache项目。类似于平台,中介
工作机制
基于观察者模式设计的分布式服务管理框架
- 接过观察者注册
- Zookeeper 通知已注册的观察者做出反应
- Zookeeper = 文件系统 + 通知机制
分布式和集群区别
- 分布式 多台服务器负责的内容不一样,多个人共同完成一件事
- 集群 多台服务器负责的内容一样
特点
- 一个leader 多个 follower(一头雄狮,多头母狮)
- 集群要只要半数以上的节点存活,Zookeeper 就能正常工作
- 全局数据一致性,每台服务器保存一份相同的数据副本
- 数据更新原子性,要么成功,要么失败
- 实时性,client能读取到最新数据
- 更新请求顺序执行,按照发送过来的顺序逐一执行。
数据结构
整体看做一棵树,每个节点ZNode
每个ZNode 默认能存储 1M数据(元数据)
配置参数
/zoo.cfg/
tickTime=2000 #通信心跳 每隔2s
initLimit=10 # 初始通信时限,follower 和leader 之间启动时能容忍的多心跳数,超过则认为失效的连接
syncLimit=5 # 最大响应时间,超过认为 follower挂掉
内部原理
选举机制
半数机制:半数以上机器存活,集群可用,适合安装奇数台机器
节点类型
- 持久型
- 持久化目录节点
- 持久化顺序编号目录节点,序号是相当于i++
- 短暂型
- 临时目录节点
- 临时顺序编号目录节点,序号是相当于i++
监听器原理
- main方法总创建 Zookeeper客户端同时创建两个线程,负责网络通信和监听
- 监听事件通过网络发送给Zookeeper
- Zookeeper获得注册的监听事件后,监听事件加到监听列表
- Zookeeper监听到数据变化或路径变化,将消息发送给客户端的监听线程
监听节点数据变化
监听子节点增减变化 - 监听线程内部调用process方法处理
客户端明令
ls /
# 查看详情
ls -s /
# 创建普通节点
create /ru
# 创建节点保存数据
create /ru "pujing"
# 创建多级节点,上级节点要存在
create /ru/city
# 创建短暂节点
create -e /uk
# 创建带序号的节点
create -s /ru/city
# 获得节点的值
get /ru/city
# 修改节点
set /ru/city "nan"
# 监听
addwatch /usa
# 递归删除
deleteall /ru
API
// 创建zookeeper客户端
ZooKeeper zkcli = new ZooKeeper(connStr, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
...
}
});
// 创建节点, Ids.OPEN_ACL_UNSAFE权限控制
String nodeCreated = zKcli.create("/lagou", "laosun".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 获取节点,false代表不监听
byte[] bs = zKcli.getData("/lagou", false, new Stat()); // 路径不存在时会报错
String data = new String(bs);
// 0 代表dataVersion
Stat stat = zKcli.setData("/lagou", "laosunA".getBytes(), 0);
// 删除节点,dataVersion = 1
zKcli.delete("/lagou", 1);
// 获取子节点
List<String> children = zKcli.getChildren("/",false); // false:不监听
// 节点是否存在
Stat stat = zKcli.exists("/lagou", false);
stat == null ? "存在" : "不存在";
分布式锁
- 所有请求进来,在/lock下创建 临时顺序节点
- 判断自己是不是/lock下最小的节点
- 是,获得锁(创建节点)
- 否,对前面小一级的节点进行监听
- 获得锁请求,处理完业务逻辑,释放锁
- 后一个节点得到通知重复步骤 2
Curator
// 重试策略 (1000毫秒试1次,最多试3次)
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
//1.创建curator工具对象
CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, retryPolicy);
client.start();
//2.根据工具对象创建“内部互斥锁”
InterProcessMutex lock = new InterProcessMutex(client, "/product_"+id);
try {
//3.加锁
lock.acquire();
productService.reduceStock(id);
}catch(Exception e){
if(e instanceof RuntimeException){ throw e; }
}finally{
//4.释放锁
lock.release();
}
Dubbo
系统架构
- 单一应用架构,核心是ORM ,减少部署节点和成本,并发 1-10,
- 垂直应用架构,应用拆分成几个互不相关的应用,采用MVC设计模式,并发10-1000
- 分布式架构,并发1000-10000
- 流动计算架构,基于访问压力调度,SOA(面向服务架构,Service-Oriented-Architecture)服务治理。
简介
Dubbo是分布式服务框架,提高性能和透明化的RPC远程服务调用方案
RPC
PRC(Remote Procedure Call)远程过程调用,进程通信方式
通信原理
- 客户端序列化对象,底层使用socket发送给服务方
- 服务方接收,反序列化,
- 服务端操作完毕,新对象序列化传输给客户端
- 客户端获得操作后的数据,反序列化,得到新对象
节点角色
- Provider,服务提供方
- Consumer,消费者
- Registry,服务注册
- Monitor,监控服务的统计中心
- Container ,服务运行容器
配置说明
- 启动检查,启动时会在注册中心检查依赖的服务是否可用,不可用时会抛出异常,服务提供方设置
- 超时时间,服务提供方设置
- 重试次数,服务提供方设置,总共调用次数 = 重试次数 + 1(第一次调用)
- 消费者单独设置
<dubbo:reference interface="service.HelloService" id="helloService">
<dubbo:method name="sayHello" retries="3">
<dubbo:method name="sayNo" retries="0">
<dubbo:reference>
- 本地存根,消费者处理一些业务逻辑,再调用提供者的过程。使用构造方法的方式注入
服务降级
根据实际情况和流量,对一些服务停止或换种简单的方式处理,释放服务器资源保证核心业务。
降级方式
- 屏蔽,直接返回null值,不发起远程调用
- 容错,服务方法调用失败,再返回null值