[转帖]BEA Tuxedo_MQ, Tuxedo及OLTP讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MQ, Tuxedo及OLTP讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4050 | 回复: 0   主题: [转帖]BEA Tuxedo        下一篇 
yaoer
注册用户
等级:列兵
经验:90
发帖:5
精华:0
注册:2014-6-9
状态:离线
发送短消息息给yaoer 加好友    发送短消息息给yaoer 发消息
发表于: IP:您无权察看 2014-10-30 9:46:21 | [全部帖] [楼主帖] 楼主

一、 错误消息处理

1.全局变量 tperrno
当一个 ATMI 调用发生错误时,全局变量 tperrno 被设置,它指示发生错误的原因。可选值如下:

代码 TPEABORT TPEBADDESC TPEBLOCK TPEINVAL TPELIMIT TPENOENT TPEOS TPEPERM TPEPROTO TPESVCERR TPESVCFAIL TPESYSTEM TPETIME TPETRAN TPGOTSIG TPERMERR TPEITYPE TPEOTYPE Transaction can not commit Bad descriptor for tpgetrply(3c)

解释

Blocking condition found and no-block specified Invalid arguments given Too many handles outstanding No entry found or no room on the Bulletin Board Operating system error Bad permissions or failed authentication Protocol error Server error while handling request Application level service failure Internal BEA TUXEDO error (userlog(3c)) message written) Time-out occurred and TPNOTIME was not specified Caller in transaction mode and transaction aborted Signal received and TPSIGRSTRT not specified Resource Manager failure Type and/or subtype do not match services Type and/or subtype do not match buffers or unknown
TPERELEASE TPEHAZARD TPEHEURISTIC TPEEVENT TPEMATCH
Caller has made a 3.0 library call Hazard exists that transaction heuristically completed Transaction heuristically completed Event occurred Service name cannot be advertised due to matching conflict


2.错误函数 tpstrerror

char *tpstrerror(int tperrno);


根据错误号 tperrno 生成一个错误信息串,把串的起始地址返回。

当错误是 TPESYSTEM 或 TPEOS 时,一个消息写到 userlog 文件。

二、 buffer 管理

1.buffer 类型
在 tuxedo 的通讯中使用的缓冲区都要使用一套自己 API 来生成和释放。buffer 类型有 CARRAY、 STRING、FML、FML32、VIEW 和 VIEW32 等。

类型 STRING CARRAY

说明 字符串,以 null 结尾

有长度的字节流 X_OCTET

FML fielded buffers FML32 VIEW C 结构 VIEW32 X_C_TYPE X_COMMON

以上类型中,只有 VIEW 系列类型是有子类型(subtype)的。FML 和 VIEW 在后面会有详细的说明。

2.STRING 型
STRING 类型主要用于处理变长的文本数据;

必须以 null 结尾;

STRING 要在配置文件的 MACHINES 部分用 TYPE 配置;

STRING 类型只由字符组成,在结构不同或使用不同的字符集的机器之前传输时,自动进行 XDR encode/decode 处理。

3.CARRAY 型
CARRAY 类型用于与机器无关的数据;

该类型要指定长度,数据中可以包含 null 数据;

tuxedo 不关心数据的内容,不进行 XDR encode/decode 转换。

4.分配 buffer-tpalloc

char *tpalloc(char *type, char *subtype, long size); 成功返回分配的缓冲区首地址,失败返回 NULL

参数说明:

type:buffer 类型;

subtype:子类型,没有子类型的填 NULL;

size:分配的缓冲区大小;

buffer 类型是 CARRAY、STRING、FML、FML32、VIEW 和 VIEW32。

失败原因主要有:

? 参数错; ? 协议错,如之前尚未调用 tpinit; ? 操作系统错; ? tuxedo 底层错。

5.重分配 buffer-tprealloc

char *tprealloc(char *bufptr, long size); 成功返回新的缓冲区地址,失败返回 NULL

参数说明:

bufptr:先前分配的 buffer 地址;

size:新的大小;

函数改变原来分配的空间的大小,并把原来的数据拷贝到新的缓冲区中。

失败原因主要有:

? 无效的原指针; ? 协议错,如之前尚未调用 tpinit; ? 操作系统错; ? tuxedo 底层错。

6.释放 buffer-tpfree

void tpfree(char *bufptr);


参数说明:

bufptr:分配的 buffer 地址;

函数没有返回值,不返回任何错误,tperrno 被设置为 0。

7.查询 buffer 的类型-tptypes

long tptypes(char *bufptr, char *type, char *subtype); 函数成功返回 buffer 的长度,失败返回-1

参数说明:

bufptr:buffer 地址;

type:成功返回的 buffer 类型;

subtype:成功返回的 buffer 子类型;

失败原因主要有:

? 无效的原指针; ? 协议错,如之前尚未调用 tpinit; ? 操作系统错; ? tuxedo 底层错。

三、 client 端 ATMI

ATMI:Application-to-Transaction Monitor Interface。
1.tpchkauth
int tpchkauth();


在调用 tpinit()之前检查是否需要认证和认证的级别。

返回值:

? TPNOAUTH:不需要认证; ? TPSYSAUTH:系统认证,需要密码; ? TPAPPAUTH:应用认证,需要密码和特殊应用数据;
当返回值为 TPSYSAUTH 和 TPAPPAUTH 时,我们必须使用 tpalloc()分配一个 TPINIT 结构,在该结构 中填入认证数据,然后用该结构作为参数调用 tpinit()。

失败原因主要有:

? 协议错; ? 操作系统错; ? tuxedo 底层错。

2.tpinit
在使用 tuxedo 其他服务之前,必须调用 tpinit 加入到应用中。

int tpinit(TPINIT *tpinfo);


参数说明:

tpinfo:指向 TPINIT 类型的指针。

TPINIT 类型在 atmi.h 中有定义,如以下几个域:

char usrname [32]; (32 characters significant) char cltname [32]; (32 characters significant) char passwd [32]; (8 characters significant) char grpname [32]; (32 characters significant) long flags; long datalen; long data;


usrname:用户名或 login 名;

cltname:应用定义;

passwd:应用密码;

grpname:在事务中使用,必须在配置文件定义的组列表中;

flags:定义请求/通知类型和系统存取方法,其中 TPU_SIG、TPU_DIP 和 TPU_IGN 不能同时指定; TPSA_FASTPATH 和 TPSA_PROTECTED 不能同时指定。有如下的值:

? TPU_SIG:选择信号通知; ? TPU_DIP:选择 dip-in 通知; ? TPU_IGN:忽略通知; ? TPSA_FASTPATH:选择 fastpath 方式系统存取; ? TPSA_PROTECTED:选择 protected 方式系统存取;
datalen:应用特殊数据的长度;

data:应用特殊数据;

域 flags 的值覆盖系统的缺省定义,前提是在配置文件中没有指定 NO_OVERRIDE。

