應用系統異質平台遠地部署

2009-01-01

在企業目前大型應用系統環境,無論系統開發、部署、運行與異地備援,均十分複雜。同時由於硬體價格效能比〈Price/Performance Ratio〉與日俱進,企業中在不同時期購進不同品牌服務器,也在所多有。

近來企業為提昇其本身服務水準〈Service Level Agreement〉,紛紛建置異地備援機制,在遠地複製最低可運行環境,撐過災難發生後復健期,已蔚為主流,隨而各式備援解決方案百家爭鳴。然而目前備援解決方案多為儲存設備〈Storage〉廠商所提出,利用網路來同步異動遠地儲存設備,達到備援目的。但是此種解決方案有以下重大缺點:

  • 儲存設備必須要同廠牌。企業無法依價格效能比購買,甚至受制於廠商。
  • 與遠地服務器必須要同廠牌,同作業系統,二進位碼必須要相容。企業無法依價格效能比購買,甚至受制於廠商。
  • 由於儲存設備間同步類似於鏡射〈Mirror〉,對於各種暫存資料、可由應用系統再製之衍生資料,亦一併同步至遠地。對於異動頻繁熱磁區,更因前次同步尚在途中,而新異動又起,造成企業網路塞爆,頻寬欲求不滿,致使通信費用居高不下。
  • 又因鏡射同步有在途延遲隱憂,倘於同步過程中,發生災難,剛異動資料磁區在途中遺失,則遠地儲存設備狀態亦處於暫態,結果往往造成遠地應用系統無法讀取關鍵磁區,根本喪失備援回復能力。
  • 雖然儲存設備鏡射有非同步機制,它能降低頻寬發生尖峰機率,充分利用費率成本較低時段進行同步,但是再未全部完成遠地同步前,發生不可回復之災難而丟失磁區資料,極有可能造成遠地服務器因為磁區被破壞而無法提供服務之窘境。

開發人員依循應用系統設計生命週期,經常困擾於重複性工作,一時之疏忽與惰性養成,常造成各應用系統環境不一致。更因隨時間逝去,人事異動等因素,甚至無法判定系統版本,造成系統運維困擾。

軟體設計生命週期

在應用系統設計生命週期中,粗分為以下步驟:

  1. 需求與塑模〈Modeling〉
  2. 設計與開發
  3. 開發環境部署
  4. 單元測試
  5. 運行環境部署
  6. 需求變更,再復始至〈1〉

在設計生命週期中,自然會產生大量的暫態資料、衍生資料、測試資料,如果採取儲存設備異地備援解決方案,備援成本十分昂貴,理由已見於前述。真正解決之道,係將運行環境部署工作自動化,並讓暫態資料、衍生資料在遠地編譯連結產生,縮短備源時間,降低網路通信成本。

為便於說明,假想情境如下:

  • 應用系統為 Oracle Pro*C,使用 make 建置。
  • 本地開發與運行環境為 HP-UX
  • 本地開發工具為 HP C 編譯器
  • 遠地開發與運行環境為 IBM AIX
  • 遠地開發工具為 IBM XL-C 編譯器

部署需求如下:

  • 本地端應用系統原始程式當異動時,需同步遠地開發環境。
  • 當本地端應用系統使用 make 時,遠地開發環境需同時建置。

