一个集群包括若干成员,要对这些成员进行管理就必需要有一张包括全部成员的列表。当要对某个节点做操作时通过这个列表能够准确找到该节点的地址进而对该节点发送操作消息。怎样维护这张包括全部成员的列表是本节要讨论的主题。

成员维护是集群的基础功能,一般划分一个独立模块或层完毕此功能,它提供成员列表查询、成员维护、成员列表改变事件通知等能力。

因为tribes定位于基于同等节点之间的通信,所以并不存在主节点选举的问题,它所要具备的功能是自己主动发现节点,即新节点增加要通知集群其它成员更新成员列表,让每一个节点都能及时更新成员列表。每一个节点都维护一份集群成员表。如图。节点1、节点2、节点3使用组播通过交换机各自已经维护一份成员列表。且他们隔一段时间向交换机组播自己节点消息,即心跳操作。当第四个节点增加集群组,节点四向交换机组播自己的节点消息,原理三个节点接收到后各自把节点四增加到各自的成员列表中。而原来三个节点也不断向交换机发送节点消息。节点四接收到后依次更新成员列表信息。终于达到四个节点都拥有四个节点成员信息。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

看下tribes的集群是怎样设计实现以上功能的。其成员列表的创建维护是基于经典的组播方式实现,每一个节点都创建一个节点信息发射器和节点信息接收器,让他们执行于独立的线程中。发射器用于向组内发送自己节点的消息,而接收器则用于接收其它节点发送过来的节点消息并进行处理。要使节点之间通信能被识别就需要定义一个语义。即约定报文协议的结构,tribes的成员报文是这样定义的,两个固定值用于表示报文的開始和结束,開始标识TRIBES_MBR_BEGIN 的值为字节数组84, 82, 73, 66, 69, 83, 45, 66, 1, 0,结束标识TRIBES_MBR_END的值为字节数组84, 82, 73, 66, 69, 83, 45, 69, 1, 0。整个协议包结构为:開始标识(10bytes)+包长度(4bytes)+存活时间(8bytes)+tcp端口(4bytes)+安全端口(4bytes)+udp端口(4bytes)+host长度(1byte)+host(nbytes)+命令长度(4bytes)+命令(nbytes)+域名长度(4bytes)+域名(nbytes)+唯一会话id(16bytes)+有效负载长度(4bytes)+有效负载(nbytes)+结束标识(10bytes)。成员发射器依照协议组织成包结构并组播,接收器接收包并依照协议进行解包,依据包信息维护成员表。

以下用一段代码简单展示实现过程。因为篇幅问题包的处理省略:

public class McastService {

private MulticastSocket socket;

private String address = "228.0.0.4";

private int port = 8000;

private InetAddress addr;

private byte[] buffer = new byte[2048];

private DatagramPacket receivePacket;

private final Object sendLock = new Object();

public void start() {

try {

addr = InetAddress.getByName(address);

receivePacket = new DatagramPacket(buffer, buffer.length, addr,port);

socket.joinGroup(addr);

new ReceiverThread().start();

new SenderThread().start();

} catch (IOException e) {

}

}

public class ReceiverThread extends Thread {

public void run() {

while (true) {

try {

receive();

} catch (ArrayIndexOutOfBoundsException ax) {

}

}

}

}

public class SenderThread extends Thread {

public void run() {

while (true) {

try {

send();

} catch (Exception x) {

}

try {

Thread.sleep(1000);

} catch (Exception ignore) {

}

}

}

}

public void send() {

byte[] data = 依照成员协议组织包结构;

DatagramPacket packet = new DatagramPacket(data, data.length, addr, port);

try {

socket.send(packet);

} catch (IOException e) {

}

}

public void receive() {

try {

socket.receive(receivePacket);

解析处理成员报文。

} catch (IOException e) {

}

}

}

第一步要先执行增加组播成员操作。接着分别启动接收器线程、发射器线程,一般接收器要优先启动。发射器每隔1秒组织协议包发送心跳,组播组内成员的接收器对接收到的协议报文进行解析,依照一定的逻辑更新各自节点本地成员列表,假设成员表已包括协议包的成员则仅仅更新存活时间等消息。

Tribes利用上述原理维护集群成员,而且由独立模块MembershipService提供成员的相关服务,比如获取集群全部成员相关信息等。

点击订购作者《Tomcat内核设计剖析》