如果参数使用(TPINIT*)NULL,则 client 使用系统缺省的通知设置和系统存取设置,若需要认证,则 出错返回 TPEPERM。

tpinit()调用失败返回-1,失败原因有:

? 参数错; ? 没有空间在 BB; ? 没有权限; ? 协议错; ? 操作系统错; ? tuxedo 底层错。
示例:

TPINIT *tpinfo; char password[9]; /* prompt user for password */ if ((tpinfo = (TPINIT *)tpalloc(“TPINIT”,NULL,TPINITNEED(0))) == NULL) { (void)userlog(“unable to allocate TPINIT buffer”); exit(1); } (void)strcpy(tpinfo->passwd, password);
(void)strcpy(tpinfo->usrname, “Smith”); (void)strcpy(tpinfo->cltname, “Teller”); tpinfo->flags = (TPU_DIP|TPSA_PROTECTED); if (tpinit(tpinfo) == -1) { (void)userlog(“failed to join application”); tpfree((char*)tpinfo); exit(1); }
3.tperm


使用 tuxedo 服务完毕,调用 tpterm()离开应用。

int tpterm();


函数出错返回-1。

错误原因有:

? 协议错; ? 操作系统错; ? tuxedo 底层错。

4.tpacall
发送异步请求。

int tpacall(char *service, char *bufptr, long length, long flags);


参数说明:

service:请求的 service 名(最大 15 个字符,以 null 结尾);

bufptr:请求发送的数据;

length:发送数据长度(只有 CARRAY 类型用,其他设为 0);

flags:发送模式,有如下的值:

? TPNOTRAN:该次调用不能在一个事务里; ? TPNOREPLY:不需要回应(reply); ? TPNOBLOCK:非阻塞; ? TPNOTIME:不超时,一直等待; ? TPSIGRSTRT:被信号中断的系统调用重启。
成功返回一个非负的描述符,该描述符可用于后续的 tpgetrply 调用,出错返回-1。

错误原因有:

? 参数错; ? 当前太多的 tpacall 处理存在,上限是 50; ? 事务错; ? 超时(time-out);

5.tpgetrply
接收异步回应数据。

int tpgetrply(int *handle, char **bufpp, long *length, long flags);


参数说明:

handle:tpacall 返回的描述符;

bufpp:接收 buffer 的地址的地址,原 buffer 会自动调整;

length:接收的 buffer 的长度的地址;

flags:接收选项。有如下值:

? TPNOBLOCK:非阻塞; ? TPNOTIME:不超时,一直等待; ? TPSIGRSTRT:被信号中断的系统调用重启; ? TPGETANY:接收任何回应; ? TPNOCHANGE:要求接收的回应与发送数据相同。
成功返回 0,失败返回-1。

出错原因:

? 参数错; ? 错误的接收 buffer 类型; ? 超时; ? 其他错误;

6.tpcancel
取消由 tpacall 发送的请求的响应,在没有事务未完时。不能取消一个已经处理的请求。

int tpcancel(int handle);


参数说明:

handle:tpacall 返回的描述符;

出错返回-1。错误原因有:

? 错误的描述符;

? 当前在事务模式; ? 其他错误;

7.tpcall
同步发送请求并接收回应数据。

int tpcall(char *service, char *sbufp, long slength, \ char **rbufpp, long *rlength, long flags);


参数说明:

service:请求的 service 名;

bufp:发送 buffer 的地址;

slength:发送数据长度(只 CARRAY 使用,其他为 0);

rbufpp:响应 buffer 的地址的地址,可以与发送 buffer 为同一块区域;

rlength:响应 buffer 的长度的地址(不能为 NULL);

flags:标志。有如下值(含义见 tpacall 和 tpgetrply):

? TPNOTRAN ? TPNOCHANGE ? TPNOBLOCK ? TPNOTIME ? TPSIGRSTRT


返回-1 表示出错,其他返回值都表示成功。

错误原因与 tpacall 和 tpgetrply 相同,除了描述符错。

8.tpgprio
获得上一次请求或接收的消息的优先级。

int tpgprio();


成功返回的范围是 1-100,值越大优先级越高。失败返回-1。

使用举例:

struct { int hdl; /* handle*/ int pr; /* priority*/ } pa[SIZE];
for (i=0; i < requests; i++) { /* Determine service and data for request */ pa [i].hdl = tpacall(Svc, buf, len, flags); /* Save priority used to send request */ pa[i].pr = tpgprio(); } /* Use qsort(3) routine to sort handles in priority order */ qsort((char*) pa, requests, sizeof(pa[0]), cmpfcn); for (i=0; i< requests; i++) { tpgetrply(&pa[i].hdl, &rbufp, &rlen, rflags); }
9.tpsprio


设置下一个要发送的消息的优先级。

int tpsprio (int prio, long flags);


参数说明:

prio:要设置的优先级;

flags:标志。有如下值:

? 0:使用相对优先级,值改为(default+prio); ? TPABSOLUTE:绝对优先级,值改为 prio;
优先级的范围是 1-100,超过次限制的值被改为相应的最大(小)值。

失败返回-1。错误原因有 TPEINVAL、TPEPROTO、TPESYSTEM、和 TPEOS。

四、 server 端 ATMI
在 server 端 tuxedo 本身提供了一个标准的 main()函数,它负责完成一些必要的工作。server 端编 程只需要编写 service 处理函数,进行 service 的请求处理和回应处理。所以,在 server 端不需要 调用 tpinit()和 tpterm()。

1.TPSVCINFO
每个 service 函数都有统一的形式:

void tpservice(TPSVCINFO *svcinfo);


只有一个参数,该参数是指向 TPSVCINFO 结构的指针(atmi.h)。该结构定义如下:

struct tpsvcinfo { char name[32]; long flags; char *data; long len; int cd; long appkey; CLIENTID cltid; }; /*service 名(最大 15 个字符)*/ /* client 调用时指定的 flags */ /* 接收的数据地址 */ /* 数据长度 */ /* 会话方式下的连接描述符 */ /* 应用认证的 key */ /* client ID */


2.buffer 管理
在 service 函数里,一样可以调用 tpalloc()、tpfree()、tprealloc()处理自定义的 buffer。

通过 TPSVCINFO 参数传递的 buffer 是使用 tpalloc()分配的,所以可以对它使用 tprealloc()。

要注意的是在 service 函数里自己调用 tpalloc()分配的空间在退出要释放,除非该空间作为 tpreturn()或 tpforward()的参数。如果分配的空间不释放,最终会耗尽该 server 的内存资源。

对于 TPSVCINFO 传递的 buffer 不用手动释放。

使用举例:

void BAL(TPSVCINFO* input) {
char *f, *f1, *f2; f=input->data; f1=tpalloc(“STRING”, NULL, 80); f2=tpalloc(“STRING”, NULL, 120); . . . tpfree((char *) f2); tpreturn (TPSUCCESS, 0, f1, 0, 0); }


可以使用 tptypes()查看 buffer 的类型。如:

void ABAL(TPSVCINFO *transb) { char type[20], subtype[20]; long len; len = tptypes(transb->data, type, subtype); if (len == 0) { /*error*/ userlog(“NULL message sent...\n”); ... } if (strcmp(type, “FML”) == 0) { /* convert FML to aud VIEW; */ } else if (strcmp(type, “VIEW”) == 0) { if (strcmp(subtype, “aud”) != 0) { /*error*/ userlog(“Wrong VIEW subtype...”); ... }
} else { /*error*/ userlog(“Invalid buffer type ...”); ... } }


3.server 的 client 角色
tuxedo 的机制允许一个 server 程序作为 client,调用 tpcall()去请求别的 service 服务。这样做 可以避免代码的冗余,但效率上会有牺牲。

这样做时有一些情况要注意:

? 如果一个 server 要把负责返回接收到的 buffer, 则不要使用这个 buffer 作为参数来请求别
的 service 服务。可以分配辅助性的 buffer 来处理,这样做可以避免在 tpcall()过程中 改变了输入 buffer 的内容和类型。

? 一个 server 不能请求一个只被它本身发布的 service。这样做会导致死锁。例外是请求时指
定 TPNOREPLY 标志。

4.tpadvertise
service 可以在启动时发布,也可使用 tmadmin 或使用 tpadvertise 动态发布。

int tpadvertise(char *svcname, void (*func)(TPSVCINFO *));


参数说明:

svcname:要发布的 service 名;

func:该 service 对应的处理函数指针;

如果该 service 用 func 已经发布,则函数立即成功返回。如果调用 server 是 MSSQ 集的一员,则该 MQSQ 中的所有 server 都发布这个 service。失败时返回-1。

出错原因:

? 该 service 已经用别的函数发布了; ? 超过了最大允许发布的 service 数量(MAXSERVICES); ? 参数错误(有为 NULL 的); ? 协议错; ? 操作系统错等。

5.tpunadvertise
一个 server 取消发布一个它已经发布的 service。

int tpunadvertise(char *svcname);


参数说明:

vcname:操作的 service 名;

如果调用 server 是 MSSQ 集的一员,则该 MQSQ 中的所有 server 都取消发布这个 service。失败时返 回-1。

失败原因:

? service 没有发布; ? 参数错误; ? 协议错等。

6.tpreturn
普通的 C 函数返回时使用 return 语句。 但在 tuxedo 程序里, 不能使用 return, 必须使用 tpreturn() 终止当前处理并发送回应给请求端;或者使用 tpforward()把请求传递给别的 service 处理。

void tpreturn(int rval, int rcode, char *data,long len, long flags);


参数说明:

rval:返回值,决定该 service 请求是否成功。如三个可选值:

? TPSUCCESS:成功。tpcall 和 tpgetrply 将返回一个非负值;如果是会话 service,则产生
TPEV_SVCSUCC 事件;

? TPFAIL:失败。tpcall 和 tpgetrply 将返回-1;tperrno 设置为 TPESVCFAIL,如果是会话
service,则产生 TPEV_SVCFAIL 事件;

? TPEXIT:除了 TPFAIL 的功能外,该 server 随后将终止,如果配置了重启动,则该 server
将重新启动。

rcode:应用定义的返回码。service 将向 client 返回该数字,tuxedo 本身不对其做任何解释,接收 端通过全局变量 tpurcode 得到该值,在成功或失败时该值都会返回;

data:返回给 client 端的数据 buffer;

len:返回数据的长度(只 CARRAY 类型有用);

flags:标志,当前没用。

7.tpforward
调用 tpforward 的 server 不向 client 返回数据,而是把更新过的 buffer 传递给另一个 service 做 更多的处理,由它处理返回 client 数据等后续的工作。本身则返回到标准的 main 流程中。

void tpforward(char *service, char *data, long len, long flags);


参数说明:

service:后续的 service 的名称;

data:指向传递的 buffer 的指针;

len:buffer 的长度(只 CARRAY 有用);

flags:当前没有使用;

该函数不能用在会话 service 中。

8.tpsvrinit/tpsvrdone
在一个 server 的实例启动时会调用 tpsvrinit(),在结束时会调用 tpsvrdown()。如果应用没有定义 这两个函数,则使用 tuxedo 提供的缺省函数。

int tpsvrinit(int argc, char **argv);


参数说明:形式类似与 main 函数的参数,函数里可以使用 getopt 和全局变量 optind 进行处理,配 置文件中的 CLOPT 命令行选项也传递到该函数。

函数成功返回 0,失败返回-1。

void tpsvrdone();


五、 会话 ATMI

1.概念
会话是一个半双工的链路,同一时刻只有一方能发送,另一方只能接收。

会话的 client 方开始时也要调用 tpinit()加入到 tuxedo 应用中, 通讯使用的缓冲区也要用 tpalloc() 分配。

在会话中有如下几个角色:

? originator, initiator:执行 tpconnect 开始会话的一方; ? subordinate:接收 tpconnect 的会话 server; ? sender:控制着会话连接的一方; ? receiver:没有会话连接控制权的一方。

2.tpconnect
建立与会话 service 的连接。

int tpconnect(char* name, char *data, long length, long flags);


参数说明:

name:会话 service 的名称;

data:发送数据的 buffer,可以是 NULL;

length:buffer 的长度(必要的话);

flags:标志。有如下值:

? TPNOTRAN:与 tpacall 介绍的相同;

? TPNOBLOCK:(同上); ? TPNOTIME:(同上); ? TPSIGRSTRT:(同上); ? TPSENDONLY:对建立的连接具有控制权,initiator 将发送数据,被调用方只能接收数据; ? TPRECVONLY:建立连接后把控制权交给被调用方,initiator 只能接收数据;
TPSENDONLY 和 TPRECVONLY 必须指定一个,以决定会话的控制权和方向,之后控制权和方向的改变由 sender 决定。

成功返回一个非负的连接描述符,供后面的 tpsend()、tprecv()和 tpdiscon()使用。失败返回-1。

失败原因:

? 无效的参数; ? 太多的连接要建立。每个进程允许建立 10 条连接; ? 错误的 service 名或非会话 service。

3.tpsend
在一个会话连接中发送消息。

int tpsend(int cd, char *data, long length, long flags,long *revent);


参数说明:

cd:会话连接描述符(tpconnect 返回值);

data:发送的数据指针。可以为 NULL,如交换控制权;

length:发送数据的长度(必要的话);

flags:标志。

? TPNOBLOCK:同 tpacall;

? TPNOTIME:(同上); ? TPSIGRSTRT:(同上); ? TPRECVONLY:在发送数据之后,放弃连接的控制权;这将导致对方收到 TPEV_SENDONLY 事件;
revent:当 tperrno 为 TPEEVENT 时返回的事件值。

失败时函数返回-1, tperrno 被设置。 tperrno 为 TPEEVENT 时, 当 导致失败的具体事件存放在 revent 中。

调用 tpsend()可能出现的 revent 值有:

? TPEV_DISCONIMM:当会话的 originator 执行 tpdiscon()、tpreturn()、tpcommit()时
subordinate 会收到该事件;当进程或网络错误时 originator 也会收到此事件;

? TPEV_SVCFAIL:当 subordinate 没有会话的控制权而使用 TPFAIL 和 TPEXIT 执行 tpreturn
时 originator 将收到该事件;

? TPEV_SVCERR:当 subordinate 没有会话的控制权而使用 TPSUCCESS 执行 tpreturn 时
originator 将收到该事件;

4.tprecv
没有会话控制权的一方执行接收消息。

int tprecv(int cd, char **data, long *length, long flags, long *revent);


参数说明:

cd:会话连接描述符;

data:接收 buffer 的地址的地址;

length:接收数据的长度的地址;

flags:标志。可选值:

? TPNOCHANGE:参见 tpacall(); ? TPNOBLOCK:同上; ? TPNOTIME:同上; ? TPSIGRSTRT:同上;
revent:当 tperrno 为 TPEEVENT 时返回的事件值。

失败时函数返回-1, tperrno 被设置。 tperrno 为 TPEEVENT 时, 当 导致失败的具体事件存放在 revent 中。

调用 tprecv()可能出现的 revent 值有:

? TPEV_DISCONIMM:当会话的 originator 执行 tpdiscon()、tpreturn()、tpcommit()时
subordinate 会收到该事件;当进程或网络错误时 originator 也会收到此事件;

? TPEV_SENDONLY:发送方已经放弃了控制权,调用进程当前只能发送不能接收。也可用此方
法获得调用者当前处于的模式;

? TPEV_SVCFAIL:当 subordinate 没有会话的控制权而使用 TPFAIL 和 TPEXIT 执行 tpreturn
时 originator 将收到该事件;

? TPEV_SVCERR:当 subordinate 没有会话的控制权而使用 TPSUCCESS 执行 tpreturn 时
originator 将收到该事件;

? TPEV_SVCSUCC:subordinate 成功结束并正在关闭连接(必须是会话的最后一个事件)。
使用举例:

for (;;) { (void)gets(reply); if (strcmp(reply, “q”) == 0 ) break; (void) strcpy(line, reply); /* send balance request and relinquish line control.*/ if (tpsend(cd,line,0,TPRECVONLY,&revent) == -1) { (void)tpterm(); exit(1); }
/* wait for service to return balance request results.*/ if (tprecv(cd, &line, &len,TPNOCHANGE, &revent) != -1) { (void) userlog(“TPEV_SENDONLY event expected”); (void)tpterm(); exit(1); } /*anything other than a send event is an error.*/ if ((tperrno != TPEEVENT) || \ (tperrno == TPEEVENT && revent != TPEV_SENDONLY)) { (void)tpterm(); exit(1); } (void) printf(Another request ?? %s\n ”,line); }
5.tpdiscon


该函数只能由会话的建立方 originator 执行,这导致会话非正常的终止。

int tpdiscon(int cd);


参数说明:

cd:会话连接描述符。

该函数执行后将导致对方收到一个 TPEV_DISCONIMM 事件。这种方法可能会丢失数据,关闭会话连接 的好的方法是由 service 执行 tpreturn。

失败返回-1。出错原因可能有:TPEBADDESC、TPETIME。

6.会话 server 正常返回的流程示例
1. client 执行 tpconnect(),使用标志 TPSENDONLY,控制连接; 2. client 使用标志 TPRECVONLY 调用 tpsend(),把控制权交个对方,在 server 端产生 TPEV_SENDONLY 事件; 3. server 执行 tpreturn(),标志 TPSUCCESS,中断连接,给 client 产生一个 TEEV_SVCSUCC 事件; 4. client 调用 tprecv(),获得该事件,得知连接已经关闭。

7.会话 server 不正常返回流程示例
1. client 执行 tpconnect(),使用标志 TPSENDONLY,控制连接; 2. client 不使用标志调用 tpsend(),控制权仍在 client 端; 3. server 使用 tprecv()得知自己不能 send 数据; 4. server 发生错误,在没有控制权的情况下执行 tpreturn(),使用标志 TPFAIL,给 client 产生 TPEV_SVCERR; 5. 当 client 调用 tpsend()时得到这个事件。

六、 VIEW 类型
VIEW(VIEW32)类型的 buffer 用于传输 C 结构数据。

1.VIEW(VIEW32)文件
tuxedo 处理 C 结构需要一个文件,描述与 C 结构的映射和可能存在的 FML 模式转换。

文件的每一行描述 C 结构中的一个域,每行的格式如下:

type:域的数据类型。可选值:short、long、float、double、char、string、CARRAY;

cname:C 结构域名;

fbname:FML buffer 域名;

count:元素个数;

flag:标志。可选值(下列之一):

? P: ? S: ? F: ? N: ? C: ? L:


size:STRING 或 CARRAY 型的大小,对于小数,两个数用”,”分隔;

NULL:定义该域的 null 值。若不定义,则 tuxedo 的缺省定义如下:对所有的数字型是 0 或(0.0); 对 char 型是”\0”; STRING 和 CARRAY 是””。 对 定义时可以使用反斜线转义字符。 指定关键字 NONE 表示该域没有缺省 null 值。对 string 和字符数组最大可为 2660 个字符。

文件中以“#”打头的行是注释,被忽略;以“$”开头的行也是注释,但它会被拷贝到生成的 C 头文 件里。

示例:

VIEW aud $ /* VIEW structure for audit information */ #type long float cname b_id fbname BRANCH_ID BALANCE count 1 1 flag size null 0 0.0
balance
string END
ermsg
STATLIN
1
-
80
“”


2.VIEWC 编译器
上一节形成了 VIEW 的描述文件(后缀为.v)后,还要使用 VIEWC 编译器编译形成一个 C 头文件(.h)和 二进制文件(.V)。

VIEWC 的语法如下:

viewc [-n] [-d viewdir] [-C] viewfile [viewfile ...] 或 viewc32 [-n] [-d viewdir] [-C] viewfile [viewfile ...]

其中 viewfile 就是上面的描述文件。

选项的含义如下:

-d viewdir:指定输出文件的存放路径(缺省放在当前目录);

-C:生成一份 COBOL 的拷贝,放在当前目录;

-n:不处理 FML 映射。

3.头文件
viewc 生成的头文件包含结构的定义,可用于应用程序中。如:

/* VIEW structure for audit information */
struct aud {
long b_id; float balance; char ermsg[80]; };
/* null=0 */ /* null=0.000000 */ /* null=”” */


4.环境变量
在应用中使用 VIEW,要指定二进制文件(.V 或.VV)的存取路径。这通过设置如下的环境变量来实现:

VIEWFILES(VIEWFILES32):用逗号分隔的 VIEW 文件列表;

VIEWDIR(VIEWDIR32):用冒号分隔的路径列表;

