}
上面的 NumberGenerator.java 很簡單的每秒送出一個累加的數字,由 1 累加到 1000 為止。對於上面程式有不了解的,可以先參考「Tibco RV request/reply 的同步與非同步」,之後再回頭來看 fault tolerance。接下來要進入主題,看一下 fault tolerance 程式。
1 package idv.steven.rv.ft;
3 import com.tibco.tibrv.Tibrv;
4 import com.tibco.tibrv.TibrvException;
5 import com.tibco.tibrv.TibrvFtMember;
6 import com.tibco.tibrv.TibrvFtMemberCallback;
7 import com.tibco.tibrv.TibrvListener;
8 import com.tibco.tibrv.TibrvMsg;
9 import com.tibco.tibrv.TibrvMsgCallback;
10 import com.tibco.tibrv.TibrvRvdTransport;
12 public class NumberReceiver implements TibrvMsgCallback, TibrvFtMemberCallback, Runnable {
13 private String service = "7500";
14 private String network = ";225.1.1.1";
15 private String daemon = "tcp:7500";
16 private String subject = "DEMO.FT.NUM";
18 private String ftservice = "7504";
19 private String ftnetwork = ";225.1.10.1";
20 private String ftdaemon = "tcp:7504";
22 private String ftgroupName = "DEMO.FT.GROUP";
23 private int ftweight = 50;
24 private int activeGoalNum = 1;
25 private double hbInterval = 1.5;
26 private double prepareInterval = 3;
27 private double activateInterval = 4.8;
29 private TibrvRvdTransport transport = null;
30 private TibrvListener listener = null;
32 private boolean active = false;
34 @Override
35 public void run() {
36 try {
37 Tibrv.open(Tibrv.IMPL_NATIVE);
38 transport = new TibrvRvdTransport(service, network, daemon);
39 TibrvRvdTransport fttransport = new TibrvRvdTransport(ftservice, ftnetwork, ftdaemon);
40 fttransport.setDescription("fault tolerance");
42 new TibrvFtMember(Tibrv.defaultQueue(), // TibrvQueue
43 this, // TibrvFtMemberCallback
44 fttransport, // TibrvTransport
45 ftgroupName, // groupName
46 ftweight, // weight
47 activeGoalNum, // activeGoal
48 hbInterval, // heartbeatInterval
49 prepareInterval, // preparationInterval,
50 // Zero is a special value,
51 // indicating that the member does
52 // not need advance warning to activate
53 activateInterval, // activationInterval
54 null); // closure
57 while(true) {
58 try {
59 Tibrv.defaultQueue().dispatch();
60 }
61 catch (TibrvException e) {
62 System.err.println("Exception dispatching default queue:");
63 System.exit(0);
64 }
65 catch(InterruptedException ie) {
66 System.exit(0);
67 }
68 }
69 } catch (TibrvException e) {
70 e.printStackTrace();
71 }
72 }
74 void enableListener() {
75 try {
76 // Subscribe to subject
77 listener = new TibrvListener(Tibrv.defaultQueue(),
78 this,
79 transport,
80 subject,
81 null);
82 System.out.println("Start Listening on: " + subject);
83 }
84 catch (TibrvException e) {
85 System.err.println("Failed to create subject listener:");
86 System.exit(0);
87 }
88 }
90 void disableListener() {
91 listener.destroy();
92 System.out.println("Destroy Listener on Subject: " + subject);
93 }
95 @Override
96 public void onFtAction(TibrvFtMember member, String ftgroupName, int action) {
97 if (action == TibrvFtMember.PREPARE_TO_ACTIVATE) {
98 System.out.println("TibrvFtMember.PREPARE_TO_ACTIVATE invoked...");
99 System.out.println("*** PREPARE TO ACTIVATE: " + ftgroupName);
100 }
101 else if (action == TibrvFtMember.ACTIVATE) {
102 System.out.println("TibrvFtMember.ACTIVATE invoked...");
103 System.out.println("*** ACTIVATE: " + ftgroupName);
104 enableListener();
105 active = true;
106 }
107 else if (action == TibrvFtMember.DEACTIVATE) {
108 System.out.println("TibrvFtMember.DEACTIVATE invoked...");
109 System.out.println("*** DEACTIVATE: " + ftgroupName);
110 disableListener();
111 active = false;
112 }
113 }
115 @Override
116 public void onMsg(TibrvListener listener, TibrvMsg msg) {
117 if (subject.equals(listener.getSubject())) {
118 try {
119 int num = msg.getAsInt("number", 0);
120 System.out.println("number: " + num);
121 } catch (TibrvException e) {
122 e.printStackTrace();
123 }
124 }
125 }
127 public static void main(String[] args) throws InterruptedException {
128 NumberReceiver rcv = new NumberReceiver();
129 Thread tRcv = new Thread(rcv);
130 tRcv.start();
131 tRcv.join();
132 System.out.println("stop");
133 }
134 }
上面的程式與 fault tolerance 有關的是第 39~54 行及第 96~113 行,在解釋程式之前,我先對 RV 提供的 fault tolerance 作簡單的說明。
RV 的 fault tolerance 以 group name 來區分,也就是同一個 group name 的程式會成為一個群組,相互備援。
RV 將 fault tolerance 的系統狀態分成三個階段,如下:
- DEACTIVATE: 顧名思義,就是非屬於提供服務的狀態,這時候系統當然就別做什麼事,只要一直傾聽 RV 的訊息,當傾聽到要切換狀態時再進行相關工作。
- PREPARE_TO_ACTIVATE: 當 RV 送來這個狀態,表示原本正提供服務的系統可能出了狀況,備援的系統要開始準備啟動,通常收到這個 event 時,會進行一些系統資源初始化的工作,以便當程式真的要啟動提供服務時,可以儘快啟動,以使服務中斷的時間儘可能的縮短。
- ACTIVATE: 收到這個 event,就真的要接手服務了!
- fault tolerance callback function
上述三個狀態的切換,RV 會透過 onFtAction 這個 callback function 通知備援的程式,所以程式要實作 TibrvFtMemberCallback 這個介面。
在我們將測試的例子裡,只會啟動兩個 reciver 程式,一次只會有一個程式提供服務 (接收 generator 傳來的數字並輸出到 console),但是,實務上要有幾支程式處於 ACTIVATE 狀態是可以設定的,這個數字稱為 active goal。
每支程式建立 fault tolerance 時,在建構子的參數裡會有個 weight 的參數,這個值由 1 到整數的最大值,數字越大優先權越大,所以,如果有三支程式 A、B、C,其權重 (weight) 分別為 50、30、100,當 RV 要從這三支程式裡挑一支啟動來提供服務時,就會挑權重最大的 C。
每個處於 ACTIVATE 狀態的程式,會不停的送出 heart beats (心跳) 訊息給其它同群組的程式,以表示它還活著,還在正常提供服務。
現在說明 NumberReceiver.java 程式,如下:
- Line 12: 所有參與 fault tolerance 的程式都要實作 TibrvFtMemberCallback。
- Line 39: 建立一個 fault tolerance 的通道。
- Line 42: 使這支程式成為群組中的一個成員 (member),這裡面有好幾個和時間有關的參數 - hbInterval、prepareInterval、activeInterval,單位是秒,指的是 heart beat 的時間、進入 PREPARE_TO_ACTIVATE 的時間及切換到 ACTIVATE 的時間,在這裡設定為 1.5、3、4.8,表示每三秒會有一次的心跳訊息,當 3 秒鐘都沒有收到訊息即進入 PREPARE_TO_ACTIVATE 狀態,當 4.8 秒沒有收到心跳訊息,就切換到 ACTIVATE 狀態。
- Line 74~90: 這兩個 method (enableListener、disableListener) 是用來啟動服務及停止服務。
- Line 96~113: onFtAction 是 fault tolerance 的 callback function,這裡可以接收到狀態改變的 event。
- Line 116~125: 收到 NumberGenerator 送來的訊息,將它輸出到 console。
現在進行測試 …
- 首先啟動 NumberGenerator …
- 開啟兩個「命令提示字元」的視窗,並同時啟動 NumberReceiver,可以看到其中一個開始提供服務,如下圖:
- 在左邊原本正在提供服務的程式按 Ctrl-C 以中斷服務,可以看到右邊的程式接手了服務。
- 再次啟動左邊的程式,左邊的程式將處於 DEACTIVATE 的狀態。
- 在右邊視窗中按 Ctrl-C 中斷右邊的程式,可以看到左邊的程式又接手服務。
转载于:https://www.cnblogs.com/stevwn/p/4635756.html
有很多系統不允許(在某個特定時段)服務中斷,這類的系統不只會有備援,通常還會有 fault tolerance 機制,當系統掛掉時,備援的系統會自動啟動服務。Tibco RV 也有提供這樣的機制,底下將作說明。這裡舉的例子會有兩支程式,一支命名為 NumberGenerator,很簡單的每秒送出一個累加的數字,另一支命名為 NumberReceiver,會由 RV 接收 NumberGener...
我们公司的SECS/GSM通讯软件是单独一套的CS结构系统,在系统里结合了许多其它系统的业务逻辑和卡控,使得RMS系统越来越来臃肿,所以能否将公司的RMS系统打造成EAP,让整个系统的结构清晰,各个系统的职责分明,不想什么逻辑都加在RMS系统里。
提示:以下是本篇文章正文内容,下面案例可供参考
一、EAP是什么?
EAP(Equipment Automation Programming)控制半导体设备进行自动化生产
C:\Users\Administrator>adb devices
List of devices attached
* daemon not running; starting now at tcp:5037
adb: CreateFileW 'nul' failed: 系统找不到指定的文件。
* failed to start daemon
error: cannot connect to daemon
C:\Users\Administrator>adb devices
List of devices attached
* daemon not running; starting now at tcp:5037
adb: CreateFileW 'nul' failed: 系统找不到指定的文件。 (2)
* failed to start daemon
error: cannot conn...