1 启动流程

1  

  1) 服务器A开始启动;

  2) 服务器A生成一个随机ServerID号,用以标识自己;

  3)服务器A读取clustering.xml文件,从中获得所有服务器的地址信息;

  4)服务器A逐个尝试与其他服务器建立连接,如果没有任何服务器有响应,则将自己标识为MainServer;

  5)如果有服务器响应,则向MainServer申请成为BackupServer,申请成功则成为BackupServer,不成功则成为普通Server;

  6) 服务器A将没有响应的服务器放入未响应服务器列表中;

  7)若有服务器B向该服务器A尝试建立连接,则服务器A将服务器B从未响应服务器列表中移除;

  8)最终达到所有服务器都有到其他服务器的连接且未响应服务器列表为空的目的,并且确立集群中的MainServer和BackupServer。

  注意:各服务器启动的先后顺序不影响集群的使用,并且在只启动单个服务器的情况下能正常工作。

 

  2 存取一般锁的流程

2

  1)服务器A需要申请锁S;

  2) 如果服务器A是MainServer,则直接分配锁S给自己,并在操作完成后释放锁S;

  3)如果服务器A不是MainServer,则发送请求向MainServer申请锁S;

  4)MainServer判断锁S是否被占用,如果被占用,则返回加锁失败消息给服务器A;

  5)如果未被占用,则将锁S分配给服务器A;

  6)服务器A执行完操作,向MainServer发送释放锁S的请求;

  7)MainServer释放锁S;

  8)MainServer连续两分钟(或指定时长,由服务器A申请锁时指定)未接收到释放锁S的请求,则自动释放锁S,并将该事件写入日志。

 

  3 获取累加锁的流程

3

  1)服务器A需要获得某一全局累加锁S;

  2)如果服务器A是MainServer,则锁S的值通过synchronized块加一,并将加一后的值返回给A,流程结束;

  3)如果服务器A不是MainServer,则向MainServer发送请求;

  4)MainServer以synchronized块加一后将值返回给服务器A,流程结束。

 

  4 消息传递的流程

4

  1)服务器A修改了某项数据,并根据需要提交消息给MainServer;

  2)MainServer接收到需要广播的消息,并根据服务器数量形成发送队列;

  3)MainServer按队列逐个发送消息;

  4)如果发送成功,则从队列中移除相应服务器,并备份队列到BackupServer;

  5)如果不成功则检查目标服务器是否存活,如果存活则继续发送直到目标服务器成功接收;

  6)各服务器接收消息后需立即返回成功标识给MainServer,只能通过另外的线程对消息进行处理。

 

  5 服务器宕机的处理流程

  假设有JVM-A,JVM-B、JVM-C、JVM-D构成的一个集群,启动时确立JVM-A为MainServer、JVM-B为BackupServer,则集群中任何获取一般锁和累加锁的操作都会导致JVM-A向JVM-B发送备份请求,备份请求通过单独的线程发送,不阻塞当前操作。某个JVM发送消息的操作会先向JVM-A提交,再由JVM-A逐个发送消息,每发送完一台服务器,则会将发送队列备份到JVM-B。

  现假设JVM-A当机,则处理流程如下:

  1)JVM-B在接收不到JVM-A心跳信息的情况下将自己切换成MainServer;

  2) 新的MainServer继续当前消息队列的发送操作;

3)  新的MainServer在存活的机器中随机指定一台为BackupServer(例如JVM-C);

  4) 新的MainServer向新的BackupServer逐项同步锁和消息队列;

  5) 若JVM-A宕机后重启,重新并入集群,则只是一台普通的服务器,不再充当MainServer的角色。

  若MainServer和BackupServer同时宕机(例如两台服务器处于同一个交换机上,此交换机发生故障),则剩下的机器中通过协商(根据获得宕机消息的先后顺序)选出新的MainServer和BackupServer,流程如下(假设还有JVM-C、JVM-D存活):

  1) 各服务器都接收不到MainServer和BackupServer的心跳信息;

  2) JVM-C发现MainServer和BackupServer同时宕机,则向其他服务器发送MainServer申请,申请成为新的MainServer;

  3) 其他服务器(JVM-D)收到消息后确认MainServer和BackupServer同时宕机,则允许JVM-C的成为新MainServer的请求;

  4) 如果出现两台机器同时发起MainServer请求的情况,则以ServerID最大的为MainServer;

  5) 新的MainServer重新初始化累加锁(初始化累加锁的逻辑由业务系统通过配置文件指定);

  6) 新的MainServer指定BackupServer,并向其同步累加锁信息;

  7) 集群重新开始正常服务,并等待JVM-A、JVM-B的复活;

  8) JVM-A、JVM-B复活后不再保持原有身份,只是一台普通的服务器。

  若MainServer完好,BackupServer宕机,则MainServer简单地存活的机器(例如JVM-C)中找一台作为BackupServer,并通过单独的线程从头向新的BackupServer备份数据。