若使用了 FML,还要指定 FML 相关的环境变量。

注意:上面的文件列表、路径列表中间不能有空白字符。

七、 FML 类型

1.概述
(1).基本概念

Field Manipulation Language(FML)或(FML32)可以定义多个有名字的域,它是一张属性和值的表。

支持的域数据类型有:short、char、long、float、double、string、carray。

FML(FML32)buffer 通过一套 API 来管理,大约有 60 多个函数接口。

FML 有较强大的功能,使用也很灵活。缺点是接口较复杂,有很多的处理函数,而且使用效率较 VIEW 等要慢。

(2).FML 的基本组成部分

FML buffer 的域通过域 ID(数字)来访问。处理 FML buffer 至少需要如下四个部分:

? 域表文件。提供名字-数字映射; ? 域头文件。提供 C 程序一些生成的宏而不是数字来访问域; ? 环境变量 FIELDTBLS(32)和 FLDTBLDIR(32)定位表文件; ? C 语言接口:
库:libfml.a 和 libfml32.a; 头文件:fml.h 和 fml32.h; 处理 16 位到 32 位转换代码:fml1632.h。

(3).FML buffer 的结构

一个域 buffer 有三部分组成:buffer 头部、数据域和索引项。

(4).处理 FML 的流程

定义所有的域名字、对应的数据类型和数字标识。数字标识 100 以下为系统保留,对 16 位 buffer, 数字标识的范围是 100-8191,32 位 buffer 是 100-33,554,431。

根据这些定义编辑一个域表文件。

使用 mkfldhdr(32)生成域头文件。

编译应用程序,使用生成的头文件和 fml.h(fml32.h),链接 libfml.a(libfml32.a)。

正确设置环境变量 FIELDTBLS(32)和 FLDTBLDIR(32)。

2.域表文件
文件形式如下:

*base 100 # name ACCOUNT_ID ACCT_TYPE ADDRESS AMOUNT number 10 11 09 16 type long char string float flags comments -


文件中以#开头的行被忽略。

文件中以$开头的行也被忽略,但会被拷贝到后面生成的头文件。

文件以*base 开头的行指出后面的域号的基本偏移。

每个域有以下部分组成:

? name:域的名字; ? rel-number:域的编号,它是一个相对当前 base 的数字; ? type:数据类型; ? flag:标志。保留; ? comment:注释。
该文件用来生成头文件,并在函数调用里使用。

3.域头文件

与域表文件对应的头文件形式如下:

/* fname fldid */ /* ----- ----- */ #define ACCOUNT_ID ((FLDID)8302)
/* number: 110 type: long */ #define ACCT_TYPE ((FLDID)16495)
/* number: 111 type: char */ #define ADDRESS ((FLDID)41069)
/* number: 109 type: string */ #define AMOUNT ((FLDID)24692)
/* number: 116 type: float */


4.mkfldhdr(32)工具
mkfldhdr(mkfldhdr32)工具将环境变量 FIELDTBLS 指定的域表文件对应生成一个 C 头文件, 头文件的 命名是在域表文件名后加后缀(.h)。缺省目标文件放在当前目录下,可以指定选项-d 来指定生成的 头文件存放位置。

使用举例:

FLDTBLDIR=/project/fldtbls; export FLDTBLDIR FIELDTBLS=maskftbl,DBftbl,miscftbl; export FIELDTBLS mkfldhdr maskftbl mkfldhdr DBftbl mkfldhdr miscftbl


5.环境变量
FIELDTBLS(FIELDTBLS32):以逗号分隔每个域表文件;

FLDTBLDIR(FLDTBLDIR32):以冒号分隔域表文件存放的路径列表。

注意列表中间不能插入空白字符。

6.Falloc(Falloc32)
使用 malloc 动态分配 fielded buffer 的存储空间并调用 Finit 进行初始化。

#include <stdio.h> #include <fml.h> FBFR *Falloc(FLDOCC F, FLDLEN V); #include <fml32.h> FBFR32 *Falloc32(FLDOCC32 F, FLDLEN32 V);


参数分别是域的个数和空间的字节数。

失败时返回 NULL 并设置全局变量 Ferror。

失败原因:

? FMALLOC:malloc 失败; ? FEINVAL:参数非法。
注意:该函数分配的空间只用于内部处理,不能用于 tpcall()和 tpacall()。

7.Fsizeof(Fsizeof32)

返回给定的 FML buffer 的大小。

long Fsizeof(FBFR *fbfr); long Fsizeof32(FBFR32 *fbfr32);


参数说明:

fbfr:buffer 指针。

8.Fneeded(Fneeded32)
计算 buffer 需要的空间大小。

#include <stdio.h> #include <fml.h> long Fneeded(FLDOCC F, FLDLEN V); #include <fml32.h> long Fneeded32(FLDOCC32 F, FLDLEN32 V);


失败返回-1。

失败原因:

FEINVAL:非法参数。

9.Finit(Finit32)
用于清除一个存在 FML buffer 的内容以便重新使用它。对于使用 Falloc 和 tpalloc 分配的 buffer 该函数不是必须的。

int Finit(FBFR *fbfr, FLDLEN buflen); int Finit32(FBFR32 *fbfr, FLDLEN32 buflen);


参数说明:

bffr:要处理的 buffer 指针;

buflen:清理的空间字节数。

使用举例:

FBFR * fbfr; fbfr = (FBFR *) tpalloc(“FML”,NULL,Fneeded(5,200)); ... Finit(fbfr,Fsizeof(fbfr));
10.Fadd(Fadd32)


往 buffer 中的某个域填值,同一个域可以填多次,按下标 0、1,2?依次存放。

int Fadd(FBFR *fbfr, FLDID fieldid, char *value, FLDLEN len); int Fadd32(FBFR32 *fbfr, FLDID32 fieldid, char *value, FLDLEN32 len);


参数说明:

fbfr:FML buffer 指针;

fieldid:域 ID 号;

value:值存放的地址(char *类型)。当数据不是 string 或 carray 时要强制转化;

len:域长度。只对 carray 类型有效。

失败返回-1。

使用举例:

long db_id; ... (void)Fadd(reqfb, ACCOUNT_ID, (char *)&db_id, (FLDLEN)0); char *t_amts; ... if (Fadd(reqfb, SAMOUNT, t_amts, (FLDLEN)0) == -1) (void)printf(“Fadd failed with error: %d\n”, Ferror); char *t_amts; ... if (Fadd32(reqfb, SAMOUNT, t_amts, (FLDLEN32)0) == -1) (void)printf(“Fadd32 failed with error: %d\n”, Ferror32);
11.Fchg(Fchg32)


修改域的值。

int Fchg(FBFR *fbfr, FLDID fieldid,int occ, char *value, FLDLEN len); int Fchg32(FBFR32 *fbfr, FLDID32 fieldid,int occ, \ char *value, FLDLEN32 len);


参数说明:

fbfr:FML buffer 指针;

fieldid:域 ID 号;

