Zookeeper——Watch机制原理_庄小焱的博客-CSDN博客_zookeeper watch


本站和网页 https://blog.csdn.net/weixin_41605937/article/details/122095904#t1 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

Zookeeper——Watch机制原理_庄小焱的博客-CSDN博客_zookeeper watch
Zookeeper——Watch机制原理
庄小焱
于 2021-12-22 22:10:38 发布
1666
收藏
分类专栏:
注册中心
文章标签:
zookeeper
未经同意窃取和转载我的内容,如果涉及到权益问题,后果自负!
本文链接:https://blog.csdn.net/weixin_41605937/article/details/122095904
版权
注册中心
专栏收录该内容
20 篇文章
2 订阅
订阅专栏
摘要
ZooKeeper 又一关键技术——Watch 监控机制,并用它实现一个发布订阅功能。
在日常生活中也有很多订阅发布的场景。比如我们喜欢观看某一个剧集,视频网站会有一个订阅按钮,用户可以订阅自己喜欢的电视剧,当有新的剧集发布时,网站会通知该用户第一时间观看。或者我们在网站上看到一件心仪的商品,但是当前没有库存,网站会提供到货通知的功能,我们开启这个商品的到货通知功能后,商品补货的时候会通知我们,之后就可以进行购买了。ZooKeeper 中的 Watch 机制很像这些日常的应用场景,其中的客户端就是用户,而服务端的数据节点就好像是我们订阅的商品或剧集。
现在我们可以从技术实现的角度分析一下上边提到的这些场景,无论是订阅一集电视剧还是订购一件商品。都有几个核心节点,即用户端注册服务、服务端处理请求、客户端收到回调后执行相应的操作。接下来我们也带着这个观点来看一下 ZooKeeper 中的 Watch 机制是如何实现的。
一、Watch机制的实现
正如我们可以通过点击视频网站上的”收藏“按钮来订阅我们喜欢的内容,ZooKeeper 的客户端也可以通过 Watch 机制来订阅当服务器上某一节点的数据或状态发生变化时收到相应的通知,我们可以通过向 ZooKeeper 客户端的构造方法中传递 Watcher 参数的方式实现:
new ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
上面代码的意思是定义了一个了 ZooKeeper 客户端对象实例,并传入三个参数:
connectString 服务端地址
sessionTimeout:超时时间
Watcher:监控事件
这个 Watcher 将作为整个 ZooKeeper 会话期间的上下文 ,一直被保存在客户端ZKWatchManager 的 defaultWatcher 中。
除此之外,ZooKeeper 客户端也可以通过 getData、exists 和 getChildren 三个接口来向ZooKeeper 服务器注册 Watcher,从而方便地在不同的情况下添加 Watch 事件:
getData(String path, Watcher watcher, Stat stat)
知道了 ZooKeeper 添加服务器监控事件的方式,下面我们来讲解一下触发通知的条件。
上图中列出了客户端在不同会话状态下,相应的在服务器节点所能支持的事件类型。例如在客户端连接服务端的时候,可以对数据节点的创建、删除、数据变更、子节点的更新等操作进行监控。
现在我们已经从应用层的角度了解了 ZooKeeper 中的 Watch 机制,而学习 ZooKeeper 过程中一个大问题就是入门容易精通难,像上边我们通过几个简单的 API 调用就可以对服务器的节点状态变更进行监控,但是在实际生产环境中我们会遇到很多意想不到的问题,要想解决好这些问题就要深入理解 Watch 的底层实现机制。
二、Watch 机制的底层原理
现在我们就深入底层了解其背后的实现原理。与上个课时直接通过底层代码的调用过程来分析不同,在 Watch 底层实现的分析阶段,由于 Watch 机制涉及了客户端和服务端的多个函数和操作节点,单单按照程序执行流程分析跳跃性对整体实现机制的理解难度大,这也是我在学习 Watch 这部分底层实现遇到的问题。为了更好地阐述 Watch 机制,我们另辟蹊径,从设计模式角度出发来分析其底层实现:
最初我在开始学习 Watch 机制的时候,它给我的第一印象是,其结构很像设计模式中的”观察者模式“,一个对象或者数据节点可能会被多个客户端监控,当对应事件被触发时,会通知这些对象或客户端。我们可以将 Watch 机制理解为是分布式环境下的观察者模式。所以接下来我们就以观察者模式的角度点来看看 ZooKeeper 底层 Watch 是如何实现的。
通常我们在实现观察者模式时,最核心或者说关键的代码就是创建一个列表来存放观察者。 而在 ZooKeeper 中则是在客户端和服务器端分别实现两个存放观察者列表,即:ZKWatchManager 和 WatchManager。其核心操作就是围绕着这两个展开的。
三、客户端 Watch 注册实现过程
我们先看一下客户端的实现过程,在发送一个 Watch 监控事件的会话请求时,ZooKeeper 客户端主要做了两个工作:
标记该会话是一个带有 Watch 事件的请求将 Watch 事件存储到 ZKWatchManager
我们以 getData 接口为例。当发送一个带有 Watch 事件的请求时,客户端首先会把该会话标记为带有 Watch 监控的事件请求,之后通过 DataWatchRegistration 类来保存 watcher 事件和节点的对应关系:
public byte[] getData(final String path, Watcher watcher, Stat stat){
...
WatchRegistration wcb = null;
if (watcher != null) {
wcb = new DataWatchRegistration(watcher, clientPath);
RequestHeader h = new RequestHeader();
request.setWatch(watcher != null);
...
GetDataResponse response = new GetDataResponse();
ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
之后客户端向服务器发送请求时,是将请求封装成一个 Packet 对象,并添加到一个等待发送队列 outgoingQueue 中:
public Packet queuePacket(RequestHeader h, ReplyHeader r,...) {
Packet packet = null;
...
packet = new Packet(h, r, request, response, watchRegistration);
...
outgoingQueue.add(packet);
...
return packet;
最后,ZooKeeper 客户端就会向服务器端发送这个请求,完成请求发送后。调用负责处理服务器响应的 SendThread 线程类中的 readResponse 方法接收服务端的回调,并在最后执行 finishPacket()方法将 Watch 注册到 ZKWatchManager 中:
private void finishPacket(Packet p) {
int err = p.replyHeader.getErr();
if (p.watchRegistration != null) {
p.watchRegistration.register(err);
...
四、服务端 Watch 注册实现过程
介绍完客户端对 Watch 请求的发送过程,下面我们来看一下服务端是如何处理一个 Watch 事件。
Zookeeper 服务端处理 Watch 事件基本有 2 个过程:
解析收到的请求是否带有 Watch 注册事件将对应的 Watch 事件存储到 WatchManager
当 ZooKeeper 服务器接收到一个客户端请求后,首先会对请求进行解析,判断该请求是否包含 Watch 事件。这在 ZooKeeper 底层是通过 FinalRequestProcessor 类中的 processRequest 函数实现的。当 getDataRequest.getWatch() 值为 True 时,表明该请求需要进行 Watch 监控注册。并通过 zks.getZKDatabase().getData 函数将 Watch 事件注册到服务端的 WatchManager 中。
public void processRequest(Request request) {
...
byte b[] =zks.getZKDatabase().getData(getDataRequest.getPath(), stat,
getDataRequest.getWatch() ? cnxn : null);
rsp = new GetDataResponse(b, stat);
..
五、服务端 Watch 事件的触发过程
在客户端和服务端都对 watch 注册完成后,我们接下来看一下在 ZooKeeper 中触发一个 Watch 事件的底层实现过程:
我们以 setData 接口即“节点数据内容发生变更”事件为例。在 setData 方法内部执行完对节点数据的变更后,会调用 WatchManager.triggerWatch 方法触发数据变更事件。
public Stat setData(String path, byte data[], ...){
Stat s = new Stat();
DataNode n = nodes.get(path);
...
dataWatches.triggerWatch(path, EventType.NodeDataChanged);
return s;
下面我们进入 triggerWatch 函数内部来看看他究竟做了哪些工作。首先,封装了一个具有会话状态、事件类型、数据节点 3 种属性的 WatchedEvent 对象。之后查询该节点注册的 Watch 事件,如果为空说明该节点没有注册过 Watch 事件。如果存在 Watch 事件则添加到定义的 Wathcers 集合中,并在 WatchManager 管理中删除。最后,通过调用 process 方法向客户端发送通知。
Set<Watcher> triggerWatch(String path, EventType type...) {
WatchedEvent e = new WatchedEvent(type,
KeeperState.SyncConnected, path);
Set<Watcher> watchers;
synchronized (this) {
watchers = watchTable.remove(path);
...
for (Watcher w : watchers) {
Set<String> paths = watch2Paths.get(w);
if (paths != null) {
paths.remove(path);
for (Watcher w : watchers) {
if (supress != null && supress.contains(w)) {
continue;
w.process(e);
return watchers;
六、客户端回调的处理过程
知道了服务器端 Watch 事件的触发过程后,我们来看一下客户端接收到通知后如何进行操作的。
客户端使用 SendThread.readResponse() 方法来统一处理服务端的相应。首先反序列化服务器发送请求头信息 replyHdr.deserialize(bbia, "header"),并判断相属性字段 xid 的值为 -1,表示该请求响应为通知类型。在处理通知类型时,首先将己收到的字节流反序列化转换成 WatcherEvent 对象。接着判断客户端是否配置了 chrootPath 属性,如果为 True 说明客户端配置了 chrootPath 属性。需要对接收到的节点路径进行 chrootPath 处理。最后调用 eventThread.queueEvent( )方法将接收到的事件交给 EventThread 线程进行处理。
if (replyHdr.getXid() == -1) {
...
WatcherEvent event = new WatcherEvent();
event.deserialize(bbia, "response");
...
if (chrootPath != null) {
String serverPath = event.getPath();
if(serverPath.compareTo(chrootPath)==0)
event.setPath("/");
...
event.setPath(serverPath.substring(chrootPath.length()));
...
WatchedEvent we = new WatchedEvent(event);
...
eventThread.queueEvent( we );
接下来我们来看一下 EventThread.queueEvent() 方法内部的执行逻辑。其主要工作分为 2 点: 第 1 步按照通知的事件类型,从 ZKWatchManager 中查询注册过的客户端 Watch 信息。客户端在查询到对应的 Watch 信息后,会将其从 ZKWatchManager 的管理中删除。因此这里也请你多注意,客户端的 Watcher 机制是一次性的,触发后就会被删除。
public Set<Watcher> materialize(...)
Set<Watcher> result = new HashSet<Watcher>();
...
switch (type) {
...
case NodeDataChanged:
case NodeCreated:
synchronized (dataWatches) {
addTo(dataWatches.remove(clientPath), result);
synchronized (existWatches) {
addTo(existWatches.remove(clientPath), result);
break;
....
return result;
完成了第 1 步工作获取到对应的 Watcher 信息后,将查询到的 Watcher 存储到 waitingEvents 队列中,调用 EventThread 类中的 run 方法会循环取出在 waitingEvents 队列中等待的 Watcher 事件进行处理。
public void run() {
try {
isRunning = true;
while (true) {
Object event = waitingEvents.take();
if (event == eventOfDeath) {
wasKilled = true;
} else {
processEvent(event);
if (wasKilled)
synchronized (waitingEvents) {
if (waitingEvents.isEmpty()) {
isRunning = false;
break;
...
最后调用 processEvent(event) 方法来最终执行实现了 Watcher 接口的 process()方法。
private void processEvent(Object event) {
...
if (event instanceof WatcherSetEventPair) {
WatcherSetEventPair pair = (WatcherSetEventPair) event;
for (Watcher watcher : pair.watchers) {
try {
watcher.process(pair.event);
} catch (Throwable t) {
LOG.error("Error while calling watcher ", t);
到目前为止我们将 ZooKeeper 中 Watch 机制的处理过程全部学习了一遍,大体上讲 ZooKeeper 实现的方式是通过客服端和服务端分别创建有观察者的信息列表。客户端调用 getData、exist 等接口时,首先将对应的 Watch 事件放到本地的 ZKWatchManager 中进行管理。服务端在接收到客户端的请求后根据请求类型判断是否含有 Watch 事件,并将对应事件放到 WatchManager 中进行管理。
在事件触发的时候服务端通过节点的路径信息查询相应的 Watch 事件通知给客户端,客户端在接收到通知后,首先查询本地的 ZKWatchManager 获得对应的 Watch 信息处理回调操作。这种设计不但实现了一个分布式环境下的观察者模式,而且通过将客户端和服务端各自处理 Watch 事件所需要的额外信息分别保存在两端,减少彼此通信的内容。大大提升了服务的处理性能。
七、订阅发布场景实现
现在我们已经知道 Watch 事件在 ZooKeeper 中的完整处理过程,接下来我们通过一个实际应用来加深我们对 ZooKeeper 中 Watch 机制的理解。
提到 ZooKeeper 的应用场景,你可能第一时间会想到最为典型的发布订阅功能。发布订阅功能可以看作是一个一对多的关系,即一个服务或数据的发布者可以被多个不同的消费者调用。一般一个发布订阅模式的数据交互可以分为消费者主动请求生产者信息的拉取模式,和生产者数据变更时主动推送给消费者的推送模式。ZooKeeper 采用了两种模式结合的方式实现订阅发布功能。下面我们来分析一个具体案例:
在系统开发的过程中会用到各种各样的配置信息,如数据库配置项、第三方接口、服务地址等,这些配置操作在我们开发过程中很容易完成,但是放到一个大规模的集群中配置起来就比较麻烦了。通常这种集群中,我们可以用配置管理功能自动完成服务器配置信息的维护,利用ZooKeeper 的发布订阅功能就能解决这个问题。
我们可以把诸如数据库配置项这样的信息存储在 ZooKeeper 数据节点中。如图中的 /confs/data_item1。服务器集群客户端对该节点添加 Watch 事件监控,当集群中的服务启动时,会读取该节点数据获取数据配置信息。而当该节点数据发生变化时,ZooKeeper 服务器会发送 Watch 事件给各个客户端,集群中的客户端在接收到该通知后,重新读取节点的数据库配置信息。
我们使用 Watch 机制实现了一个分布式环境下的配置管理功能,通过对 ZooKeeper 服务器节点添加数据变更事件,实现当数据库配置项信息变更后,集群中的各个客户端能接收到该变更事件的通知,并获取最新的配置信息。要注意一点是,我们提到 Watch 具有一次性,所以当我们获得服务器通知后要再次添加 Watch 事件。
八、Watch机制的总结
当服务端某一节点发生数据变更操作时,所有曾经设置了该节点监控事件的客户端都会收到服务器的通知吗?
答案是否定的,通过本课时对 ZooKeeper 内部实现机制的解析可以知道,Watch 事件的触发机制取决于会话的连接状态和客户端注册事件的类型,所以当客户端会话状态或数据节点发生改变时,都会触发对应的 Watch 事件。
博文参考
庄小焱
关注
关注
点赞
收藏
打赏
评论
Zookeeper——Watch机制原理
摘要ZooKeeper 又一关键技术——Watch 监控机制,并用它实现一个发布订阅功能。在日常生活中也有很多订阅发布的场景。比如我们喜欢观看某一个剧集,视频网站会有一个订阅按钮,用户可以订阅自己喜欢的电视剧,当有新的剧集发布时,网站会通知该用户第一时间观看。或者我们在网站上看到一件心仪的商品,但是当前没有库存,网站会提供到货通知的功能,我们开启这个商品的到货通知功能后,商品补货的时候会通知我们,之后就可以进行购买了。ZooKeeper 中的 Watch 机制很像这些日常的应用场景,其中的客户端就是
复制链接
扫一扫
专栏目录
zookeeper watch机制的理解
08-29
主要介绍了zookeeper watch机制的相关内容,内容比较详细,需要的朋友可以参考下。
从 paxos 到 zookeeper 总结(三)Watcher—数据变更的通知
kmlh20102010的博客
04-23
146
ZooKeeper提供了分布式数据的发布订阅功能。一个典型的发布订阅模型系统定义了一种一对多的订阅关系,能够让多个订阅者同时监听某个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使它们能够做出相应的处理。在 ZooKeeper中,引入了 Watcher机制来实现这种分布式的通知功能。
ZooKeeper允许客户端向服务端注册一个 Watcher监听,当服务端的一些指定事件触发了这个 Watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能。整个 Watcher注册与通知过程如图
参与评论
您还未登录,请先
登录
后发表或查看评论
分布式限流面试专题系列之zookeeper系列
weixin_45137090的博客
05-30
366
1.ZooKeeper 是什么?
ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了监听器,这个监听器也是由所连接...
【面试普通人VS高手系列】Zookeeper中的Watch机制的原理?
跟着Mic学架构
05-12
116
需要高手面试文档(附赠阿里内部十万字面试文档)或者有不懂的技术面试题想咨询的小伙伴可以扫描下方二维码
Zookeeper Watch机制
qianshanding0708的博客
11-30
1万+
Znode发生变化(Znode本身的增加,删除,修改,以及子Znode的变化)可以通过Watch机制通知到客户端。那么要实现Watch,就必须实现org.apache.zookeeper.Watcher接口,并且将实现类的对象传入到可以Watch的方法中。Zookeeper中所有读操作(getData(),getChildren(),exists())都可以设置Watch选项。Watch事件具有o...
Apache ZooKeeper - Watch 机制的底层原理
小工匠
12-08
3244
文章目录Watch 机制API 使用Watch 机制的底层原理客户端 Watch 注册实现过程服务端 Watch 注册实现过程服务端 Watch 事件的触发过程客户端回调的处理过程实现一个订阅发布场景
Watch 机制
ZooKeeper 又一关键技术——Watch 监控机制 。
API 使用
ZooKeeper 的客户端可以通过 Watch 机制来订阅当服务器上某一节点的数据或状态发生变化时收到相应的通知,我们可以通过向 ZooKeeper 客户端的构造方法中传递 Watcher 参数的方式实现
zookeeper的watch机制详细讲解
怪咖@的博客
06-26
1539
我们可以把 Watch 理解成是注册在特定 Znode 上的。当这个 Znode 发⽣改变,也就是调⽤了 create , delete , setData ⽅法的时候,将会触发 Znode 上注册的对应事件,请求 Watch 的客户端会接收到异步通知。具体交互过程如下:这里的服务端指的是zk的服务端。
客户端使⽤了NIO通信模式监听服务端的调⽤。zkCli客户端常用命令详解:https://blog.csdn.net/weixin_43888891/article/details/125400879创建
Zookeeper的watch 机制
阳光宅男
03-16
3274
大数据相关
Watch的内部原理(deep+immediate)
weixin_42937036的博客
09-16
733
watch主要用来监听组件中某个值的改变,并执行对应的回调函数。
wtach和computed的区别
watch是一个值影响多个值
computed是多个值影响一个值
watch的内部原理
先看源码中对于vm.$watch的实现
// watch可以监听一个表达式(a.b.c)或者函数
Vue.prototype.$watch = function (expOrFn, cb, options) {
const vm = this;
options = options || {};
const wa
Zookeeper中的Watch机制的原理
weixin_49349744的博客
07-04
484
Zookeeper中的Watch机制的原理面试
Zookeeper watch机制原理
LiuRenyou的博客
10-30
1075
Zookeeper watch机制原理准备工作watch示例源码解析
准备工作
经过上一小节的学习我们知道ZookeeperServerMain是单机版的服务器主类
我们可以自己写一个ZkClient类
public class ZkClient {
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
final CountDownLatch
Zookeeper的watch机制
qq_29860591的博客
12-15
238
Zookeeper的watch机制
概况:大体上讲 ZooKeeper 实现的方式是通过客服端和服务端分别创建有观察者的信息列表。客户端调用 getData、exist 等接口时,首先将对应的 Watch 事件放到本地的 ZKWatchManager 中进行管理。服务端在接收到客户端的请求后根据请求类型判断是否含有 Watch 事件,并将对应事件放到 WatchManager 中进行管理...
ZooKeeper Watch机制
gangmae的博客
11-27
530
为什么添加Watch
ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建更多复杂的分布式协调功能。
多个分布式进程通过ZooKeeper提供的API来操作共享的ZooKeeper内存数据对象ZNode来达成某种一致的行为或结果,这种模式本质上是基于状态共享的并发模型,与Java的多线程并发模型一致,他们的线程或进程...
zookeeper watch 实现原理笔记
DavidSoCool的博客
05-09
386
zk三种注册监听方式:getData(),exists,getChildren。
客户端发送的监听请求会放到队列中(outgoingQueue),队列会有一个 sendThread 处理,sendThread 通过发送 path 路径和 watcher 为 true ,到 server 注册 watch 事件。
zk服务端会有一个 WatchManger 该类中有 HashMap<String,HashSet<Watcher>> watchTable ,key为path , Wa
zookeeper中watch事件
热门推荐
jack的博客
08-01
1万+
zookeeper中watch监听事件如图
主要是KeeperState.SyncConnected 中几种事件类型:
EventType.NodeCreated : 节点创建事件类型
EventType.NodeDeleted : 节点被删除
EventType.NodeDataChanged : 节点被修改
EventType.None : 客户端与服务器成功建立会话
EventTy...
2.ZooKeeper的watch机制「第二章 ZooKeeper使用」「架构之路ZooKeeper理论和实战」
悟空学院
04-25
1万+
在实际中我们客户端希望能够时时感知到数据的变化,这时候ZK的watch机制就起了很重要的作用。
一、ZooKeeper 的watch机制
ZooKeeper支持 Watch,客户端可以在znode上设置 Watch。
znode更改时,将触发并删除监视。触发监视后,客户端会收到一个数据包,说明znode已更改。
3.6.0中的新增功能:
客户端还可以在znode上设置永久性的递归监视,这些监视在触发时不会删除,并且会以递归方式触发注册zn...
Zookeeper的Watcher机制及Watcher原理分析
weixin_40055163的博客
09-14
557
Zookeeper的Watcher机制及Watcher原理分析
1 什么是Watcher监听机制
Watcher 监听机制是 Zookeeper中非常重要的特性,我们基于zookeeper上创建的节点,可以对这些节点绑定监听事件,比如可以监听节点数据变更、节点删除、子节点状态变更等事件,通过这个事件机制,可以基于zookeeper实现分布式锁,发布订阅(多个订阅者同时监听某一个主题对象,当这个主题对象自身状态发生变化时,会通知所有订阅者)等功能。
Watcher 特性:当数据发生变化的时候, zookeep
Zookeeper watch机制
架构师与哈苏
11-08
117
客户端,可以通过在znode上设置watch,实现实时监听znode的变化
Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端
父节点的创建,修改,删除都会触发Watcher事件
子节点的创建,删除会触发Watcher事件
一次性:一旦被触发就会移除,再次使用需要重新注册,因为每次变动都需要通知所有客户端...
原理系列之——zookeeper的watch监控机制
最新发布
weixin_44827241的博客
08-08
548
watch监控机制是zk的一个关键技术,zk通过它来实现发布订阅的功能,通过watch我们可以联想到设计模式中的观察者模式,二者确实有点类似,你可以将其看成是分布式场景下的观察者模式。
zookeeper的watch机制
zhoushimiao1990的博客
08-04
1849
zookeeper的watch监听机制,用于监听节点数据变化。当watch监听的数据发生变化时,通知该watch的client,即watcher。
那么既然有watch监听数据变化事件,就有对应的事件类型和状态类型。
zk连接状态类型:
KeeperState.Disconnected:客户端连接断开
KeeperState.SyncConnected:客户端和服务器的某一个节点建立连接,并完成一次version、zxid的同步。
KeeperState.AuthFailed:客户端进行连接认证失
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
©️2022 CSDN
皮肤主题:程序猿惹谁了
设计师:我叫白小胖
返回首页
庄小焱
CSDN认证博客专家
CSDN认证企业博客
码龄5年
DELL EMC高级软件工程师
820
原创
8466
周排名
1650
总排名
77万+
访问
等级
9694
积分
1482
粉丝
516
获赞
231
评论
3258
收藏
私信
关注
热门文章
项目管理工具——Jira使用和配置
31512
pycharm出现了pytest模式下怎修改会run模式
29595
Python——回调函数(callback)
19656
计算机网络——计算机网络知识脑图
10269
计算机网络——tcpdump/Wireshark抓包实战
10026
分类专栏
数据结构与算法
29篇
操作系统
17篇
计算机网络
26篇
JDK源码分析
38篇
计算机语言
35篇
软件设计模式
12篇
JUC并发编程
18篇
数据库
60篇
数据库中间件
5篇
Spring框架
29篇
JVM虚拟机
22篇
Netty
24篇
RPC框架
23篇
注册中心
20篇
Nginx
2篇
KafkaMQ
8篇
RabbitMQ
15篇
Redis
30篇
Mybatis
9篇
Kubernetes
36篇
Docker
28篇
软件测试
5篇
Git
14篇
DevOps
11篇
云计算
1篇
大数据技术
29篇
分布式技术
3篇
系统架构设计
35篇
计算机AI
19篇
工作经历
23篇
资源共享仓库
3篇
兴趣爱好
2篇
项目管理工具
4篇
常见业务error示例
3篇
系统开发环境设置
13篇
工作项目实战
42篇
最新评论
Python——回调函数(callback)
轩木冰:
回调函数的本质还是普通函数,只是这一类用法的统称
MySQL——高可用架构:mysql+keepalived实战
qq_45406247:
测试过,id一致才表明是同一组,不然先停掉keepalived的master端上的mysql时,vip绑定到slave端,等master端重启mysql后,vip不会从slave飘过来,而是直接在master端多生成一个vip
系统架构设计——基于OAuth 2.0原理与(微博/微信)实战
庄小焱:
是的。没有写完啊。后期我将会对博文进行补充完整。同时后面将更好的分享给大家。
系统架构设计——基于OAuth 2.0原理与(微博/微信)实战
bigzqquant:
好像没写完
高并发系统设计——系统架构的微服务化选型
.猫的树:
不错的文章,受益匪浅,欢迎回访!
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
剑指 Offer 10- II. 青蛙跳台阶问题
剑指 Offer 57 - II. 和为s的连续正数序列
剑指 Offer 53 - II. 0~n-1中缺失的数字
2022
12月
9篇
11月
5篇
10月
4篇
09月
3篇
07月
5篇
06月
22篇
05月
16篇
04月
5篇
03月
23篇
02月
40篇
01月
61篇
2021年439篇
2020年181篇
2019年4篇
2018年3篇
目录
目录
分类专栏
数据结构与算法
29篇
操作系统
17篇
计算机网络
26篇
JDK源码分析
38篇
计算机语言
35篇
软件设计模式
12篇
JUC并发编程
18篇
数据库
60篇
数据库中间件
5篇
Spring框架
29篇
JVM虚拟机
22篇
Netty
24篇
RPC框架
23篇
注册中心
20篇
Nginx
2篇
KafkaMQ
8篇
RabbitMQ
15篇
Redis
30篇
Mybatis
9篇
Kubernetes
36篇
Docker
28篇
软件测试
5篇
Git
14篇
DevOps
11篇
云计算
1篇
大数据技术
29篇
分布式技术
3篇
系统架构设计
35篇
计算机AI
19篇
工作经历
23篇
资源共享仓库
3篇
兴趣爱好
2篇
项目管理工具
4篇
常见业务error示例
3篇
系统开发环境设置
13篇
工作项目实战
42篇
目录
评论
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
打赏作者
庄小焱
我将坚持分享更多知识
¥2
¥4
¥6
¥10
¥20
输入1-500的整数
余额支付
(余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付
您的余额不足,请更换扫码支付或充值
打赏作者
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。
余额充值