[訊息論壇] ICE Messaging
Forum 蔣居裕
技術篇:iPush®
Server 部署之道 (下 ─ 叢集篇)
再說一次:沒有良好的部署,就沒有良好的服務。
為何需要為某種訊息應用服務,架構起由多部伺服器所組成的叢集 (Server Cluster)
呢?通常商業上的理由只有一個:
也就是說,它要能夠同時服務的使用者人數,是相對的高數量。在這個商業服務目標之下,整體系統技術架構要能夠符合下列特性需求:
- Fail Over (錯誤轉介):為系統中某一部份發生錯誤狀況時,可以將作業轉介至其他部分,以便系統得以持續正常運作的一種能力。詳細名詞解釋,請參見本電子週報第
10 期訊息技術說文解字。
- Fault Tolerance (容錯機制):為一種可有效因應電腦硬體或軟體故障的系統能力。詳細名詞解釋,請參見本電子週報第
10 期訊息技術說文解字。
- Load Balancing (負載平衡):在電腦網路中,平均地分配溝通及通訊行為至相對應的多組電腦裝置,以此防止某單一機組/裝置超過負荷的機制。詳細名詞解釋,請參見本電子週報第
9 期訊息技術說文解字。
- Scalability (擴充性):因為很少有人能正確地判斷一個服務中、長期的同時使用者連線數
(concurrent connection) 需求,所以最好一開始上線的這個系統即必須具備相當好的服務擴充能力,以期縮短擴充時的服務停止運轉時間,以及降低維護難度。詳細名詞解釋,請參見本電子週報第
4 期訊息技術說文解字。
以多台 iPush® Server 主機部署起來的訊息應用服務叢集
(以下簡稱 iPush® Clustering),即具備上述所有特性。
一套完整的 iPush® Clustering,跟單台的
iPush® Server 一樣,也是由四個部分組成的:
-
iPush®
Messaging Kernel:又稱為 iCore,為 iPush®
Server 的即時傳訊核心;一般即稱之為 iPush® Server。
- BackOffice:提供各項管理的功能與介面。
- AuthService:即
Auth Center Server (簡稱 AC Server),對欲連線登入的 User 進行認證作業 (Authentication)。
-
License Daemon:對
License Key 進行管控。
先撇開 Redundant 備援不談,在 iPush®
Clustering 中,BackOffice、AuthService、與 License Daemon 都只要有一份執行著即可;至於即時傳訊核心
iPush® Messaging Kernel,則就真的是要視該應用服務的容量需求,而要多套部署的組件。因為也只有
iPush® Messaging Kernel,才會直接面對眾多的服務使用者。是以,所謂的「服務容量擴充」,當然就是指擴充 iPush®
Messaging Kernel (即一般稱 iPush® Server
者) 了。
| 給定一個
iPush® Clustering 範例 (不含 Redundant Connection
Center) |
為了要能夠完整說明後續的 iPush® Clustering
諸要項,我們要在此先提出一套由三台 iPush® Server 主機所組成的 iPush®
Clustering 範例系統,其詳細組件架構圖,即如下所示:
| 
|
| 圖
1. 由三台 iPush® Server 主機所組成的 iPush®
Clustering 訊息應用系統範例組件架構圖 |
各組件說明如下:
-
Connection Center:即一套
iPush® Clustering 中,位居上層 (Level 1) 的 iPush®
Server。通常同一台主機裡頭,也同時部署執行 License Daemon、AC Server、BackOffice,以供整個
iPush® Clustering 使用。
不管就訊息傳遞的角色,還是使用者驗證的角色,Connection Center 都不直接面對使用者,而是做為第二層
(Level 2,簡稱為 L2) iPush® Server 的上層訊息傳遞樞紐
(用到 iPush® Messaging Kernel)、全體使用者共用的認證中心
(用到 AC Server)、以及所有 iPush® Server 主機的 License
管理 (用到 License Daemon)。而為了整套 iPush® Clustering
的系統管理,也將 BackOffice 與執行所需的 Web Server 部署於此。
-
L2 iPush®
Server A / B:這兩台皆為第二層 (L2) 的 iPush®
Server,只需部署 iPush Messaging Kernel 於其中。
不管部署了幾台,L2 iPush® Server 的角色都很單純且一致,就是直接面對使用者
(iPush® Client),執行應用服務的即時訊息傳遞功能。
對使用者而言,在每一次連線期間,只會連結到一個 L2 iPush® Server,而因為訊息可以雙向
(Bi-directional) 流動,對照 Pub / Sub 模式,當使用者 X 發送 (Publish)
一個屬於 Channel P 的訊息給連結著的 L2 iPush® Server
(比如 A),那這個訊息,會有兩種傳遞路徑:
-
直接由 L2 iPush® Server
A,主動推播 (Push) 給也連結著 L2 iPush®
Server A,且訂閱 Channel P 的其他 iPush® Client
接收。此種傳遞路徑亦可稱為區域訊息交換 (Local
Message Exchange);這在廣域分點部署的情況下,有其強固性 (Robustness)
上的價值。
-
訊息流經 L2 iPush® Server
A → Connection Center → L2 iPush® Server
B,再由 L2 iPush® Server B 主動推播給連結著它,且訂閱
Channel P 的其他 iPush® Client 接收。此種傳遞路徑亦可稱為全區訊息交換
(Global Message Exchange);一個訊息藉由 L2 iPush®
Server 到 Connection Center,再到其他的 L2 iPush®
Server,即可遍流整套 iPush® Clustering。
-
Load Balancer:負責使用者到全部
L2 iPush® Server 間的連結負載平衡機制。這個機制可以由各種不同的技術或產品來達成,如軟體的
DNS Round-Robin、硬體的 Network Switch、負載平衡器等等。稍後,我們會示範如何用
DNS Round-Robin 來實現 Load Balancing 的功能。
另外值得注意的,是上圖中的兩種圖例路徑:
-
紅色單向虛線:代表對使用者身份進行驗證的路徑。主要發生在
iPush® Client 連結到任一 L2 iPush®
Server,要進行登錄作業時,會由 iPush® Messaging Kernel
與 AC Server 協同完成。
-
藍色雙向實線:代表訊息傳遞的繞徑
(Routing) 為跨主機雙向。會由上、下層間的 iPush® Messaging
Kernel 協同完成全區訊息交換。
以下的說明,將以圖 1. 這個範例架構為準。
| L2 iPush®
Server 對 Connection Center 的認證與傳訊 Uplink 組態設定 |
承上說明,為了要執行使用者身份進行驗證與訊息傳遞繞徑的功能,我們必須在每一台 L2 iPush®
Server 的 iPush.ini 檔案中,正確組態相關的設定:
- L2 iPush® Server 串聯使用的 AC
Server 設定
/**************************************************************/
/* AuthAddress & AuthPort */
/* Where the iPush should connect to, to be it's AC. A blank */
/*AuthAddress represent no AuthConnection needed. */
/**************************************************************/
AuthAddress=192.168.0.211
AuthPort=1111
- L2 iPush® Server Uplink 上層
iPush® Server 的設定
/************************************************************/
/* SourceAddress & SourcePort */
/* Where the iPush should connect to, to be it's uplink.
A blank */
/*SourceAddress represent no SourceConnection needed. */
/************************************************************/
SourceAddress=192.168.0.211
SourcePort=8000
-
SourceAddress:必須給定此
L2 iPush® Server 所串聯使用的上層 iPush®
Server IP 位址。如圖 1.,即 Connection Center 所在的主機 IP。
-
SourcePort:該上層
iPush® Server 服務聆聽的埠號;此值必須等同 Connection
Center 上 iPush.ini 中的 ListenPort 值。Windows 版本預設為 8000;Linux
版本預設為 443。
| L2 iPush®
Server 對上層 iPush® Server 的 Channel Subscription |
為了要達成全區訊息交換,除了上面所提的 L2 iPush®
Server Uplink 上層 iPush® Server 設定之外,上、下層的 iPush®
Messaging Kernel 間,還必須要有訊息流動所需的 Channel Subscription 組態。這個組態所在,即是
L2 iPush® Server iPush.ini 檔案中的設定項目 SourceSubscribe:
/**************************************************************/
/* SourceSubscribe */
/* When the Source Connection enable and connected, it will
subscribe */
/*from its uplink with these channels. */
/**************************************************************/
SourceSubscribe=00-ff
預設為 00-ff,即 L2 iPush® Server
要向上層的 iPush® Server 訂閱所有的 Channel (即代表連續區段
0x00000000-0xffffffff)。
這裡的 Channel Subscription 值,只能使用 16 進位 ASCII
字元內碼格式,且前面不必加上 '0x' ,至於其他規則,如不連續區段 (使用 ',')、連續區段
(使用 '-') 表示方式等,卻都是照常使用。
註一:關於 Channel
訂閱的諸項規則,請參考本電子週報第
11 期:與 Developer 息息相關的 iPush API (下) 。
| 如何部署具
Load Balancing 能力的 iPush® Clustering? |
接下來說明要如何部署 Load Balancer,以便可以平均分散不斷連結進來的 iPush®
Client 服務需求。我們在此將以 DNS 的 Round-Robin 功能,來做為 Load Balancing
負載平衡機制。
承圖 1.,面對所有 iPush® Client 的是
L2 iPush® Server A 與 L2 iPush®
Server B 這兩台主機,假設它們的 IP 位址分別為 192.168.0.38 與 192.168.0.39,那做為這套
iPush® Clustering Load Balancing 機制的 DNS Server
設定中,就必須要為這兩個 IP 位址建立相同的 Canonical Name。舉例如下,ipush
即為此 Canonical Name:
ipush IN A 192.168.0.38
ipush IN A 192.168.0.39
若此套 iPush® Clustering 所在的網域名稱為
xyz.com.tw,那麼,iPush® Client 在存取此 iPush®
Clustering 應用服務時,只要連結主機名稱 ipush.xyz.com.tw,DNS
Server 就會自動將陸續進來的 iPush® Client 連結,輪流分配給 L2
iPush® Server A 與 L2 iPush®
Server B 這兩台主機去服務,而達到負載平衡的目的。
若部署者要使用其他的負載平衡機制,相同的道理,只要將 L2 iPush®
Server A 與 L2 iPush® Server B 擺入對應的設定即可達成,毋須將之想得太複雜。
| 完美簡約的
iPush® Clustering Scalability |
前面曾經說過,關於擴充性 (Scalability) 的需求,最好是上線的這個系統須具備好的服務擴充能力,以期縮短擴充時的服務停止運轉時間,以及降低維護難度。
iPush® Clustering 的服務容量擴充,可以做到不必停止服務運轉,也不會增加系統的複雜度。因為它只需要新增任意數目的
L2 iPush® Server 即可完成,可說是相當的完美簡約。如下圖 2. 所示:
| 
|
| 圖
2. 由二台 L2 iPush® Server 擴充為四台 L2
iPush® Server 的範例架構圖 |
圖 2. 省略了幾個與圖 1. 相同的 Connection Center 組件,如
License Daemon、BackOffice、與 Web Server,因為服務容量的擴充,只須以增加 L2
iPush® Server 數量的方式即可辦到。如圖 2.,由二台 L2 iPush®
Server 擴充為四台 L2 iPush® Server,整套 iPush®
Clustering 的服務容量可立即提昇為兩倍 (暫不考慮 License 之限制)。
擴充後的 Connection Center、L2 iPush®
Server A、L2 iPush® Server B 組態都毋須改變,只有新增加的
L2 iPush® Server C 與 L2 iPush®
Server D 這兩台主機,必須依照上述的說明,完成下列組態設定項目:
-
L2 iPush® Server 串聯使用的
AC Server 設定
-
L2 iPush® Server Uplink
上層 iPush® Server 的設定
-
L2 iPush® Server 對上層 iPush®
Server 的 Channel Subscription
事實上,就是沿用 L2 iPush® Server A
或 B 的 iPush.ini 組態檔即可。增加部署 L2 iPush® Server
C 與 D 時,原本系統中的 Connection Center、L2 iPush®
Server A、L2 iPush® Server B,都可持續服務,毋須停機。
另外,我們還必須將 L2 iPush® Server C
與 D 加入既有的 Load Balancing 負載平衡機制中。承上 DNS Server 的例子,假設 L2 iPush®
Server C 與 D 的 IP 位址分別為 192.168.0.40 與 192.168.0.41,那就繼續相同的
Canonical Name 即可。舉例如下:
ipush IN A 192.168.0.38
ipush IN A 192.168.0.39
ipush IN A 192.168.0.40
ipush IN A 192.168.0.41
這樣,iPush® Client 也毋須修改,依舊連結主機名稱
ipush.xyz.com.tw,透過 Load Balancer
的分配,L2 iPush® Server C 與 D 這兩台主機就加入服務的行列了。
註二:DNS 在組態修改過後,可能需要重新啟動
DNS Server,才能讓新的組態生效。實際情況,請自行參考您所使用的 DNS Server 相關技術資訊。
| iPush®
Clustering 與 Firewall |
關於要不要為 iPush® Clustering 部署
Firewall,其實與上一期單機篇中所說的一樣,不外是要考量系統中流動的資訊,其內容安全性等級需求有多高?以及
Firewall 本身的執行效能如何?
一旦決定要將全部的 L2 iPush® Server 部署在
Firewall 內 (當然,此時 Connection Center 也會被部署在 Firewall 內),那麼搭配
Load Balancer 的使用,Firewall 的 Proxy 組態設定,一定要正確。在此不再贅述。
| iPush®
Client 如何連結存取具 Load Balancer 的 iPush® Clustering? |
前面已經說過,當 iPush® Client 要存取一套提供應用服務的
iPush® Clustering 時,只要依照 Load Balancer 所設定的
L2 iPush® Server 存取規則,如依循上面 DNS Round-Robin
例子所設定的主機名稱 ipush.xyz.com.tw,以及所有
L2 iPush® Server 都相同的 ListenPort,就可順利連結這個具負載平衡能力的
iPush® Clustering 了。
| Web
Server 與 L2 iPush®
Server (Java
Applet Client 部署) |
由於 BackOffice / Web Server 被部署在 Connection
Center 那台主機上,所以一般來說,所有的 L2 iPush® Server 主機上就不需要再執行
Web Server 了。但這在一個情況之下例外 ─ 即當 iPush Client 的類型為 Java Applet
時。
熟悉 Java Applet 行為的人都曉得,為了安全性的考量,當一個嵌入網頁的 Java
Applet 被下載到客戶端的 Web Browser 之後,該 Web Browser 所在電腦的 JVM (Java
Virtual Machine) 會限制該 Java Applet 只能連結回其 Java Class 所在的那台主機。
所以,若要利用 iPush® Java Applet Client
/ iPush® Server 來進行訊息的傳遞作業,那麼就必須將 iPush®
Server、Web Server,隨同該 Java Applet (Class)、iPush®
Java Package API (Jar),統統部署在同一台主機上。在具 Load Balancer 的 iPush
Clustering 中,這主機就是所有的 L2 iPush® Server。如下圖
3. 所示:
| 
|
| |
| 圖
3. Client Browser 由 L2 iPush® Server
主機上的 Web Server 下載 Java Applet 與 API 後, Java Applet
即會與 iPush Messaging Kernel 進行雙向訊息傳遞 (Connection Center
省略不畫 ) |
假設現在有一個 HTML 網頁,被放置在網路任一 Web Server 上 (當然也可以是
L2 iPush® Server 主機上的 Web Server),此網頁內嵌有一個
Java Applet,整個 HTML 原始碼如下:
<HTML>
<BODY>
<APPLET code="http://www.xyz.com.tw/test/iMonitor_AWT.class"
width=300 height=80 Archive="http://www.xyz.com.tw/test/iceipush.jar">
<param name="ip" value ="ipush.xyz.com.tw">
<param name="port" value ="8000">
<param name="channel" value="ch01-ch05">
<param name="company" value="ICE">
<param name="product" value="AUTOMATION">
<param name="account" value="auto_monitor">
<param name="password" value="auto_monitor">
</APPLET>
</BODY>
</HTML>
且承上例,以 DNS Round-Robin 為 Load Balancing 機制,為所有的
L2 iPush® Server 主機,分別為 iPush®
Messaging Kernel 與 Web Server 建立相同的 Canonical Name ─ ipush
與 www:
ipush IN A 192.168.0.38
ipush IN A 192.168.0.39
www IN A 192.168.0.38
www IN A 192.168.0.39
所以當這個網頁被 Client Browser 開啟後,由於 tag <APPLET>
中的屬性 code 與 Archive,其路徑都指向 http://www.xyz.com.tw,
所以 Client Browser 會透過 Load Balancer 的分配,不是連結 L2 iPush®
Server A 上的 Web Server,就是連結 L2 iPush® Server
B 上的 Web Server。然後:
-
下載 Web Server 虛擬目錄 /test 下的 iMonitor_AWT.class
(iPush® Java Applet Client)與 iceipush.jar
(iPush® Java Package API)。
-
此後之作業,就再也跟 Web Server 無關了。在 Client Browser
中啟動 JVM,載入 iMonitor_AWT.class 與 iPush®
Java Package API,開始與剛才 Web Server 同一主機的 iPush®
Messaging Kernel (ipush.xyz.com.tw) 建立 TCP 連線,以其他參數資訊
(如 company、product、account、password) 執行登錄作業,讓 Connection
Center 中的 AC Server 進行這個使用者身份的驗證。
就是這樣,為了要符合 JVM 的安全性限制,我們就是必須要將 iPush®
Server、Web Server、Java Applet、以及 iPush® Java
Package API,統統部署在同一台主機上。而在具 Load Balancer 的 iPush®
Clustering 中,所有 L2 iPush® Server 上頭的 Java Applet
與 iPush® Java Package API 檔案擺放虛擬路徑,都要相同。
至於其他種類的 iPush® Client,就沒有這樣的限制。即便如
Microsoft ASP 的網頁程式運作,在 Client Browser 將 ASP 程式所需要用到的 ActiveX
Control 元件下載之後,並不會限制它只能連回元件所在的主機。所以在系統部署上,會比 Java Applet 多一些彈性
(少一些安全性?)。
| iPush®
Clustering 與 Fail Over |
最後,我們要來談一下 iPush® Clustering
中的 Fail Over (錯誤轉介) 要如何組態與實作。
可分兩個層面來看:
- Connection Center Fail Over
- L2 iPush® Server Fail
Over
以下分別討論之。
<Connection Center
Fail Over>
上面所有範例中的 Connection Center 都只是單台主機,所以當這台主機發生問題時,可能會導致整套
iPush® Clustering 的運作連帶發生問題,如 AC Server、BackOffice
無法正常發揮該有的功能。
我們可以建立第二台 Connection Center 主機的 Redundant 備援方式,來實踐
Connection Center 的 Fail Over 特性。範例架構如圖 4. 所示:
| 
|
| 圖
4. 具 Fail Over 能力的雙 Connection Center 主機範例架構 (Load Balancer
與 iPush® Client 省略不畫 ) |
假設 Connection Center 1 主機與 Connection Center
2 主機的 IP 位址分別為 192.168.0.211 與 192.168.0.212,而其中的 AC Server
與 iPush® Messaging Kernel 的 ListenPort 皆為預設值。那
L2 iPush® Server A 與 L2 iPush®
Server B 必須要有相同的雙 Connection Center 組態,iPush.ini 中的相關組態設定項目如上:
- L2 iPush® Server 串聯使用的雙 AC
Server 設定
/**************************************************************/
/* AuthAddress & AuthPort */
/* Where the iPush should connect to, to be it's AC. A blank */
/*AuthAddress represent no AuthConnection needed. */
/**************************************************************/
AuthAddress=192.168.0.211
AuthPort=1111
AuthAddress=192.168.0.212
AuthPort=1111
- L2 iPush® Server Uplink 雙上層
iPush® Server 的設定
/************************************************************/
/* SourceAddress & SourcePort */
/* Where the iPush should connect to, to be it's uplink.
A blank */
/*SourceAddress represent no SourceConnection needed. */
/************************************************************/
SourceAddress=192.168.0.211
SourcePort=8000
SourceAddress=192.168.0.212
SourcePort=8000
實際執行時,在正常情況下,都只串聯使用第一組的 AC Server 與上層 iPush®
Server,但若第一組所設定的 AC Server 或上層 iPush® Server
無法正常連結,就會自動切換 (Auto-switch) 連結第二組的 AC Server 或上層 iPush®
Server。
另外,完整的 Redundant 備援,應該包含 BackOffice 資料庫的一致性與
L2 iPush® Server License 的一致性,這是系統部署與上線運作後,要持續維持的。
藉此,即可達到 Connection Center Fail Over 的能力。
<L2 iPush®
Server Fail Over>
其實,藉由 Load Balancer 的容錯能力,即可為 iPush®
Client 避開無法正常提供服務的 L2 iPush® Server,而不與之連結。
若是在連線期間,所使用的 L2 iPush® Server
發生錯誤,那麼 iPush® Client 可以在被 iPush®
API 發出的 Server Connection Timeout 事件通知 (Event: Connection
Lost) 之後,決定是要自動,或是讓使用者以手動方式,重新要求 Load Balancer
分配一個可供正常連結的 L2 iPush® Server,以便繼續其應用服務。
雖然本期我們用了不短的篇幅,來介紹完整的 iPush®
Clustering 各項部署細節。不過正確部署之道的大原則卻相單簡單,設定作業只集中在兩處:
相信讀者在詳讀研究之後,對於 iPush® Clustering
的運作原理,以及日後的部署規劃,可以更加得心應手。
若您還是任何的疑問或指教,十分歡迎寫
E-Mail 來與筆者進行交流。
【後註】
在 iPush2000 v1.2.43 以後,L2 iPush®
Server 對 Connection Center 的認證與傳訊 Uplink 組態設定方式有所改變。iPush.ini
相關異動項目如下:
SourceCount=0
AuthCount=1
[SOURCE_SERVER_0]
SourceAddress=
SourcePort=8000
[SOURCE_SERVER_1]
SourceAddress=
SourcePort=3002
[AUTH_SERVER_0]
AuthAddress=192.168.0.211
AuthPort=1111
[AUTH_SERVER_1]
AuthAddress=
AuthPort=1112
-
<[AUTH_SERVER_n]:特定串聯之
AC Server 的組態;從 0 開始編號者為第一台,然後依序加編,直至 <AuthCount-1>
為止。
-
AuthAddress:給定此
L2 iPush® Server 所串聯使用的 AC Server IP
位址。留空即表示不設定。
-
AuthPort:該
AC Server 服務聆聽的埠號。
|