occ:域的下标。从 0 开始计算,-1 表示增加值;

value:值的地址(char *);

len:域长度。只对 carray 类型有效。

失败返回-1。

若域指定下标当前没有值,则增加该下标的值。

使用举例:

char *t_amts; ... if (Fchg(reqfb,SAMOUNT, 0, t_amts,(FLDLEN)0) == -1) (void)printf(“Fchg failed with error: %s”,Fstrerror(Ferror));
12.Fget(Fget32)


取域的值。

int Fget(FBFR *fbfr, FLDID fieldid,int occ, char *value, FLDLEN *maxlen); int Fget32(FBFR32 *fbfr, FLDID32 fieldid,int occ, \ char *value, FLDLEN32 *maxlen);


参数说明:

fbfr:FML buffer 指针;

fieldid:域 ID 号;

occ:域的下标。从 0 开始计算,-1 表示增加值;

value:存放地址(char *);

maxlen:最大长度的指针,返回时被置为实际长度。

失败返回-1。

若当前空间不足以存放实际的值,函数并不截断数据,而是返回-1。

使用举例:

FLDLEN len2; long amount; . . . len2 = sizeof(amount); (void)Fget(transf, MID_INIT, 3, (char *) &amount, &len2);
13.Fcpy(Fcpy32)


进行 FML buffer 的拷贝。

int Fcpy(FBFR *dest, FBFR *src); int Fcpy32(FBFR32 *dest, FBFR32 *src);


失败返回-1。

函数认为两者都是 FML buffer,当目标 buffer 足够大时进行复制。

14.输入/输出函数

int Fprint(FBFR *fbfr); int Fprint32(FBFR32 *fbfr);


以可读形式打印 FML buffer 的内容,输出到标准输出。

int Ffprint(FBFR *fbfr, FILE *iop); int Ffprint32(FBFR32 *fbfr, FILE *iop);


同上,但输出到指定的流中。

int Fextread(FBFR *fbfr, FILE *iop); int Fextread32(FBFR32 *fbfr, FILE *iop);


从流中读取数据到 buffer 中。

参数说明:

fbfr:buffer 指针;

iop:输入/输出流。

格式的说明见 ud 部分的说明。

15.Fvftos(Fvftos32)


把 FML buffer 的数据拷贝到 VIEW C 结构中。

int Fvftos(FBFR *fbfr, char *cstruct, char *view);
int Fvftos32 (FBFR32 *fbfr, char *cstruct, char *view);


参数说明:

fbfr:要拷贝的 FML buffer 指针;

cstruct:指向 C 结构数据的指针;

view:VIEW 名称。

若 FML 中的域在结构中没有对应的项,则忽略。对于多记录的域,相应结构的域要是一个数组,如果 buffer 中的记录数小于结构中域数组的个数,则结构中多余部分置为 null 值。如果 buffer 记录数 大于数组个数,则多余的值被忽略。

16.Fvstof(Fvstof32)


把 VIEW 结构中的数据拷贝到 FML buffer 中。

int Fvstof(FBFR *fbfr, char *cstruct, int mode, char *view); int Fvstof32(FBFR32 *fbfr, char *cstruct, int mode, char *view);


参数说明:

fbfr:FML buffer 地址;

struct:C 结构数据地址;

mode:拷贝模式。有以下可选值:

? FJOIN:把结构和 FML buffer 匹配的域中结构的值拷贝到结果 buffer 中; ? FOJOIN:执行 FJOIN 功能之外,也把 FML buffer 中其他内容拷贝到结果 buffer 中; ? FUPDATE:执行 FJOIN 功能之外,也把 FML buffer 和结构的其他内容拷贝到结果 buffer 中;

? FCONCAT:把结构和 FML buffer 的全部内容都拷贝到结果 buffer 中。
view:VIEW 名称。

八、 开发环境

1.使用 buildclient 构造 client 端程序
步骤:

1. client 端程序包含 atmi.h 头文件; 2. 正确设置 TUXDIR 环境变量; 3. 使用 buildclient 工具编译程序;

buildclient 的语法如下:

buildclient [-v] [-C] -o executable -f first-file [-f first-file]... \ [-l last-file]...


选项含义:

-C:编译 COBOL 代码;

-o:可执行文件的名字;

-f option:在链接 tuxedo 库之前处理该文件;

-l option:在链接 tuxedo 库之后处理该文件;

-v:打印实际的编译命令行。

buildclient 在运行中使用下面的环境变量:

CFLAGS:自动在该变量中增加"-I${TUXDIR}/include";

CC:使用该变量指向的编译器。

2.使用 tmloadcf
tmloadcf 用于将 tuxedo 文本配置文件转化为运行时需要的二进制文件。

二进制文件的文件名由环境变量 TUXCONFIG 指定,该文件名必须是绝对路径的。

tmloadcf 的语法如下:

tmloadcf [option] text-file;


选项有如下几个:

-c:计算该配置需要的 IPC 资源而不生成目标文件;

-n:进行语法检查而不生成目标文件;

-b:限制目标文件的大小;

-y:不提示直接覆盖现有的目标文件;

3.使用 tmunloadcf
tmunloadcf 将二进制配置文件以 ASCII 形式输出。

4.使用 tmboot
tmboot 启动 tuxedo 应用服务,创建必要的 IPC 资源。

有如下选项,无选项时启动所有配置的服务:

-A:只启动所有机器的管理 server(BBL、DBBL);

-g grpname:只启动指定 group 的 server;

-i srvid:只启动指定的 server ID 的所有 server;

-S:启动所有应用 server;

-s servername:启动指定的 server;

-c:只计算最小的 IPC 资源需求。

5.使用 tmshutdown
tmshutdown 停止 tuxedo 服务,必要是删除相关的 IPC 资源。

有如下选项:

-A、-g、-i、-S、-s:与 tmboot 相同;

-R:在多机环境下停止除 BB 外的服务;

6.使用 buildserver 构造 server 端程序
语法如下:

buildserver [-o executable]... [-v] \ [-s service2, service3:func] \ [-f source/object]...\ [-l object] ... \ [-r resource manager]


选项含义:

-o:生成的可执行程序名;

-v:打印实际的编译命令行;

-s:指定提供的 service 和对应的处理函数;

-f:在链接 tuxedo 库之前处理该文件;

-l:在链接 tuxedo 库之后处理该文件;

-r:要链接相关资源库(在$TUXDIR/udataobj/目录下)。

九、 配置文件

tuxedo 的运行需要配置文件 UBBCONFIG,该文件由管理员编写,然后使用 tmloadcf 编译成二进制文 件。它有以下几个部分组成:

1.RESOURCES

该部分包括整个应用系统的一些配置信息,必须存在而且是配置文件的第一部分。有如下几个参数:

(1).IPCKEY(必需)

用于指定 tuxedo 分配和存取 IPC 资源的 key,范围是 32,768 到 262,143,该值在系统是唯一的,不 能和别的应用同时使用这个值。

