bea tuxedo中间件入门
§? TUXEDO是什么?
l? 客戶端/服務(wù)器模式的演化
l? 基本的客戶端/服務(wù)器模式
l? 多層結(jié)構(gòu)
l? TUXEDO的客戶端/服務(wù)器方法
l? 一個(gè)完整的例子
l? 應(yīng)用配置文件:ubbconfig
l? 運(yùn)行應(yīng)用的步驟
tuxedo是什么?
?????? BEA TUXEDO是在企業(yè)、Internet 這樣的分布式運(yùn)算環(huán)境中開發(fā)和管理三層結(jié)構(gòu)的客 戶/服務(wù)器型關(guān)鍵任務(wù)應(yīng)用系統(tǒng)的強(qiáng)有力工具。它具備分布式事務(wù)處理和應(yīng)用通信功能,并提供完善的各種服務(wù)來建立、運(yùn)行和管理關(guān)鍵任務(wù)應(yīng)用系統(tǒng)。開發(fā)人員能夠用它建立跨多個(gè)硬件平臺(tái)、數(shù)據(jù)庫和操作系統(tǒng)的可互操作的應(yīng)用系統(tǒng)。BEA TUXEDO是企業(yè)、 Internet 分布式應(yīng)用中的基礎(chǔ)主干平臺(tái)。它提供了一個(gè)開放的環(huán)境,支持各種各樣的客戶、數(shù)據(jù)庫、網(wǎng)絡(luò)、遺留系統(tǒng)和通訊方式。
特點(diǎn):
2? 大量在線用戶
2? 巨量數(shù)據(jù)
2? 信息訪問
2? 小事務(wù)
2? 復(fù)雜網(wǎng)絡(luò)
?
C/S系統(tǒng)的層次結(jié)構(gòu)
以下列出了分布式系統(tǒng)的主要層次:
2? 用戶界面:被分成表示管理和表示邏輯。代表有主機(jī)框架的3270仿真終端;UNIX系統(tǒng)的X終端等,最新的Web瀏覽器界面也是。
2? 商業(yè)邏輯:包含應(yīng)用邏輯和應(yīng)用規(guī)則。
2? 數(shù)據(jù)管理:分為數(shù)據(jù)訪問邏輯(SQL)和數(shù)據(jù)庫管理。
區(qū)分C/S結(jié)構(gòu)的類型可以根據(jù)以下特性:
客戶端和服務(wù)端程序間邏輯分布,如何實(shí)現(xiàn)層次功能;中間件產(chǎn)品及技術(shù)的使用。
?
C/S模式的演化
????? 上圖列舉了不同種類的C/S模式。其中大型主機(jī)系統(tǒng)仍然統(tǒng)治著最大的OLTP應(yīng)用;基于X終端和UNIX工作站的應(yīng)用在80年代后期興起;廉價(jià)的WINTEL機(jī)器支持的Windows GUI通常用于2層模式;數(shù)據(jù)庫新技術(shù)和OSF帶領(lǐng)了3層應(yīng)用模式。
?
基本C/S模式
?????? C/S系統(tǒng)是一種分布式系統(tǒng),由其程序決定其特點(diǎn):
2? 客戶端部分執(zhí)行前端功能,如:提供用戶界面,向后臺(tái)發(fā)出用戶請(qǐng)求的交易,將結(jié)果返回給用戶。
2? 服務(wù)提供一般后端功能,按交易組織,將結(jié)果返回前端。
2? 交易是分散的,按需求的操作,可以被遠(yuǎn)程客戶端訪問的程序。
C/S模式可能會(huì)有如下優(yōu)點(diǎn):
2? 減小客戶端程序體積,提高反應(yīng)速度
2? 位置無關(guān)
2? 模塊化
2? 擴(kuò)展性好
?
?
可管理多層C/S模式
?
?
?????? 在可管理多層(Managed Multi-Tier –MMT)C/S模式中,提出了中間件管理。在本書范圍內(nèi),此點(diǎn)由交易處理(TransactionProcessing –TP)管理完成,提供以下功能:
2? 在客戶端和服務(wù)端之間進(jìn)行通訊和傳輸
2? 提供良好的系統(tǒng)管理
2? 提供交易、配置的分布式管理
它管理服務(wù)端從多個(gè)客戶端收到的數(shù)據(jù)流,并不是在C/S間建立一對(duì)一的關(guān)系,而且客戶端可以向多個(gè)服務(wù)發(fā)出請(qǐng)求。這種特點(diǎn)保證了TUXEDO可以提供強(qiáng)大的分布式交易處理框架。
由于不必進(jìn)行通訊和交易管理,數(shù)據(jù)庫引擎可以專注于其特長:管理數(shù)據(jù)!在這種情況下,數(shù)據(jù)庫成了一個(gè)純RM(Resource Manager)。
?
MMT C/S模式給OLTP應(yīng)用增加了如下優(yōu)點(diǎn):
2? 所有C/S模式的優(yōu)點(diǎn)在MMT模式下都得到了增強(qiáng)。實(shí)際上,由于中間件的引入,處理能力得到改善。
2? 由于中間件管理了數(shù)據(jù)流,帶來了許多新功能,如:交易路由、服務(wù)分布、管道、數(shù)據(jù)依賴路由等成為可能。
2? 統(tǒng)一的數(shù)據(jù)流控限制了最大交易數(shù),總的數(shù)據(jù)庫過程少了,服務(wù)器空閑時(shí)間也少了,這就增加了數(shù)據(jù)庫和系統(tǒng)效率。
2? 應(yīng)用代碼的設(shè)計(jì)可以不考慮物理地址和內(nèi)部數(shù)據(jù)表示。
2? 配置成了一件單純的管理工作,進(jìn)一步的,可以通過配置輕易的改變系統(tǒng)結(jié)構(gòu)。服務(wù)可以動(dòng)態(tài)的增加、刪除和重啟動(dòng)。
?
TUXEDO的C/S方案
?????? 構(gòu)成TUXEDO系統(tǒng)的各部分、工具和其特性組成的MMT C/S模式給應(yīng)用帶來的便利及TUXEDO的實(shí)現(xiàn)方法:
| MMT C/S模式的優(yōu)點(diǎn) | TUXEDO的實(shí)現(xiàn)技術(shù) |
| 模塊化 | 客戶端,交易,服務(wù) |
| 最大化的處理能力和流量 | 客戶端交易流量控制,分布式配置,快速消息匹配和路由 |
| 通訊傳輸技術(shù) | ATMI訪問,一種簡單且容易定義的接口 |
| 實(shí)時(shí)應(yīng)用管理 | 核心配置文件,MIB,管理工具和基于瀏覽器界面的GAI |
| 名字服務(wù)和交易位置無關(guān) | 公告牌提供目錄交易便利 |
| 應(yīng)用數(shù)據(jù)服務(wù) | 應(yīng)用服務(wù)位置可以在配置中隨意配置 |
?
?
TUXEDO系統(tǒng)的特點(diǎn)
?
2? TUXEDO /T
n? 管理C/S數(shù)據(jù)流
n? 支持3層結(jié)構(gòu)
n? 多平臺(tái)支持
n? 協(xié)同(BEAConnect, /TxRPC, /OSITP)
n? 開發(fā)
u? 通訊手段
l? 同步
l? 異步
l? 會(huì)話
l? 廣播通知
l? 管道
l? 事件訂閱
u? 緩沖數(shù)據(jù)類型(自動(dòng)編、解碼)
u? 事務(wù)
n? 管理
u? 核心配置管理
u? 管理信息庫(MIB)
u? Web界面管理接口
u? 負(fù)載平衡
u? 網(wǎng)絡(luò)配置
u? 安全
u? 數(shù)據(jù)依賴路由
u? 數(shù)據(jù)壓縮
2? BEA JOLT 將TUXEDO中間件框架擴(kuò)展到Internet和Java客戶端
2? TUXEDO /Q
n? 通訊保障
n? 預(yù)定處理
2? TUXEDO /WS
n? 多平臺(tái)支持
n? 把BEATUXEDO ATMI API擴(kuò)展到客戶應(yīng)用程序中
2? TUXEDO /Domains
2? TUXEDO /COBOL
?
一個(gè)例子
? 一個(gè)TUXEDO 應(yīng)用可以分成3部分
2? 發(fā)布交易請(qǐng)求的客戶端
2? 運(yùn)行響應(yīng)請(qǐng)求交易的服務(wù)
2? 描述應(yīng)用機(jī)器和服務(wù)信息的配置文件
上圖是本例的示意圖:
?????? 客戶端請(qǐng)求交易“TOUPPER”,數(shù)據(jù)是“hello world”。交易“TOUPPER”將字符串轉(zhuǎn)成大寫,將結(jié)果成功返回客戶端。
?
客戶端范例
#include <stdio.h>
#include “atmi.h”
main()
{
?????? char????? *buf;
?????? long????? len;
?????? if? (tpinit((TPINIT * )NULL) == -1)
?????? {
????????????? exit(1);
?????? }
?????? if((buf=tpalloc(“STRING”,NULL,80))==NULL)
?????? {
????????????? tpterm();
????????????? exit(2);
?????? }
?????? strcpy(buf, “helloworld”);
?????? if (tpalloc(“TOUPPER”,buf,0,&buf,&len,0)== -1)
?????? {
????????????? fprintf(stderr,”servicerequst fail\n”);
????????????? tpfree(buf);
????????????? tpterm();
????????????? exit(3);
?????? }
?????? printf(“return string is:%s\n”,buf);
?????? tpfree(buf);
?????? tpterm();
?????? exit(0);
}
包含TUXEDO系統(tǒng)的頭文件”atmi.h”,以便引用TUXEDO的函數(shù)和變量定義。
客戶端調(diào)用tpinit()連接應(yīng)用
用tpalloc()分配一個(gè)STRING類型數(shù)據(jù)緩沖
將”helloworld”拷貝進(jìn)緩沖
用tpcall()包含數(shù)據(jù)緩沖,向交易“TOUPPER”發(fā)一個(gè)同步請(qǐng)求
打印出改變的數(shù)據(jù)緩沖
調(diào)用tpterm()切斷與應(yīng)用的連接
?
?
交易范例
#include <stdio.h>
#include <ctype.h>
#include “atmi.h”
void TOUPPER (TPSVCINFO *rqst)
{
?????? int i;
?????? for (i=0;i<rqst->len-1;i++)
????????????? rqst->data[i]= toupper(rqst->data[i]);
?????? tpreturn(TPSUCCESS,0,rqst->data,0L,0);
}
包含TUXEDO系統(tǒng)頭文件”atmi.h”
象所有的TUXEDO交易函數(shù)一樣,TOUPPER不用直接返回任何值,所以返回類型為void
從客戶端收到的數(shù)據(jù)放在TPSVCINFO結(jié)構(gòu)中,是唯一的入?yún)?/p>
交易處理…
用tpreturn()將數(shù)據(jù)緩沖返回客戶端
?
配置文件
?????? 有關(guān)應(yīng)用的信息,如可用交易,交易位置,應(yīng)用范圍等,有必要集中管理于單一資源。事實(shí)上,這些信息被集中于文件UBBCONFIG。該文件分7節(jié),主要部分內(nèi)容描述如下:
*RESOURCES節(jié)包含全局信息,如:標(biāo)識(shí)公告牌位置的唯一鍵值(IPCKEY),主控節(jié)點(diǎn)的名字(MASTER),應(yīng)用類型(MODEL),下文例子中設(shè)為SHM表示是一個(gè)單節(jié)點(diǎn)應(yīng)用。
*MACHINES節(jié)包含節(jié)點(diǎn)信息,如:機(jī)器物理名,TUXEDO系統(tǒng)位置(TUXDIR),服務(wù)碼位置(APPDIR),以及本文件的二進(jìn)制碼文件名(TUXCONFIG)。
*GROUPS節(jié)包含一些管理用信息,如設(shè)定服務(wù)或交易的分布式事務(wù)處理。
*SERVERS節(jié)包含需要啟動(dòng)的交易和其組信息等其他信息。
*SERVICES節(jié)包含影響應(yīng)用操作方式的的必要信息。本節(jié)列出的交易都是需要特別配置的,如有特別的優(yōu)先級(jí),裝入?yún)?shù),數(shù)據(jù)依賴路由等。
配置文件范例
#file : ubbconfig
*RESOURCES
IPCKEY??????????????????? 5000
MASTER?????????? SITE1
MODEL????????????? SHM
*MACHINES
gumby??????????????? LMID=SITE1
TUXDIR???????????? =”/usr/tuxedo”
APPDIR??????????????????? =”/usr/apps/simpapp”
TUXCONFIG???? =”/usr/apps/simpapp/simpapp.tux”
*GROUPS
GROUP1?????????? LMID=SITE1???? GRPNO=1
*SERVERS
simpserv?????????????????? SRVGRP=GROUP1????? SRVID=1
*SERVICES
TOUPPER
?
建立應(yīng)用
?????? 建立一個(gè)TUXEDO應(yīng)用,必須進(jìn)行以下步驟:
2? 設(shè)置環(huán)境變量。
TUXDIR表示TUXEDO用戶目錄;TUXCONFIG是二進(jìn)制配置文件名;在路徑中加入TUXEDO的可執(zhí)行文件路徑;如果用到公共庫,還必須包含LD_LIBRARY_PATH,指出公共庫位置。
TUXDIR=/usr/tuxedo
PATH=$PATH:$TUXDIR/bin
TUXCONFIG=/usr/apps/simpapp/simpapp.tux
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TUXDIR/lib
export LD_LIBRARY_PATH PATH TUXDIR
2? 用buildclient命令從源程序編譯出客戶端可執(zhí)行文件。
buildclient –f client.c –o client -v
2? 用buildserver命令從源程序編譯出服務(wù)端可執(zhí)行文件。-s參數(shù)列出提供的交易。
Buildserver –f simpserv.c –o simpserv –s TOUPPER -v
2? 用tmloadcf命令從文本配置文件ubbconfig生成二進(jìn)制配置文件tuxconfig。
Tmloadcf –y ubbconfig
?
開發(fā)TUXEDO C/S系統(tǒng)的必要步驟
2? 配置環(huán)境變量
2? 編碼并編譯客戶端和服務(wù)端的程序
2? 由文本的ubbconfig生成二進(jìn)制TUXCONFIG
2? 啟動(dòng)系統(tǒng)和服務(wù)
2? 測試應(yīng)用
2? 關(guān)閉系統(tǒng)
?
?
小結(jié)
l? 客戶端/服務(wù)器模式的演化
l? 用TUXEDO管理多層客戶端/服務(wù)器模式
l? 一個(gè)簡單應(yīng)用:simpapp
?
?
?
客戶端開發(fā)??? Client Development
本節(jié)要點(diǎn)
l? 客戶端在客戶端/服務(wù)器模式中的作用
l? 開發(fā)客戶端的過程
l? 查找錯(cuò)誤
tperrno,tperrordetail
tpstrerror(),tpstrerrordetail()
userlog()
l? 使用ATMI
進(jìn)程管理
緩沖管理
請(qǐng)求/響應(yīng)通訊
l? 建立并編譯一個(gè)TUXEDO客戶端應(yīng)用
buildclient
客戶端在C/S模式中的作用
?
?
?????? 為了更好的了解客戶端的所有任務(wù)以編寫客戶端應(yīng)用,有必要重新認(rèn)識(shí)客戶端在C/S模式中扮演的角色。
?????? 首先,客戶端是用戶界面。意思是當(dāng)用戶在系統(tǒng)上用程序進(jìn)行一次操作的整個(gè)過程就是一個(gè)客戶端過程。前端過程是對(duì)客戶端的另一個(gè)描述。客戶端的首要任務(wù)就是獲得執(zhí)行操作應(yīng)該得到的數(shù)據(jù)。
?????? 一旦客戶端得到了應(yīng)有的信息,應(yīng)該將數(shù)據(jù)按服務(wù)能夠識(shí)別并適合傳輸?shù)母袷酱虬?/p>
?????? 然后,向服務(wù)端發(fā)送請(qǐng)求并等待回應(yīng)。
?????? 收到回應(yīng)數(shù)據(jù)后,將其按一定格式返回給終端用戶。
?
??????????????????????????????????????????????????????????
?
?
?
?
客戶端開發(fā)過程
?????? 客戶端程序的設(shè)計(jì)和實(shí)現(xiàn)可以被分成2部分考慮:
2?用戶處理過程
2?TUXEDO功能部分
下文的客戶端程序只描述了TUXEDO功能部分。
利用TUXEDO的ATMI API調(diào)用可以做到:
——基本的TUXEDO調(diào)試技巧(tperrno,tpstrerror,userlog)
——TUXEDO進(jìn)程管理(tpinit,tpterm)
——基本數(shù)據(jù)緩沖管理(tpalloc,tprealloc,tpfree)
——基本通訊(tpcall,tpacall,tpgetrply)
?
調(diào)試和錯(cuò)誤處理
?
?????? 當(dāng)調(diào)用ATMI出錯(cuò)時(shí),返回值為-1,全程變量tperrno被設(shè)值,該變量提供系統(tǒng)定義的出錯(cuò)原因。函數(shù)tpstrerror()以此變量為參數(shù),返回錯(cuò)誤的字符說明信息。
?????? 完整的錯(cuò)誤號(hào)和文本錯(cuò)誤信息存在于文件$TUXDIR/include/atmi.h。
?????? 函數(shù)userlog()重定向輸出文件為ULOG.mmddyy。使用方法同printf()。該函數(shù)每次輸出都寫硬盤,這樣在系統(tǒng)失敗時(shí)也能保留調(diào)試信息。
?
代碼范例
?
main()
{
int?? ret;
?
ret = [a ATMI call]
if ( ret == -1 )
{
?????? printf(“Errorin ATMI call\n”);
?????? usrlog(“ATMIerror logged %d %s”,tperrno,tpstrerror(tperrno));
}else
?????? printf(“ATMIcall OK\n”);
?
……
?
ret = tpterm();
if ( ret == -1 )
{
?????? printf(“Errorin exiting application\n”);
?????? usrlog(“ATMIerror logged %d %s”,tperrno,tpstrerror(tperrno));
}
?
}
?
?
?
tperrno – 全程變量
(char *)tpstrerror(int)
userlog(…) – 語法同printf()
ULOG.mmddyy – 日志文件
?
?
?
?
?
進(jìn)程管理
?
?????? 為了使客戶端能夠訪問TUXEDO交易,客戶端程序必須連接TUXEDO應(yīng)用并進(jìn)行登記。這種管理性步驟在切斷連接時(shí)也要類似執(zhí)行一次。API如下:
?
inttpinit(TPINIT *tpinfo)
?
客戶端通過調(diào)用tpinit()與應(yīng)用連接,進(jìn)行交互,有以下事件發(fā)生:
調(diào)用安全接口檢查客戶端是否需要認(rèn)證
連接BB,使進(jìn)一步的ATMI函數(shù)得到信息
使BBL了解BB中已經(jīng)存在請(qǐng)求
建立客戶端消息隊(duì)列使服務(wù)可以發(fā)回返回信息,系統(tǒng)可以送出廣播通知等
?
錯(cuò)誤時(shí)返回-1,可能由以下原因引起:
2? TPEINVAL???????? 參數(shù)錯(cuò)誤
2? TPENOENT????? BB無空間
2? TPEPERM???????? 無連接權(quán)限
2? TPEPROTO????? 協(xié)議錯(cuò)誤 – 被服務(wù)調(diào)用
?
inttpterm()
?
客戶端調(diào)用tpterm()切斷與應(yīng)用的連接,結(jié)束了客戶端的TUXEDO進(jìn)程,該過程發(fā)生以下事件:
BB入口刪除,使BBL知道客戶端已經(jīng)離開
客戶端離開BB,客戶端的信號(hào)量被移除
客戶端消息隊(duì)列被移除
錯(cuò)誤時(shí)返回-1,可能由以下原因引起:
TPEPROTO????? 協(xié)議錯(cuò)誤 – 被服務(wù)調(diào)用
TPESYSTEM??? /T系統(tǒng)下錯(cuò)誤
TPEOS?????????????? 操作系統(tǒng)錯(cuò)
范例
main()
{
?????? intret;
?????? ret=tpinit((TPINIT*)NULL);
?????? ……
?????? ret=tpterm();
}
?
數(shù)據(jù)緩沖管理
?????? ATMI提供函數(shù)分配(tpalloc(),tprealloc())、釋放(tpfree())TUXEDO數(shù)據(jù)緩沖。應(yīng)用負(fù)責(zé)將應(yīng)用數(shù)據(jù)填入緩沖。應(yīng)用的數(shù)據(jù)類型和組織決定應(yīng)該選擇何種數(shù)據(jù)緩沖。函數(shù)type()可以返回正在使用的數(shù)據(jù)緩沖類型。
?????? 以下是TUXEDO基本的數(shù)據(jù)緩沖類型:
2?STRING????? 以空值結(jié)尾的單域字符數(shù)據(jù)。
2?CARRAY??? 有長度定義的單域二進(jìn)制數(shù)據(jù),不進(jìn)行編、解碼。
2?VIEW?????????? 類C結(jié)構(gòu)或COBOL記錄的多域組織。
2?FML???????????? 無固定結(jié)構(gòu)的自定義緩沖。
tpalloc(),tprealloc()在出錯(cuò)時(shí)返回空值,可能由以下原因引起:
2?TPEOS??????? 操作系統(tǒng)
2?TPEINVAL? 非法或不正確的類型
2?TPESYSTEM??? TUXEDO之下的錯(cuò)誤
?
范例
main()
{
?????? intret;
?????? char*bufptr;
?????? ret= tpinit((TPINIT *)NULL);
?????? if( ret == -1)
?????? {
????????????? printf(“Errorin joining application\n”);
????????????? userlog(“tpiniterror %d %s”,tperrno,tpstrerror(tperrno));
?????? }else
????????????? printf(“tpinitok\n”);
?????? bufptr=tpalloc(“STRING”,NULL,1*1024);
?????? if( bufptr==NULL)
?????? {
????????????? printf(“Errorin allocating buffers \n”);
????????????? userlog(“tpiniterror %d %s”,tperrno,tpstrerror(tperrno));
????????????? tpterm();
????????????? exit(-1);
?????? }
?????? ……
?????? tpfree(bufptr);
?????? ret= tpterm();
?????? if( ret == -1)
?????? {
????????????? printf(“Errorin exiting application\n”);
????????????? userlog(“tptermerror %d %s”,tperrno,tpstrerror(tperrno));
?????? }
}
函數(shù)用法
(char *)tpalloc((char *)type,(char*)subtype,long size)
(char *)tprealloc((char *)bufptr,longnewsize)
void tpfree((char *)bufptr)
?
?
?
?
?
?
?
?
?
同步通訊
??????
函數(shù)tpcall()有6個(gè)參數(shù)。如下:
2? 交易名
2? 請(qǐng)求數(shù)據(jù)緩沖
2? 請(qǐng)求數(shù)據(jù)緩沖的長度(僅緩沖類型為CARRY時(shí)需要)
2? 返回?cái)?shù)據(jù)緩沖的地址。緩沖大小可以根據(jù)收到數(shù)據(jù)而改變。
2? 返回?cái)?shù)據(jù)緩沖大小的地址
2? 標(biāo)志量
標(biāo)志量可以是以下值:
2? TPNOTRAN????? 如有交易不調(diào)用
2? TPNOBLOCK?? 如有阻塞不等待
2? TPNOTIME??????? 愿意等待直到超時(shí)
2? TPSIGRSTRT?? 系統(tǒng)中斷信號(hào)在TUXEDO完成后再發(fā)布
出錯(cuò)返回-1,錯(cuò)誤原因如下:
2? TPEINVAL? 參數(shù)錯(cuò)誤
2? TPETRAN? 交易相關(guān)錯(cuò)誤
2? TPETIME??? 超時(shí)
?
代碼范例
main()
{
?????? intret;
?????? longlen=0,flags=0;
?????? char*bufptr;
?????? if? (tpinit((TPINIT * )NULL) == -1)
?????? {
????????????? exit(1);
?????? }
?????? if((buf=tpalloc(“STRING”,NULL,801*1024==NULL)
?????? {
????????????? tpterm();
????????????? exit(2);
?????? }
?????? ret= tpcall(“TOUPPER”,bufptr,len,&bufptr,&len,flags);
?????? if(ret == -1)
?????? {
????????????? userlog(“Errorrequesting %d %s”,tperrno,tpstrerror(tperrno));
????????????? tpfree(bufptr);
????????????? exit(-2);
?????? }
?????? tpfree(bufptr);
?????? if(tpterm()==-1)
?????? {
????????????? userlog(“tptermerror %d %s”,tperrno,tpstrerror(tperrno));
?????? }
}
int tpcall((char *)servicename,(char*)bufptr,long length,(char **)bufptr,(long *)length,long flags)
??????
?
異步通訊I tpacall()
ATMI提供2個(gè)異步通訊函數(shù)
2?tpacall()
2?tpgetrply()
tpacall()有4個(gè)參數(shù)
2? 交易名
2? 請(qǐng)求數(shù)據(jù)緩沖
2? 請(qǐng)求數(shù)據(jù)緩沖的長度(僅緩沖類型為CARRY時(shí)需要)
2? 標(biāo)志量(同tpcall())
返回值是一個(gè)非負(fù)描述符(句柄),用于其后的tpgetrply()調(diào)用。如果tpacall()調(diào)用失敗,句柄是-1,錯(cuò)誤原因設(shè)置在tperrno,可能是以下值:
2?TPELIMIT??? 過多未處理的tpacall()
2?TPETIME??? 超時(shí)
tpacall()后總跟隨一個(gè)tpgetrply(),有4個(gè)參數(shù)
2? 變量地址,可以傳入tpcall()所得句柄,或另設(shè)一個(gè)
2? 返回?cái)?shù)據(jù)緩沖的地址。緩沖大小可以根據(jù)收到數(shù)據(jù)而改變。
2? 返回?cái)?shù)據(jù)緩沖大小的地址
2? 標(biāo)志量
標(biāo)志量的值可以是如下之一:
2?TPGETANY???????????????????? 取第一個(gè)返回值,設(shè)句柄
2?TPNOCHANGE????????????? 取發(fā)送請(qǐng)求的匹配的類型的信息
2?參見tpcall()中的值
返回值0表示成功,-1表示失敗,錯(cuò)誤原因可能如下:
2? TPEINVAL???????? 參數(shù)錯(cuò)誤
2? TPEOTYPE????????????? 返回?cái)?shù)據(jù)緩沖類型錯(cuò)誤
2? TPETIME??? 超時(shí)
main()
{
?????? if(tpinit((TPINIT *)NULL)== -1)
????????????? ……
?????? bufptr=tpalloc(“STRING”,NULL,100);
?????? if(bufptr==NULL)
????????????? ……
?????? cd=tpacall(“TOUPPER”,bufptr,len,flags);
?????? if(tpgetrply(&cd,&bufptr,&len,flags)== -1)
????????????? ……
?????? tpfree(bufptr);
?????? if(tpterm()== -1)
????????????? ……
}
inttpacall((char *)service,(char *)bufptr,long len,long flags);
flag:TPNOBLOCK,TPSIGRSTRT,TPNOTIME,TPNOTRAN,TPNOCHANGE,TPGETANY
inttpgetrply((int *)handle,(char **)bufptr,(long *)len, long flags);
flag:TPNOBLOCK,TPSIGRSTRT,TPNOTIME,TPNOTRAN
?
編譯C語言客戶端程序
?????? 當(dāng)C語言的客戶端程序編碼完后,需要連接正確的庫并編譯。使用buildclient可以使該過程容易一點(diǎn)。該命令引用了C語言編譯器并按正確的次序連接TUXEDO系統(tǒng)的庫。為使用buildclient,應(yīng)確認(rèn)客戶端程序包含了”atmi.h”,TUXDIR被設(shè)了正確的值。命令語法如下:
buildclient[-v] –o executable –f first-file [-f first-file] [-l last-file]
?????? 此處first-file表示的應(yīng)該是編譯器可以識(shí)別的文件。缺省的編譯器是cc。一般是.c(c源程序),.C(C++源程序),.o(object)或.a(庫)文件。
?????? 參數(shù)解釋如下:
-o??? 生成的可執(zhí)行文件名
-f???? 需要在連接TUXEDO庫之前傳給編譯器的文件名。如有多于一個(gè)的文件名,名字應(yīng)用空格分隔并用引號(hào)引起。也可以使用多個(gè)-f參數(shù)。
-l???? 需要在連接TUXEDO庫之前傳給編譯器的文件名。語法同上。
-v??? 編譯過程顯示。
?
小結(jié)
l? 不同的客戶端/服務(wù)器模式
l? 用TUXEDO管理多層客戶端/服務(wù)器模式
l? 一個(gè)簡單應(yīng)用:simpapp
l? 開發(fā)TUXEDO客戶端
?
服務(wù)端開發(fā)??? Server Development
本節(jié)要點(diǎn)
l? 服務(wù)的運(yùn)行流程
l? 返回控制
l? 創(chuàng)建服務(wù)
l? 規(guī)劃服務(wù)的考慮
l? 啟動(dòng)和關(guān)閉
l? 一個(gè)服務(wù)中的交易可以調(diào)用另一個(gè)服務(wù)中的交易
l? 一個(gè)服務(wù)可以提供多個(gè)交易
l? 發(fā)布交易
服務(wù)的運(yùn)行流程
?????? 為了更好的了解服務(wù)端的所有任務(wù)以編寫服務(wù)端應(yīng)用,有必要重新認(rèn)識(shí)服務(wù)端在C/S模式中扮演的角色。
?????? 首先,服務(wù)是系統(tǒng)資源的聯(lián)系點(diǎn)。例如,一個(gè)數(shù)據(jù)庫服務(wù)聯(lián)系實(shí)際數(shù)據(jù)庫并對(duì)其進(jìn)行查詢和修改。為有效進(jìn)行,應(yīng)建立一個(gè)數(shù)據(jù)庫連接。
?????? 其次,服務(wù)必須發(fā)布系統(tǒng)內(nèi)可以訪問的交易,保證客戶端可以知道把請(qǐng)求發(fā)往何處。
?????? 以上兩步結(jié)束后,服務(wù)進(jìn)入一個(gè)循環(huán)——接收請(qǐng)求、處理請(qǐng)求并返回結(jié)果。接收請(qǐng)求包括進(jìn)入消息隊(duì)列,得到交易請(qǐng)求。處理請(qǐng)求包括檢查請(qǐng)求數(shù)據(jù)緩沖,運(yùn)行商業(yè)規(guī)則和邏輯,可能還包括訪問數(shù)據(jù)庫和返回結(jié)果數(shù)據(jù)緩沖。
?????? 當(dāng)系統(tǒng)管理員需要關(guān)閉系統(tǒng),可以通過系統(tǒng)管理工具將關(guān)閉系統(tǒng)的消息發(fā)給服務(wù)。服務(wù)完成所有交易,取消交易發(fā)布,關(guān)閉資源連接然后結(jié)束。
?
返回控制
?
?????? 在一般的C程序中,函數(shù)通過調(diào)用return()將控制返回,函數(shù)調(diào)用堆棧清空,控制返回調(diào)用點(diǎn)。
?????? TUXEDO系統(tǒng)的交易函數(shù)必須結(jié)束于將回應(yīng)返回給客戶端或前轉(zhuǎn)到另一交易。函數(shù)tpreturn()用來結(jié)束交易將回應(yīng)數(shù)據(jù)緩沖發(fā)給客戶端。函數(shù)tpforward()將交易前轉(zhuǎn)給另一個(gè)交易,由其負(fù)責(zé)回應(yīng)原來的客戶端。下圖是tpreturn()的示意圖。
?????? tpreturn()設(shè)計(jì)來代替常規(guī)的return(),結(jié)束絕大多數(shù)函數(shù)。它將回應(yīng)數(shù)據(jù)緩沖返回請(qǐng)求的客戶端,控制權(quán)返回給服務(wù)程序的標(biāo)準(zhǔn)main()(由TUXEDO提供)。
?
?????? tpreturn()使用下列參數(shù):
?
第一個(gè)值表示交易是否成功,有3種可能:
2?TPSUCCESS?? 交易完全成功,如果是一個(gè)會(huì)話,TPEV_SVCSUCC被生成
2?TPFAIL??????? 交易失敗,tperrno將被設(shè)成TPESVCFAIL。如果是事務(wù)模式,事務(wù)被標(biāo)志成abort-only,如果是會(huì)話,TPEV_SVCFAIL被生成。
2?TPEXIT????????????? 與TPFAIL類似,但服務(wù)會(huì)中斷,如果服務(wù)設(shè)成可以重啟動(dòng),則可以由TUXEDO系統(tǒng)將其重啟動(dòng)。
第二個(gè)值是應(yīng)用定義返回碼,此處使交易可以發(fā)送一個(gè)整形代碼到客戶端,給出交易處理結(jié)果的詳細(xì)信息。該值與/T系統(tǒng)無關(guān),通過全程變量tpurcode送到客戶端程序。
第三個(gè)值是回應(yīng)數(shù)據(jù)緩沖的的指針
第四個(gè)值是回應(yīng)數(shù)據(jù)緩沖的長度(僅緩沖類型為CARRY時(shí)需要)
第五個(gè)值是標(biāo)志位,通常不用
?
?
初始化和結(jié)束服務(wù)
?????? tpsvrinit()和tpsvrdone()分別用來啟動(dòng)和關(guān)閉服務(wù)。如果應(yīng)用不提供這兩個(gè)函數(shù),可以使用替代函數(shù)。tpsvrinit()用tpopen()缺省打開RM連接。tpsvrdone()用tpclose()關(guān)閉RM連接。
?????? tpsrvinit()象標(biāo)準(zhǔn)C語言的main()一樣使用參數(shù)argc,argv。服務(wù)的命令行參數(shù)可以傳入該函數(shù),被getopt()解析。該部分的用法參見應(yīng)用配置部分。本函數(shù)出錯(cuò)時(shí)返回-1,成功返回0。
?????? tpsvrdone()無參數(shù),無返回值。
?
創(chuàng)建服務(wù)
?
當(dāng)C語言的交易程序編碼完后,需要連接正確的庫并編譯。使用buildserver可以使該過程容易一點(diǎn)。該命令引用了C語言編譯器并按正確的次序連接TUXEDO系統(tǒng)的庫,連接TUXEDO生成的main()等。buildserver還用-s參數(shù)產(chǎn)生合適的交易名/函數(shù)名映射表。要使用buildserver,必須先正確設(shè)定環(huán)境變量TUXDIR,PATH,LD_LIBRARY_PATH。命令語法如下:
buildserver[-v] [–o executable] [-s service2,service3:func] [-f source/object] [-lobject/library file]
例:
buildserver –s DEPOSIT –o TLR –f TLR.o –fappinit.o??
?????? 參數(shù)解釋如下:
-o??? 生成的可執(zhí)行文件名
-f???? 需要在連接TUXEDO庫之前傳給編譯器的文件名。如有多于一個(gè)的文件名,名字應(yīng)用空格分隔并用引號(hào)引起。也可以使用多個(gè)-f參數(shù)。
-l???? 需要在連接TUXEDO庫之前傳給編譯器的文件名。語法同上。
-v??? 編譯過程顯示。
-b??? 指定SHM或MP模式。如無此項(xiàng),兩種模式都包括;使用此項(xiàng)可以使生成的可執(zhí)行文件小一點(diǎn)
-r???? 連接此處指出的RM庫。該RM的名字必須含在$TUXDIR/udataobj/RM文件中。
?
?
規(guī)劃服務(wù)的考慮
?????? 在TUXEDO應(yīng)用中,必要時(shí)服務(wù)可以仿客戶端方式工作。例如:一個(gè)服務(wù)可能需要其他服務(wù)提供的交易,而建立一個(gè)副本并不太合理;當(dāng)然,有時(shí)這樣做會(huì)高效些。這種特性使程序員在多機(jī)配置應(yīng)用邏輯可以改善編碼和執(zhí)行效率。關(guān)于這方面的例子,請(qǐng)參見TUXEDO提供的應(yīng)用實(shí)例bankapp中的TRANSFER交易。
?????? 一般是出于以下考慮,使用此種方式:
2?最好不要使用收到的數(shù)據(jù)緩沖向其他服務(wù)請(qǐng)求,因?yàn)樵摼彌_可能被改變引起錯(cuò)誤
2?服務(wù)中的交易不應(yīng)調(diào)用本服務(wù)中的交易,因?yàn)槿菀桩a(chǎn)生死鎖(僅當(dāng)設(shè)置TPNOREPLY時(shí)可以)
2?一個(gè)MSSQ集中的服務(wù)需要返回時(shí),應(yīng)有自己的返回隊(duì)列;否則會(huì)與本集中其他服務(wù)沖突。
?
??????
?
數(shù)據(jù)緩沖管理
數(shù)據(jù)緩沖管理大部分內(nèi)容與客戶端相同
與請(qǐng)求數(shù)據(jù)緩沖不同,傳給交易的數(shù)據(jù)緩沖可能已經(jīng)被tpalloc(),tprealloc(),tpfree()函數(shù)處理過。
因?yàn)閭鹘o交易的請(qǐng)求數(shù)據(jù)緩沖已經(jīng)被tpalloc()分配,所以可以tprealloc()。
所有在服務(wù)中分配的數(shù)據(jù)緩沖,在程序結(jié)束時(shí)必須全部釋放;唯一例外是用在tpreturn()中的返回?cái)?shù)據(jù)緩沖。
如有剩余數(shù)據(jù)緩沖沒有釋放,會(huì)在每次交易調(diào)用時(shí)都生成一些,最終耗盡服務(wù)器內(nèi)存。這可以很容易通過監(jiān)視進(jìn)程大小發(fā)現(xiàn),它會(huì)隨時(shí)間增長而加大。
?
仿客戶端的方式
?????? 下圖展示的流程控制表示一個(gè)服務(wù)仿客戶端方式工作。服務(wù)接收客戶端請(qǐng)求,進(jìn)一步向另一個(gè)交易進(jìn)行請(qǐng)求。后者處理后返回前者,前者繼續(xù)進(jìn)行處理,準(zhǔn)備回應(yīng)數(shù)據(jù)緩沖,發(fā)回客戶端。
此結(jié)構(gòu)不能超過2級(jí)!
?
轉(zhuǎn)發(fā)的方式
?????? 下圖展示的流程控制表示交易請(qǐng)求從客戶端來到一個(gè)服務(wù),轉(zhuǎn)發(fā)到另一個(gè)服務(wù),然后返回客戶端。
?
?
多個(gè)交易
?????? 一個(gè)商業(yè)應(yīng)用處理可能會(huì)需要來自不同數(shù)據(jù)源的相似信息或功能。
?????? 例如下圖,TUXEDO有多種方式實(shí)現(xiàn):
2?各交易功能分隔在獨(dú)立的可執(zhí)行服務(wù)中
因?yàn)楣δ芊植荚诓煌目蓤?zhí)行服務(wù)中,編譯如下:
buildserver –f read70.c –o read70 –sREAD70
buildserver –f read80.c –o read80 –sREAD80
buildserver –f read90.c –o read90 –sREAD90
2?將不同功能組織在一個(gè)可執(zhí)行服務(wù)中,分隔成不同交易
服務(wù)程序包含3個(gè)交易函數(shù),編譯如下:
buildserver –f read.c –o read –s READ70–s READ80 –s READ90
2?合并各功能成一個(gè)交易,使用別名調(diào)用
使用TUXEDO的別名功能,使交易以不同名字發(fā)布,如:
buildserver –f read.c –o read –sREAD70,READ80,READ90:READ
READ是真正的交易函數(shù),但服務(wù)可以接受對(duì)READ70,READ80和READ90的請(qǐng)求
?
動(dòng)態(tài)發(fā)布
?
?????? 當(dāng)交易運(yùn)行時(shí),交易可以用tmadmin在啟動(dòng)時(shí)發(fā)布,也可以通過調(diào)用ATMI動(dòng)態(tài)發(fā)布。交易例程可以通過調(diào)用服務(wù)發(fā)布或取消發(fā)布。
tpadvertise()可以被一個(gè)服務(wù)調(diào)用,發(fā)布一個(gè)交易
tpunadvertise()可以被一個(gè)服務(wù)調(diào)用,取消發(fā)布一個(gè)交易
tpadvertise()
該函數(shù)允許服務(wù)為自己動(dòng)態(tài)發(fā)布一個(gè)交易,參數(shù)如下:
2? 被發(fā)布的交易名
2? 交易請(qǐng)求處理函數(shù)地址
返回值-1表示失敗。
?????? 如果交易已經(jīng)被同一函數(shù)發(fā)布,tpadvertise()立即返回成功。
?????? 如果tpadvertise()被一個(gè)MSSQ集中的服務(wù)調(diào)用,交易被發(fā)布到該集所有服務(wù)上。
?????? 出錯(cuò)原因包括:
2?TPEMATCH 交易已經(jīng)被其他函數(shù)發(fā)布
2?TPELIMIT 可發(fā)布交易最大數(shù)已經(jīng)達(dá)到,該限制在配置文件中的MAXSERVICES規(guī)定
2?TPEINVAL? 有參數(shù)為NULL
2?TPEPROTO 協(xié)議錯(cuò)誤(如被客戶端調(diào)用)
動(dòng)態(tài)發(fā)布范例1
$tmadmin
>advertise AUDIT:doaudit –g SYSGRP –i1
AUDIT發(fā)布在組SYSGRP,服務(wù)srvid=1
?
動(dòng)態(tài)發(fā)布范例2
void Adminservices(TPSVCINFO *transb)
{
?????? /*取時(shí)間time*/
?????? if( time>12 midnight && time < 6 a.m.)
?????? {
????????????? if(tpadvertise(“AUDIT”,doaudit) == -1)
????????????? {
???????????????????? userlog(“unableto advertise AUDIT service”);
???????????????????? tpreturn(TPFAIL,0,transb->data,0L,0);
????????????? }
?????? }
}
void doaudit(TPSVCINFO *transb)
{
……
}
?
應(yīng)用配置ApplicationConfiguration
?
本節(jié)要點(diǎn)
l? 應(yīng)用配置概覽
l? 管理進(jìn)程
l? 使用IPCS資源
*RESOURCES
*MACHINES
*GROUPS
*SERVERS
*SERVICES
l? 管理命令
應(yīng)用配置總覽
?
?????? 應(yīng)用的描述信息配置在系統(tǒng)核心位置,用一個(gè)文件描述,通常稱為ubbconfig文件,在主控機(jī)器上。整個(gè)TUXEDO系統(tǒng)的管理任務(wù)可以在一臺(tái)機(jī)器上完成,在配置中被定為主控節(jié)點(diǎn)。
?????? 在運(yùn)行時(shí),這些信息被裝入一段共享內(nèi)存(一個(gè)IPC資源),稱為公告牌(Bulletin Board—BB);包含有配置中不同機(jī)器的信息,在這些機(jī)器上運(yùn)行的服務(wù)的信息,這些服務(wù)提供的交易的信息以及其他相關(guān)信息。
?????? 客戶端在運(yùn)行時(shí)連接公告牌。當(dāng)客戶端程序調(diào)用一個(gè)交易,將根據(jù)公告牌找到合適的服務(wù)隊(duì)列。
?????? 所以,公告牌是:
?????? ——供客戶端尋找適當(dāng)?shù)姆?wù)運(yùn)行一個(gè)交易請(qǐng)求
?????? ——包含應(yīng)用信息:機(jī)器,服務(wù),交易,網(wǎng)絡(luò)等
?????? ——?jiǎng)?chuàng)建于ubbconfig文件
?????? TUXEDO提供一個(gè)管理進(jìn)程,稱為BBL(Bulletin Board Liaison),包含了一個(gè)公告牌的本地拷貝和本地服務(wù)器上應(yīng)用的狀態(tài)。
?????? TUXEDO提供的另一個(gè)管理進(jìn)程DBBL(Distinguished Bulletin Board Liaison),用于多服務(wù)器配置時(shí)。DBBL與BBL協(xié)同,保證所有部分的公告牌內(nèi)容的一致性。
?
配置文件
?????? 任何TUXEDO應(yīng)用系統(tǒng)的最基本的管理任務(wù),是建立并維護(hù)配置文件。該文件通常稱為ubbconfig文件。負(fù)責(zé)該工作的系統(tǒng)管理員必須很好的了解分布于各臺(tái)機(jī)器上的應(yīng)用服務(wù)的數(shù)據(jù)流,消息隊(duì)列的構(gòu)造,資源間的相互關(guān)系。ubbconfig文件可視作包含應(yīng)用啟動(dòng)信息的容器,需編譯成二進(jìn)制文件tuxconfig,作為啟動(dòng)時(shí)的參考。
?????? 其內(nèi)信息包括:
2? 系統(tǒng)范圍信息(*RESOURCES節(jié))
2? 機(jī)器信息(*MACHINES節(jié))
2? 組信息(*GROUPS節(jié))
2? 服務(wù)信息(*SERVERS節(jié))
2? 交易信息(*SERVICES節(jié))
2? 網(wǎng)絡(luò)組信息(*NETGROUPS節(jié))
2? 網(wǎng)絡(luò)信息(*NETWORK節(jié))
2? 路由原則信息(*ROUTING節(jié))
當(dāng)完成了ubbconfig文件后,用tmloadcf命令生成tuxconfig
另一種從ubbconfig生成tuxconfig的方法是使用圖形管理界面(GAI—Graphical Administration Interface)。
?
應(yīng)用的信息
?
?????? *RESOURCES節(jié)包含整個(gè)應(yīng)用范圍的信息。本節(jié)必須在配置文件第一節(jié),不可缺少。信息說明如下:
?
參數(shù)??????????????????? 意義
?
*RESOURCES *RESOURCES節(jié)
IPCKEY???????????? 共享內(nèi)存id
UID??????????????????????????? TUXEDO管理員用戶id
GID??????????????????????????? TUXEDO管理員用戶id
PERM??????????????? TUXEDO管理員組用戶的權(quán)限
MAXACCESSERS 服務(wù)端和客戶端的最大進(jìn)程數(shù)
MAXSERVERS?????? ?????? 限制可以啟動(dòng)服務(wù)總數(shù)
MAXSERVICES???????????? 限制可以發(fā)布交易總數(shù)
MASTER????????????????? 指出主控節(jié)點(diǎn)的邏輯名,第二個(gè)是備份節(jié)點(diǎn)
MODEL??????????????????????????? 應(yīng)用構(gòu)架,MP表示多機(jī)
OPTIONS????????? LAN,MIGRATE表示是一個(gè)網(wǎng)絡(luò)應(yīng)用,服務(wù)可以移植到替代處理器上
SECURITY?????????????? 安全級(jí)別(5個(gè))
AUTHSVC??????????????? 客戶端可以通過交易“AUTHSVC”獲得認(rèn)證
NOTIFY???????????????????? DIPIN,客戶端通過dip-in收到廣播通知
SYSTEM_ACCESS????? PROTECTED,NO_OVERRIDE,應(yīng)用代碼不得干擾共享內(nèi)存
LDBAL????????????????????? 設(shè)Y則進(jìn)行負(fù)載平衡
MAXBUF[S]TYPE?? 數(shù)據(jù)緩沖類型及子類的最大數(shù)
SCANUNIT????????????? 內(nèi)部時(shí)間間隔單位,單位是秒
SANITYSCAN? 檢索公告牌的內(nèi)部時(shí)間間隔,單位是SCANUNIT
BLOCKTIME???? 交易超時(shí)時(shí)間,單位是SCANUNIT
BBLQUERY????? DBBL查詢所有BLL的時(shí)間間隔
DBBLWAIT??????? DBBL等待BBL回應(yīng)的超時(shí)時(shí)間
MAXCONV??????? 同時(shí)最大會(huì)話數(shù)
?
注意:本處未列出全部參數(shù)。這些系統(tǒng)范圍內(nèi)參數(shù)可以被后序節(jié)內(nèi)參數(shù)超越。
?
范例
?
*RESOURCES
IPCKEY?????????????????????????? 80952
UID????????????????????????????????????????? 213
GID????????????????????????????????????????? 1
PERM????????????????????????????? 0660????
MAXACCESSERS??????? 150
MAXSERVERS???????????????????? 75
MAXSERVICES??????????????????? 200
MASTER???????????????????????? SITE1,SITE2
MODEL?????????????????????????????????? MP
OPTIONS??????????????????????? LAN,MIGRATE
SECURITY????????????????????? APP_PW
AUTHSVC?????????????????????? AUTHSVC
NOTIFY??????????????????????????? DIPIN
SYSTEM_ACCESS???????????? PROTECTED,NO_OVERRIDE
LDBAL???????????????????????????? Y
MAXBUFTYPE?????????????? 10
MAXBUFSTYPE??????????? 15
SCANUNIT??????????????????????????? 10
SANITYSCAN??????????????? 12
BLOCKTIME?????????????????? 3
BBLQUERY??????????????????? 24
DBBLWAIT????????????????????? 10
MAXCONV????????????????????? 10
?
?
?
?
?
機(jī)器信息
?
?????? *MACHINES節(jié)包含應(yīng)用有關(guān)的每個(gè)處理器的信息。本節(jié)必須在*RESOURCES節(jié)后列出。
參數(shù)??????????????????? 意義
*MACHINES???? MACHINES節(jié)
gumby??????????????? 物理處理器名,可以通過”uname –n”或節(jié)點(diǎn)名得到
TUXDIR???????????? TUXEDO系統(tǒng)軟件安裝位置
APPDIR???????????? 應(yīng)用服務(wù)位置全路徑
TUXCONFIG???? TUXEDO配置文件全路徑
ENVFILE?????????? 環(huán)境文件全路徑
ULOGPFX???????? 應(yīng)用日志文件全路徑
MAXACCESSERS 本機(jī)最多處理器數(shù),可以超越*RESOURCES節(jié)定義
MAXCONV??????? 本機(jī)最大會(huì)話數(shù),可以超越*RESOURCES節(jié)定義
?
范例
*MACHINES
gumby??????????????? LMID=SITE1
TUXDIR=”/usr/tuxedo”
APPDIR=”/usr/apps/atmapp”
TUXCONFIG=” /usr/apps/atmapp/atmapp.tux”
ENVFILE=” /usr/apps/atmapp/ENVFILE”
ULOGPFX=”/usr/apps/atmapp/logs/ULOG”
MAXACCESSERS=100
MAXCONV=15
?
組定義
?????? *GROUP節(jié)包含服務(wù)組的定義。一臺(tái)機(jī)器至少要定義一個(gè)服務(wù)組。如果沒有定義組,管理命令tmadmin可能依然能運(yùn)行。
?????? 每個(gè)組只要定義組名,映射組名的組號(hào)和邏輯機(jī)器名。組為分布式交易系統(tǒng)和數(shù)據(jù)依賴路由等靈活性措施提供了支持。
參數(shù)??????????????????? 意義
*GROUPS???????? GROUP節(jié)
BANKB1??????????? 組的唯一標(biāo)識(shí)符,可以是字母數(shù)字
GRPNO???????????? 組的唯一數(shù)字標(biāo)識(shí)符
LMID?????????????????? 組所在的機(jī)器
范例
*GROUPS
BANKB1???? GRPNO=200??? LMID=SITE1
BANKB2???? GRPNO=220??? LMID=SITE1
SYSGRP??? GRPNO=110??? LMID=SITE1
EVTGRP1? GRPNO=120??? LMID=SITE1
?
服務(wù)定義
?????? ubbconfig的*SERVERS???? 節(jié)包含的是服務(wù)進(jìn)程的信息。本節(jié)中每一個(gè)入口代表一個(gè)應(yīng)用啟動(dòng)時(shí)加載的服務(wù)。這些信息包含服務(wù)名,命令行參數(shù),服務(wù)環(huán)境,重啟動(dòng)等等。由于每個(gè)服務(wù)功能各不相同,其配置參數(shù)也因此相同或相異。
參數(shù)??????????????????? 意義
*SERVERS????????????? SERVER節(jié),列出所有服務(wù)程序
DEFAULT:? ?????? 本處列出的參數(shù)為其下列出的服務(wù)的缺省值,但可以被單列條目替代相應(yīng)值
RESTART? 如果設(shè)成Y,則服務(wù)可以重啟動(dòng)
MAXGEN??? 在GRACE定義時(shí)間之內(nèi),服務(wù)可以重啟動(dòng)MAXGEN次
GRACE????????????? 周期,單位是秒
?????? RCMD???????? 每次服務(wù)重啟動(dòng),本處定義的腳本或命令被執(zhí)行
?????? ENVFILE??? 列有環(huán)境變量的文件,在交易啟動(dòng)前設(shè)入環(huán)境
TLR????????????? ?????? 一個(gè)服務(wù)名,用buildserver建立,應(yīng)在APPDIR或$TUXDIR/bin
SRVGRP??? 服務(wù)屬于一個(gè)在*GROUPS節(jié)中定義的服務(wù)組;如果需要移植服務(wù),也可以定義在多個(gè)組中。
SRVID???????? 服務(wù)組中代表服務(wù)的唯一值
MIN????????????? 最少在啟動(dòng)時(shí)啟動(dòng)的服務(wù)數(shù)
MAX??????????? 運(yùn)行時(shí),最多可以起的實(shí)例數(shù)
CLOPT??????? 跟隨服務(wù)啟動(dòng)的其他參數(shù)
-A ??????? 服務(wù)內(nèi)建交易全發(fā)布
–r?????????? 指定服務(wù)記錄時(shí)間戳,用于以后計(jì)算交易處理時(shí)間
????????????? -e???????? 定義標(biāo)準(zhǔn)錯(cuò)誤重定向文件
????????????? -o???????? 定義標(biāo)準(zhǔn)輸出重定向文件
????????????? --??????????? TUXEDO參數(shù)和服務(wù)特定參數(shù)的分隔符
????????????? …????????? 傳給tpsvrinit()的參數(shù)
SYSTEM_ACCESS???????????? 設(shè)定后,應(yīng)用錯(cuò)誤不干擾公告牌
RQADDR?? 當(dāng)設(shè)定此項(xiàng)后,所有本服務(wù)的實(shí)例都使用相同的請(qǐng)求隊(duì)列。這是在應(yīng)用中設(shè)置MSSQ(Multiple Server Single Queue)的方便辦法,可以改善處理流量。任何時(shí)候,所有MSSQ集中的實(shí)例發(fā)布相同的交易集。
XFER???????????????? 另一個(gè)服務(wù)
REPLYQ???? 設(shè)成Y,則服務(wù)又作為一個(gè)MSSQ集配置,任何其中的交易調(diào)用其他交易,就建立一個(gè)單獨(dú)的回應(yīng)隊(duì)列。
范例
*SERVERS
DEFAULT:? RESTART=Y??? MAXGEN=5????? GRACE=3600
???????????????????? RCMD=”/sur/apps/atmapp/scripts/beeper”
???????????????????? CLOPT=”-A”????? ENVFILE=”/usr/apps/atmapp/envfile”
TLR????????????? SRVGRP=BANKB1????? SRVID=10? MIN=1? MAX=2
???????????????????? CLOPT=”-A–r
???????????????????? -e/usr/apps/atmapp/logs/TLR1.err
???????????????????? -o/usr/apps/atmapp/logs/TLR1.out
???????????????????? --
???????????????????? -T101 –e 300 –d dbfile”
???????????????????? SYSTEM_ACCESS=PROTECTED
???????????????????? RQADDR=”TLR_Q1”
XFER?? SRVGRP=BANKB1????? SRVID=20? MIN=1? MAX=2
????????????? RQADDR=”XFER_Q1” REPLYQ=Y
????????????? CLOPT=”-A–r”
?
交易定義
???? *SERVICES節(jié)提供了應(yīng)用的特殊交易的信息。包括負(fù)載平衡(LOAD)和數(shù)據(jù)緩沖類型檢查(BUFTYPE)。如果全部都是缺省值則本節(jié)可以省略。
參數(shù)??????????????????? 意義
*SERVICES????? 交易節(jié)
#????????????????????????? 注釋行符號(hào)
大寫字母??? 交易名,由應(yīng)用服務(wù)提供
BUFTYPE? 任何向該交易的請(qǐng)求,數(shù)據(jù)應(yīng)該是此處定義類型
GROUP????? 交易所在服務(wù)所在的組
LOAD????????? 負(fù)載因子,表示處理請(qǐng)求的時(shí)間,用于計(jì)算負(fù)載平衡
PRIO?????????? 優(yōu)先級(jí)
?
范例
*SERVICES
#comment line
DEPOSIT??? BUFTYPE=”FML”
???????????????????? SRVGRP=BANKB1
???????????????????? LOAD=25?? PRIO=70
?
?生成TUXCONFIG文件
?????? UBBCONFIG文件是一個(gè)可以編輯成需要的應(yīng)用配置的文本文件。但是,/T在實(shí)際應(yīng)用上讀取的是二進(jìn)制TUXCONFIG文件用于操作。命令tmloadcf可以把UBBCONFIG文件轉(zhuǎn)化成TUXCONFIG文件。
?????? tmloadcf命令接受以下4個(gè)參數(shù):
-c??? 計(jì)算運(yùn)行應(yīng)用需要的IPC資源,該信息將提供給管理員,用于在各機(jī)器上配置資源。
-n?? 進(jìn)行語法檢查并不生成TUXCONFIG。
-b??? 控制TUXCONFIG占用的物理頁數(shù)。
-y??? 無條件覆蓋TUXCONFIG
環(huán)境變量TUXCONFIG必須設(shè)定指向二進(jìn)制TUXCONFIG文件。
在安全要求高的應(yīng)用中,tmloadcf不能從標(biāo)準(zhǔn)輸入接受,環(huán)境變量APP_PW必須包含應(yīng)用密碼。
tmunloadcf將TUXCONFIG轉(zhuǎn)換成ASCII格式用于檢查。該工具讀取環(huán)境變量TUXCONFIG指向的文件。輸出包含所有的參數(shù),包括TUXEDO設(shè)定的缺省值,是UBBCONFIG文件的一個(gè)超集。
管理命令A(yù)dministrative Commands
?
?
本節(jié)要點(diǎn)
l? 命令tmboot
l? 命令tmshutdown
l? 命令tmadmin
l? 批處理命令
l? 服務(wù)移植
?
命令tmboot
tmboot命令啟動(dòng)TUXEDO系統(tǒng)的/T應(yīng)用,創(chuàng)建必要的IPC資源、啟動(dòng)相關(guān)機(jī)器的規(guī)定的系統(tǒng)和應(yīng)用服務(wù)進(jìn)程。大多數(shù)的tmboot的參數(shù)啟動(dòng)了部分系統(tǒng)進(jìn)程。在以下說明和例子中,lmid,grpname和srvid是配置文件中指定的值。
-A????????? 啟動(dòng)所有機(jī)器上的管理進(jìn)程。??????????
-M????????? 啟動(dòng)主控機(jī)器上的管理進(jìn)程。
-i srvid? 啟動(dòng)服務(wù)id等于????? srvid的進(jìn)程。
-g grpname 啟動(dòng)指定的一組服務(wù)(含TMS)
-S????????? 啟動(dòng)所有應(yīng)用服務(wù)。
-s server-name 啟動(dòng)可執(zhí)行文件名為server-name的服務(wù)。
-l lmid?? 啟動(dòng)TMS和指定機(jī)器上的應(yīng)用服務(wù)。
-T grpname ????? 啟動(dòng)指定組中所有TMS。
-B lmid???????? 啟動(dòng)指定機(jī)器上的BBL。
-e command???????????? 指定啟動(dòng)進(jìn)程失敗后在主控機(jī)器上運(yùn)行的命令名。
-c?????????? 打印本配置所需最少的IPC資源。
?
?
命令tmshutdown
tmshutdown命令用于關(guān)閉所有或部分應(yīng)用并釋放IPC資源。
本命令所用參數(shù)與tmboot類似(如:-A, -g, -i, -s, -S, -l, -M, -B),意義相同。
如果需要移動(dòng)服務(wù),關(guān)閉服務(wù)時(shí)用-R參數(shù)即可不刪除BB中的入口。
在非主控節(jié)點(diǎn)上,可以用-P參數(shù)僅關(guān)閉該機(jī)器上的應(yīng)用。
當(dāng)有客戶端正在連接時(shí),tmshutdown 不能關(guān)閉管理服務(wù)。參數(shù)-c則可以超越此規(guī)則。該參數(shù)僅用于管理員需要立即關(guān)機(jī)而又無法及時(shí)通知客戶端時(shí)。
參數(shù)-wdelay 在delay秒后進(jìn)行強(qiáng)制關(guān)閉。指定的服務(wù)當(dāng)即被掛起,使之不能繼續(xù)接受交易請(qǐng)求。delay的值則允許服務(wù)在一個(gè)合理的時(shí)間內(nèi)完成已經(jīng)接受的請(qǐng)求。在延遲的時(shí)間到達(dá)后,信號(hào)SIGKILL(或SIGTERM)將發(fā)給指定的服務(wù)。該參數(shù)目的是使管理員能夠關(guān)閉發(fā)生死循環(huán)或死鎖的服務(wù)。
管理工作和工具
?
主要有以下兩個(gè)管理工具:
2? 使用圖形界面的圖形管理接口(Graphical Administration Interface—GAI)
2? tmadmin
通常管理工作有以下3類:
2? 監(jiān)視運(yùn)行系統(tǒng)
一般監(jiān)視以下信息:應(yīng)用、服務(wù)、客戶端、交易、隊(duì)列、組、會(huì)話、網(wǎng)絡(luò)等。
2? 動(dòng)態(tài)修改服務(wù)或交易參數(shù)
使用GAI 或tmadmin可以動(dòng)態(tài)進(jìn)行以下調(diào)整:
——交易可以掛起、恢復(fù)、發(fā)布和取消
——交易參數(shù)可以修改,如:LOAD和PRIORITY
——指定交易的超時(shí)時(shí)間
——交易口令
2? 進(jìn)行啟動(dòng),關(guān)閉,移動(dòng)服務(wù)等管理員的任務(wù)
服務(wù)信息
?????? 來自GAI的信息本處略去。
?????? 以下是tmadmin命令的printserver(簡寫為psr)的簡單輸出。
列號(hào)???????????? 描述
1.????服務(wù)的可執(zhí)行文件名
2.????服務(wù)連接的隊(duì)列名
3.????組名
4.????服務(wù)的數(shù)字id
5.????服務(wù)已經(jīng)處理的請(qǐng)求數(shù)
6.????服務(wù)處理的全部請(qǐng)求的參數(shù)和
服務(wù)正在處理的交易,若為IDLE則服務(wù)當(dāng)前是空閑
ccsmis:/home2/ccsmis>tmadmin
tmadmin - Copyright (c) 1996 BEA Systems, Inc.
Portions * Copyright 1986-1997 RSA Data Security, Inc.
All Rights Reserved.
Distributed under license by BEA Systems, Inc.
Tuxedo is a registered trademark.
?
> printserver
Prog Name????? Queue Name? Grp Name?????ID RqDone Load Done Current Service
---------????? ----------? --------?????-- ------ --------- ---------------
rz_Ecsb??????? 00004.04000 APGP2?????? 4000?????0???????? 0 (? IDLE )
BBL??????????? 70020?????? simple???????? 0?????1??????? 50 (? IDLE )
IFMTMS???????? APGP2_TMS?? APGP2?????30001????? 1??????? 50 (?IDLE )
ftpserv32????? 00002.00001 FTPGP????????? 1????60????? 3000 (? IDLE )
WSL??????????? 00001.00001 SYSGP????????? 1?????0???????? 0 (? IDLE )
IFMTMS???????? APGP2_TMS?? APGP2?????30002???? 12??????600 (? IDLE )
ftpserv32????? 00002.00002 FTPGP????????? 2?????0???????? 0 (? IDLE )
IFMTMS???????? APGP2_TMS?? APGP2?????30003???? 11?????? 550 (?IDLE )
CCS_QUANBIA_6000004.06004 APGP2?????? 6004????? 0????????0 (? IDLE )
CCS_SCBB_4099? 00004.04099 APGP2?????? 4099?????2?????? 100 (? IDLE )
CCS_GEKEZI_30000004.03000 APGP2?????? 3000????? 0????????0 (? IDLE )
:
交易信息
?????? 來自GAI的信息本處略去。
?????? 以下是tmadmin命令的printservice(簡寫為psc)的簡單輸出。
列號(hào)????? 描述
1.????交易名
2.????交易函數(shù)名
3.????服務(wù)可執(zhí)行文件名
4.????服務(wù)所在組名
5.????服務(wù)的數(shù)字id
6.????提供交易的機(jī)器的LMID
7.????交易已經(jīng)執(zhí)行的次數(shù)
8.????交易當(dāng)前狀態(tài)
Service NameRoutine Name Prog Name? Grp Name? ID???Machine? # Done Status
------------------------ ---------? --------? --???-------? ------ ------
416701?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
416601?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
416501?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
416401?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
416201?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000 ????simple??????0 AVAIL
416301?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
416101?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
416001?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
415901?????? rz_Ecsb????? rz_Ecsb???APGP2?? 4000???? simple?????? 0 AVAIL
:
?
隊(duì)列信息
????????????? 以下是tmadmin命令的printqueue(簡寫為pq)[qaddress]的簡單輸出。如果不指定address,所有隊(duì)列信息將被輸出。
列號(hào)?????????????????????????? 描述
1.????隊(duì)列連接的服務(wù)的可執(zhí)行文件名
2.????字符隊(duì)列名,是RQADDR參數(shù)或一個(gè)隨機(jī)值
3.????連接的服務(wù)數(shù)
4.????當(dāng)前隊(duì)列的所有請(qǐng)求的參數(shù)和
5.????實(shí)際請(qǐng)求數(shù)
6.????平均隊(duì)列長度
7.????隊(duì)列所在機(jī)器的LMID
> pq 00004.05062
Prog Name????? Queue Name? # Serve Wk Queued? # Queued?Ave. Len??? Machine
---------????? ------------------- ---------? --------?--------??? -------
CCS_GEDAIPC_5000004.05062?????? 1???????? 0???????? 0??????0.0???? simple
客戶端信息
?????? 來自GAI的信息本處略去。
?????? 以下是tmadmin命令的printclient(簡寫為pclt)的輸出,來自TUXEDO系統(tǒng)的日志信息。主要有以下信息:
客戶端id,用戶名和當(dāng)前狀態(tài)
登錄的LMID和進(jìn)程號(hào)(PID)
服務(wù)組和上一訪問過的服務(wù)組
交易(啟動(dòng)/提交/中斷)和會(huì)話的統(tǒng)計(jì)數(shù)字
中繼隊(duì)列id,通知方法和提交控制
列號(hào)?????????????????????????? 描述
1.????已經(jīng)登錄的客戶端機(jī)器的LMID
2.????用戶名,由tpinit()提供的
3.????客戶端名,由tpinit()提供的
4.????客戶端連接后經(jīng)過的時(shí)間
5.????客戶端狀態(tài)
6.????IDLE——表示客戶端目前沒有任何交易在工作
7.????IDLET——表示客戶端啟動(dòng)了一個(gè)交易
8.????BUSY——表示客戶端在工作中
9.????BUSYT——表示客戶端正在交易控制下工作
10.? 啟動(dòng)/提交/中斷的交易數(shù)
> pclt
???? LMID???????? User Name?????? Client Name??? Time???Status? Bgn/Cmmt/Abrt
------------------------------ --------------- -------- ------- -------------
simple????????? ccsmis???????? ?WSH????????????17:42:47 IDLE??? 0/0/0
simple????????? ccsmis????????? tmadmin????????? 0:44:28 IDLE??? 0/0/0
?
用tmadmin寫腳本
輸出所有服務(wù)/交易/隊(duì)列信息
$tmadmin 2>&1<<!
echo
verbose
psr
psc
pq
!
掛起bankapp內(nèi)所有AUDIT交易
(tmadmin2>&1 <<!
pq
!
) |
awk ‘BEGIN { print “tmadmin <<! \necho”}
{if ( $1 == “AUDIT”) print “susp –q” , $2, “-S $1”}
END {print “q\n!”}’ |
/bin/sh
移植服務(wù)
該功能使管理員可以將服務(wù)移動(dòng)到其他位置。服務(wù)可以用migrategroup(migg)[-cancel] group移植一組服務(wù),或用migratemach(migm) [-cancel] machine移植一臺(tái)機(jī)器上的服務(wù)。
以下是移植服務(wù)的步驟:
1. 服務(wù)必須用tmshutdown或-R參數(shù)關(guān)閉。該參數(shù)包含公告牌中的服務(wù)名。 ?
2.在配置文件中的*RESOURCES段必須指明MIGRATE
*RESOURCES
…
OPTIONS?? MIGRATE
…
?
3.在*GROUP段中,被移植的服務(wù)組在LMID參數(shù)中必須有替代位置。當(dāng)移植機(jī)器時(shí),所有組的LMID參數(shù)的替代位置必須相同。
*GROUP
…
APGP2 LMID=SITE1,SITE2
…
?
4.服務(wù)必須可以重啟動(dòng),以下是*SERVERS段有關(guān)內(nèi)容
*SERVERS
…
rz_Ecsb?????? SRVGRP=APGP2? RESTART=Y
…
?
移植在關(guān)閉后將被取消。migg 和migm–cancel 參數(shù)在服務(wù)關(guān)閉后從公告牌刪除服務(wù)名。所以,服務(wù)需要重啟動(dòng)才可以使用。
$tmadmin
>stop –R –g APGP2
Shutting down server processes …
>psr –g APGP2
Prog Name????? Queue Name? Grp Name?????ID RqDone Load Done Current Service
---------????? ----------? --------?????-- ------ --------- ---------------
rz_Ecsb??????? 00004.04000 APGP2?????? 4000?????0???????? 0 (? IDLE )
IFMTMS???????? APGP2_TMS?? APGP2?????30001????? 1??????? 50 (?IDLE )
IFMTMS???????? APGP2_TMS?? APGP2?????30002???? 16?????? 800 (?IDLE )
IFMTMS???? ????APGP2_TMS??APGP2????? 30003???? 15??????750 (? IDLE )
CCS_QUANBIA_6000004.06004 APGP2?????? 6004????? 0????????0 (? IDLE )
CCS_SCBB_4099? 00004.04099 APGP2?????? 4099?????2?????? 100 (? IDLE )
>migg APGP2
migration successfully completed
?
?
緩沖數(shù)據(jù)類型????? Buffer Types
?
本節(jié)要點(diǎn)
l? STRING
l? VIEW
定義
偽代碼中VIEW的使用
代碼示例
l? FML
定義
偽代碼中FML的使用
代碼示例
l? 結(jié)合FML和VIEW
l? CARRAY的定義
l? FML32和VIEW32
簡介和STRING
TUXEDO使用固定類型的數(shù)據(jù)緩沖進(jìn)行遠(yuǎn)程或本地進(jìn)程間通訊。例如”STRING”就是一種包含了字符數(shù)組的一種數(shù)據(jù)緩沖。絕大多數(shù)商業(yè)應(yīng)用需要不止一種數(shù)據(jù)。
TUXEDO已經(jīng)預(yù)定義了一些數(shù)據(jù)緩沖類型用以傳遞各種數(shù)據(jù)。每種都有其獨(dú)特的處理方法和相應(yīng)特性。
STRING
STRING類型緩沖是一串以NULL結(jié)尾的字符。TUXEDO為STRING類型編、解碼。無論緩沖分配了多大,將由NULL所在位置決定其長度。
TUXEDO的STRING緩沖的使用與C語言程序中的字符數(shù)組非常類似。
分配
buf = tpalloc ( “STRING”, NULL, 4*1024);
用法
strcpy ( buf “HELLO WORLD”);
調(diào)用交易
tpcall (“INQUIRY”, buf , 0, &buf,&len, 0);
?
?
?
?
VIEW
VIEW的概念和例子
TUXEDO使用VIEW類型數(shù)據(jù)緩沖處理結(jié)構(gòu)或復(fù)雜數(shù)據(jù)類型。
使用VIEW的優(yōu)點(diǎn):
2?結(jié)構(gòu)化數(shù)據(jù)表示,可以方便地訪問數(shù)據(jù)元素
2?將多個(gè)數(shù)據(jù)元素綁定在一個(gè)定義良好的數(shù)據(jù)結(jié)構(gòu)上
缺點(diǎn):
2?所有數(shù)據(jù)元素都通過,不檢查合法性
范例:
struct MYVIEW {
? float??float1;
? double?double1;
? long???long1;
? short??short1;
? int????int1;
? dec_t??dec1;
? char???char1;
? char???string1[20];
? unsigned short L_carray1[2];??? /* length array of carray1 */
? short??C_carray1;????????????? /* countof carray1 */
? char???carray1[2][20];
};
$ /* View data structure */
? VIEW MYVIEW
? #type??cname?? fbname? count??flag??? size??? null
? float??float1? -?????? 1??????-?????? -?????? -
? double?double1 -?????? 1?????? -??????-?????? -
? long???long1?? -?????? 1??????-?????? -?????? -
? short??short1? -?????? 1??????-?????? -?????? -
? int????int1??? -?????? 1??????-?? ????-??????-
? dec_t??dec1??? -?????? 1??????-?????? 9,16??? -
? char???char1?? -?????? 1??????-?????? -?????? -
? string?string1 -?????? 1?????? -??????20????? -
? carray?carray1 -?????? 2?????? CL?????20????? -
? END
??
使用VIEW的步驟:
2?建立一個(gè)VIEW文件
2?設(shè)置環(huán)境變量
VIEWDIR=$APPDIR
VIEWFILES=cust.V,other.V
export VIEWDIRVIEWFILES
2?編譯VIEW文件
viewc –ncust.V
2?在代碼中包含頭文件
2?編譯
2?運(yùn)行
代碼范例:
#include <stdio.h>
#include “atmi.h”
#include “cust.h”
main(int argc, char *argv [ ])
{
?????? structcust *buf;
?????? longrcvlen;
?????? if(tpinit ((TPINIT *) NULL) == -1)
{
?????? ?????? ptintf(“tpinit(): %s\n”,tpstrerror(tperrno));
?????? ?????? exit(1);
}
?????? buf=(structcust *)tpalloc(“VIEW”,”cust”,sizeof(struct cust));
?????? if(buf == (struct cust *)NULL)
{
????????????? printf(“ERROR:tpalloc(VIEW,cust),%s\n”,tpstrerror(tperrno));
????????????? tpterm();
????????????? exit(1);
}
?????? strcpy(buf->fsst_name,”Mel”);
?????? strcpy(buf->lst_name,”Gibson”);
?????? buf->acct_id= 10002;
?????? buf->branch_id= 5;
?????? ret= tpcall (“INQUIRY”,(char *)buf,0,
?????????????????????????????????? (char**)&buf,&rcvlen,0);
?????? if(ret == -1)
{
????????????? printf(“tpcall(INQUIRY): %s\n”, tpstrerror(tperrno));
?????? ?????? tpfree((char *) buf);
?????? ?????? tpterm();
?????? ?????? exit(1);
}
????????????? printf(“Returned amount is : %1.1s\n”, buf->amount);
????????????? tpfree((char*)buf);
????????????? tpterm();
}
?
?
FML
?
概念
?
?????? 預(yù)定義方式的VIEW有一些缺點(diǎn):
2? 改變不靈活
2? 結(jié)構(gòu)變化時(shí),所有程序需要重新編譯
2? 即使沒有數(shù)據(jù),空間也被占用
為克服以上缺點(diǎn),TUXEDO提供另一種預(yù)定義數(shù)據(jù),按照‘名字/值’組對(duì)格式組織數(shù)據(jù)。該方式稱為FML(Fielded Manipulation Language)。
FML由以下部分構(gòu)成:
2? FML API
2? FML命令行工具
?
| FML頭部,包含索引 | |
| FLOAT1 | 5.00 |
| DOUBLE1 | 12.34 |
| LONG1 | 12345 |
| SHORT1 | 12 |
| … | … |
| 域名 | 域值 |
?
?
使用FML的步驟
2?建立一個(gè)FML文件:bank.flds
# name?????? number???type???? flags?? comments
? FLOAT1???? 110??????float??? -??????-
? DOUBLE1??? 111??????double?? -?????? -
? LONG1????? 112??????long???? -?????? -
? SHORT1???? 113??????short??? -?????? -
? INT1?????? 114??????long???? -?????? -
? DEC1?????? 115??????string?? -?????? -
? CHAR1????? 116??????char???? -?????? -
? STRING1??? 117??????string?? -?????? -
? CARRAY1??? 118??????carray?? -?????? -
?
?
2?設(shè)置環(huán)境變量
FLDTBLDIR=$APPDIR:$TUXDIR/udataobj
FIELDTBLS=bank.flds,Usysflds
exportFLDTBLDIR FIELDTBLS
2?用mkfldhdr編譯
mkfldhdrbank.flds
2?編碼
參見下一章節(jié)
2?編譯程序
buldclient –fatmclt.c –o atmclt
FMLAPI
#include <fml.h>
Falloc(int num_of_flds,FLDLEN space)
Finit(FBFR *f)
Fsizeof(FBFR *f,FLDLEN len)
Fadd(FBFR *f,FLDID fldid,int oc,char*value,FLDLEN len)
Fprint(FBFR *f)
Fget(FBFR *f,FLDID fldid,int oc,char*value,FLDLEN len)
Fchg(FBFR *f,FLDID fldid,int oc,char*value,FLDLEN len)
Fcpy(FBFR *f, FBFR *f2)
f = (FBFR *)tpalloc(“FML”,NULL,200)
Ffprint(FBFR *fbfr,FILE *iop)
2?Fprint()是一個(gè)有用的調(diào)試函數(shù),因?yàn)樗梢源蛴〕鼍彌_內(nèi)容而不需要定義數(shù)據(jù)類型和輸出格式。
2?Falloc()用于內(nèi)部進(jìn)程通訊
2?Fcpy()用來復(fù)制FML的內(nèi)容,特別是在不同服務(wù)的交易之間
代碼范例:
#include <stdio.h>
#include “atmi.h”
#include<fml.h>
#include “bank.flds.h”
int main (int argc,char **argv)
{
?????? longaccount ;
?????? floatbalance;
?????? floatamount;
?????? FBFR*sendBuf, *recvBuf;
?????? sendBuf= (FBFR *) tpalloc(RMLTYPE,NULL,Fneeded(20,4*1024));
?????? recvBuf= (FBFR *) tpalloc(RMLTYPE,NULL,Fneeded(20,4*1024));
?????? if(Fchg(sendBuf, ACCOUNT_ID,0,(char * )&account,0) == -1)
{
????????????? printf(“\nERROE:Fchg(ACCOUNT_ID):%s\n”,Fstrerror(Ferror));
}
?????? if(tpcall(“INQUIRY”,(char*)sendBuf,0,
(char**)&recvBuf,&len,TPSIGRSTRT)== -1
{
?????? if(Fget(recvBuf,STATLIN,0,tmpstr,0)!=-1)
{
????????????? printf(“\n%s\n”,tmpstr);
}
????????????? printf(“\nERROR:tpcall(INQUIRY):%s\n”,tpstrerror(tperrno));
?????? else
{
?????? if(Fget(recvBuf,BALANCE,0,(char*)&balance,0) == -1)
{
????????????? printf(“\nERROR:Fget(BALANCE):%s\n”,Fstrerror(Ferror));
}
?????? else
{
????????????? printf(“\nBalance:%s\n”,balance);
}
}
????????????? tpfree((char*) sendbuf);
????????????? tpfree((char*) recvbuf);
?????? tpterm();
}
?
結(jié)合FML和VIEW
?????? FML的使用需要進(jìn)一步的考慮,例如,訪問FML數(shù)據(jù)會(huì)慢一些,因?yàn)榻涌谝迦牖蛉』財(cái)?shù)據(jù)。在某些場合,需要進(jìn)行一些推敲。而VIEW則提供了一個(gè)通用管理數(shù)據(jù)緩沖的方案。
?????? FML的優(yōu)點(diǎn)是可以在機(jī)器間傳遞數(shù)據(jù)和靈活的存儲(chǔ)數(shù)據(jù)。而VIEW則傳遞整個(gè)定義好的C結(jié)構(gòu),不管域里面是否有數(shù)據(jù)。可以使用它們的混合:FML-VIEWS。
?????? TUXEDO提供了2個(gè)API把FML轉(zhuǎn)換成VIEW
2? int Fvstof(FBRF *bufptr,char *cstruct,int mode,char *view)將VIEW結(jié)構(gòu)轉(zhuǎn)成FML
2? int Fvftos(FBFR *bufptr, char *cstruct, char *view)?? 將FML數(shù)據(jù)轉(zhuǎn)成VIEW結(jié)構(gòu)
?
其他數(shù)據(jù)類型
?????? 除FML,VIEW和STRING類型外,另外一個(gè)主要的數(shù)據(jù)緩沖類型是CARRY。
CARRY
CARRY數(shù)據(jù)緩沖類型是一種定長的,相對(duì)獨(dú)立于機(jī)器的數(shù)據(jù)。
2?長度需要定義
2?不進(jìn)行編/解碼
2?可用來傳遞二進(jìn)制數(shù)據(jù)
2?可以作為FML和VIEW的子項(xiàng)
2?用于文件、圖形傳輸
FML32和VIEW32
?????? 在對(duì)FML和VIEWS初始化時(shí),尋址是16位的。隨著主要的平臺(tái)都變成32位的,TEXUDO增加了FML32和VIEWS32。
2?使用32位尋址方式
2?有更大的尋址空間(2GB)
2?API與16位的相似,只在名字上加了‘32’字樣
?
?
數(shù)據(jù)依賴型路由??? Data Dependent Routing
?
本節(jié)要點(diǎn)
l? 定義
l? 過程
ubbconfig
?
?
?
簡介
?????? 當(dāng)遇到非常巨大的數(shù)據(jù)需要傳遞時(shí),可以將單一的數(shù)據(jù)分割成幾個(gè)部分進(jìn)行傳遞。分割的標(biāo)準(zhǔn)根據(jù)其商業(yè)應(yīng)用而定。例如,可以根據(jù)省份、郵政編碼或金額來分割數(shù)據(jù)。
?????? 在TUXEDO中,數(shù)據(jù)依賴型路由解決了此類大型商業(yè)應(yīng)用的難點(diǎn),而且不需要進(jìn)行任何程序工作。僅僅改變一下ubbconfig文件就可以了。
數(shù)據(jù)依賴型路由是根據(jù)數(shù)據(jù)緩沖區(qū)中一個(gè)指定域的值,把一個(gè)交易請(qǐng)求映射到一個(gè)指定的服務(wù)組的機(jī)制。
?
?
?
數(shù)據(jù)依賴型路由
?????? 數(shù)據(jù)依賴路由(DDR-Data Dependent Routing)需要在UBBCONFIG文件中的*GROUPS節(jié)創(chuàng)建多個(gè)入口,并分割組中應(yīng)用的資源或任務(wù)。每個(gè)組可以訪問各自的數(shù)據(jù)庫并且可以屬于獨(dú)立的機(jī)器。注意:一個(gè)組不能同時(shí)跨越一臺(tái)以上的機(jī)器。
?????? 一個(gè)有多組獨(dú)立服務(wù)的大型數(shù)據(jù)庫可以被分成幾個(gè)獨(dú)立數(shù)據(jù)集。
?????? 此類數(shù)據(jù)分割的實(shí)現(xiàn)是通過對(duì)交易請(qǐng)求的緩沖數(shù)據(jù)值的路由。DDR是基于FML,FML32,VIEW和VIEW32數(shù)據(jù)緩沖。
???? TUXEDO使用的路由信息位于共享內(nèi)存中的公告牌。在ubbconfig文件中有特別的部分對(duì)路由進(jìn)行定義。路由的定義包含了數(shù)據(jù)使用的域和數(shù)據(jù)區(qū)間及其對(duì)應(yīng)的服務(wù)組。
?????? TUXEDO通過對(duì)比調(diào)用交易內(nèi)碼和共享內(nèi)存中公告牌中數(shù)據(jù)路由的值的區(qū)間選擇目標(biāo)服務(wù)。
?????? 在我們的例子中,路由決定于數(shù)據(jù)域ID。交易請(qǐng)求映射于組G1,G2和G3。每個(gè)遠(yuǎn)程或本地機(jī)器上的組都提供相同的交易。
?
使用DDR的ubbconfig的范例
*GROUP
BANKB1??????????? LMID=SITE1???? GRPNO=200
BANKB2??????????? LMID=SITE2???? GRPNO=220
*SERVICES
WITHDRAWAL??????? ROUTING=ACCOUNT_ID
*ROUTING
ACCOUNT_ID? FIELD=ACCOUNT_ID
????????????? BUFTYPE=”FML”
????????????? RANGES=”1-10:BANKB1,
?????????????????????????????????? 11-20:BANKB2”
BRANCH_ID??? FIELD=BRANCH_ID
???????????????????? BUFTYPE=”FML”
???????????????????? RANGES=”0-555:BANKB1,
????????????????????????????????????????? 556-888:BANKB2”
*GROUPS節(jié)說明
LMID與每個(gè)組相聯(lián)系。本例中是同一臺(tái)機(jī)器上的設(shè)置。當(dāng)然也可以設(shè)成遠(yuǎn)程機(jī)器。
*SERVICES節(jié)說明
分割標(biāo)準(zhǔn)是為此交易設(shè)置。ROUTING是分割標(biāo)準(zhǔn)的名字
*ROUTING節(jié)說明
FILED表示請(qǐng)求交易的那些值用于映射組。
BUFTYPE表示其緩沖數(shù)據(jù)類型。RANGE定義路由到不同組的數(shù)據(jù)邊界。
可以使用通配符’*’。
?
網(wǎng)絡(luò)??? Networking
簡介
?
基于以下原因,一個(gè)商業(yè)應(yīng)用需要分布于多臺(tái)機(jī)器上:
2? 負(fù)載均衡
2? 容錯(cuò)
2? 地理分布
???????使用TUXEDO,不需編程,應(yīng)用就可以被分布配置在多臺(tái)機(jī)器上。
????????
本節(jié)要點(diǎn)
l? 概念
l? UBBconfig
?
?
?
?
多機(jī)配置
TUXEDO通過一些部件實(shí)現(xiàn)和管理一個(gè)多機(jī)應(yīng)用。以下是這些部件和功能描述:
?
?
| 部件 | 功能 |
| BBL | BBL(Bulletin Board Liaison)記錄所有應(yīng)用服務(wù)狀態(tài),顯示于公告牌(Bulletin Board)。BBL同時(shí)修改來自DBBL的全局信息。 |
| DBBL | DBBL(Distinguished Bulletin Board Liaison)記錄所有BBL的狀態(tài)。運(yùn)行于主節(jié)點(diǎn)上,只有一份。 |
| BRIDGE | 提供TUXEDO節(jié)點(diǎn)間的通訊機(jī)制,僅處理ATMI數(shù)據(jù)。作為系統(tǒng)提供的服務(wù),是最早啟動(dòng)的兩個(gè)進(jìn)程。 |
| tlisten | ‘tlisten’在啟動(dòng)過程中被使用,必須先于TUXEDO應(yīng)用的啟動(dòng)。 |
?
?
?
?
多機(jī)配置
tlisten用法
tlisten –d /dev/tcp –l//lcspn1:3050 –L/usr/apps/atmapp/logs/tlog
特點(diǎn)
2?無須編程
2?交易位置對(duì)程序員和用戶透明
2?公告牌提供全局名字服務(wù)
?
?
?
一個(gè)簡單的UBBCONFIG范例
#ubbconfig file for MP configuration
*RESOURCES
MASTER?????????? SITE1,SITE2
BBLQUERY???????????? 100
DBBLWAIT??????? 20
MODEL????????????? MP
OPTIONS????????? LAN,MIGRATE
*MACHINES
lcspn1??????????????? LMID??????????? =SITE1
??????????????????????????? TUXDIR????? =”/usr/tuxedo”
??????????????????????????? TUXCONFIG=”/home/apps/atmapp/atmapp.tux”
??????????????????????????? APPDIR???????????? =”/home/apps/atmapp”
??????????????????????????? TYPE?????????? =RS6000
Lcspn2?????????????? LMID??????????? =SITE2
??????????????????????????? TUXDIR????? =”/usr/tuxedo”
??????????????????????????? TUXCONFIG=”/home/apps/atmapp/atmapp.tux”
??????????????????????????? APPDIR???????????? =”/home/apps/atmapp”
??????????????????????????? TYPE?????????? =RS6000
*NETWORKS
SITE1????????? NADDR???????????? =”//lcspn1:3050”
???????????????????? NLSADDR??????? =”//lcsnp1:3051”
???????????????????? BRIDGE???????????? =”/dev/xti/tcp”
SITE2????????? NADDR???????????? =”//lcspn2:3050”
???????????????????? NLSADDR??????? =”//lcsnp2:3051”
???????????????????? BRIDGE???????????? =”/dev/xti/tcp”
*GROUPS
BANKB1???? GRPNO1=1????????????? LMID=SITE1
BANKB2???? GRPNO1=2????????????? LMID=SITE2
*SERVICES
WITHDRAWAL
*RESOURCES節(jié)說明
MASTER參數(shù)表示TUXEDO在此處初始化它的啟動(dòng)次序,同時(shí)表示DBBL在何處運(yùn)行,出錯(cuò)時(shí)SITE2將作為SITE1的備份。
BBLQUERY決定應(yīng)用的BBL訪問主控節(jié)點(diǎn)上DBBL的頻率,單位是秒。
當(dāng)BBL在規(guī)定的BBLQUERY時(shí)間內(nèi)沒有響應(yīng),DBBL會(huì)發(fā)送一條信息給它,DBBLWAIT即等待響應(yīng)的超時(shí)時(shí)間,單位是秒。
MODEL表示TUXEDO是否運(yùn)行在多臺(tái)機(jī)器上。
*MACHINES節(jié)說明
?????? 描述了TUXEDO應(yīng)用或系統(tǒng)安裝的物理方面的信息。物理機(jī)器名”lcspn1”映射到邏輯機(jī)器名”SITE1”和LMID(Logical MachineIdentifier)邏輯機(jī)器標(biāo)識(shí)符。
?????? 參數(shù)TYPE用來決定是否在機(jī)器間傳輸時(shí)需要進(jìn)行編、解碼。它可被設(shè)置成任何字符串。當(dāng)兩機(jī)此參數(shù)不同時(shí),進(jìn)行編、解碼。
*NETWORKS節(jié)說明
?????? 在單機(jī)配置時(shí),此節(jié)略去。在多機(jī)時(shí),此節(jié)必須。
?????? TUXEDO機(jī)器間通過主機(jī)地址和端口號(hào)傳遞ATMI數(shù)據(jù),這些由NADDR按以下的規(guī)定定義:
?????? //lcspn1????????????? 主機(jī)名
?????? :??????????????????????? 分隔符
端口號(hào)
NLSADDR定義的是tlisten進(jìn)程的主機(jī)地址和端口號(hào)。
BRIDGE用于和其他TUXEDO機(jī)器通訊的網(wǎng)絡(luò)設(shè)備由BRIDGE定義。
?
分布式事務(wù)處理Distributed TransactionProcessing
?
簡介
?????? 分布式事務(wù)處理(DistributedTransation Processing-DTP)是運(yùn)行一組需要訪問一定量資源的交易或工作的必須的功能。要求保證交易動(dòng)作必須全部成功或者全部失敗,不能存在‘部分成功’的情況。
?????? TUXEDO系統(tǒng)使用XA協(xié)議在本地與遠(yuǎn)程機(jī)器間協(xié)同事務(wù)活動(dòng)。
?
本節(jié)要點(diǎn)
l? 定義
l? XA
l? 2段式提交協(xié)議
l? ATMI事務(wù)API
l? 過程
l? ubbconfig
創(chuàng)建格式化事務(wù)日志
用ATMI交易API寫程序
分布式事務(wù)處理和XA接口
分布式事務(wù)處理(Distributed Transation Processing-DTP)有能力處理多數(shù)據(jù)庫間、全局事務(wù)而不必考慮交易各方及其資源的位置。
服務(wù)使用嵌入式SQL接口去訪問數(shù)據(jù)庫。在一個(gè)“全局交易”中TM和RM使用XA接口保證執(zhí)行所有的資源訪問動(dòng)作。
全局事務(wù)通常最初被ATMI調(diào)用,包含一個(gè)以上的組;由客戶端和服務(wù)端啟動(dòng)、提交或撤消。TUXEDO通過全局事務(wù)標(biāo)識(shí)符(Global TransactionIdentifier-GTRID)控制所有參與部分。
RM?????????????? 資源管理者(Resource Manager),本例中是一個(gè)數(shù)據(jù)庫。
XA??????????????? 控制RM提交或回滾所有動(dòng)作的協(xié)議。
TMS??????????????????? TUXEDO的事務(wù)管理服務(wù)(Transaction Management Server),能夠按XA協(xié)議與RM聯(lián)系。TMS負(fù)責(zé)協(xié)調(diào)系統(tǒng)范圍內(nèi)事務(wù)相關(guān)資源管理。應(yīng)用程序員可以通過ATMI事務(wù)API與TMS聯(lián)系。
GTRID? ?????? 全局事務(wù)標(biāo)識(shí)符(Global TransactionIdentifier)。
TLOG??? ?????? 事務(wù)日志,用于跟蹤交易所有部分。
?
?
?
二段式提交(2 Phase Commit)
?
?
分布式事務(wù)處理的UBBCONFIG
?
分布式事務(wù)處理的UBBCONFIG范例
#A NULL TMS Example
*RESOURCES
?MAXGTT????????? 20
?CMTRET????????? COMPLETE
*MACHINES
?lcspn1?????? LMID??????????? =SITE1
????????????? TUXDIR????? =”/usr/tuxedo”
????????????? APPDIR???????????? =”/usr/apps/atmapp”
????????????? TUXCONFIG=”/usr/apps/atmapp/atmapp.tux”
????????????? ENVFILE?????????? =”/usr/apps/atmapp/ENVFILE”
????????????? TLOGDEVICE? =”/usr/apps/atmapp/logs/TLOG”
????????????? TLOGNAME????? =TLOG
????????????? TLOGSIZE???????? =100
*GROUPS
DEFAULT:
?????? TMSNAME =TMS
?????? TMSCOUNT=2
?????? OPENINFO=”“
?????? CLOSEINFO=”“
BANKB1???? LMID=SITE1???? GRPNO=200
BANKB2???? LMID=SITE2???? GRPNO=220
*SERVICES
TRANSFER????? AUTOTRAN=Y TRANTIME=30
*RESOURCES節(jié)說明
?????? MAXGTT限制了一臺(tái)機(jī)器上同時(shí)可以提供的GTRID數(shù)。最大值是2048,最小是0,缺省100;
?????? CMTRET設(shè)成LOGGED時(shí)表示tpcommit()在所有部分都成功預(yù)提交時(shí)返回;設(shè)成COMPLETE時(shí)表示tpcommit()在所有部分都成功提交才返回。
*MACHINES節(jié)說明
?????? TLOGDEVICE指出了該機(jī)器包含事務(wù)日志(TLOG)的文件系統(tǒng)。
?????? TLOGNAME指出了該機(jī)器的事務(wù)日志名字。
?????? TLOGSIZE指出了該機(jī)器事務(wù)日志的大小,單位是物理頁數(shù)。最大值是2048,最小是0,缺省100
*GROUPS節(jié)說明
?????? TMSNAME是事務(wù)管理服務(wù)的可執(zhí)行文件名
?????? TMSCOUNT是TMS啟動(dòng)的數(shù)量(最小2,最大10,缺省3)
?????? OPENINFO是一個(gè)用于打開RM的信息的字符串
?????? CLOSEINFO是一個(gè)用于關(guān)閉RM的信息的字符串
?????? AUTOTRAN設(shè)成N則該交易初始化成無事務(wù)方式,Y則反之。
?????? TRANTIME事務(wù)創(chuàng)建的超時(shí)時(shí)間,單位為秒。
創(chuàng)建事務(wù)日志的腳本
tmadmin <<!
crdl –b 500 –z /usr/apps/atmapp/logs/TLOG–O 0
crlog –m STIE1
!
為支持分布式事務(wù)處理,必須創(chuàng)建一個(gè)格式化的設(shè)備記錄事務(wù)信息。上文是用tmadmin命令的腳本生成此種設(shè)備的例子。
?
?
ATMI 事務(wù)API
事務(wù)API通過ATMI給應(yīng)用提供了以下操作
2?通過tpbegin(),tpcommit(),tpabort()控制事務(wù)的開始和結(jié)束。
int tpbegin(int timeout, long flags)
int tpcommit(long flags)
int tpabort(long flags)
2?通過tpsuspend(),tpresume()管理多個(gè)并發(fā)的事務(wù)。
int tpsuspend(TPTRANID *tranid, longflags)
int tpresume(TPTRANID *tranid, longflags)
2?通過tpscmt()設(shè)定提交返回方式為”logged”或”complete”
int tpscmt(long flags)
TP_CMT_LOGGED-在第一段后返回
TP_CMT_COMPLETE-在第二段后返回
2?通過tpgetlev()決定當(dāng)前事務(wù)模式
int tpgetlev(void)
2?通過tpopen(),tpclose()為服務(wù)組打開或關(guān)閉RM
int tpopen(void)
int tpclose(void)
使用ATMI事務(wù)API的代碼范例
/* 確保交易TRANSFER沒有設(shè)成AUTOTRAN? */
#include <atmi.h>
FBFR?? *sendBuf=NULL;
FBFR?? *recvBuf=NULL;
Void TRANSFER(TPSVCINFO *transb)
{
?????? sendBuf= (FBFR *)transb;
?????? …
?????? if(tpbegin(30,0) == -1)
?????? {
????????????? userlog(“FAILEDTO BEGIN TRANSACTION:%s”,tpstrerror(tperrno));
????????????? tpreturn(TPFAIL,-1, (char *)recvBuf, 0, 0);
?????? }
?????? if( tpcall(“WITHDRAWAL”, (char *)sendBuf, 0, (char **)&recvBuf, &len,0)==-1)
?????? {
????????????? userlog(“tpcall(WITHDRAWAL) fail:%s”, tpstrerror(tperrno));
????????????? tpreturn(TPFAIL,-1, (char *)recvBuf, 0, 0);
?????? }
…
if ( tpcall(“DEPOSIT”, (char *)sendBuf,0, (char **)&recvBuf, &len, 0)==-1)
?????? {
????????????? userlog(“tpcall(DEPOSIT) fail:%s”, tpstrerror(tperrno));
????????????? tpreturn(TPFAIL,-1, (char *)recvBuf, 0, 0);
?????? }
?????? if( tpcommit(0) == -1)
?????? {
????????????? userlog(“tpcommit()fail:%s”, tpstrerror(tperrno));
????????????? tpreturn(TPFAIL,-1, (char *)recvBuf, 0 ,0);
?????? }
userlog(“Transaction committedsuccessfully”);
tpreturn(TPSUCCESS, 0 , (char *)recvBuf,0 , 0);
}
本例中的TRANSFER交易使用了TUXEDO XA事務(wù)API;本例使用了TUXEDO的NULL TMS配置。當(dāng)TRANSFER被調(diào)用,首先起一個(gè)事務(wù),調(diào)用交易WITHDRAWAL,然后調(diào)用交易DEPOSIT。如果一切都運(yùn)行成功,TRANSFER調(diào)用tpcommit()結(jié)束事務(wù)。任何錯(cuò)誤都將導(dǎo)致RM回滾事務(wù)。
?
?
?
?
?
?
管理類API AdminAPI(MIB)
?
?
?
本節(jié)要點(diǎn)
l? 定義
l? 過程
l? 代碼例子
l? 錯(cuò)誤處理和管理類API域
簡介
?????? 在TUXEDO下管理應(yīng)用有很多手段,如下:
2? tmadmin
2? tmadmin的腳本
2? 調(diào)用ATMI
2? X-Windows GUI
2? JAVA applet Web GUI
2? Admin API (MIB)
每一種方法都有其優(yōu)點(diǎn)和適用場合。Admin API提供訪問TUXEDO信息的控制方法和結(jié)構(gòu)。這些信息被分類成組,稱為管理信息庫(Management Information Base—MIB)。通過Admin API可以訪問MIB。使用AdminAPI有以下優(yōu)勢:
2? 可訪問的TUXEDO系統(tǒng)信息更多
2? 管理應(yīng)用有更高的靈活度
2? 可以集成到外部系統(tǒng)工具中
?
AdminAPI(MIB)
?????? TUXEDO系統(tǒng)組成的各個(gè)部分都有自己的MIB,每部分的MIB是一組相關(guān)的類,每個(gè)類代表一個(gè)MIB可管理的實(shí)體或項(xiàng)目,有其自身的屬性、許可權(quán)限和語義。TUXEDO系統(tǒng)的MIB有5部分,如下:
2?TM_MIB
2?EVENT_MIB
2?APPQ_MIB
2?WS_MIB
2?ACL_MIB
下邊的例子是訪問TM_MIB并顯示了/T部分的管理信息庫。
?
范例
?????? AdminAPI使用了一些預(yù)定義的FML32的域,這些數(shù)據(jù)組織存放在文件$TUXEDO/udataobj/tpadm中。環(huán)境變量必須設(shè)置如下:
?????? FLDTBLDIR32=$TUXDIR/udataobj
?????? FIELDTBLS32=Usysfl32,tpadm,evt_mib
?????? ExportFLDTBLDIR32 FIELDTBLS32
使用AdminAPI的代碼范例
#include <stdio.h>
#include <fml32.h>
#include <atmi.h>
#include <tpadm.h>
main(int argc, char **argv)
{
?????? longblen;
?????? FBFR32????? *ibuf;
?????? /*tpinit() 連接TUXEDO */
?????? ibuf= (FBFR32 *)tpalloc(FMLTYPE32,NULL,0);
?????? Fchg32(ibuf,TA_OPERATION,0,”GET”,0);
?????? Fchg32(ibuf,TA_CLASS,0,”T_MACHINE”,0);
?????? printf(“Queryth T_MACHINE class before:\n”);
?????? Fprint32(ibuf);
?????? printf(“\n”);
?????? if(tpcall(“.TMIB”,(char *)ibuf,0,(char **)&ibuf,&blen,0)== -1){
????????????? printf(“tpcall(.TMIB)failed:%s\n”,tpstrerror(tperrno));
????????????? Fprint32(ibuf);
????????????? Return(-1);
?????? }
?????? printf(“Queryth T_MACHINE class after:\n”);
?????? Fprint32(ibuf);
?????? printf(“\n”);
?????? tpfree((char*)ibuf);
?????? tpterm();
?????? return(0);
}
因?yàn)锳dmin API是基于FML32類型的數(shù)據(jù),所以要包含TUXEDO系統(tǒng)頭文件“fml32.h”。
因?yàn)锳dmin API要用一些預(yù)定義的域去訪問MIB信息,如TA_OPERATION和TA_CLASS,所以要包含TUXEDO系統(tǒng)頭文件“tpadm.h”。
用tpinit()連接TUXEDO系統(tǒng)。
分配一個(gè)FML32數(shù)據(jù)緩沖。
在本例中,我們通過“GET(ing)”得到“MACHINE”的信息。
用tpcall()調(diào)用.TMIB服務(wù)。
顯示結(jié)果。
釋放FML32緩沖。
切斷連接。
本例的輸出(域名和域值)
TA_ERROR???????????? 0
TA_MORE??????????????? 0
TA_OCCURS????????? 1
TA_PERM??????????????? 438
TA_GID??????????????????????????? 302
TA_MAXACCESSERS 20
TA_MAXCONV???????????????????? 1
TA_MAXGTT?????????????????? 20
TA_MAXWSCLIENTS?? 0
TA_MINOR????????????????????? 6000
TA_RELEASE??????????????? 60
TA_SPINCOUNT?????????? 0
TA_TLOGSIZE?????????????? 100
TA_TMNETLOAD????????? 0
TA_UID?????????????????????????????????? 261
TA_MAXCLCACHE???????????? 100
TA_CLASS??????????????????????????? T_MACHINE
TA_STATE????????????????????? ACTIVE
TA_APPDIR??????????????????? /usr/apps/atmapp
TA_CMPLIMIT??????????????? MAXLONG,MAXLONG
TA_ENVFILE????????????????? /usr/apps/atmapp/ENVFILE
TA_PMID???????????????????????? lcspn1
TA_TLOGDEVICE???????? /usr/apps/atmapp/logs/TLOG
TA_TLOGNAME???????????? TLOG
TA_TUXCONFIG?????????? /usr/apps/tuxconfig
TA_TUXDIR???????????? ?????? /usr/tuxedo
TA_TYPE??????????????????????? RS6000
TA_ULOGPFX??????????????? /usr/apps/atmapp/logs/ULOG
TA_LMID???????????????????????? SITE1
?
其他Admin API域和錯(cuò)誤處理
?
?????? 除基本的域外,其他一些Admin API域在管理MIB信息時(shí)也非常有用。如:
在一個(gè)大應(yīng)用中,server節(jié)會(huì)包含很多條目,以下3個(gè)域在取得這些信息時(shí)很有用。
?
| TA_OCCURS | 在請(qǐng)求時(shí),表示需要得到信息的行數(shù)。 在返回結(jié)果后,表示成功得到信息的行數(shù)。 |
| TA_CURSOR | 表示上一次GET操作停止的位置。配合TA_OPERATION的GETNEXT屬性,可以順序遍歷MIB。 |
| TA_FILTER | 客戶端程序可以通過該域得到一個(gè)特定域信息 |
?
?????? 使用AdminAPI發(fā)生錯(cuò)誤時(shí),在回應(yīng)緩沖中會(huì)帶回來自MIB的錯(cuò)誤信息
?
| TA_ERROR | 返回一個(gè)長整形操作結(jié)果值,參見診斷信息 |
| TA_STATUS | 用文本格式描述錯(cuò)誤 |
| TA_BADFLD | 如果有一個(gè)域發(fā)生錯(cuò)誤,用一個(gè)長整形值描述出錯(cuò)的FML32域 |
?
代碼范例
/* 得到前3項(xiàng) */
long n=3;
Fchg32(sendbuf,TA_OPERATION,0,”GET”,0);
Fchg32(sendbuf,TA_CLASS,0,”T_SERVER”,0);
Fchg32(sendbuf,TA_OCCURS,0,n,0);
Fchg32(sendbuf,TA_CURSOR,0,NULL,0);
/* 打印rpbuf中返回值*/
ret = tpcall(“.MIB”,(char*)sendbuf,0,(char **)&recvbuf,&len,0);
/* 如果出錯(cuò)打印TA_ERROR和TA_STATUS*/
if ( ret == -1 && tperrno ==TPESVCFAIL){
?????? Fget32(recvbuf,TA_ERROR,0,(char*)&ta_error,NULL);
?????? Ta_status=Ffind32(recvbuf,TA_STATUS,0,NULL);
?????? Printf(“Failure:%ld,%s\n”,ta_error,ta_status);
}else
?????? Fprint32(recvbuf);
/* 從recvbuf傳遞TA_CURSOR,得到下3項(xiàng)*/
Fget(recvbuf,TA_CURSOR,0,cursor,0);
Fchg32(sendbuf,TA_OPERATION,0,”GETNEXT”,0);
Fchg32(sendbuf,TA_CURSOR,0,cursor,0);
?
tpadmcall()
?
tpadmcall(FBFR32 *inbuf, FBFR32 **outbuf,long flags)
?
用法:
?
| Unbooted App Unconfigured App | ?用戶是管理員,用于SET一個(gè)NEW T_RESOURCE類,然后定義一個(gè)初始配置給應(yīng)用 |
| Unbooted App Configured App | 在有權(quán)限的UID/GID情況下,GET并SET任何TM_MIB(5)中任何類的任何屬性。 |
| Booted App Unattached Process | 在有權(quán)限的UID/GID情況下或用戶是管理員,當(dāng)返回值不是ACTIVE時(shí),可以GET任何TM_MIB(5)中有合適權(quán)限的任何類的任何屬性。 |
| Booted App Attached Process | 權(quán)限在tpinit()時(shí)由授權(quán)key決定,可以GET任何TM_MIB(5)中有合適權(quán)限的任何類的任何屬性。 |
?
?
代碼范例:
?
#include <stdio.h>
#include <fml32.h>
#include <atmi.h>
#include <tpadm.h>
main(int argc , char **argv)
{
FBFR32????? *ibuf;
?????? /*tpinit() 連接TUXEDO */
?????? ibuf= (FBFR32 *)tpalloc(FMLTYPE32,NULL,0);
?????? Fchg32(ibuf,TA_OPERATION,0,”GET”,0);
?????? Fchg32(ibuf,TA_CLASS,0,”T_DOMAIN”,0);
?????? printf(“Queryth T_DOMAIN class before:\n”);
?????? Fprint32(ibuf);
?????? printf(“\n”);
?????? if(tpadmcall(ibuf,&ibuf,0)== -1){
????????????? printf(“tpadmcall()failed:%s\n”,tpstrerror(tperrno));
????????????? Fprint32(ibuf);
????????????? Return(-1);
?????? }
?????? printf(“Queryth T_MACHINE class after:\n”);
?????? Fprint32(ibuf);
?????? printf(“\n”);
?????? tpfree((char*)ibuf);
?????? tpterm();
?????? return(0);
}
?
?
?
?
安全??????? Security
簡介
?????? TUXEDO在其系統(tǒng)框架中集成了進(jìn)程間通訊安全功能。在商業(yè)應(yīng)用中可以由用戶決定安全級(jí)別。
?????? 本節(jié)中,我們將討論TUXEDO提供的不同的安全保障能力和應(yīng)用實(shí)現(xiàn)的必要步驟。
?
?
?
?
?
本節(jié)要點(diǎn)
l? 概念
l? 管理文件和命令
l? ubbconfig
l? API使用說明
l? 代碼范例
概念
?????? TUXEDO系統(tǒng)在第一次ATMI調(diào)用時(shí)——tpinit()就進(jìn)行安全工作。
?????? 安全級(jí)別信息先傳入tpinit(),在公告牌上進(jìn)行校驗(yàn),然后用AUTHSVR進(jìn)行二次檢查。如果驗(yàn)證通過,tpinit()允許客戶端連上TUXEDO系統(tǒng)。
?????? TUXEDOAPI tpchkauth()用來決定應(yīng)用的安全級(jí)別。下表是各安全級(jí)別認(rèn)證需要的資源。
| tpchkauth()的返回值 | 管理文件設(shè)置 | UBBCONFIG的設(shè)置 |
| TPNOAUTH | ? | ? |
| TPSYSAUTH | ? | SECURITY APP_PW |
| TPAPPAUTH | tpusr tpgrp tpacl | SECURITY USERAUTH ACL MANDATORY_ACL AUTHSVC AUTHSVC |
?
?
?
?
?
?
相關(guān)管理命令
組命令
tpgrpadd –g GID groupname
tpgrpdel groupname
tpgrpmod –g GID –n new_groupnamegroupname
入口在$APPDIR/tpgrp
用戶命令
tpusradd –u UID –g GID –c clntnameusrname
tpusrdel –c clntname
tpusrmod –u UID –g GID –c clntname –lnewlogin –n newclntname –p usrname
入口在$APPDIR/tpusr
ACL命令
tpacladd –g GID entity_name
tpacldel entity_name
tpaclmod –g GID entity_name
入口在$APPDIR/tpacl
簡要說明
?????? 以上管理命令維護(hù)AUTHSVR的安全入口。只有安全級(jí)別要求到ACL(Access Control List)時(shí),這些操作過程才是必須的。
?????? AUTHSVR對(duì)每一個(gè)用戶進(jìn)行認(rèn)證。當(dāng)客戶端進(jìn)程調(diào)用tpinit()去連接應(yīng)用時(shí),發(fā)生以下過程:
AUTHSVR校驗(yàn)用戶名,客戶端名和密碼
當(dāng)成功,AUTHSVR提供一不可偽造的應(yīng)用key
每次交易請(qǐng)求時(shí),客戶端都要提交此應(yīng)用key
?
ubbconfig有關(guān)安全的部分
*RESOURCES
AUTHSVC? “..AUTHSVC”
SECURITY “ACL”
*SERVERS
AUTHSVR? SVRGRP=”AUTHGRP”SRVID=100
???????????????????? RESTART=YMAXGEN=2 GRACE=0
???????????????????? CLOPT=”-A”
AUTHSVR提供的交易名字叫“..AUTHSVC”
SECURITY設(shè)置了安全的級(jí)別
?
客戶端代碼范例
#include “atmi.h”
int?? ConnectToTuxedo()
{
?????? FBFR?? *f;
?????? TPINIT? *tpinfo;
?????? char???????????? *passwd2=”penquin”;
?????? int?? do_auth = 0,no_auth = 0;
?????? do_auth= tpchkauth();
?????? switch(do_auth)
?????? {
?????? case????? -1:
????????????? printf(“tpchkauth()err:%s”,tpstrerrno(tperrno));
????????????? return(-1);
?????? case????? TPNOAUTH:
????????????? no_auth= 1;
????????????? break;
?????? case????? TPSYSAUTH:
????????????? tpinfo= (TPINIT *)tpalloc(“TPINIT”, NULL, 0);
????????????? if(tpinfo ==NULL)
????????????? {
???????????????????? printf(“tpchkauth()err:%s”,tpstrerrno(tperrno));
???????????????????? return(-1);
????????????? }
????????????? break;
?????? case????? TPAPPAUTH:
????????????? tpinfo= (TPINIT *)tpalloc(“TPINIT”, NULL, TPINITNEED(15));
????????????? if(tpinfo ==NULL)
????????????? {
???????????????????? printf(“tpchkauth()err:%s”,tpstrerrno(tperrno));
???????????????????? return(-1);
????????????? }
????????????? tpinfo->datalen=strlen(passwd)+1;
????????????? memcpy((char*)&tpinfo->data, passwd2, tpinfo->datalen);
????????????? break;
?????? default:
????????????? printf(“Invalidsecurity setting %d\n”,do_auth);
????????????? return(-1);
?????? }
?????? if(!no_auth)
?????? {
????????????? strcpy(tpinfo->usrname,”tuxedo”);
????????????? strcpy(tpinfo->passwd,”hello”);
????????????? strcpy(tpinfo->grpname,”“);
?????? }
?????? if((tpinit(TPINIT *)tpinfo))==-1
?????? {
????????????? printf(“Failedto join application\n”);
????????????? return(-1);
?????? }
}
tpchkauth()返回TPNOAUTH,TPSYSAUTH,TPAPPAUTH或錯(cuò)誤用以決定加密強(qiáng)度。
tpalloc()將分配一個(gè)TPINIT結(jié)構(gòu),存儲(chǔ)與公告牌對(duì)比的密碼。
Struct TPINIT {
char????? usrname[MAXTIDENT+2];
char????? cltname[MAXTIDENT+2];
char????? passwd[MAXTIDENT+2];
char????? grpname[MAXTIDENT+2];
long????? flags;
long????? datalen;
long????? data;
}
?
?????? tpalloc()還將根據(jù)TPINITNEED()分配一段空間存儲(chǔ)用戶密碼。
?????? 用tpinit()與TUXEDO連接。
?
?
?
?
事件代理?????? Event Broker
簡介
?????? 在事件代理出現(xiàn)前,所有的通訊由用戶發(fā)起。通過事件代理,TUXEDO系統(tǒng)增加了另一種進(jìn)程間通訊方式——通訊可以由事件發(fā)起。事件可以獨(dú)立于客戶端,促使其他活動(dòng)發(fā)生。
?????? 事件代理搜尋并報(bào)告一些預(yù)定義的事件,如系統(tǒng)錯(cuò)誤和用戶定義錯(cuò)誤。
?????? 在本節(jié)中,我們將研究事件監(jiān)視模塊,練習(xí)TUXEDO的’publish’和’subscribe’事件模塊的程序設(shè)計(jì)。
??????
?
本節(jié)要點(diǎn)
l? ubbconfig范例
tpsubscribe和tpunsubscribe的代碼范例
tppost的范例
概念
?????? 事件代理提供了這樣一種通訊方式:一些進(jìn)程可以發(fā)布消息給訂閱了這些消息的進(jìn)程或客戶端。例如:服務(wù)可以在價(jià)格發(fā)生變化時(shí)發(fā)布信息,所有連接系統(tǒng)的客戶端都可以收到信息。
?????? 事件代理只能執(zhí)行一些該事件預(yù)定動(dòng)作,這些動(dòng)作包括:
2? 調(diào)用交易(tpacall)
2? 將請(qǐng)求送入一個(gè)可靠隊(duì)列(tpenqueue)
2? 用戶通知之類(tpnotify)
2? 記錄日志到ULOG.mmddyy
2? 執(zhí)行系統(tǒng)調(diào)用
主要有2類事件:
2? 系統(tǒng)???????????? TUXEDO系統(tǒng)內(nèi)部活動(dòng)引起,如網(wǎng)絡(luò)故障等
2? 用戶定義???? 應(yīng)用中與業(yè)務(wù)流程有關(guān)的
觸發(fā)事件的ATMI API是tppost()。
訂閱和取消訂閱的ATMI API是tpsubscribe(),tpunsubscribe()。
?
?
Subscribing&? Unsubscribing ATMI
?
longtpsubscribe(char *eventexpr, char *filter, TPEVCTL *ctl, long flags)
?
進(jìn)行訂閱。返回訂閱句柄,-1失敗
char *eventexpr?????? 表示事件的字符串,可以含有通配符*
char *filter????????? 一個(gè)布爾表達(dá)式,決定是否收到消息。
TPEVCTL ctl???? 一個(gè)描述事件代理將進(jìn)行的動(dòng)作
flags?????????????????? 可以是[TPNOTIME|TPSIGRSTRT|TPNOBLOCK]
?
inttpunsubscribe(long subscription, long flags)
?
取消訂閱
long eventexpr tpsubscribe()返回的句柄
flags?????????????????? 可以是[TPNOTIME|TPSIGRSTRT|TPNOBLOCK]
?
struct TPEVCTL
?
?{
?????? longflags;
?????? charname1[32];
?????? charname2[32];
?????? TPQCTLqctl;
}
調(diào)用另一個(gè)交易
ctl->flags=TPEVSERVICE;
strcpy(ctl->name1,”SERVICENAME”);
進(jìn)入隊(duì)列
ctl->flags=TPEVQUEUE;
strcpy(ctl->name1,”QSPACENAME”);
strcpy(ctl->name2,”QUEUENAME”);
ctl->qctl.flags=TPQREPLYQ;
strcpy(ctl->qctl.replyqueue,”RPLYQ”);
通知
ctl=(struct TPEVCTL *)NULL;
int tppost(char *eventname, char *data,long len, long flags)
tpsubscribe()和tpunsubscribe()的范例代碼
#include <atmi.h>
static long sub_serv;
int tpsvrinit(int argc, char **argv)
{
?????? TPEVCTLevctl;
?????? /*連接TUXEDO系統(tǒng)——tpinit() */
?????? evctl.flags=TPEVSERVICE;
?????? strcpy(evctl.name1,”BANK_MANAGER”);
?????? sub_serv=tpsubscribe(“BANK_TLR_WITHDRAWAL”,
”AMOUNT>300.00”,&evctl,TPSIGRSTRT);
?????? if(sub_serv == -1)
return(-1);
}
int tpsvrdone()
{
?????? if(tpunsubscribe(sub_serv,TPSIGRSTRT)== -1)
?????? {
????????????? printf(“Errorunsubscribing to service event\n”);
?????? }
}
建立一個(gè)服務(wù)調(diào)用訂閱事件,被調(diào)用服務(wù)是BANK_MANAGER,當(dāng)交易BANK_TLR_WITHDRAWAL的AMOUNT域的值大于300.00觸發(fā)。
?????? 用tpunsubscribe()取消訂閱。
?
tppost()的范例代碼
?
void WITHDRAWAL(TPSVCINFO *transb)
{
……
?????? if(amt > 300.00)
?????? {
????????????? if( (Fchg(transf,EVENT_NAME,0,”BANK_TLR_WITHDRAWAL”,0)<0) ||
(Fchg(transf,EVENT_NAME,0,gettime(),0)<0)||
(Fchg(transf,EVENT_NAME,0,(char*)&amt,0)<0) ))
????????????? {
???????????????????? sprintf(emsg,”Fchg(eventflds) failed :%s”,Fstrerror(Ferror));
????????????? }elseif( tppost(“BANK_TLR_WITHDRAWAL”,(char *)transf,0L,
TPNOTRAN|TPSIGRSTRT)<0)
????????????? {
???????????????????? if(tperrno!=TPENOENT)
???????????????????? {
??????????????????????????? sprintf(emsg,”tppost()failed :%s”,tpstrerror(tperrno));
???????????????????? }
????????????? }
????????????? if( strcmp(emsg,””)!=0)
????????????? {
???????????????????? userlog(“WARN:EventBANK_TLR_WITHDRAWAL not posted:%s”
,emsg);
???????????????????? strcpy(emsg,””);
????????????? }
?????? }
}
從傳入FML中分離交易金額;增加交易過濾規(guī)則:金額>300.00,給FML域賦值;調(diào)用tppost()。
?
?
?
?
?
?
?
?
Ubbconfig相應(yīng)改變
*SERVERS
TMSYSEVT????????????? SRVGRP=EVTGRP1??? SRVID=100
??????????????????????????? RESTART=YMAXGEN=5 GRACE=3600
??????????????????????????? CLOPT=”-A?-- -f tmsysevt.dat”
TMUSREVT????? SRVGRP=EVTGRP1??? SRVID=150
??????????????????????????? RESTART=YMAXGEN=5 GRACE=3600
??????????????????????????? CLOPT=”-A? -- -f tmusrevt.dat”
?
TMUSREVT????? SRVGRP=EVTGRP1??? SRVID=200
??????????????????????????? RESTART=YMAXGEN=5 GRACE=3600
??????????????????????????? CLOPT=”-A? -- -S –p 120”
TMSYSEVT????????????? 系統(tǒng)事件代理服務(wù)進(jìn)程
TMUSREVT????? 用戶事件代理服務(wù)進(jìn)程
-f???? 指定了包含訂閱信息的數(shù)據(jù)文件
-S?? 表示有第二事件代理,-p決定其輪循時(shí)間(單位:秒)
?
?
消息隊(duì)列??? Queued Message
?
本節(jié)要點(diǎn)
l? 定義
l? 基本隊(duì)列
l? 隊(duì)列設(shè)定—qmadmin
l? 高級(jí)隊(duì)列
l? 交易和管道
l? ubbconfig
l? 代碼范例
?
可靠隊(duì)列
?????? 當(dāng)進(jìn)程通過消息方式進(jìn)行通訊時(shí),消息在被取用前存儲(chǔ)的地方稱為消息隊(duì)列。這些隊(duì)列是一些存儲(chǔ)空間,或者是內(nèi)存(IPC消息隊(duì)列),或在硬盤上。內(nèi)存中的隊(duì)列在寫硬盤前可以清除;這樣,在主機(jī)故障時(shí),就有丟失信息的風(fēng)險(xiǎn)。基于硬盤的隊(duì)列可以在主機(jī)或網(wǎng)絡(luò)癱瘓時(shí)可靠地保存信息,代價(jià)是讀寫硬盤的開銷。
?????? 商業(yè)上用隊(duì)列方式使任務(wù)可以同步完成。一般地,商業(yè)系統(tǒng)需要保證系統(tǒng)總是穩(wěn)定可靠,良好地完成任務(wù)。傳統(tǒng)上是使用昂貴的容錯(cuò)系統(tǒng)達(dá)到此目標(biāo),花費(fèi)主要是在冗于硬件上,使用隊(duì)列,往往只要復(fù)制部分系統(tǒng)就能達(dá)到此效果。
?
?
?
?
?
概念
?????? 作為請(qǐng)求/應(yīng)答通訊方式的一種替代,可靠隊(duì)列允許商業(yè)應(yīng)用通過同步或時(shí)序方式使用可靠存儲(chǔ)隊(duì)列進(jìn)行通訊。BEA TUXEDO /Q提供了這種機(jī)制。
?????? 其特性提供優(yōu)點(diǎn)如下:
2?可靠傳遞
2?同步的、自由處理
2?審計(jì)、恢復(fù)
/Q ATMI通過按照2段式XA事務(wù)協(xié)議操作,保證可靠的傳輸,并且有內(nèi)建的錯(cuò)誤處理能力處理意外情況。
?
?
基本隊(duì)列
?????? /Q提供的API簡單而功能強(qiáng)大,有以下兩個(gè)函數(shù):
2?tpenqueue() – 將消息置入隊(duì)列
2?tpdequeue() – 從隊(duì)列中得到消息
?????? 隊(duì)列由BEATUXEDO管理員創(chuàng)建,定義隊(duì)列并指定大小。隊(duì)列全部位于隊(duì)列空間,隊(duì)列空間的名字是函數(shù)參數(shù)之一。每個(gè)隊(duì)列都有一個(gè)名字,函數(shù)通過名字調(diào)用隊(duì)列。
tpenqueue()參數(shù)如下:
2?隊(duì)列空間名
2?隊(duì)列名
2?包含置入隊(duì)列信息的結(jié)構(gòu)
2?置入隊(duì)列的數(shù)據(jù)緩沖
2?長度
2?控制標(biāo)志
tpenqueue(qspace,qname,control_info,buffer,len,flags)
tpdequeue()參數(shù)如下:
2?隊(duì)列空間名
2?隊(duì)列名
2?包含取隊(duì)列信息的結(jié)構(gòu)
2?取隊(duì)列的數(shù)據(jù)緩沖
2?長度
2?控制標(biāo)志
tpdequeue(qspace,qname,control_info,buffer,len,flags)
?
?
qmadmin范例
?????? qmadmin是一個(gè)命令行工具,TUXEDO /Q的一個(gè)部分,使管理員可以建立基于硬盤的的隊(duì)列;qmadmin用于在設(shè)備上建立、初始化、列出和刪除隊(duì)列和隊(duì)列空間。
$qmadmin
QMCONFIG=/usr/apps/atmapp/QUE
>crdl /usr/apps/atmapp/QUE
Starting Offset :0
Size in disk pages:400
Created decice/usr/apps/atmapp/QUE,offset 0,size 400
>qspacecreate
Queue space name:QSPACE
IPC Key for queue space:62639
Size of queue space in disk space:100
Number of queues in queue space:6
Number of concurrent transaction in queuespace:4
Number of concurrent processes in queuespace:9
Number of messages in queue space:3
Error queue name:errque
Initialize exter\nts(y,n[default=n]):y
Blocking factor[default=16]:16
>qopen QSPACE
>qcreate
Queue name:DEPOSIT
Queue order(priority,time,fifo,lifo):fifo
Out-of-ordering enqueuing(top,msgid):none
Retries[default=0]:2
Retry dela in seconds[default=0]:30
High limit for queue capacity warning:80%
Reset(low)limit for queue capacitywarning:0%
Queue capacity command:
No default queue capacity command
Queue ‘DEPOSIT’ created
>qcreate
Queue name:REPLYQ
Queue order(priority,time,fifo,lifo):fifo
Out-of-ordering enqueuing(top,msgid):none
Retries[default=0]:2
Retry dela in seconds[default=0]:30
High limit for queue capacity warning:80%
Reset(low)limit for queue capacitywarning:0%
Queue capacity command:
No default queue capacity command
Queue ‘REPLYQ’ created
說明:
用crdl命令在/usr/apps/atmapp/QUE上建立一個(gè)400頁的設(shè)備
用qspacecreate命令在設(shè)備上建立一個(gè)100頁的隊(duì)列空間QSPACE,有6個(gè)隊(duì)列。
用qopen命令打開隊(duì)列空間QSPACE。
用qcreate命令在隊(duì)列空間QSPACE上建立隊(duì)列DEPOSIT,FIFO方式,消息可以取出2次。同樣建立隊(duì)列REPLYQ。
?
?
高級(jí)隊(duì)列
?????? 每個(gè)隊(duì)列都有與之相關(guān)的一些控制信息;其中絕大多數(shù)內(nèi)容由應(yīng)用設(shè)定,但是有些由BEA TUXEDO隊(duì)列軟件直接設(shè)定。
隊(duì)列次序
?????? 缺省的,消息進(jìn)出隊(duì)列的次序由管理員確定,一般是先入先出(FIFO-first in first out);但有時(shí)消息不需要立即處理,這樣就需要其他的隊(duì)列次序。BEA TUXEDO提供了幾種方案解決之,有:
2? 按優(yōu)先級(jí)
2? 按時(shí)序
2? 先進(jìn)先出
2? 后進(jìn)先出
管理員甚至可以合并使用上述幾種方式?jīng)Q定隊(duì)列次序。
按時(shí)釋放
?????? 當(dāng)一個(gè)消息進(jìn)隊(duì)列時(shí),程序員可以決定其在某時(shí)間前不可出隊(duì)列。這個(gè)時(shí)間可以是一個(gè)定值(如:1月7號(hào)下午2點(diǎn))或相對(duì)于入隊(duì)列的時(shí)間。當(dāng)程序試圖出隊(duì)列時(shí),那些‘還沒到時(shí)間’的消息是不可見的。例:
control_info->deq_time=3600;/* 3600秒后才可以出隊(duì)列*/
control_info->flags=TPQTIME_REL;/* 表示相對(duì)時(shí)間值被設(shè)定*/
TPQCTL結(jié)構(gòu)
TPQCTL結(jié)構(gòu)用來控制一個(gè)消息如何進(jìn)/出隊(duì)列
struct tpqctl{
?????? long??? flags;
?????? long????? deq_time;
?????? long????? priority;
?????? long??? diagnostic;
?????? char????? msgid[TMMSGIDLEN];
?????? char????? corrid[TMCORRIDLEN];
?????? char????? replyqueue[TMQNAMELEN+1];
?????? char????? failurequeue[TMQNAMELEN+1];
?????? CLENTID??? cltid;
?????? long????? urcode;
?????? long????? appkey;
};
tpenqueue的flags有如下可能:
TPNOFLAGS,TPQPRIORITY,TPQCORRID,[TPQTOP|TPQBEFOREMSGID],[TPQTIME_ABS|TPQTIME_REL], TPQREPLYQ,TPQFAILUREQ
tpdequeue的flags有如下可能:
TPNOFLAGS,TPQWAIT,[TPQGETBYMSGID|TPQGETBYCORID]
本節(jié)中有定義:
typedef struct tpqctl TPQCTL;
優(yōu)先級(jí)
?????? 一條消息可以被設(shè)置一個(gè)優(yōu)先級(jí);優(yōu)先級(jí)決定消息相對(duì)于隊(duì)列中其他消息的位置。高優(yōu)先級(jí)的消息較靠近隊(duì)列頭,可以較早出隊(duì)列。例:
control_info->priority=100;? /*設(shè)入隊(duì)列優(yōu)先級(jí)為最高級(jí)*/
control_info->flags=TPQPRIORITY;????? /* 表示優(yōu)先級(jí)的值已經(jīng)設(shè)定*/
返回和錯(cuò)誤隊(duì)列
?????? 在將消息入隊(duì)列前,程序可以定義兩個(gè)隊(duì)列:返回隊(duì)列和錯(cuò)誤隊(duì)列。當(dāng)消息出隊(duì)列時(shí),這些隊(duì)列中存有原消息的處理結(jié)果:返回或錯(cuò)誤消息。
相關(guān)標(biāo)識(shí)
?????? 應(yīng)用可以在消息上加一個(gè)‘標(biāo)記’,當(dāng)消息被從一個(gè)隊(duì)列移動(dòng)到另一個(gè)隊(duì)列并被應(yīng)用的不同部分處理時(shí)可以識(shí)別它。這些標(biāo)記被稱為‘相關(guān)標(biāo)識(shí)’。
超次序
?????? 雖然隊(duì)列被定義了一個(gè)固定的出/入次序,但有時(shí)應(yīng)用需要超越這個(gè)次序。BEA TUXEDO的隊(duì)列工具允許管理員配置程序入隊(duì)列時(shí)可以超越次序的隊(duì)列。
2?可以將一條消息置于隊(duì)列頭
2?可以將一條消息置于特定消息前
錯(cuò)誤診斷
如果tperrno被設(shè)成TPEDIAGNOSTIC,則TPQCTL結(jié)構(gòu)中的診斷域?qū)⒈辉O(shè)成一個(gè)錯(cuò)誤狀態(tài),有以下:
2?QMEINVAL????????????? 調(diào)用時(shí)使用了非法標(biāo)志值
2?QMEDADMSGID??? 非法錯(cuò)誤消息ID
2?QMENOMSG??? 隊(duì)列沒有可以取出的消息
2?QMEINUSE????????????? 隊(duì)列中有消息,但現(xiàn)在不可用
?
事務(wù)和管道
事務(wù)
?????? 事務(wù)是一種保證一系列操作全部成功或全部失敗的機(jī)制;通常用來保證對(duì)數(shù)據(jù)庫的多次操作全部完成。
?????? BEATUXEDO可以協(xié)調(diào)本隊(duì)列修改、其他隊(duì)列修改和數(shù)據(jù)庫系統(tǒng)操作。當(dāng)程序調(diào)用tpdequeue()將一條消息出隊(duì)列時(shí),事實(shí)上消息僅在程序事務(wù)確認(rèn)時(shí)才從隊(duì)列中除去。如果事務(wù)回滾或超時(shí),消息仍在隊(duì)列中;可以再次操作。系統(tǒng)從而有效地保障該消息僅被處理一次。
?????? TMQUEUE是一個(gè)BEATUXEDO系統(tǒng)提供的當(dāng)程序調(diào)用tpenqueue()和tpenqueue()時(shí)將消息入、出隊(duì)列的服務(wù)。tpenqueue()和tpenqueue()的第一個(gè)參數(shù)是隊(duì)列空間名;該名字必須由TMQUEUE的一個(gè)交易發(fā)布過。
管道
?????? TMQFORWARD是BEATUXEDO提供的將消息通過調(diào)用tpenqueue()將消息前轉(zhuǎn)的服務(wù)。
?????? 消息將被發(fā)送到一個(gè)有與讀出隊(duì)列名匹配的交易的服務(wù)。消息將在一個(gè)事務(wù)中出隊(duì)列并送給服務(wù)。如果交易失敗,事務(wù)回滾、消息將被送回隊(duì)列,可以重試的次數(shù)決定于隊(duì)列配置;如果達(dá)到了限制次數(shù),消息將送入隊(duì)列空間的錯(cuò)誤隊(duì)列。
ubbconfig的相應(yīng)改變
*GROUPS
QUE1?? LMID=SITE1???? GRPNO=2
????????????? TMSNAME=TMS_QM?? TMSCOUNT=2
????????????? OPENINFO=”TUXEDO/QM:/apps/atmapp/QUE:QSPACE”
*SERVERS
TMQUEUE??????? SRVGRP=QUE1???? SRVID=1
????????????? CLOPT=”-sQSPACE:TMQUEUE –“
TMQFORWARD????? SRVGRP=QUE1???? SRVID=5
????????????? CLOPT=”---I 2 –q DEPOSIT”
說明:
?????? 每個(gè)隊(duì)列空間需要單獨(dú)創(chuàng)建一個(gè)組,本例中為QUE1。TMSNAME是事務(wù)管理服務(wù)的名字。TMCOUNT決定最少啟動(dòng)幾個(gè)TMS_QM服務(wù)。
?????? TMQUEUE是處理tpenqueue()將請(qǐng)求置入隊(duì)列的/Q服務(wù)。TMQFORWARD是將請(qǐng)求出隊(duì)列并通過tpcall()將請(qǐng)求送相應(yīng)的交易。-i決定再次讀隊(duì)列前應(yīng)該延遲的秒數(shù)。-q決定前轉(zhuǎn)請(qǐng)求的來源隊(duì)列。
客戶端代碼范例
#include <stdio.h>
#include <atmi.h>
main()
{
?????? char *reqstr;
?????? long len;
?????? TPQCTL qctl;
?????? /* 用tpinit()連接TUXEDO*/
?????? qctl.flags = TPQREPLYQ;
?????? strcpy(qctl.rplyqueue,”RPLYQ”);
?????? if (tpenqueue(“QSPACE”,”TOUPPER”,&qctl,reqstr,0,0)== -1)
{
????????????? printf(“tpenqueue(TOUPPER):%s\n”,tpstrerror(tperrno));
?????? if(tperror ==TPEDIAGNOSTIC)
{
????????????? printf(“Queuemanager diagnostic %ld\n”,qctl.diagnostic);
}
?????? tpfree(reqstr);
?????? tpterm();
?????? exit (-1);
}
?????? sleep(10);
?????? qctl.flags = TPQWAIT;
?????? if(tpdequeue(“QSACE”,?“REPLYQ”,&qctl,&reqstr,&len,TPNOTIME) == -1)
{
????????????? printf(“tpdequeue(REPLYQ):%s\n”, tpstrerror(tperrno));
?????? if (tperrno ==TPEDIAGNOSTIC)
{
????????????? printf(“Queuemanager diagnotic %ld\n”, qctl.diagnostic);
}
?????? tpfree(reqstr);
?????? tpterm();
?????? exit(-1);
}
?????? printf(“after:%s\n”,reqstr);
?????? tpfree(reqstr);
?????? tpterm();
?????? return (0);
}
會(huì)話 Conversations
?
本節(jié)要點(diǎn)
l? 簡介
l? 定義
l? ATMI
l? UBBconfig
簡介
?????? 作為對(duì)呼叫/應(yīng)答方式的補(bǔ)充,TUXEDO提供了一種稱為會(huì)話的通訊方式。該方式用于客戶端和服務(wù)端需要進(jìn)行大量、多次數(shù)據(jù)傳輸并保持連接時(shí)。在一個(gè)會(huì)話過程中雙方會(huì)有多次發(fā)送和接收。例如,一對(duì)客戶端/服務(wù)端之間傳誦一個(gè)大的數(shù)據(jù)庫查詢結(jié)果游標(biāo)時(shí),需要進(jìn)行幾次傳輸。
?????? 在呼叫/應(yīng)答方式中,所有的數(shù)據(jù)必須在一次通訊中傳遞,不保留任何中間狀態(tài)信息。在會(huì)話模式中,通訊雙方使用了一種“半雙工”協(xié)議。一個(gè)進(jìn)程只能處于發(fā)送數(shù)據(jù)或接收數(shù)據(jù)狀態(tài)之一。該通訊協(xié)議中,狀態(tài)信息與數(shù)據(jù)一同傳送。
?????? 會(huì)話被用來傳送大量數(shù)據(jù),如:
2? 報(bào)表
2? 數(shù)據(jù)/圖形文件傳輸
2? 大型數(shù)據(jù)庫查詢
此模式必須進(jìn)行另外的ATMI編程才能實(shí)現(xiàn)。以下函數(shù)協(xié)助實(shí)現(xiàn)此種連接:
2?tpconnect() 建立連接
2?tpsend() 發(fā)送信息
2?tprecv() 接收信息
2?discon() 撤消連接(出錯(cuò)時(shí))
在會(huì)話持續(xù)期間,客戶端被綁定在服務(wù)上。不利之處是服務(wù)在會(huì)話期間不能響應(yīng)其他請(qǐng)求。
?
ATMI
int tpconnect (char *svc, char *data,long len, long flag)
int tpsend( int cd, char *data, long len,long flag, long *revent)
int tprecev(int cd, char *data, long len,long flag, long *revent)
int tpdiscon(int cd )
?
?
?
?
?
范例
ubbconfig應(yīng)作的改動(dòng)
*RESOURCES MAXCONV??????? 域內(nèi)缺省最大會(huì)話數(shù)
MACHINES?????? MAXCONV??????? 本機(jī)器上最大會(huì)話數(shù),可以超越*RESOURCES節(jié)定義的域內(nèi)缺省最大會(huì)話數(shù)
*SERVERS????????????? CONV=Y?????????? 定義該服務(wù)是一個(gè)會(huì)話方式的服務(wù)。
ubbconfig的例子
*RESOURCES
?MAXCONV????? 20
*MACHINES
?lcspn1????????????? TUXDIR=”/usr/tuxedo”
???????????????????? MAXCONV=25
*SERVERS
?audit????????? SRVGRP=BANKB1????? SRVID=1
???????????????????? CONV=Y
???????????????????? CLOPT=”-A”
會(huì)話方式的客戶端源程序
main(int argc, char *argv[])
{
int?? ret,cd;?? /* 循環(huán)計(jì)數(shù)器 */
char *buf;??? /* 數(shù)據(jù)指針 */
long len;??????????? /*長度 */
long revent;?????? /* tpsend 失敗的事件方式 */
?
/* 連接TUXEDO – tpinit() */
if ( buf = (char*)tpalloc(“STRING”,NULL,1024)==NULL)
{
printf(“tpaclloc():%s\n”,tpstrerror(tperrno));
tpterm();
exit(-1);
}
if ( cd =tpconnect(“AUDIT”,NULL,0,TPSENDONLY)==-1)
{
?????? printf(“tpconnect():%s”,tpstrerror(tperrno));
?????? tpfree(buf);
?????? tpterm();
?????? exit(-1);
}
strcpy(buf, “humpty dumpty”);
if (tpsend(cd , buf ,(long)strlen(buf), 0, &revent) == -1)
{
?????? printf(“tpconnect():%s”,tpstrerror(tperrno));
}
strcpy(buf,“mickey mouse”);
if(tpsend(cd , buf ,(long)strlen(buf), 0 , &revent) == -1)
…
if(tpsend(cd , NULL , 0, TPRECVONLY , &revent) == -1)
…
if( tprecv(cd, &buf , &len, 0, &revent) == -1 )
…
tpfree(buf);
tpterm();
}
連接TUXEDO域;
分配一個(gè)1K的ATMI緩沖;
使用tpconnect()連接名為’AUDIT’的一個(gè)會(huì)話交易;
客戶端通過TPSENDONLY將通訊控制權(quán)交給服務(wù)端。此時(shí)無數(shù)據(jù)傳送。返回的通訊描述符存儲(chǔ)于cd,用來跟蹤綁定在會(huì)話上的唯一服務(wù)過程;
數(shù)據(jù)首先被復(fù)制到ATMI緩沖中;
數(shù)據(jù)被發(fā)送到會(huì)話服務(wù)上;
第二部分?jǐn)?shù)據(jù)被復(fù)制到ATMI緩沖中;
用tpsend()發(fā)送到會(huì)話服務(wù)上;
客戶端用TPRECVONLY標(biāo)志放棄控制權(quán)。此處調(diào)用tpsend()沒有發(fā)送數(shù)據(jù),客戶端準(zhǔn)備接收數(shù)據(jù);
客戶端用tprecv()接收數(shù)據(jù)。
會(huì)話方式的服務(wù)端源程序
voidCONV(TPSVCINFO *rqst)
{
?????? static???? state= SRECV;
?????? long???????????? len,revent;
?????? for ( ; ;)
?????? {
????????????? switch(state)
????????????? {
????????????? case???????????? SRECV:
???????????????????? if ( tprecv(rqst->cd,&buf, &len, 0, &revent ) == -1)
???????????????????? {
??????????????????????????? if ( tperrno == TPEEVENT&& revent == TPEV_SENDONLY)
??????????????????????????? {
?????????????????????????????????? userlog(“statechange from receive to send”);
?????????????????????????????????? state =SSEND;
??????????????????????????? }else
??????????????????????????? {
?????????????????????????????????? tpreturn(TPFAIL,0, rqst->data, 0, 0 );
??????????????????????????? }
???????????????????? }
???????????????????? break;
????????????? case???????????? SSEND:
???????????????????? strcpy(buf, “all done &protocol complete”);
???????????????????? if ( tpsend(rqst->cd,buf, 0, 0, &revent)==-1)
???????????????????? {
??????????????????????????? userlog(“tpsend(%d):%s”,revent,tpstrerror(tperrno));
???????????????????? }else
???????????????????? {
??????????????????????????? userlog(“SENDMESSAGE”);
???????????????????? }
???????????????????? state = SDONE;
???????????????????? break;
????????????? case???????????? SDONE:
???????????????????? tpfree(buf);
???????????????????? tpreturn(TPSUCCESS, 0,rqst->data, 0, 0);
???????????????????? break;
????????????????????
????????????????????
????????????? }
?????? }
}
#define?????? SRECV????????????? 1
#define?????? SSEND????????????? 2
#define?????? SDONE????????????? 3
以上宏定義在程序中用到;
當(dāng)客戶端剛連接交易時(shí),狀態(tài)被設(shè)為RECEIVE;
此部分代碼是會(huì)話交易在RECEIVE狀態(tài)中;
tprecv()用來接收客戶端數(shù)據(jù);
協(xié)議在以下情況把狀態(tài)由RECEIVE轉(zhuǎn)成SEND:
tprecv()返回-1
tperrno被設(shè)成TPEEVNT
revent被設(shè)成TPEV_SENDONLY
在狀態(tài)變成SEND后,服務(wù)可以調(diào)用tpsend();
如果協(xié)議有“部分”失敗,服務(wù)切斷客戶端連接去處理錯(cuò)誤;
代碼將會(huì)話交易狀態(tài)轉(zhuǎn)成SEND;
使用tpsend()發(fā)送數(shù)據(jù);
在一次數(shù)據(jù)傳送后,服務(wù)狀態(tài)被設(shè)成DONE;
注意tpreturn用來結(jié)束一個(gè)成功的會(huì)話;tpdiscon()用于出錯(cuò)時(shí)結(jié)束會(huì)話。
廣播通知Unsolicited Notification
?
本節(jié)要點(diǎn)
l? 定義
l? ATMI
簡介
?????? 一般情況下,客戶端發(fā)起并控制通訊。TUXEDO額外提供了一種允許客戶端接收消息的通訊方式。該通訊方式的發(fā)起方可以是其他客戶端或服務(wù)。我們稱之為廣播通知。
?????? 有兩種方式的廣播通知:目標(biāo)是一個(gè)客戶端(通知);目標(biāo)是多個(gè)客戶端(廣播)。
?????? 為接收此種非主動(dòng)請(qǐng)求信息,客戶端必須指定處理此種信息的回應(yīng)函數(shù)。客戶端通常使用信號(hào)傳遞處理信息。而不使用此種方式的客戶端可以通過tpchkunsol(),或DIPIN方法處理此種信息。當(dāng)任何TUXEDO ATMIAPI 被調(diào)用時(shí),DIPIN被定義成此類信息的檢查標(biāo)志。
?????? 管理員使在系統(tǒng)出錯(cuò)時(shí)用此類信息通知客戶端。此外,該類信息還有其他許多用途。
ATMI
int tpbroadcast(char *lmid, char*usrname, char *cltname, char *data, long length, long flags)
int tpnotify( CLTID *clentid, char *data,long length, long flags)
int tpchkunsol()
void *tpsetunsol( void (* disp) (char*data, long len, long flags)))()
?
范例
ubbconfig中的相應(yīng)信息
*RESOURCES NOTIFY?????? DIPIN
TUXEDO 將用DIPIN方法與客戶端進(jìn)行廣播通知方式的通訊。
客戶端使用廣播通知方式通訊的源代碼
#include <atmi.h>
void main()
{
/*作為一個(gè)柜員客戶端連接TUXEDO——tpinit()*/
if ( tpsetunsol(unsolfunc)==TPUNSOLERR)
{
?????? printf(“tpsetunsol():%s\n”,tpstrerror(tperrno));
}
…
tpchkunsol();/*在一個(gè)輪循中*/
…
tpterm();
}
void unsolfunc(char *data,long len,longflag)
{
?????? printf(“Unsolicitedmessage is %s”,data);
?????? return;
}
客戶端連接TUXEDO域;
客戶端登記回應(yīng)函數(shù),unsolfunc,當(dāng)收到廣播通知的信息時(shí)觸發(fā);
客戶用tpchkunsol()端輪循處理信息;
接下來是回應(yīng)函數(shù)的定義;
在本例中,廣播通知的信息是一個(gè)字符串,客戶端將其打印出來。
?
服務(wù)端廣播通知消息的源代碼
void UNSOL(TPSVCINFO *incoming)
{
?????? char*data;
?????? if(data = (char *)tpalloc(“STRING”,NULL,1024)==NULL)
?????? {
????????????? userlog(“Errorallocating buffer”);
?????? }
?????? strcpy(data,”Thisdata will be sent to clents”);
?????? if(tpnotify(&incoming->cltid,data,0,0) == -1)
?????? {
????????????? userlog(“tpnotify():%s”,tpstrerror(tperrno));
?????? }
?????? if(tpbroadcast(“SITE1”,NULL,”TELLER”,0,0)==-1)
?????? {
????????????? userlog(“tpbroadcast():%s”,tpstrerror(tperrno));
?????? }
?????? tpreturn(TPSUCCESS,0,incoming->data,0, 0);
}
廣播通知信息必須使用ATMI緩沖,所以,先分配一個(gè)ATMI緩沖。
用tpnotify()發(fā)送消息給請(qǐng)求了UNSOL交易的客戶端。
服務(wù)使用tpbroadcast()將同一消息發(fā)送到SITE1上所有以TELLER登錄的用戶。
?
?
?
?
?
?工作站的客戶端workstation Client
簡介
BEA TUXEDO 的/WS部分實(shí)際上是工作站擴(kuò)展件。此前,所有的客戶端平臺(tái)都是運(yùn)行著TUXEDO系統(tǒng)的UNIX,這就限制了TUXEDO的客戶端只能運(yùn)行于UNIX平臺(tái)。在今天是不可思議的。
?????? /WS通過以下幾點(diǎn)突破了以上限制:
2?允許遠(yuǎn)端不需公告牌即可運(yùn)行
2?不需要TUXEDO系統(tǒng)域資源
2?不限制客戶端的平臺(tái)
2?服務(wù)器上無進(jìn)程對(duì)客戶端的一對(duì)一的限制
突破這些限制后,服務(wù)器不再考慮客戶端的表示,不必管理大量的客戶端進(jìn)程而專注于TUXEDO和應(yīng)用服務(wù),大大擴(kuò)展了系統(tǒng)的可伸縮性。
本節(jié)中,我們開始研究/WS應(yīng)用。
?
?本節(jié)要點(diǎn)
l? 定義
l? 過程
l? 改變ubbconfig
l? 網(wǎng)絡(luò)阻塞
l? buildclient
概念
?????? 遠(yuǎn)程/WS客戶端(WSC)可以是UNIX或WINDOWS客戶端。所有的客戶端與TUXEDO通過工作站監(jiān)聽進(jìn)程(WSL-Workstation Listener)和工作站處理進(jìn)程(WSH-WorkstationHandler)進(jìn)行通訊。
?????? 當(dāng)客戶端進(jìn)行tpinit()或tpchkauth()調(diào)用時(shí),進(jìn)程讀取本地環(huán)境變量WSNADDR。該變量應(yīng)該與監(jiān)聽連接請(qǐng)求的WSL進(jìn)程的地址相符。地址值設(shè)定在WSL可執(zhí)行服務(wù)的CLOPT的參數(shù)中。
?????? WSL進(jìn)程處理請(qǐng)求,將WSC的網(wǎng)絡(luò)地址通知WSH進(jìn)程。WSH進(jìn)程處理WSC與TUXEDO系統(tǒng)的進(jìn)一步通訊。
?????? WSH將請(qǐng)求發(fā)給合適的服務(wù)并將結(jié)果返回WSC。如果交易在遠(yuǎn)程機(jī)器上,WSH將請(qǐng)求發(fā)給BRIDGE,由它將請(qǐng)求前轉(zhuǎn)到合適的節(jié)點(diǎn)。
??????
??????
?
ubbconfig的相應(yīng)變化
*RESOURCES
?NOTIFY ?? DIPIN
*MACHINES
?SITE1
?????? …
?????? MAXWSCLIENTS=150
?????? …
?SITE2
?????? …
?????? MAXWSCLIENTS=0
*SERVERS
?WSL SRVGRP=”BANKB1” SRVID=500 RESTART=Y
?????? CLOPT=”-A–
??????????????????????????? -n//lcspn1:3060
??????????????????????????? -d/dev/xti/tcp
??????????????????????????? -m2 –M 7 –x 5 –I 5 –T 60”
通知客戶端的方式設(shè)為“DIPIN”,使用Windows的消息仿UNIX信號(hào),若消息為WM_TIMER則對(duì)應(yīng)tpchkunsol()。
MAXWSCLIENTS表示該機(jī)最多允許連接的工作站數(shù)目。
工作站監(jiān)聽進(jìn)程啟動(dòng)參數(shù)如下:
-n?? 指定交易請(qǐng)求連接TUXEDO應(yīng)用環(huán)境的監(jiān)聽進(jìn)程的主機(jī)名和端口號(hào)。格式如下:
?????? //lcspn1????????????? 主機(jī)名
?????? :???????????????? 間隔符
?????? 3060??????????? 端口號(hào)
-d??? WSL和WSH用于傳遞ATMI數(shù)據(jù)的的設(shè)備
-m tmboot最少啟動(dòng)的WSH進(jìn)程數(shù)
-M?? tmboot最多啟動(dòng)的WSH進(jìn)程數(shù)
-x??? 每個(gè)WSH支持的工作站數(shù)
-I???? 工作站連接應(yīng)用許可的最大耗時(shí)
-T??? 無響應(yīng)連接許可時(shí)間
?
?
PC上的環(huán)境變量設(shè)置
set TUXDIR=C:\TUXEDO
set WSNADDR=//lcspn1:3060
set WSDEVICE=/dev/xti/tcp
set WSENVFILE= C:\ENV4WS
set WSTYPE=DIFF
set TMPDIR= C:\tmp
set WSRPLYMAX=64K
set APP_PW=HOMERUN
注意:WSNADDR可以是一些由逗號(hào)隔開的使用相同端口的地址,或由豎線隔開自由選擇端口。例:
WSNADDR=//lcspn1:3050,//lcspn2:3050??
WSNADDR=(//lcspn1:3050|//lcspn2:3050)
?
TUXDIR??????????????????? TUXEDO系統(tǒng)軟件位置
WSNADDR???????????????????? WSL網(wǎng)絡(luò)地址
WSDEVICE??????????????????? 網(wǎng)絡(luò)設(shè)備
WSENVFILE??????????? 環(huán)境變量文件
WSTYPE????????????????? 機(jī)器類型,控制編、解碼
TMPDIR??????????????????? 存儲(chǔ)返回的目錄
WSRPLYMAX???????? 應(yīng)用返回緩沖內(nèi)存大小
APP_PW????????????????? 應(yīng)用密碼
編譯:
buildclient –w –v –o atmclt –f atmclt.c
-w 表示是WS客戶端,Windows將通過一個(gè)DLL去訪問ATMI。
域
簡介
?
/Domain作為TUXEDO的一組件,使獨(dú)立的TUXEDO應(yīng)用可以進(jìn)行通訊和共享資源。每個(gè)應(yīng)用環(huán)境視作一個(gè)’domain’。這種結(jié)構(gòu)有以下優(yōu)點(diǎn):
l? 仍然可以訪問遠(yuǎn)程其他域的數(shù)據(jù)
l? 應(yīng)用管理工作可以分散進(jìn)行
l? 資源可以根據(jù)計(jì)算的需要合適地分配
一個(gè)域可以跨越多臺(tái)(個(gè))機(jī)器或處理器。所有的客戶端通過BB(Bulletin Board)了解所有的機(jī)器上提供的交易。BB間的一致性通過DBBL(DistinguishedBulletin Board Liaison)來保證。
通過/Domain,可以維護(hù)獨(dú)立于主域的BB,可以設(shè)定那些交易可以響應(yīng)其他機(jī)器。當(dāng)一個(gè)遠(yuǎn)程域提出一個(gè)合法的交易請(qǐng)求時(shí),/Domain將請(qǐng)求發(fā)送到被請(qǐng)求域并把返回送到請(qǐng)求進(jìn)程。
以下介紹進(jìn)行域間通訊時(shí)需修改的配置。
?本節(jié)要點(diǎn)
l? 概念解釋
l? 配置過程
——環(huán)境變量
——ubbconfig
——dmconfig
——dmloadcf
?
使用TUXEDO組件/DOMAINS時(shí),需要對(duì)管理配置作一些改變。在以下例子中,會(huì)創(chuàng)建一個(gè)獨(dú)立的測試應(yīng)用環(huán)境(DOMAINID是TEST),它可以讀取/請(qǐng)求另一個(gè)應(yīng)用的交易(ProdCust)的數(shù)據(jù)。
服務(wù)GWTDOMAIN(GWT)負(fù)責(zé)響應(yīng)域間通訊。GWADM和DMADM是處理管理交易和域服務(wù)的管理服務(wù)。這些服務(wù)必須配置在UBBCONFIG文件中。配置信息必須在遠(yuǎn)程和本地應(yīng)用環(huán)境中定義。
服務(wù)GWTDOMAIN通過TCP/IP協(xié)議與其他域進(jìn)行通訊。物理上遠(yuǎn)程的域的應(yīng)用位置是透明的。
服務(wù)GWTDOMAIN是雙向的:可以處理遠(yuǎn)程域發(fā)來的請(qǐng)求也可以向遠(yuǎn)程域發(fā)出請(qǐng)求。
除UBBCONFIG外,配置/DOMAINS還需要一些信息。這些信息在DMCONFIG文件中。DMCONFIG的文本文件通過BDMCONFIG編譯成二進(jìn)制文件。
?過程
第一步:UBBCONFIG應(yīng)作相應(yīng)改動(dòng)
?????? 為/DOMAIN建立的新組應(yīng)該和其他應(yīng)用組隔離開。其一用于管理,其他是網(wǎng)關(guān)服務(wù)。
UBBCONFIG
*RESOURCES
?IPCKEY????????????????? 49152
?MAXACCESSERS????? 2
?MAXSERVERS?????????? 25
?MASTER??????????????? SITE1
?MODEL?????????????????? SHM
*MACHINES
?class2????????????????????? LMID=SITE1
?????????????????????????????????? TUXDIR=”/usr/tuxedo”
????????????????????????????????? APPDIR=”/usr/apps/atmapp”
?????????????????????????????????? TUXCONFIG=”/usr/apps/atmapp/atmapp.tux”
*GROUPS
?LDMGRP??????????????? LMID=SITE1???? GRPNO=20
?LGWGRP?????????????? LMID=SITE1???? GRPNO=30
#下一行用于‘prod’域
?APP1?????????????????????? LMID=SITE1 ?? GRPNO=10
*SERVERS
?DMADM????????????????? SRVGRP=LDMGRP???? SRVID=200
?GWADM???????????????? SRVGRP=LGWGRP???? SRVID=310
?GWTDOMAIN??????? SRVGRP=LGWGRP???? SRVID=320
#下一行用于‘prod’域
?CUSTOMER????????? CLOPT=”-A”????? SRVGRP=APP1???? SRVID=100
*SERVICES
#下一行用于‘prod’域
ProdCust
第二步:為域間請(qǐng)求創(chuàng)建DMCONFIG
?????? 下文的ASCII數(shù)據(jù)存在的文件一般稱為DMCONFIG,由此生成的二進(jìn)制格式文件稱為BDMCONFIG。以下的DMCONFIG存在于“TEST“域,用來請(qǐng)求遠(yuǎn)程的”prod“域的”ProdCust“交易。
DMCONFIG on TEST DOMAIN
*DM_LOCAL_DOMAINS
test?????????????? GWGRP=LGWGRP
??????????????????????????? TYPE=TDOMAIN
??????????????????????????? DOMAINID=”TEST”
??????????????????????????? DMTLOGDEV=”/usr/apps/atmapp/logs/DLOG”
*DM_REMOTE_DOMAINS
production???????? TYPE=TDOMAIN
??????????????????????????? DOMAINID=”prod”
*DM_TDOMAIN
prod??????????????????? NWADDR=”//lcspn1:3070”
??????????????????????????? NWDEVICE=”/dev/xti/tcp”
TEST????????????????? NWADDR=”//lcspn2:3070”
??????????????????????????? NWDEVICE=”/dev/xti/tcp”
*DM_REMOTE_SERVICES
?ProdCust
*DM_LOCAL_SERVICES
第三步:創(chuàng)建DMCONFIG指定對(duì)域外提供的交易
下文的DMCONFIG位于域’prod’,該域?qū)⑾蚱渌蛱峁┛烧{(diào)用交易:ProdCust。
域‘prod’上的DMCONFIG
#本地域信息
*DM_LOCAL_DOMAINS
??????????????????????????? #LMID
production???????? GWGRP=LGWGRP
??????????????????????????? #域描述:TDOMAIN即TUXEDODOMAINS
??????????????????????????? TYPE=TDOMAIN???
??????????????????????????? #域的唯一標(biāo)識(shí)符
??????????????????????????? DOMAINID=”prod”
??????????????????????????? #交易的日志
??????????????????????????? DMTLOGDEV=”/usr/apps/atmapp/logs/DLOG”
#遠(yuǎn)程域信息
*DM_REMOTE_DOMAINS
test?????????????? TYPE=TDOMAIN
??????????????????????????? DOMAINID=”TEST”
*DM_TDOMAIN
??????????????????????????? #地址和設(shè)備名
prod??????????????????? NWADDR=”//lcspn1:3070”
??????????????????????????? NWDEVICE=”/dev/xti/tcp”
TEST????????????????? NWADDR=”//lcspn2:3070”
??????????????????????????? NWDEVICE=”/dev/xti/tcp”
*DM_REMOTE_SERVICES
*DM_LOCAL_SERVICES
#遠(yuǎn)程域可以使用的交易
?ProdCust
?第四步:設(shè)定環(huán)境變量
/DOMAIN進(jìn)程需要額外的環(huán)境變量去訪問/DOMAINS配置信息
exportBDMCONFIG=/usr/apps/atmapp/atmapp.bdm
?第五步:編譯ubbconfig
本過程是從兩個(gè)域中相同的UBBCONFIG生成二進(jìn)制文件TUXCONFIG。在本例中,UBBCONFIG的信息位于’ubbconfig’。
tmloadcf –y ubbconfig?
第六步:編譯dmconfig
本過程是創(chuàng)建二進(jìn)制DOMAINS配置文件,BDMCONFIG,在兩個(gè)域中相同;而兩者都有的文件‘dmconfig’內(nèi)容是不同的。
dmloadcf –y dmconfig
總結(jié)
以上是生活随笔為你收集整理的bea tuxedo中间件入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聊聊前端八股文?
- 下一篇: Promise 到底是什么?看这个小故事