在前一篇文章中Zookeeper-watcher机制源码分析(一)说过Watcher的基本流程,在此文中详细剖析服务端几首请求处理流程。node
服务端有一个NettyServerCnxn类,用来处理客户端发送过来的请求 程序员
NettyServerCnxn 数据库
1编程 2promise 3服务器 4session 5架构 6app 7异步 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
|
处理客户端传送过来的数据包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
|
负责在服务端提交当前请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
1.firstProcessor的初始化是在ZookeeperServer的setupRequestProcessor中完成的,代码以下
1 2 3 4 5 6 7 |
|
从上面咱们能够看到firstProcessor的实例是一个PrepRequestProcessor,而这个构造方法中又传递了一个Processor构成了一个调用链。
RequestProcessor syncProcessor = new SyncRequestProcessor(this, finalProcessor);
而syncProcessor的构造方法传递的又是一个Processor,对应的是FinalRequestProcessor
2.因此整个调用链是PrepRequestProcessor -> SyncRequestProcessor ->FinalRequestProcessor
经过上面了解到调用链关系之后,咱们继续再看firstProcessor.processRequest(si); 会调用到PrepRequestProcessor
1 2 3 |
|
唉,很奇怪,processRequest只是把request添加到submittedRequests中,根据前面的经验,很天然的想到这里又是一个异步操做。而subittedRequests又是一个阻塞队列
LinkedBlockingQueue<Request> submittedRequests = new LinkedBlockingQueue<Request>();
而PrepRequestProcessor这个类又继承了线程类,所以咱们直接找到当前类中的run方法以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
预处理这块的代码太长,就很差贴了。前面的N行代码都是根据当前的OP类型进行判断和作相应的处理,在这个方法中的最后一行中,咱们会看到以下代码
nextProcessor.processRequest(request);
1 |
|
很显然,nextProcessor对应的应该是SyncRequestProcessor
1 2 3 4 |
|
这个方法的代码也是同样,基于异步化的操做,把请求添加到queuedRequets中,那么咱们继续在当前类找到run方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
这个方法就是咱们在课堂上分析到的方法了,FinalRequestProcessor.processRequest方法并根据Request对象中的操做更新内存中Session信息或者znode数据。
这块代码有小300多行,就不所有贴出来了,咱们直接定位到关键代码,根据客户端的OP类型找到以下的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 |
|
一路向下,在下面这个方法中,讲ServerCnxn向上转型为Watcher了。 由于ServerCnxn实现了Watcher接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
其大体流程以下
①经过传入的路径(节点路径)从watchTable获取相应的观察者集合,进入②
② 判断①中的观察者是否为空,若为空,则进入③,不然,进入④
③ 新生成观察者集合,并将路径路径和此集合添加至watchTable中,进入④
④将传输的观察者添加至观察者集合,即完成了路径和观察者添加至watchTable的步骤,进入⑤
⑤经过传入的观察者从watch2Paths中获取相应的路径集合,进入⑥
⑥ 判断路径集合是否为空,若为空,则进入⑦,不然,进入⑧
⑦ 新生成路径集合,并将观察者和路径添加至watch2Paths中,进入⑧
⑧将传入的路径(节点路径)添加至路径集合,即完成了路径和观察者添加至watch2Paths步骤的
总结
调用关系链以下
图文里的技术如何学习,有没有免费资料?
对Java技术,架构技术感兴趣的同窗,欢迎加QQ群619881427,一块儿学习,相互讨论。
群内已经有小伙伴将知识体系整理好(源码,笔记,PPT,学习视频),欢迎加群免费领取。
分享给喜欢Java的,喜欢编程,有梦想成为架构师的程序员们,但愿可以帮助到大家。
不是Java的程序员也不要紧,帮忙转发给更多朋友!谢谢。
一个分享小技巧点击阅读原文也。能够轻松到电子杂志学习资料哦!