集群通信组件Tribes之怎样维护集群成员信息的更多相关文章

  1. 集群通信组件Tribes之如何维护集群成员信息

    一个集群包含若干成员,要对这些成员进行管理就必须要有一张包含所有成员的列表,当要对某个节点做操作时通过这个列表可以准确找到该节点的地址进而对该节点发送操作消息.如何维护这张包含所有成员的列表是本节要讨 ...

  2. 集群通信组件Tribes之整体介绍

    接下来一系列文章会对集群通信框架tribes进行源码级别的分析,欢迎讨论. 把若干机器组合成一个集群,集群为了能协同工作,成员之间的通信是必不可少的,当然可以说这也是集群实现中重点需要解决的核心问题, ...

  3. 集群通信组件tribes之集群的平行通信

    前面的集群成员维护服务为我们提供了集群内所有成员的地址端口等信息,可以通过MembershipService可以轻易从节点本地的成员列表获取集群所有的成员信息,有了这些成员信息后就可以使用可靠的TCP ...

  4. 集群通信组件tribes之使用方法

    上面已经对tribes的内部实现机制及原理进行了深入的剖析,在理解它的设计原理后看看如何使用tribes,整个使用相当简单便捷,只需要四步: ① 定义一个消息对象,由于这个消息对象是要在网络之间传递的 ...

  5. 集群通信组件tribes之用法

    上面已经对tribes的内部实现机制及原理进行了深入的剖析.在理解它的设计原理后看看怎样使用tribes.整个使用相当简单便捷,仅仅须要四步: ① 定义一个消息对象,因为这个消息对象是要在网络之间传递 ...

  6. 集群通信组件tribes之集群的消息接收通道

    与消息发送通道对应,发送的消息需要一个接收端接收消息,它就是ChannelReceiver.接收端负责接收处理其他节点从消息发送通道发送过来的消息,实际情况如图每个节点都有一个ChannelSende ...

  7. 集群通信组件tribes之应用程序处理入口

    Tribes为了更清晰更好地划分职责,它被设计成用IO层和应用层,IO层专心负责网络传输方面的逻辑处理,把接收到的数据往应用层传送,当然应用层发送的数据也是通过此IO层发送,数据传往应用层后必须要留一 ...

  8. 集群通信组件tribes之通道拦截器

    拦截器应该可以说是一个很经典的设计模式,它有点类似于过滤器,当某信息从一个地方流向目的地的过程中,可能需要统一对信息进行处理,如果考虑到系统的可扩展性和灵活性通常就会使用拦截器模式,它就像一个个关卡被 ...

  9. Python爬虫使用selenium爬取qq群的成员信息(全自动实现自动登陆)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: python小爬虫 PS:如有需要Python学习资料的小伙伴可以 ...

随机推荐

  1. Java数据结构-------Map

    常用Map:Hashtable.HashMap.LinkedHashMap.TreeMap 类继承关系: HashMap 1)无序:  2)访问速度快:  3)key不允许重复(只允许存在一个null ...

  2. js动态添加select菜单 联动菜单

    原文发布时间为:2009-11-14 -- 来源于本人的百度文章 [由搬家工具导入] <html> <head> <title>http://hi.baidu.co ...

  3. [LeetCode] Maximum Product Subarray 连续数列最大积

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  4. 容易混淆的某些Math方法说明

    1. Math.round 返回最接近的整数值,实际上就是我们说的对小数进行四舍五入. /** * 返回最接近参数的long */ static long round(double a) /** * ...

  5. depletion mosfet 的 depletion 解釋

    Origin mosfet 除了有 n channel 及 p channel 外, 還分為 enhanced 及 depletion 兩種, 引起我注意的是, depletion 代表什麼, Exp ...

  6. 移动开发平台 apicloud、wex5

    http://www.apicloud.com/deepengine http://www.wex5.com

  7. 【C/C++】快速排序的两种实现思路

    方法一:不断填坑,一次确定一个值.http://blog.csdn.net/morewindows/article/details/6684558 #include<stdio.h> vo ...

  8. Educational Codeforces Round 39 (Rated for Div. 2) B. Weird Subtraction Process[数论/欧几里得算法]

    https://zh.wikipedia.org/wiki/%E8%BC%BE%E8%BD%89%E7%9B%B8%E9%99%A4%E6%B3%95 取模也是一样的,就当多减几次. 在欧几里得最初的 ...

  9. [Machine Learning with Python] My First Data Preprocessing Pipeline with Titanic Dataset

    The Dataset was acquired from https://www.kaggle.com/c/titanic For data preprocessing, I firstly def ...

  10. JMeter部分功能详解

    JMeter 介绍: 一个非常优秀的开源免费的性能测试工具. 优点:你用着用着就会发现它的重多优点,当然不足点也会呈现出来. 从性能工具的原理划分: Jmeter工具和其他性能工具在原理上完全一致,工 ...