(2).MASTER(必需)

指定系统的主节点,主节点控制着整个应用系统的启动和管理。它的值是一个 Logical Machine Identifier(LMID),LMID 在后面的 MACHINES 定义。当主节点是集群时,需要指定两个 LMID。

(3).UID、GID、PERM

指定系统的存取权限。UID 和 GID 是 tuxedo 管理员的用户 id 和组 id,PERM 是一个八进制数指定读 写权限。

(4).MAXACCESSERS、MAXSERVERS、MAXSERVICES

MAXACCESSERS: 指定能连接到 tuxedo 一个节点的最大进程数。 缺省是 50, 这包括所有的 client、 server 和管理进程 BBL 等。增加该值将会消耗更多的系统信号量 IPC 资源。

MAXSERVERS:整个应用系统中最大的 server 进程数。包括管理 server 进程,缺省是 50。提高该值 需要共享内存资源。

MAXSERVICES:整个系统可以发布的 service 的最大数量。缺省是 100。提高该值需要更多的共享内 存资源。一个 service 可以被多个 server 发布,此时,它的数量要算多份。

(5).MODEL(必需)

有两个可选值:

? SHM:应用运行在单机或多机下,使用全局共享内存; ? MP:不使用共享内存,运行在网络多机环境下。
(6).OPTIONS

有两个可选值:

? LAN:支持网络; ? MIGRATE:支持 server 集群。
可同时指定这两个值,用逗号分隔。

(7).LDBAL

是否打开 load balancing(负载均衡)功能。可设置为 Y 或 N,缺省为 N。

(8).NOTIFY

设置 client 接收 unsolicited message(请求消息)的方法。有如下三个可选值:

? IGNORE:client 忽略此类消息; ? DIPIN:当 client 调用 tpchkunsol 或其他 ATML 调用时接收此类消息; ? SIGNAL: 通过系统产生信号通知 client 接收消息。 有两个信号可以产生: SIGUSR1 和 SIGUSR2,
缺省是 SIGUSR2。若要指定为 SIGUSR1 则需设置下面的 USIGNAL 参数。

缺省是 DIPIN。

(9).USIGNAL

设置系统产生的信号是 SIGUSR1 还是 SIGUSR2。

(10).SCANUNIT、SANITYSCAN、BLOCKTIME

管理 server(BBL)定期对所属机器上的 servers 进行正常检测。下面是有关的设置。

? SCANUNIT:指定检测粒度。单位是秒,值必须是 5 的倍数。缺省是 10。 ? SANITYSCAN: 在两次检测之前间隔几个 SCANUNIT。 缺省是 12(120 秒)。 SANITYSCAN*SCANUNIT
不能大于 300。

? BLOCKTIME:一个消息超时前可阻塞的 SCANUNIT。缺省是 6(60 秒)。BLOCKTIME*SCANUNIT 不
能超过 32767。

2.MACHINES
该部分包括整个应用系统中所有计算机的信息。在配置文件中必须存在,而且是第二部分。

每个主机有如下的属性:

(1).主机名

使用命令”uname –n”获得的名称。

(2).LMID(必需)

主机的逻辑 id:logical identifier of the machine(LMID)。

(3).TUXCONFIG(必需)

配置文件所在的绝对路径(最大 64 字符)。

(4).TUXDIR(必需)

Tuxedo 的安装绝对目录(最大 64 字符)。

(5).APPDIR(必需)

应用 server 所在的绝对目录(最大 64 字符)。

(6).ENVFILE

环境文件所在绝对路径(最大 64 字符)。

(7).ULOGPFX

用户日志文件的绝对路径和前缀。

其他

UID、GID、PERM、MAXACCESSERS、MAXCONV 可以在此定义而覆盖 RESOURCES 部分对该计算机的定义。

3.GROUPS
该部分包括所有 server 组的定义。每台机器必须至少定义一个组。每个组有如下属性:

(1).组名

(2).GRPNO(必需)

组名对应的组号,它必须是唯一的数字。

(3).LMID(必须)

该组属于的逻辑主机 id。

4.SERVERS
该部分包括所有 server 的信息。每个条目描述一个 server。Server 有如下属性:

(1).server 名

server 可执行程序名(用 buildserver 编译)。

(2).SRVGRP(必需)

该 server 所属的 group id(在 GROUPS 定义)。

(3).SRVID(必需)

每个 server 在 group 里定义一个唯一的 id 号。

对于同一个可执行程序可以在 SERVERS 中有多个条目,即 server 名不是唯一的。

(4).CLOPT

指定传递给程序的命令行选项。命令行串由”--"分隔,之前的部分由标准 main()处理,后面的部分 (有的话)由 tpsvrinit()处理,用户自定义的选项放在此处。

缺省 CLOPT=“-A”,表示发布该 server 所有的 services。

部分选项如下:

-e filename:重定向标准出错文件(缺省是$APPDIR/stderr);

-o filename:重定向标准输出文件(缺省是$APPDIR/stdout);

-p [L][low_water][,[terminate_time]][:[high_water][,create_time]]: 允许 server 的动态伸缩;

-s services:发布特定的 services(语法同 buildserver)。该部分优先于 buildserver;

-r:记录 services 的统计信息和标准错误。

(5).ENVFILE

每个 server 也可指定环境文件,它与 MACHINES 定义的 ENVFILE 都起作用,相同的变量以 server 的 为主。

(6).RQADDR、RQPERM、REPLYQ、RPPERM

RQADDR:起用 MSSQ(Multiple Server Single Queue)集合。指定一个名字,集合中其他 server 用同 样的名字。

RQPERM:指定队列的访问权限(如 0666)。

REPLYQ:属于 MSSQ 中 server 的 service 从队列中取消息的话,它必须回应该消息,这通过指定 REPLYQ=Y 完成。缺省 REPLYQ=N。

RPPERM:当 REPLYQ=Y 时,指定相关权限。

(7).CONV

如果 server 是一个会话 server,则该属性必须指定为 Y。缺省是 N,表示它不是一个会话 server。

(8).SEQUENCE

指定 server 的启动顺序,范围是 1-9,999。该值小的先于值大的启动;指定该值的 server 比没有指 定的 server 先启动;如果 server 都没有指定该选项,则按定义的顺序启动。

server 终止时按照启动的反序停止。

(9).MIN

指定启动 server 的最小实例数。缺省为 1。

(10).MAX

指定 server 能启动的最大实例数。缺省等于 MIN。

(11).RESTART、RCMD、MAXGEN、GRACE

RESTART:指定当 server 死后是否重新启动它。当 RESTART=Y 时,下面的选项有用。

RCMD:指定重启时同时执行的命令,它必须是一个可执行文件。

MAXGEN:在 GRACE 时间范围内能重启的次数(MAXGEN-1)。如果 GRACE=0 则表示重启没有限制。

GRACE:值必须大于等于 0,小于等于 2,147,483,647 秒(大概 70 年)。缺省是 24 小时。