解決方案如下:

  • 兩地異質平台檔案同步方案分析如下:
    1. 使用 unison
      • 它是一套跨平台之間目錄檔案同步系統,提供單向複寫、雙向同步功能,遠地檔案版本衝突解決機制。
      • 它可以指定需要同步的檔案型態,如:*.pc。
      • 需要部署於兩地服務器中。
    2. 使用 rsync
      • 它是一套跨平台〈*nix〉之間目錄檔案同步系統,提供一個非常快速的檔案傳輸方法, 使兩地服務器間目錄檔案同步,它傳送兩地檔案異動部份,而非每次都整份傳送,因此速度相當地快。
      • 它無法指定需要同步的檔案型態,因此在 Makefile 要將各種暫存檔、衍生檔規劃在不同步之目錄中。
      • 需要部署於兩地服務器中。
    3. 使用 ftp/sftp:
      • 遠地需要啟動 ftp/sftp 服務。
      • 先設計好 ftp/sftp 命令稿,將要同步的目錄檔案型態,產生壓縮檔,ftp/sftp 傳送至遠地服務器相應目錄下。
      • 以應用系統為對象,對於簡單目錄結構,同步檔案數不多者適用。
      • 在遠地 Makefile 中,要先解壓縮檔後才真正建置。
      • 在本地 Makefile remote 工作項目中,先執行ftp/sftp 命令稿,再執行 rmake_client〈看後面說明〉。
      • 自近端同步遠地檔案 ftp 命令稿範例:
        #!/bin/sh
        
        REMOTE_SITE=aix53
        REMOTE_USER=scott
        REMOTE_PASS=tiger 
        
        SYNC_PATH=/home/scott/myProCProject
        SYNC_FILE=myProC.pc 
        
        ftp -n $REMOTE_SITE << EOF
        quote USER $REMOTE_USER
        quote PASS $REMOTE_PASS
        cd $SYNC_PATH
        put $SYNC_FILE
        bye
        EOF
    4. 使用 HTTP:
      • 本地需要啟動 HTTP 服務,設定只接受來自遠地服務器 IP 之請求。
      • 先設計好命令稿,將要同步的目錄檔案型態,產生壓縮檔,複製至 HTTP 服務相應目錄下。
      • 以應用系統為對象,對於簡單目錄結構,同步檔案數不多者適用。
      • 在遠地 Makefile 中,要先使用 wget 工具取回壓縮檔,並解開至相應目錄下後才真正建置。
      • 在本地 Makefile remote 工作項目中,先執行選檔並壓縮之命令稿,再執行 rmake_client〈看後面說明〉。
  • 設計 主從式網路程式 如下:
    • 遠地建置請求程式〈rmake_client〉:
      • 部署於本地服務器〈HP-UX〉
      • 配合本地應用程式 Makefile 設計
      • Makefile 至少有下列工作項目〈make Tasks〉:
        • default:編譯/連結
        • test:配合測試資料單元測試
        • install:本地部署
        • remote:遠地部署,在本地佈署至運行環境並啟用無誤後,採用 rsync 目錄檔案同步機制者,執行此項工作前需先檔案同步完成。採用其他機制者,將檔案同步命令稿先於 rmake_client 即可。
      • 用法:rmake_client -h {遠地服務器名稱} -n {TCP 埠號} -u {遠地帳號識別碼} -d {遠地應用系統目錄} -c {遠地建置命令稿} -p {遠地建置命令稿參數} -l {遠地建置命令槁輸出列緩衝區 KB}
      • 使用範例:rmake_client -h aix -u 1000 -d /home/app -c /usr/bin/make -p install
      • TCP 埠號預設為 82
      • 遠地建置命令槁輸出每一列緩衝區大小預設為 1 KB
      • 遠地建置命令稿參數若有多個時,使用 ‘^’ 取代空白。如:"aaa 111 bbb" 指定為 “aaa^111^bbb"
    • 遠地建置服務程式〈rmake_server〉:
      • 部署於遠地服務器〈IBM AIX〉
      • 配合 inet 或 xinet 機制,接聽建置請求
      • 服務程式會轉換指定之帳號識別碼建置 應用系統
      • xinet 設定範例如下:
      • service rmake
        {
        	disable		= no
        	server		= /usr/local/bin/rmake_server
        	flags		= REUSE
        #	only_from	= 127.0.0.1
        	log_on_failure	+= USERID
        #	port		= 82
        #	id		= rmake-server
        	socket_type	= stream
        	protocol	= tcp
        	user		= root
        	wait		= no 
        }
  • 設計資料庫範例程式
    • 資料庫: Oracle
    • 作業平台: IBM AIX
    • 程式平台: Pro*C
    • C 編譯器: IBM XLC
    • 範例程式
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h> 
      
      #include "sqlca.h"
      
      void sql_error(char *msg) {
      	char buf[1024];
      	int buflen=0, msglen=0; 
      
      	EXEC SQL WHENEVER SQLERROR CONTINUE;
      	EXEC SQL ROLLBACK WORK RELEASE;
      
      	buflen = sizeof(buf);
      	memset(buf, 0, buflen);
      
      	sqlglm(buf, &buflen, &msglen);
      
      	if (msglen) {
      		printf("\n%s: %.*s)", msg, msglen, buf);
      
      		exit(1);
      	}
      }
      
      struct {
      	char	UserID[16];
      	char	Password[16];
      }	USERINFO = {  "SCOTT@STEDB", "TIGER" };
      
      struct {
      	int	DEPTNO;
      	char	DNAME[15];
      	char	LOC[14];
      }	DEPT;
      
      int main() {
      	char *userID, *userPassword;
      
      	userID = getenv("ORA_USERID");
      	userPassword = getenv("ORA_PASSWORD");
      
      	if (userID != NULL) strcpy(USERINFO.UserID, userID);
      	if (userPassword != NULL) strcpy(USERINFO.Password, userPassword);
      
      	EXEC SQL WHENEVER SQLERROR do sql_error("Oracle Error");
      	EXEC SQL CONNECT :USERINFO.UserID IDENTIFIED BY :USERINFO.Password; 
      
      	EXEC SQL DECLARE DEPT_CURSOR SCROLL CURSOR FOR
      		SELECT DEPTNO,DNAME,LOC FROM DEPT ORDER BY DEPTNO;
      
      	EXEC SQL OPEN DEPT_CURSOR;
      	EXEC SQL WHENEVER NOT FOUND DO break;
      
      	while (1) {
      		EXEC SQL FETCH DEPT_CURSOR INTO :DEPT;
      
      		printf("DEPTNO=%d\n", DEPT.DEPTNO);
      		printf("\tDNAME=%s\n", DEPT.DNAME);
      		printf("\tLOC=%s\n", DEPT.LOC);
      	}
      
      	EXEC SQL CLOSE DEPT_CURSOR;
      	EXEC SQL COMMIT WORK RELEASE;
      
      	return 0;
      }
      Makefile
      include $(ORACLE_HOME)/precomp/lib/env_precomp.mk
      
      CC=xlc_r
      LFLAGS64=-q64
      
      ORA_USERID=SCOTT@STEDB
      ORA_PASSWORD=TIGER 
      
      .SUFFIXES: .pc .c .o 
      
      .pc.c:
      	$(PROC_64) $(PROCFLAGS) iname=$*
      
      .pc.o:
      	$(PROC_64) $(PROCFLAGS) iname=$*
      	$(C2O_64)
      
      .c.o:
      	$(C2O_64)
      
      clean:
      	rm -f *.o *.lis *.c sample_cursor tp* *~
      
      test:
      	./sample_cursor
      
      sample_cursor:
      	$(MAKE) -f Makefile-AIX64 OBJS=$@.o EXE=$@ build
      	rm -f tp*
      
      build: $(OBJS)
      	$(DEMO_PROC_BUILD_SHARED_64)
      建置與測試
      #!/bin/sh
      
      make -f Makefile-AIX64 clean
      make -f Makefile-AIX64 sample_cursor
      make -f Makefile-AIX64 test
    • HP-UX 與 AIX 兩地編譯器並不相同,其編譯參數也不一致,在不變動 Makefile 前提下,必須要藉兩地不同之環境變數,才能同步建置。此與現有 HP-UX Pro*C 建置方式有關,要想達成異質平台建置目標,如何建立一套兩地通用標準建置作業程序至為關鍵,也是軟體工程重要課題之一。

採用此種結合應用系統設計生命週期之解決方案,非但降低異地備援及應用系統派送成本,且提高運維品質與風險,相較於儲存設備備援機制,實在優點甚多。更不用說,儲存設備備援機制無法解決遠地開發中心部署 多點外地運行環境 所衍生之相關需求。

廣告
%d 位部落客按了讚: