转自:http://www.javaarm.cn/faces/display.xhtml;jsessionid=sYVoogXkNnafK4P6BL+h-Nkg?tid=3650&page=1&print=true
概述 JGroups的源代码非常赏心悦目,组织非常清晰,有必要深入研究它,不仅仅为了学会JGroups工作原理,而且也能学到诸如项目组织、模块划分之类的项目开发经验。
本文概述了JGroups源代码组织结构、设计框架。很多内容都是在编写了其它系列文章之后,才总结出来的。这样能给读者一个大致的框架,便于读者剖析JGroups。如果直接对各个模块进行描述,读者会莫名其妙。
|
JGroups代码组织结构 我们决定研究JGroups 3.6.0的源代码,请参见
链接处的描述,下载下面文件:
- jgroups-3.6.0.Final-src_github.zip (工程源代码)
- jgroups-3.6.0.Final.jar (二进制发行包,包含demo,test-cases)
- jgroups-3.6.0-sources.jar (纯java文件,包含demo,test-cases,不包含项目配置文件等等)
目录结构 - jgroups-3.6.0.Final.jar (二进制发行包)
[-]jgroups-3.6.0.Final
EncryptKeyStore.xml
EncryptNoKeyStore.xml
INSTALL.html
LICENSE
README
auth_X509.xml
auth_fixedlist.xml
auth_krb5.xml
auth_md5.xml
auth_regex.xml
auth_simple.xml
encrypt-entire-message.xml
encrypt.xml
execution-service.xml
fast.xml
flush-tcp.xml
flush-udp.xml
fork-stacks.xml
fork-stacks.xsd
jg-magic-map.xml
jg-messages.properties
jg-messages_de.properties
jg-protocol-ids.xml
jgroups-3.6.xsd
jgroups.xsd
log4j2.xml
mping.xml
relay.xsd
relay1.xml
relay2.xml
rules.xml
rules.xsd
sequencer.xml
settings.xml
tcp-nio.xml
tcp.xml
tcpgossip.xml
toa.xml
tunnel.xml
udp-largecluster.xml
udp.xml
[-]META-INF
MANIFEST.MF
[-]org
[-]jgroups
Address.class
AnycastAddress.class
Channel$State.class
Channel.class
ChannelListener.class
Event.class
Global.class
Header.class
...
JChannel.class
...
我们会在后面的章节描述这些class文件,本节我们只简单描述
这个包里面的XML文件的作用:
- EncryptKeyStore.xml:包含加密协议的协议栈。可以指定keystore以及keystore访问密码,和配置SSL一样。
- EncryptNoKeyStore.xml:包含加密协议的协议栈。非对称算法为RSA,对称算法为"Blowfish"。(自动生成临时keystore?)
- INSTALL.html:如何使用JGroups以及运行其中的演示例子。
- LICENSE:许可证为 "Apache License, Version 2.0"。
- README:JGroups介绍。
- auth_X509.xml:包含含身份认证协议的协议栈。使用标准的X509技术,设置keystore、加密类型(如:RSA)等等。
- auth_fixedlist.xml:包含含身份认证协议的协议栈。列举出固定的受信任的集群成员。
- auth_krb5.xml:包含含身份认证协议的协议栈。用Kerboras技术认证。
- auth_md5.xml:包含含身份认证协议的协议栈。用MD5哈希算法对认证口令计算哈希值,再通过网络传输哈希值,供集群成员相互认证。
- auth_regex.xml:包含含身份认证协议的协议栈。只接受某个正则表达式所描述的IP地址范围。
- auth_simple.xml:包含含身份认证协议的协议栈。简单口令认证。
- encrypt-entire-message.xml:包含加密协议的协议栈。非对称算法为RSA,对称算法为"AES/ECB/PKCS5Padding"。(自动生成临时keystore?)
- encrypt.xml:包含加密协议的协议栈。非对称算法为RSA,对称算法为"AES/ECB/PKCS5Padding"。(自动生成临时keystore?)
- execution-service.xml:包含CENTRAL_EXECUTOR协议的协议栈。供ExecutionService使用。
- fast.xml:快速配置的协议栈,供本地模式使用,也就是说所有集群成员位于相同的主机上。
- flush-tcp.xml:基于TCP的协议栈。包含flush、流控和消息绑定协议。常用于IP多播被禁用的情况。
- flush-udp.xml:基于UDP的协议栈。包含flush协议。
- fork-stacks.xml:分叉协议栈。<fork-stacks/>
- fork-stacks.xsd:分叉协议栈的语法。
- jg-magic-map.xml:魔数映射表。比如,1对应"org.jgroups.stack.IpAddress",31对应"org.jgroups.View"。应用场合之一:为消息打标签。
- jg-messages.properties:国际化文件,英文。
- jg-messages_de.properties:国际化文件,德文。
- jg-protocol-ids.xml:JGroups各官方协议ID。所有协议的ID必须唯一,客户化协议不要和这些ID重复。
- jgroups-3.6.xsd:JGroups 3.6 协议栈配置语法。
- jgroups.xsd:JGroups 协议栈配置语法(和jgroups-3.6.xsd相同)。
- log4j2.xml:log4j配置。
- mping.xml:基于TCP的协议栈。包含MPING协议。
- relay.xsd:RelayConfigurationType的语法。
- relay1.xml:RelayConfiguration协议,开发之中,尽量不要使用。
- relay2.xml:RelayConfiguration协议,开发之中,尽量不要使用。
- rules.xml:rules配置。
- rules.xsd:rules配置的语法。
- sequencer.xml:基于UDP的协议栈。包含SEQUENCER协议,将所有消息和视图进行排序。
- settings.xml:JGroups Maven settings.xml 示例文件。
- tcp-nio.xml:基于TCP_NIO的协议栈。包含flush、流控和消息绑定协议。常用于IP多播被禁用的情况。
- tcp.xml:基于TCP的协议栈。包含flush、流控和消息绑定协议。常用于IP多播被禁用的情况。
- tcpgossip.xml:基于TCP的协议栈。包含TCPGOSSIP协议。
- toa.xml:基于UDP的协议栈。包含TOA协议。
- tunnel.xml:基于TUNNEL的协议栈。
- udp-largecluster.xml:基于UDP的协议栈。用于大型集群中。该配置文件还在开发之中。
- udp.xml:基于UDP的协议栈。这是JGroups默认使用的协议栈。
注意:
- 大多数XML文件的顶部注解都描述了这个文件的作用,不过有些注解明显是拷贝过来的,不匹配。
- JGroups的协议栈处理方式为:"底层传输协议"将报文向上递交,每经过一些协议都会被处理一次,直到最后被交给应用程序。所以,身份认证协议以及加密协议通常位于传输协议之上,GMS(分组成员关系)协议之下;越靠近传输协议,那么被加密的包头就越多。
|
目录结构 - jgroups-3.6.0-sources.jar (发行包配套源代码)
[-]jgroups-3.6.0-sources
[-]META-INF
MANIFEST.MF
[-]org
[-]jgroups
Address.java
AnycastAddress.java
Channel.java
ChannelListener.java
Event.java
Global.java
Header.java
JChannel.java
...
|
目录结构 - jgroups-3.6.0.Final-src_github.zip (工程源代码) 这个源代码包中的内容相当重要!尤其是红色标记的内容。
[-]jgroups-3.6.0.Final-src_github
[-]JGroups-JGroups-3.6.0.Final
.gitignore
INSTALL.html
LICENSE
README
build.properties.template
build.properties.template.ipv6
build.xml
ivy.xml
ivysettings.xml
pom.xml
project.properties
[-]bin
count-tests.sh
draw.bat 启动Draw示例的Windows脚本。
draw.sh 启动Draw示例的Linux脚本。
gaps.sh
gossiprouter.sh
jgroups.bat
jgroups.sh
jt
mperf.sh 启动性能测试示例MPerf的脚本。
probe.bat 启动JGroups探测器的Windows脚本。
probe.sh 启动JGroups探测器的Windows脚本。
release_to_local_repo.sh
release_to_nexus.sh
toa-test.sh
uperf.sh
[-]conf #下面的XML文件都是协议栈配置文件,和二进制发行包中的那些文件一样。
EncryptKeyStore.xml
EncryptNoKeyStore.xml
auth_X509.xml
auth_fixedlist.xml
...
udp-largecluster.xml
udp.xml
[-]kerberos
kerbtest.ldif
krb5.conf
login.conf
[-]scripts
[-]BecomeServerTest
testSendingOfMsgsOnUnconnectedChannel.btm
[-]ForwardToCoordFailoverTest
testSendingDuringViewChange.btm
...
|
[-]doc 关于各种设计的说明,我们将在
JGroups 3.6.0 源码分析 - 文档一文详细分析这些文档。 ENCRYPT.html ENCRYPT1_4.html JmxSupport.txt PerformanceNotes.txt README RELEASE_INSTRUCTIONS RULES ReleaseNotes.txt history.txt structure.txt todo.lst [-]design AUTH.txt AddressTranslation.txt Bundling.txt CLOUD_TCP.txt CloudBasedDiscovery.txt ConcurrentConnectionEstablishment.txt ConcurrentStack.txt CounterService.txt DataCenterReplication.fig DataCenterReplication.png DataCenterReplication.txt FILE_PING.txt FLUSH.txt FLUSH2.txt FORK.txt ... [-]manual 包含了JGroups手册的源文件。 advanced.adoc api.adoc blocks.adoc installation.adoc manual.adoc overview.adoc protocols.adoc writing.adoc [-]images Architecture.fig Architecture.png ... [-]stylesheets asciidoctor.css colony.css github.css golo.css [-]tests ManualTests.txt [-]tutorial 包含了JGroups教程的源文件。 installation.adoc sampleapp.adoc tutorial.adoc [-]code SimpleChat.java [-]images DrawScreenshot.png [-]src 二进制发行包中的class文件对应的源代码 [-]org [-]jgroups Address.java ... JChannel.java ...
待续(下面是测试代码)...
|
[-]tests # 各种测试演示了JGroups各个class的功能,非常值得深入研究
[-]byteman #利用JBoss byteman在运行期间插入一些代码,以便模拟出特殊的运行场景。
[-]org
[-]jgroups
[-]tests
[-]byteman
BecomeServerTest.java
ForwardToCoordFailoverTest.java
...
[-]helpers
BecomeServerTestHelper.java
...
[-]junit #单元测试
[-]org
[-]jgroups
[-]blocks
MuxMessageDispatcherTest.java
...
RpcDispatcherUnitTest.java
...
...
[-]junit-functional #功能性单元测试
[-]org
[-]jgroups
[-]blocks
ConnectionMapTest.java
GroupRequestTest.java
LazyRemovalCacheTest.java
LockServiceTest.java
RpcDispatcherTest.java
RpcLockingTest.java
[-]protocols
AUTHTest.java
ENCRYPTAsymmetricTest.java
...
[-]tests
AckCollectorTest.java
...
ViewIdTest.java
ViewTest.java
|
[-]other # 对应JGroups发行包中的org.jgroups.test包下面的各种功能测试/演示
[-]org
[-]jgroups
[-]tests
CheckGaps.java
CheckMonotonicallyIncreasingNumbers.java
CheckToaOrder.java
FlowControlTest.java
...
[-]perf # 对应JGroups发行包中的org.jgroups.tests.perf包下的各种功能测试/演示
[-]org
[-]jgroups
[-]tests
[-]perf
JPerf.java
MPerf.java
MPerfRpc.java
UPerf.java
UUPerf.java
UdpPerf.java
[-]stress #压力测试 (和二进制发行包无关)
[-]org
[-]jgroups
[-]tests
NakReceiverWindowStressTest.java
NakReceiverWindowStressTest2.java
RemoteGetStressTest.java
RingBufferLocklessStressTest.java
RingBufferStressTest.java
TableStressTest.java
TimeSchedulerStressTest.java
[-]util # 测试中使用的辅助类
[-]org
[-]jgroups
[-]util
CountTests.java
DumpData.java
JUnitXMLReporter.java
|
JGroups源代码架构 这一章是在YBXIANG研究了JGroups的设计文档(参见:
JGroups 3.6.0 源码分析 - 文档一文)以及大部分JGroups源代码框架之后,才总结出来的。
JGroups源代码主要由下面几个部分构成:
- 核心对象:位于 org.jgroups 这个根中。主要包含JGroups中最核心的组件/术语,比如JChannel(信道)、Address(地址)、Header(消息的包头)、Message(消息)、Event(事件)、Membership(成员关系)、View(成员关系视图)、Receiver(接收者)、等等。
- 协议实现:主要位于org.jgroups.protocols这个包中。AUTH(身份认证)协议位于org.jgroups.auth这个包中。FORK(分叉)协议位于org.jgroups.fork中。
- 认证口令:位于org.jgroups.auth这个包中。主要是一些身份认证加密算法,最重要的是和X509相关的org.jgroups.auth.X509Token。关于X509非对称加密和解密的文档,请参见:http://javaarm.com/faces/display.xhtml?tid=3658&page=1#post_44750
- 协议栈实现:位于org.jgroups.stack包中。协议栈用于将在JGroups的XML配置文件中定义的各种协议层按照配置顺序串联起来。
- 构建模块:位于org.jgroups.blocks包中。实现了一些比较复杂的功能,主要供应用程序使用。
- 配置模块:位于org.jgroups.conf包中。用于加载XML文件中的配置。
- 注解:位于org.jgroups.annotations包中。用于标注XML配置属性、JMX属性/操作等等。分别供JGroups将XML配置映射到对象的变量上;将属性暴露给JMX MBean Server。
- 辅助功能:位于org.jgroups.util包中。用于处理字节、序列化等等。免得污染框架代码。
- JMX 支持:位于org.jgroups.jmx包中。主要供外界通过JMX方式操控运行中的JGroups,非常有用!非常有借鉴意义!
- 日志框架:位于org.jgroups.logging包中。JGroups的所有Logger都是用自己的org.jgroups.logging.LogFactory重定位的。非常有借鉴意义!
- 场景测试:位于org.jgroups.tests包中。尤其要注意org.jgroups.tests.perf子包中的性能测试。这些测试主要用于对产品部署环境进行基础检测、性能优化、故障排除。
- 客户端:位于org.jgroups.client包中。只有一个StompConnection,演示了STOMP客户端如何访问STOMP协议。
- 各种示例:位于org.jgroups.demos包中。
自己设计类似的独立模块时,最好也包含那些具有借鉴意义的模块!
|
JGroups架构基本介绍
下面我们用类图对各个子模块进行展示。 类图都是用Dia(参见:http://javaarm.com/faces/display.xhtml?tid=3473#post_42805)这个UML工具绘制的。 Dia工程文件以及图像位置: http://javaarm.com/file/opensource/jgroups/jgroups-3.6.0-src_study/xml
JGroups协议栈处理事件(可包含消息)的流程图
同时请参见我们在
JGroups 3.6.0 源码分析 - org.jgroups.blocks.RpcDispatcher一文中截取的协议栈调试图:
(a) 请求图
(b) 响应图
JGroups抽象协议层介绍 上图中,JGroups协议栈中的每层协议都扩展自org.jgroups.stack.Protocol。
我们首先看看这个类的核心成员变量以及成员方法:
描述:
- 我们可以看到,该抽象协议有一个上层协议(up_proto)的引用,也有一个下行协议(down_proto)的引用。这样所有协议就能够串联起来,组成一个协议栈!
- 底层传输协议收到事件(可包含消息)之后,调用它的up()方法来处理该消息,该方法做预处理之后再调用up_prot.up(evt)从而将该消息交给其上层协议(up_proto)接着处理。
.
|
JGroups类型层次结构(classes-hierarchy) 下面,我们分析JGroups中的主要类型层次结构。
协议的类型层次结构
...
地址的类型层次结构
注意:
- UUID是一个长度为16字节的逻辑地址。
- IpAddress和UUID相反,用于记录JGroups成员的实际网络地址及其端口号。
身份认证的类型层次结构 主要信息:
- AUTH是认证协议。
- 协调者中的AUTH协议层会调用消息头中的AuthenToken对请求加入集群或者合并入集群的成员发出的认证请求进行身份认证。
- 身份认证通过之后,后续普通消息的收发就不需要认证了。
关于AuthenToken,注意:
- SimpleToken:它的认证口令是明文传输的,这样非常不安全。只适合用于测试或者私有局域网,不适合托管机房这样的公共场合。如果要在公共场合使用,则需要为JGroups协议栈添加ENCRYPT协议层,对通信信道进行加密。
- MD5Token:它的认证口令是用哈希算法(SHA或MD5)扰乱过的,认证口令明文不会泄露,但是黑客可以自己改写自己程序中的MD5Token,直接发送它窃听到的哈希值,也能通过认证!这也是不安全的,只是明文口令不会被泄露而已。只适合用于测试或者私有局域网,不适合托管机房这样的公共场合。如果要在公共场合使用,则需要为JGroups协议栈添加ENCRYPT协议层,对通信信道进行加密。
- X509Token:只有X509Token是通过非对称加密/解密方式进行身份认证的,这种方式能够提供绝对的安全。
|
|
|
|