5.SERVICES
该部分包括应用中的所有 service 的信息。每个 service 一个条目。有如下属性:

(1).LOAD

当 LDBAL 为 Y 时,指定该 service 的负载因子。缺省是 50。

(2).PRIO

指定 service 的优先级。缺省是 50。值越大级别越高。

(3).SRVGRP

(4).BUFTYPE

十、 Workstation C/S 配置

1.Workstation client
(1).编程

client 使用 ATMI 的编程方法不变。

对于 buildserver,多指定一个选项:

-w:指定链接 WS 库而不是 native 库。

(2).设置环境变量

TUXDIR:tuxedo 软件的安装目录;

WSNADDR:指定 WSL 的网络地址,它必须要和服务端配置的 WSL 设置一样;

下面的环境变量不是必须的:

WSDEVICE:用于 TLI 的网络设备。缺省为空串;

WSENVFILE:指定环境变量文件;

WSTYPE:指定机器类型。如果类型与 WSL 所属的机器的类型匹配,则不进行 encoding/decoding。缺 省为空串;

WSRPLYMAX:应用回应的缓存大小。缺省是 32,000 字节;

TMPDIR:当 WSRPLYMAX 的限制到达时,存储新回应数据的目录。缺省是工作目录;

APP_PW:应用密码。

2.配置文件 UBBCONFIG
(1).设置 MAXWSCLIENTS

在 MACHINES 部分增加该设置,指定最大的可连接 client 数目。缺省为 0,表示不能连接。形式:

MAXWSCLIENTS=number


(2).增加 WSL server

在 SERVERS 部分增加 WSL(Workstation Listener),它的定义方法与普通 server 一样。命令行的选 项如下(在 CLOPT 中”--"之后):

-n netaddr:指定网络地址,多个地址用逗号分隔;

-d device:网络设备,用于 TLI;

-t timeout:指定 client 连接超时,该值是 SCANUNIT 的倍数。缺省值对不需安全的应用是 3,对安 全的应用是 6;

-w name:指定与该 listener 对应的要启动的 WSH(Workstation Handler)的名字。缺省是 WSH;

-m number:指定最小应启动的处理进程数。缺省是 0;

-M number:指定最大启动的处理进程数。缺省等于 MAXWSCLIENTS 的值;

-x number:WSH 同时能处理的 client 数。缺省值是 10;

-T inactive-client-timeout:当 client 在指定时间没有请求时,WSH 将断开与 client 的连接,单 位是分钟。不指定该选项则不超时;

-p miniwshport:与 listener 相关的 WSHs 能使用的最小端口号,范围是 0-65535。缺省是 2048;

-p maxwshport:与 listener 相关的 WSHs 能使用的最大端口号,范围是 0-65535。缺省是 65535;

-c compression-threshold:进行报文压缩的最大限度。缺省值是 2,147,483,647;

-k compression-threshold:同上,出现于 tuxedo 来版本;

-z [0|40|128]:用于安全设置,建链时的密钥长度;

-Z [0|40|128]:用于安全设置(LLE),建链时的密钥长度。

3.示例

*MACHINES SITE1 . . . MAXWSCLIENTS=150 . . . SITE2 . . . MAXWSCLIENTS=0 . . .
*SERVERS . . . WSL SRVGRP=”BANKB1” SRVID=500 RESTART=Y \ CLOPT=”-A -- -n //train4:32000 -d /dev/tcp -m 5 -M 30 -x 5”


十一、

tuxedo 安全机制

Tuxedo 提供四个级别的安全认证机制。分别介绍如下:

1.无认证(基于本地操作系统的认证)
基于 UNIX 的系统在访问 tuxedo 的相关资源时都需要相应的权限, 该级别的认证使用了操作系统的功 能,tuxedo 本身不做额外处理。

在配置文件 UBBCONFIG 中不需要增加任何处理。

也可指定如下的参数进行更具体的设置:

在 RESOURCE 中指定 SECURITY 的值为 NONE;指定 UID、PID、PERM 来代替操作系统的缺省设置。如:

SECURITY
NONE


2.密码认证
这是基于整个应用系统的认证,要访问该应用系统都必须提供一个相同的密码。

使用该级别的方法如下:

在 UBBCONFIG 的 RESOURCE 部分指定认证级别:

SECURITY
APP_PW


当调用 tmloadcf 时,tuxedo 会提示输入一个密码。该密码可以在 tmadmin 中使用 passwd 命令进行 修改。

此时 client 端调用 tpchkauth()时会返回 TPSYSAUTH。

client 要加入应用,必须使用 tpalloc 分配一个 TPINIT 结构,在该结构中的 passwd 域填入上面的 密码,然后调用 tpinit()才会成功。

如:

... TPINIT *tpinfo; char *passwd; tpinfo = (TPINIT*) tpalloc(“TPINIT”, NULL, TPINITNEED(0)); /*prompt for user password*/ strcpy(tpinfo -> passwd, passwd); tpinit(tpinfo); ...


3.用户认证 server
使用认证 server,由用户实现一个用于认证的 service,该 service 决定具体的认证方法。

使用该级别认证的方法如下:

在 UBBCONFIG 的 RESOURCE 部分指定认证级别和认证的 service:

SECURITY AUTHSVC
USER_AUTH MYSVC


在 SERVER 部分指定包含认证 service 的相应 server:

MYAUTHSVR SRVID=100 CLOPT=“-A” SRVGRP=GROUP1


具体的例子见 TUXDIR/lib/AUTHSVC.c。它检查 tpinit 结构的 username、cltname、passwd 并返回一 个认证的 key。

4.ACLs
Access Control Lists(ACLs)是 tuxedo 自己提供一套基于组管理的认证机制。该机制由用户、组以 及对资源(service、event 等)的相应存取权限组成。

使用该级别认证的方法如下:

在 RESOURCE 部分定义:

SECURITY


ACL 或

MANDATORY_ACL


ACL 和 ACL 或 MANDATORY_ACL 的区别是:若当前要访问的对象没有定义存取规则,则 ACL 方式允许访 问,而 MANDATORY_ACL 方式不允许访问。如:

*RESOURCES SECURITY ACL /* or */
MANDATORY_ACL
AUTHSVC “..AUTHSVC” *SERVERS AUTHSVR SRVID=100 SRVGRP=AdminGroup RESTART=Y CLOPT=”-A”


该方法要涉及文件 tpusr、tpgrp 和 tpacl,在$APPDIR 目录下。使用如下命令处理用户:

tpusradd;
tpusrdel;
tpusrmod;


使用如下命令处理组:

tpgrpadd;
tpgrpdel;
tpgrpmod;


使用如下命令处理对象的存取权限:

tpacladd;
tpacldel;
tpaclmod;


如:

tpgrpadd -g 801 Beatles tpusradd -g Beatles Ringo tpusradd -g Beatles John tpusradd -g Beatles George
tpusradd -u 9 Paul tpacladd -g Beatles -t SERVICE TOUPPER


--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论