bea tuxedo中间件入门

时间:2022-04-17 04:02:48


§  TUXEDO是什么?

l  客户端/服务器模式的演化

l  基本的客户端/服务器模式

l  多层结构

l  TUXEDO的客户端/服务器方法

l  一个完整的例子

l  应用配置文件:ubbconfig

l  运行应用的步骤


tuxedo是什么?

       BEA TUXEDO是在企业、Internet 这样的分布式运算环境中开发和管理三层结构的客 户/服务器型关键任务应用系统的强有力工具。它具备分布式事务处理和应用通信功能,并提供完善的各种服务来建立、运行和管理关键任务应用系统。开发人员能够用它建立跨多个硬件平台、数据库和操作系统的可互操作的应用系统。BEA TUXEDO是企业、 Internet 分布式应用中的基础主干平台。它提供了一个开放的环境,支持各种各样的客户、数据库、网络、遗留系统和通讯方式。


特点:

²  大量在线用户

²  巨量数据

²  信息访问

²  小事务

²  复杂网络


 

C/S系统的层次结构

以下列出了分布式系统的主要层次:

²  用户界面:被分成表示管理表示逻辑。代表有主机框架的3270仿真终端;UNIX系统的X终端等,最新的Web浏览器界面也是。

²  商业逻辑:包含应用逻辑应用规则

²  数据管理:分为数据访问逻辑(SQL)和数据库管理。

区分C/S结构的类型可以根据以下特性:

客户端和服务端程序间逻辑分布,如何实现层次功能;中间件产品及技术的使用。


 

C/S模式的演化

      上图列举了不同种类的C/S模式。其中大型主机系统仍然统治着最大的OLTP应用;基于X终端和UNIX工作站的应用在80年代后期兴起;廉价的WINTEL机器支持的Windows GUI通常用于2层模式;数据库新技术和OSF带领了3层应用模式。


 

基本C/S模式

       C/S系统是一种分布式系统,由其程序决定其特点:

²  客户端部分执行前端功能,如:提供用户界面,向后台发出用户请求的交易,将结果返回给用户。

²  服务提供一般后端功能,按交易组织,将结果返回前端。

²  交易是分散的,按需求的操作,可以被远程客户端访问的程序。

C/S模式可能会有如下优点:

²  减小客户端程序体积,提高反应速度

²  位置无关

²  模块化

²  扩展性好

 


 

可管理多层C/S模式

 

 

       在可管理多层(Managed Multi-Tier –MMT)C/S模式中,提出了中间件管理。在本书范围内,此点由交易处理(TransactionProcessing –TP)管理完成,提供以下功能:

²  在客户端和服务端之间进行通讯和传输

²  提供良好的系统管理

²  提供交易、配置的分布式管理

它管理服务端从多个客户端收到的数据流,并不是在C/S间建立一对一的关系,而且客户端可以向多个服务发出请求。这种特点保证了TUXEDO可以提供强大的分布式交易处理框架。

由于不必进行通讯和交易管理,数据库引擎可以专注于其特长:管理数据!在这种情况下,数据库成了一个纯RM(Resource Manager)。


 

MMT C/S模式给OLTP应用增加了如下优点:

²  所有C/S模式的优点在MMT模式下都得到了增强。实际上,由于中间件的引入,处理能力得到改善。

²  由于中间件管理了数据流,带来了许多新功能,如:交易路由、服务分布、管道、数据依赖路由等成为可能。

²  统一的数据流控限制了最大交易数,总的数据库过程少了,服务器空闲时间也少了,这就增加了数据库和系统效率。

²  应用代码的设计可以不考虑物理地址和内部数据表示。

²  配置成了一件单纯的管理工作,进一步的,可以通过配置轻易的改变系统结构。服务可以动态的增加、删除和重启动。

 


TUXEDOC/S方案

       构成TUXEDO系统的各部分、工具和其特性组成的MMT C/S模式给应用带来的便利及TUXEDO的实现方法:

MMT C/S模式的优点

TUXEDO的实现技术

模块化

客户端,交易,服务

最大化的处理能力和流量

客户端交易流量控制,分布式配置,快速消息匹配和路由

通讯传输技术

ATMI访问,一种简单且容易定义的接口

实时应用管理

核心配置文件,MIB,管理工具和基于浏览器界面的GAI

名字服务和交易位置无关

公告牌提供目录交易便利

应用数据服务

应用服务位置可以在配置中随意配置

 


 

TUXEDO系统的特点

 

²  TUXEDO /T

n  管理C/S数据流

n  支持3层结构

n  多平台支持

n  协同(BEAConnect, /TxRPC, /OSITP)

n  开发

u  通讯手段

l  同步

l  异步

l  会话

l  广播通知

l  管道

l  事件订阅

u  缓冲数据类型(自动编、解码)

u  事务

n  管理

u  核心配置管理

u  管理信息库(MIB)

u  Web界面管理接口

u  负载平衡

u  网络配置

u  安全

u  数据依赖路由

u  数据压缩

²  BEA JOLT 将TUXEDO中间件框架扩展到Internet和Java客户端

²  TUXEDO /Q

n  通讯保障

n  预定处理

²  TUXEDO /WS

n  多平台支持

n  把BEATUXEDO ATMI API扩展到客户应用程序中

²  TUXEDO /Domains

²  TUXEDO /COBOL


 

一个例子

  一个TUXEDO 应用可以分成3部分

²  发布交易请求的客户端

²  运行响应请求交易的服务

²  描述应用机器和服务信息的配置文件

上图是本例的示意图:

       客户端请求交易“TOUPPER”,数据是“hello world”。交易“TOUPPER”将字符串转成大写,将结果成功返回客户端。


 

客户端范例

#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系统的头文件”atmi.h”,以便引用TUXEDO的函数和变量定义。

客户端调用tpinit()连接应用

用tpalloc()分配一个STRING类型数据缓冲

将”helloworld”拷贝进缓冲

用tpcall()包含数据缓冲,向交易“TOUPPER”发一个同步请求

打印出改变的数据缓冲

调用tpterm()切断与应用的连接

 


 

交易范例

#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系统头文件”atmi.h”

象所有的TUXEDO交易函数一样,TOUPPER不用直接返回任何值,所以返回类型为void

从客户端收到的数据放在TPSVCINFO结构中,是唯一的入参

交易处理…

用tpreturn()将数据缓冲返回客户端


 

配置文件

       有关应用的信息,如可用交易,交易位置,应用范围等,有必要集中管理于单一资源。事实上,这些信息被集中于文件UBBCONFIG。该文件分7节,主要部分内容描述如下:

*RESOURCES节包含全局信息,如:标识公告牌位置的唯一键值(IPCKEY),主控节点的名字(MASTER),应用类型(MODEL),下文例子中设为SHM表示是一个单节点应用。

*MACHINES节包含节点信息,如:机器物理名,TUXEDO系统位置(TUXDIR),服务码位置(APPDIR),以及本文件的二进制码文件名(TUXCONFIG)。

*GROUPS节包含一些管理用信息,如设定服务或交易的分布式事务处理。

*SERVERS节包含需要启动的交易和其组信息等其他信息。

*SERVICES节包含影响应用操作方式的的必要信息。本节列出的交易都是需要特别配置的,如有特别的优先级,装入参数,数据依赖路由等。


配置文件范例

#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


 

建立应用

       建立一个TUXEDO应用,必须进行以下步骤:

²  设置环境变量。

TUXDIR表示TUXEDO用户目录;TUXCONFIG是二进制配置文件名;在路径中加入TUXEDO的可执行文件路径;如果用到公共库,还必须包含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

²  用buildclient命令从源程序编译出客户端可执行文件。

buildclient –f client.c –o client -v

²  用buildserver命令从源程序编译出服务端可执行文件。-s参数列出提供的交易。

Buildserver –f simpserv.c –o simpserv –s TOUPPER -v

²  用tmloadcf命令从文本配置文件ubbconfig生成二进制配置文件tuxconfig。

Tmloadcf –y ubbconfig


 

开发TUXEDO C/S系统的必要步骤

²  配置环境变量

²  编码并编译客户端和服务端的程序

²  由文本的ubbconfig生成二进制TUXCONFIG

²  启动系统和服务

²  测试应用

²  关闭系统

 


 

小结

l  客户端/服务器模式的演化

l  用TUXEDO管理多层客户端/服务器模式

l  一个简单应用:simpapp

 

 

 


客户端开发    Client Development


本节要点

l  客户端在客户端/服务器模式中的作用

l  开发客户端的过程

l  查找错误

tperrno,tperrordetail

tpstrerror(),tpstrerrordetail()

userlog()

l  使用ATMI

进程管理

缓冲管理

请求/响应通讯

l  建立并编译一个TUXEDO客户端应用

buildclient


客户端在C/S模式中的作用

 

 

       为了更好的了解客户端的所有任务以编写客户端应用,有必要重新认识客户端在C/S模式中扮演的角色。

       首先,客户端是用户界面。意思是当用户在系统上用程序进行一次操作的整个过程就是一个客户端过程。前端过程是对客户端的另一个描述。客户端的首要任务就是获得执行操作应该得到的数据。

       一旦客户端得到了应有的信息,应该将数据按服务能够识别并适合传输的格式打包。

       然后,向服务端发送请求并等待回应。

       收到回应数据后,将其按一定格式返回给终端用户。

 

                                                          

 

 

 

 


客户端开发过程

       客户端程序的设计和实现可以被分成2部分考虑:

² 用户处理过程

² TUXEDO功能部分

下文的客户端程序只描述了TUXEDO功能部分。

利用TUXEDO的ATMI API调用可以做到:

——基本的TUXEDO调试技巧(tperrno,tpstrerror,userlog)

——TUXEDO进程管理(tpinit,tpterm)

——基本数据缓冲管理(tpalloc,tprealloc,tpfree)

——基本通讯(tpcall,tpacall,tpgetrply)


 

调试和错误处理

 

       当调用ATMI出错时,返回值为-1,全程变量tperrno被设值,该变量提供系统定义的出错原因。函数tpstrerror()以此变量为参数,返回错误的字符说明信息。

       完整的错误号和文本错误信息存在于文件$TUXDIR/include/atmi.h。

       函数userlog()重定向输出文件为ULOG.mmddyy。使用方法同printf()。该函数每次输出都写硬盘,这样在系统失败时也能保留调试信息。

 

代码范例

 

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 – 日志文件

 

 

 

 


 

进程管理

 

       为了使客户端能够访问TUXEDO交易,客户端程序必须连接TUXEDO应用并进行登记。这种管理性步骤在切断连接时也要类似执行一次。API如下:

 

inttpinit(TPINIT *tpinfo)

 

客户端通过调用tpinit()与应用连接,进行交互,有以下事件发生:

调用安全接口检查客户端是否需要认证

连接BB,使进一步的ATMI函数得到信息

使BBL了解BB中已经存在请求

建立客户端消息队列使服务可以发回返回信息,系统可以送出广播通知等

 

错误时返回-1,可能由以下原因引起:

²  TPEINVAL         参数错误

²  TPENOENT      BB无空间

²  TPEPERM         无连接权限

²  TPEPROTO      协议错误 – 被服务调用

 

inttpterm()

 

客户端调用tpterm()切断与应用的连接,结束了客户端的TUXEDO进程,该过程发生以下事件:

BB入口删除,使BBL知道客户端已经离开

客户端离开BB,客户端的信号量被移除

客户端消息队列被移除

错误时返回-1,可能由以下原因引起:

TPEPROTO      协议错误 – 被服务调用

TPESYSTEM    /T系统下错误

TPEOS               操作系统错

范例

main()

{

       intret;

       ret=tpinit((TPINIT*)NULL);

       ……

       ret=tpterm();

}


 

数据缓冲管理

       ATMI提供函数分配(tpalloc(),tprealloc())、释放(tpfree())TUXEDO数据缓冲。应用负责将应用数据填入缓冲。应用的数据类型和组织决定应该选择何种数据缓冲。函数type()可以返回正在使用的数据缓冲类型。

       以下是TUXEDO基本的数据缓冲类型:

² STRING      以空值结尾的单域字符数据。

² CARRAY    有长度定义的单域二进制数据,不进行编、解码。

² VIEW           类C结构或COBOL记录的多域组织。

² FML             无固定结构的自定义缓冲。

tpalloc(),tprealloc()在出错时返回空值,可能由以下原因引起:

² TPEOS        操作系统

² TPEINVAL  非法或不正确的类型

² TPESYSTEM    TUXEDO之下的错误


 

范例

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));

       }

}

函数用法

(char *)tpalloc((char *)type,(char*)subtype,long size)

(char *)tprealloc((char *)bufptr,longnewsize)

void tpfree((char *)bufptr)

 

 

 

 

 

 

 

 


 

同步通讯

      

函数tpcall()有6个参数。如下:

²  交易名

²  请求数据缓冲

²  请求数据缓冲的长度(仅缓冲类型为CARRY时需要)

²  返回数据缓冲的地址。缓冲大小可以根据收到数据而改变。

²  返回数据缓冲大小的地址

²  标志量

标志量可以是以下值:

²  TPNOTRAN      如有交易不调用

²  TPNOBLOCK   如有阻塞不等待

²  TPNOTIME        愿意等待直到超时

²  TPSIGRSTRT   系统中断信号在TUXEDO完成后再发布

出错返回-1,错误原因如下:

²  TPEINVAL  参数错误

²  TPETRAN  交易相关错误

²  TPETIME    超时

 

代码范例

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个异步通讯函数

² tpacall()

² tpgetrply()

tpacall()有4个参数

²  交易名

²  请求数据缓冲

²  请求数据缓冲的长度(仅缓冲类型为CARRY时需要)

²  标志量(同tpcall())

返回值是一个非负描述符(句柄),用于其后的tpgetrply()调用。如果tpacall()调用失败,句柄是-1,错误原因设置在tperrno,可能是以下值:

² TPELIMIT    过多未处理的tpacall()

² TPETIME    超时

tpacall()后总跟随一个tpgetrply(),有4个参数

²  变量地址,可以传入tpcall()所得句柄,或另设一个

²  返回数据缓冲的地址。缓冲大小可以根据收到数据而改变。

²  返回数据缓冲大小的地址

²  标志量

标志量的值可以是如下之一:

² TPGETANY                     取第一个返回值,设句柄

² TPNOCHANGE              取发送请求的匹配的类型的信息

² 参见tpcall()中的值

返回值0表示成功,-1表示失败,错误原因可能如下:

²  TPEINVAL         参数错误

²  TPEOTYPE              返回数据缓冲类型错误

²  TPETIME    超时

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语言客户端程序

       当C语言的客户端程序编码完后,需要连接正确的库并编译。使用buildclient可以使该过程容易一点。该命令引用了C语言编译器并按正确的次序连接TUXEDO系统的库。为使用buildclient,应确认客户端程序包含了”atmi.h”,TUXDIR被设了正确的值。命令语法如下:

buildclient[-v] –o executable –f first-file [-f first-file] [-l last-file]

       此处first-file表示的应该是编译器可以识别的文件。缺省的编译器是cc。一般是.c(c源程序),.C(C++源程序),.o(object)或.a(库)文件。

       参数解释如下:

-o    生成的可执行文件名

-f     需要在连接TUXEDO库之前传给编译器的文件名。如有多于一个的文件名,名字应用空格分隔并用引号引起。也可以使用多个-f参数。

-l     需要在连接TUXEDO库之前传给编译器的文件名。语法同上。

-v    编译过程显示。


 

小结

l  不同的客户端/服务器模式

l  用TUXEDO管理多层客户端/服务器模式

l  一个简单应用:simpapp

l  开发TUXEDO客户端

 


服务端开发    Server Development


本节要点

l  服务的运行流程

l  返回控制

l  创建服务

l  规划服务的考虑

l  启动和关闭

l  一个服务中的交易可以调用另一个服务中的交易

l  一个服务可以提供多个交易

l  发布交易


服务的运行流程

       为了更好的了解服务端的所有任务以编写服务端应用,有必要重新认识服务端在C/S模式中扮演的角色。

       首先,服务是系统资源的联系点。例如,一个数据库服务联系实际数据库并对其进行查询和修改。为有效进行,应建立一个数据库连接。

       其次,服务必须发布系统内可以访问的交易,保证客户端可以知道把请求发往何处。

       以上两步结束后,服务进入一个循环——接收请求、处理请求并返回结果。接收请求包括进入消息队列,得到交易请求。处理请求包括检查请求数据缓冲,运行商业规则和逻辑,可能还包括访问数据库和返回结果数据缓冲。

       当系统管理员需要关闭系统,可以通过系统管理工具将关闭系统的消息发给服务。服务完成所有交易,取消交易发布,关闭资源连接然后结束。


 

返回控制

 

       在一般的C程序中,函数通过调用return()将控制返回,函数调用堆栈清空,控制返回调用点。

       TUXEDO系统的交易函数必须结束于将回应返回给客户端或前转到另一交易。函数tpreturn()用来结束交易将回应数据缓冲发给客户端。函数tpforward()将交易前转给另一个交易,由其负责回应原来的客户端。下图是tpreturn()的示意图。

       tpreturn()设计来代替常规的return(),结束绝大多数函数。它将回应数据缓冲返回请求的客户端,控制权返回给服务程序的标准main()(由TUXEDO提供)。

 

       tpreturn()使用下列参数:

 

第一个值表示交易是否成功,有3种可能:

² TPSUCCESS   交易完全成功,如果是一个会话,TPEV_SVCSUCC被生成

² TPFAIL        交易失败,tperrno将被设成TPESVCFAIL。如果是事务模式,事务被标志成abort-only,如果是会话,TPEV_SVCFAIL被生成。

² TPEXIT              与TPFAIL类似,但服务会中断,如果服务设成可以重启动,则可以由TUXEDO系统将其重启动。

第二个值是应用定义返回码,此处使交易可以发送一个整形代码到客户端,给出交易处理结果的详细信息。该值与/T系统无关,通过全程变量tpurcode送到客户端程序。

第三个值是回应数据缓冲的的指针

第四个值是回应数据缓冲的长度(仅缓冲类型为CARRY时需要)

第五个值是标志位,通常不用

 


 

初始化和结束服务

       tpsvrinit()和tpsvrdone()分别用来启动和关闭服务。如果应用不提供这两个函数,可以使用替代函数。tpsvrinit()用tpopen()缺省打开RM连接。tpsvrdone()用tpclose()关闭RM连接。

       tpsrvinit()象标准C语言的main()一样使用参数argc,argv。服务的命令行参数可以传入该函数,被getopt()解析。该部分的用法参见应用配置部分。本函数出错时返回-1,成功返回0。

       tpsvrdone()无参数,无返回值。


 

创建服务

 

当C语言的交易程序编码完后,需要连接正确的库并编译。使用buildserver可以使该过程容易一点。该命令引用了C语言编译器并按正确的次序连接TUXEDO系统的库,连接TUXEDO生成的main()等。buildserver还用-s参数产生合适的交易名/函数名映射表。要使用buildserver,必须先正确设定环境变量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  

       参数解释如下:

-o    生成的可执行文件名

-f     需要在连接TUXEDO库之前传给编译器的文件名。如有多于一个的文件名,名字应用空格分隔并用引号引起。也可以使用多个-f参数。

-l     需要在连接TUXEDO库之前传给编译器的文件名。语法同上。

-v    编译过程显示。

-b    指定SHM或MP模式。如无此项,两种模式都包括;使用此项可以使生成的可执行文件小一点

-r     连接此处指出的RM库。该RM的名字必须含在$TUXDIR/udataobj/RM文件中。

 


 

规划服务的考虑

       在TUXEDO应用中,必要时服务可以仿客户端方式工作。例如:一个服务可能需要其他服务提供的交易,而建立一个副本并不太合理;当然,有时这样做会高效些。这种特性使程序员在多机配置应用逻辑可以改善编码和执行效率。关于这方面的例子,请参见TUXEDO提供的应用实例bankapp中的TRANSFER交易。

       一般是出于以下考虑,使用此种方式:

² 最好不要使用收到的数据缓冲向其他服务请求,因为该缓冲可能被改变引起错误

² 服务中的交易不应调用本服务中的交易,因为容易产生死锁(仅当设置TPNOREPLY时可以)

² 一个MSSQ集中的服务需要返回时,应有自己的返回队列;否则会与本集中其他服务冲突。

 

      


 

数据缓冲管理

数据缓冲管理大部分内容与客户端相同

与请求数据缓冲不同,传给交易的数据缓冲可能已经被tpalloc(),tprealloc(),tpfree()函数处理过。

因为传给交易的请求数据缓冲已经被tpalloc()分配,所以可以tprealloc()。

所有在服务中分配的数据缓冲,在程序结束时必须全部释放;唯一例外是用在tpreturn()中的返回数据缓冲。

如有剩余数据缓冲没有释放,会在每次交易调用时都生成一些,最终耗尽服务器内存。这可以很容易通过监视进程大小发现,它会随时间增长而加大。


 

仿客户端的方式

       下图展示的流程控制表示一个服务仿客户端方式工作。服务接收客户端请求,进一步向另一个交易进行请求。后者处理后返回前者,前者继续进行处理,准备回应数据缓冲,发回客户端。

此结构不能超过2级!


 

转发的方式

       下图展示的流程控制表示交易请求从客户端来到一个服务,转发到另一个服务,然后返回客户端。

 


 

多个交易

       一个商业应用处理可能会需要来自不同数据源的相似信息或功能。

       例如下图,TUXEDO有多种方式实现:

² 各交易功能分隔在独立的可执行服务中

因为功能分布在不同的可执行服务中,编译如下:

buildserver –f read70.c –o read70 –sREAD70

buildserver –f read80.c –o read80 –sREAD80

buildserver –f read90.c –o read90 –sREAD90

² 将不同功能组织在一个可执行服务中,分隔成不同交易

服务程序包含3个交易函数,编译如下:

buildserver –f read.c –o read –s READ70–s READ80 –s READ90

² 合并各功能成一个交易,使用别名调用

使用TUXEDO的别名功能,使交易以不同名字发布,如:

buildserver –f read.c –o read –sREAD70,READ80,READ90:READ

READ是真正的交易函数,但服务可以接受对READ70,READ80和READ90的请求


 

动态发布

 

       当交易运行时,交易可以用tmadmin在启动时发布,也可以通过调用ATMI动态发布。交易例程可以通过调用服务发布或取消发布。

tpadvertise()可以被一个服务调用,发布一个交易

tpunadvertise()可以被一个服务调用,取消发布一个交易

tpadvertise()

该函数允许服务为自己动态发布一个交易,参数如下:

²  被发布的交易名

²  交易请求处理函数地址

返回值-1表示失败。

       如果交易已经被同一函数发布,tpadvertise()立即返回成功。

       如果tpadvertise()被一个MSSQ集中的服务调用,交易被发布到该集所有服务上。

       出错原因包括:

² TPEMATCH 交易已经被其他函数发布

² TPELIMIT 可发布交易最大数已经达到,该限制在配置文件中的MAXSERVICES规定

² TPEINVAL  有参数为NULL

² TPEPROTO 协议错误(如被客户端调用)


动态发布范例1

$tmadmin

>advertise AUDIT:doaudit –g SYSGRP –i1

AUDIT发布在组SYSGRP,服务srvid=1

 

动态发布范例2

void Adminservices(TPSVCINFO *transb)

{

       /*取时间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)

{

……

}

 


应用配置ApplicationConfiguration


 

本节要点

l  应用配置概览

l  管理进程

l  使用IPCS资源

*RESOURCES

*MACHINES

*GROUPS

*SERVERS

*SERVICES

l  管理命令


应用配置总览

 

       应用的描述信息配置在系统核心位置,用一个文件描述,通常称为ubbconfig文件,在主控机器上。整个TUXEDO系统的管理任务可以在一台机器上完成,在配置中被定为主控节点。

       在运行时,这些信息被装入一段共享内存(一个IPC资源),称为公告牌(Bulletin Board—BB);包含有配置中不同机器的信息,在这些机器上运行的服务的信息,这些服务提供的交易的信息以及其他相关信息。

       客户端在运行时连接公告牌。当客户端程序调用一个交易,将根据公告牌找到合适的服务队列。

       所以,公告牌是:

       ——供客户端寻找适当的服务运行一个交易请求

       ——包含应用信息:机器,服务,交易,网络等

       ——创建于ubbconfig文件

       TUXEDO提供一个管理进程,称为BBL(Bulletin Board Liaison),包含了一个公告牌的本地拷贝和本地服务器上应用的状态。

       TUXEDO提供的另一个管理进程DBBL(Distinguished Bulletin Board Liaison),用于多服务器配置时。DBBL与BBL协同,保证所有部分的公告牌内容的一致性。


 

配置文件

       任何TUXEDO应用系统的最基本的管理任务,是建立并维护配置文件。该文件通常称为ubbconfig文件。负责该工作的系统管理员必须很好的了解分布于各台机器上的应用服务的数据流,消息队列的构造,资源间的相互关系。ubbconfig文件可视作包含应用启动信息的容器,需编译成二进制文件tuxconfig,作为启动时的参考。

       其内信息包括:

²  系统范围信息(*RESOURCES节)

²  机器信息(*MACHINES节)

²  组信息(*GROUPS节)

²  服务信息(*SERVERS节)

²  交易信息(*SERVICES节)

²  网络组信息(*NETGROUPS节)

²  网络信息(*NETWORK节)

²  路由原则信息(*ROUTING节)

当完成了ubbconfig文件后,用tmloadcf命令生成tuxconfig

另一种从ubbconfig生成tuxconfig的方法是使用图形管理界面(GAI—Graphical Administration Interface)。


 

应用的信息

 

       *RESOURCES节包含整个应用范围的信息。本节必须在配置文件第一节,不可缺少。信息说明如下:

 

参数                    意义

 

*RESOURCES *RESOURCES节

IPCKEY             共享内存id

UID                            TUXEDO管理员用户id

GID                            TUXEDO管理员用户id

PERM                TUXEDO管理员组用户的权限

MAXACCESSERS 服务端和客户端的最大进程数

MAXSERVERS              限制可以启动服务总数

MAXSERVICES             限制可以发布交易总数

MASTER                  指出主控节点的逻辑名,第二个是备份节点

MODEL                            应用构架,MP表示多机

OPTIONS          LAN,MIGRATE表示是一个网络应用,服务可以移植到替代处理器上

SECURITY               安全级别(5个)

AUTHSVC                客户端可以通过交易“AUTHSVC”获得认证

NOTIFY                     DIPIN,客户端通过dip-in收到广播通知

SYSTEM_ACCESS      PROTECTED,NO_OVERRIDE,应用代码不得干扰共享内存

LDBAL                      设Y则进行负载平衡

MAXBUF[S]TYPE   数据缓冲类型及子类的最大数

SCANUNIT              内部时间间隔单位,单位是秒

SANITYSCAN  检索公告牌的内部时间间隔,单位是SCANUNIT

BLOCKTIME     交易超时时间,单位是SCANUNIT

BBLQUERY      DBBL查询所有BLL的时间间隔

DBBLWAIT        DBBL等待BBL回应的超时时间

MAXCONV        同时最大会话数

 

注意:本处未列出全部参数。这些系统范围内参数可以被后序节内参数超越。

 

范例

 

*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

 

 

 

 


 

机器信息

 

       *MACHINES节包含应用有关的每个处理器的信息。本节必须在*RESOURCES节后列出。

参数                    意义

*MACHINES     MACHINES节

gumby                物理处理器名,可以通过”uname –n”或节点名得到

TUXDIR             TUXEDO系统软件安装位置

APPDIR             应用服务位置全路径

TUXCONFIG     TUXEDO配置文件全路径

ENVFILE           环境文件全路径

ULOGPFX         应用日志文件全路径

MAXACCESSERS 本机最多处理器数,可以超越*RESOURCES节定义

MAXCONV        本机最大会话数,可以超越*RESOURCES节定义

 

范例

*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节包含服务组的定义。一台机器至少要定义一个服务组。如果没有定义组,管理命令tmadmin可能依然能运行。

       每个组只要定义组名,映射组名的组号和逻辑机器名。组为分布式交易系统和数据依赖路由等灵活性措施提供了支持。

参数                    意义

*GROUPS         GROUP节

BANKB1            组的唯一标识符,可以是字母数字

GRPNO             组的唯一数字标识符

LMID                   组所在的机器

范例

*GROUPS

BANKB1     GRPNO=200    LMID=SITE1

BANKB2     GRPNO=220    LMID=SITE1

SYSGRP    GRPNO=110    LMID=SITE1

EVTGRP1  GRPNO=120    LMID=SITE1


 

服务定义

       ubbconfig的*SERVERS     节包含的是服务进程的信息。本节中每一个入口代表一个应用启动时加载的服务。这些信息包含服务名,命令行参数,服务环境,重启动等等。由于每个服务功能各不相同,其配置参数也因此相同或相异。

参数                    意义

*SERVERS              SERVER节,列出所有服务程序

DEFAULT:         本处列出的参数为其下列出的服务的缺省值,但可以被单列条目替代相应值

RESTART  如果设成Y,则服务可以重启动

MAXGEN    在GRACE定义时间之内,服务可以重启动MAXGEN次

GRACE              周期,单位是秒

       RCMD         每次服务重启动,本处定义的脚本或命令被执行

       ENVFILE    列有环境变量的文件,在交易启动前设入环境

TLR                     一个服务名,用buildserver建立,应在APPDIR或$TUXDIR/bin

SRVGRP    服务属于一个在*GROUPS节中定义的服务组;如果需要移植服务,也可以定义在多个组中。

SRVID         服务组中代表服务的唯一值

MIN              最少在启动时启动的服务数

MAX            运行时,最多可以起的实例数

CLOPT        跟随服务启动的其他参数

-A         服务内建交易全发布

–r           指定服务记录时间戳,用于以后计算交易处理时间

              -e         定义标准错误重定向文件

              -o         定义标准输出重定向文件

              --            TUXEDO参数和服务特定参数的分隔符

              …          传给tpsvrinit()的参数

SYSTEM_ACCESS             设定后,应用错误不干扰公告牌

RQADDR   当设定此项后,所有本服务的实例都使用相同的请求队列。这是在应用中设置MSSQ(Multiple Server Single Queue)的方便办法,可以改善处理流量。任何时候,所有MSSQ集中的实例发布相同的交易集。

XFER                 另一个服务

REPLYQ     设成Y,则服务又作为一个MSSQ集配置,任何其中的交易调用其他交易,就建立一个单独的回应队列。

范例

*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节提供了应用的特殊交易的信息。包括负载平衡(LOAD)和数据缓冲类型检查(BUFTYPE)。如果全部都是缺省值则本节可以省略。

参数                    意义

*SERVICES      交易节

#                          注释行符号

大写字母    交易名,由应用服务提供

BUFTYPE  任何向该交易的请求,数据应该是此处定义类型

GROUP      交易所在服务所在的组

LOAD          负载因子,表示处理请求的时间,用于计算负载平衡

PRIO           优先级

 

范例

*SERVICES

#comment line

DEPOSIT    BUFTYPE=”FML”

                     SRVGRP=BANKB1

                     LOAD=25   PRIO=70


 

 生成TUXCONFIG文件

       UBBCONFIG文件是一个可以编辑成需要的应用配置的文本文件。但是,/T在实际应用上读取的是二进制TUXCONFIG文件用于操作。命令tmloadcf可以把UBBCONFIG文件转化成TUXCONFIG文件。

       tmloadcf命令接受以下4个参数:

-c    计算运行应用需要的IPC资源,该信息将提供给管理员,用于在各机器上配置资源。

-n   进行语法检查并不生成TUXCONFIG。

-b    控制TUXCONFIG占用的物理页数。

-y    无条件覆盖TUXCONFIG

环境变量TUXCONFIG必须设定指向二进制TUXCONFIG文件。

在安全要求高的应用中,tmloadcf不能从标准输入接受,环境变量APP_PW必须包含应用密码。

tmunloadcf将TUXCONFIG转换成ASCII格式用于检查。该工具读取环境变量TUXCONFIG指向的文件。输出包含所有的参数,包括TUXEDO设定的缺省值,是UBBCONFIG文件的一个超集。


管理命令Administrative Commands


 

 

本节要点

l  命令tmboot

l  命令tmshutdown

l  命令tmadmin

l  批处理命令

l  服务移植


 

命令tmboot

tmboot命令启动TUXEDO系统的/T应用,创建必要的IPC资源、启动相关机器的规定的系统和应用服务进程。大多数的tmboot的参数启动了部分系统进程。在以下说明和例子中,lmid,grpname和srvid是配置文件中指定的值。

-A          启动所有机器上的管理进程。          

-M          启动主控机器上的管理进程。

-i srvid  启动服务id等于      srvid的进程。

-g grpname 启动指定的一组服务(含TMS)

-S          启动所有应用服务。

-s server-name 启动可执行文件名为server-name的服务。

-l lmid   启动TMS和指定机器上的应用服务。

-T grpname       启动指定组中所有TMS。

-B lmid         启动指定机器上的BBL。

-e command             指定启动进程失败后在主控机器上运行的命令名。

-c           打印本配置所需最少的IPC资源。

 


 

命令tmshutdown

tmshutdown命令用于关闭所有或部分应用并释放IPC资源。

本命令所用参数与tmboot类似(如:-A, -g, -i, -s, -S, -l, -M, -B),意义相同。

如果需要移动服务,关闭服务时用-R参数即可不删除BB中的入口。

在非主控节点上,可以用-P参数仅关闭该机器上的应用。

当有客户端正在连接时,tmshutdown 不能关闭管理服务。参数-c则可以超越此规则。该参数仅用于管理员需要立即关机而又无法及时通知客户端时。

参数-wdelay 在delay秒后进行强制关闭。指定的服务当即被挂起,使之不能继续接受交易请求。delay的值则允许服务在一个合理的时间内完成已经接受的请求。在延迟的时间到达后,信号SIGKILL(或SIGTERM)将发给指定的服务。该参数目的是使管理员能够关闭发生死循环或死锁的服务。


管理工作和工具

 

主要有以下两个管理工具:

²  使用图形界面的图形管理接口(Graphical Administration Interface—GAI)

²  tmadmin

通常管理工作有以下3类:

²  监视运行系统

一般监视以下信息:应用、服务、客户端、交易、队列、组、会话、网络等。

²  动态修改服务或交易参数

使用GAItmadmin可以动态进行以下调整:

——交易可以挂起、恢复、发布和取消

——交易参数可以修改,如:LOADPRIORITY

——指定交易的超时时间

——交易口令

²  进行启动,关闭,移动服务等管理员的任务

服务信息

       来自GAI的信息本处略去。

       以下是tmadmin命令的printserver(简写为psr)的简单输出。

列号             描述

1.    服务的可执行文件名

2.    服务连接的队列名

3.    组名

4.    服务的数字id

5.    服务已经处理的请求数

6.    服务处理的全部请求的参数和

服务正在处理的交易,若为IDLE则服务当前是空闲

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)的简单输出。

列号      描述

1.    交易名

2.    交易函数名

3.    服务可执行文件名

4.    服务所在组名

5.    服务的数字id

6.    提供交易的机器的LMID

7.    交易已经执行的次数

8.    交易当前状态

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

:

 

队列信息

              以下是tmadmin命令的printqueue(简写为pq)[qaddress]的简单输出。如果不指定address,所有队列信息将被输出。

列号                           描述

1.    队列连接的服务的可执行文件名

2.    字符队列名,是RQADDR参数或一个随机值

3.    连接的服务数

4.    当前队列的所有请求的参数和

5.    实际请求数

6.    平均队列长度

7.    队列所在机器的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系统的日志信息。主要有以下信息:

客户端id,用户名和当前状态

登录的LMID和进程号(PID)

服务组和上一访问过的服务组

交易(启动/提交/中断)和会话的统计数字

中继队列id,通知方法和提交控制

列号                           描述

1.    已经登录的客户端机器的LMID

2.    用户名,由tpinit()提供的

3.    客户端名,由tpinit()提供的

4.    客户端连接后经过的时间

5.    客户端状态

6.    IDLE——表示客户端目前没有任何交易在工作

7.    IDLET——表示客户端启动了一个交易

8.    BUSY——表示客户端在工作中

9.    BUSYT——表示客户端正在交易控制下工作

10.  启动/提交/中断的交易数

> 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写脚本

输出所有服务/交易/队列信息

$tmadmin 2>&1<<!

echo

verbose

psr

psc

pq

!

挂起bankapp内所有AUDIT交易

(tmadmin2>&1 <<!

pq

!

) |

awk ‘BEGIN { print “tmadmin <<! \necho”}

{if ( $1 == “AUDIT”) print “susp –q” , $2, “-S $1”}

END {print “q\n!”}’ |

/bin/sh


移植服务

该功能使管理员可以将服务移动到其他位置。服务可以用migrategroup(migg)[-cancel] group移植一组服务,或用migratemach(migm) [-cancel] machine移植一台机器上的服务。

以下是移植服务的步骤:

1. 服务必须用tmshutdown或-R参数关闭。该参数包含公告牌中的服务名。  

2.在配置文件中的*RESOURCES段必须指明MIGRATE

*RESOURCES

OPTIONS   MIGRATE

 

3.在*GROUP段中,被移植的服务组在LMID参数中必须有替代位置。当移植机器时,所有组的LMID参数的替代位置必须相同。

*GROUP

APGP2 LMID=SITE1,SITE2

 

4.服务必须可以重启动,以下是*SERVERS段有关内容

*SERVERS

rz_Ecsb       SRVGRP=APGP2  RESTART=Y

 

移植在关闭后将被取消。migg 和migm–cancel 参数在服务关闭后从公告牌删除服务名。所以,服务需要重启动才可以使用。

$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

 

 


缓冲数据类型      Buffer Types


 

本节要点

l  STRING

l  VIEW

定义

伪代码中VIEW的使用

代码示例

l  FML

定义

伪代码中FML的使用

代码示例

l  结合FML和VIEW

l  CARRAY的定义

l  FML32和VIEW32


简介和STRING

TUXEDO使用固定类型的数据缓冲进行远程或本地进程间通讯。例如”STRING”就是一种包含了字符数组的一种数据缓冲。绝大多数商业应用需要不止一种数据。

TUXEDO已经预定义了一些数据缓冲类型用以传递各种数据。每种都有其独特的处理方法和相应特性。

STRING

STRING类型缓冲是一串以NULL结尾的字符。TUXEDO为STRING类型编、解码。无论缓冲分配了多大,将由NULL所在位置决定其长度。

TUXEDO的STRING缓冲的使用与C语言程序中的字符数组非常类似。

分配

buf = tpalloc ( “STRING”, NULL, 4*1024);

用法

strcpy ( buf “HELLO WORLD”);

调用交易

tpcall (“INQUIRY”, buf , 0, &buf,&len, 0);

 

 

 


 

VIEW

VIEW的概念和例子

TUXEDO使用VIEW类型数据缓冲处理结构或复杂数据类型。

使用VIEW的优点:

² 结构化数据表示,可以方便地访问数据元素

² 将多个数据元素绑定在一个定义良好的数据结构上

缺点:

² 所有数据元素都通过,不检查合法性

范例:

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的步骤:

² 建立一个VIEW文件

² 设置环境变量

VIEWDIR=$APPDIR

VIEWFILES=cust.V,other.V

export VIEWDIRVIEWFILES

² 编译VIEW文件

viewc –ncust.V

² 在代码中包含头文件

² 编译

² 运行

代码范例:

#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

 

概念

 

       预定义方式的VIEW有一些缺点:

²  改变不灵活

²  结构变化时,所有程序需要重新编译

²  即使没有数据,空间也被占用

为克服以上缺点,TUXEDO提供另一种预定义数据,按照‘名字/值’组对格式组织数据。该方式称为FML(Fielded Manipulation Language)。

FML由以下部分构成:

²  FML API

²  FML命令行工具

 

FML头部,包含索引

FLOAT1

5.00

DOUBLE1

12.34

LONG1

12345

SHORT1

12

域名

域值

 

 

使用FML的步骤

² 建立一个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   -       -

 

 

² 设置环境变量

FLDTBLDIR=$APPDIR:$TUXDIR/udataobj

FIELDTBLS=bank.flds,Usysflds

exportFLDTBLDIR FIELDTBLS

² 用mkfldhdr编译

mkfldhdrbank.flds

² 编码

参见下一章节

² 编译程序

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)

² Fprint()是一个有用的调试函数,因为它可以打印出缓冲内容而不需要定义数据类型和输出格式。

² Falloc()用于内部进程通讯

² Fcpy()用来复制FML的内容,特别是在不同服务的交易之间

代码范例:

#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();

}


 

结合FMLVIEW

       FML的使用需要进一步的考虑,例如,访问FML数据会慢一些,因为接口要插入或取回数据。在某些场合,需要进行一些推敲。而VIEW则提供了一个通用管理数据缓冲的方案。

       FML的优点是可以在机器间传递数据和灵活的存储数据。而VIEW则传递整个定义好的C结构,不管域里面是否有数据。可以使用它们的混合:FML-VIEWS。

       TUXEDO提供了2个API把FML转换成VIEW

²  int Fvstof(FBRF *bufptr,char *cstruct,int mode,char *view)将VIEW结构转成FML

²  int Fvftos(FBFR *bufptr, char *cstruct, char *view)   将FML数据转成VIEW结构


 

其他数据类型

       除FML,VIEW和STRING类型外,另外一个主要的数据缓冲类型是CARRY。

CARRY

CARRY数据缓冲类型是一种定长的,相对独立于机器的数据。

² 长度需要定义

² 不进行编/解码

² 可用来传递二进制数据

² 可以作为FML和VIEW的子项

² 用于文件、图形传输

FML32和VIEW32

       在对FML和VIEWS初始化时,寻址是16位的。随着主要的平台都变成32位的,TEXUDO增加了FML32和VIEWS32。

² 使用32位寻址方式

² 有更大的寻址空间(2GB)

² API与16位的相似,只在名字上加了‘32’字样

 


 

数据依赖型路由    Data Dependent Routing


 

本节要点

l  定义

l  过程

ubbconfig

 

 

 


简介

       当遇到非常巨大的数据需要传递时,可以将单一的数据分割成几个部分进行传递。分割的标准根据其商业应用而定。例如,可以根据省份、邮政编码或金额来分割数据。

       在TUXEDO中,数据依赖型路由解决了此类大型商业应用的难点,而且不需要进行任何程序工作。仅仅改变一下ubbconfig文件就可以了。

数据依赖型路由是根据数据缓冲区中一个指定域的值,把一个交易请求映射到一个指定的服务组的机制。

 

 


 

数据依赖型路由

       数据依赖路由(DDR-Data Dependent Routing)需要在UBBCONFIG文件中的*GROUPS节创建多个入口,并分割组中应用的资源或任务。每个组可以访问各自的数据库并且可以属于独立的机器。注意:一个组不能同时跨越一台以上的机器。

       一个有多组独立服务的大型数据库可以被分成几个独立数据集。

       此类数据分割的实现是通过对交易请求的缓冲数据值的路由。DDR是基于FML,FML32,VIEW和VIEW32数据缓冲。

     TUXEDO使用的路由信息位于共享内存中的公告牌。在ubbconfig文件中有特别的部分对路由进行定义。路由的定义包含了数据使用的域和数据区间及其对应的服务组。

       TUXEDO通过对比调用交易内码和共享内存中公告牌中数据路由的值的区间选择目标服务。

       在我们的例子中,路由决定于数据域ID。交易请求映射于组G1,G2和G3。每个远程或本地机器上的组都提供相同的交易。

 


使用DDRubbconfig的范例

*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节说明

LMID与每个组相联系。本例中是同一台机器上的设置。当然也可以设成远程机器。

*SERVICES节说明

分割标准是为此交易设置。ROUTING是分割标准的名字

*ROUTING节说明

FILED表示请求交易的那些值用于映射组。

BUFTYPE表示其缓冲数据类型。RANGE定义路由到不同组的数据边界。

可以使用通配符’*’。


 

网络    Networking


简介

 

基于以下原因,一个商业应用需要分布于多台机器上:

²  负载均衡

²  容错

²  地理分布

       使用TUXEDO,不需编程,应用就可以被分布配置在多台机器上。


        

本节要点

l  概念

l  UBBconfig

 

 

 


 

多机配置

TUXEDO通过一些部件实现和管理一个多机应用。以下是这些部件和功能描述:

 

 

部件

功能

BBL

BBL(Bulletin Board Liaison)记录所有应用服务状态,显示于公告牌(Bulletin Board)。BBL同时修改来自DBBL的全局信息。

DBBL

DBBL(Distinguished Bulletin Board Liaison)记录所有BBL的状态。运行于主节点上,只有一份。

BRIDGE

提供TUXEDO节点间的通讯机制,仅处理ATMI数据。作为系统提供的服务,是最早启动的两个进程。

tlisten

‘tlisten’在启动过程中被使用,必须先于TUXEDO应用的启动。

 

 

 

 

多机配置

tlisten用法

tlisten –d /dev/tcp –l//lcspn1:3050 –L/usr/apps/atmapp/logs/tlog

特点

² 无须编程

² 交易位置对程序员和用户透明

² 公告牌提供全局名字服务

 

 


 

一个简单的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节说明

MASTER参数表示TUXEDO在此处初始化它的启动次序,同时表示DBBL在何处运行,出错时SITE2将作为SITE1的备份。

BBLQUERY决定应用的BBL访问主控节点上DBBL的频率,单位是秒。

BBL在规定的BBLQUERY时间内没有响应,DBBL会发送一条信息给它,DBBLWAIT即等待响应的超时时间,单位是秒。

MODEL表示TUXEDO是否运行在多台机器上。

*MACHINES节说明

       描述了TUXEDO应用或系统安装的物理方面的信息。物理机器名”lcspn1”映射到逻辑机器名”SITE1”和LMID(Logical MachineIdentifier)逻辑机器标识符。

       参数TYPE用来决定是否在机器间传输时需要进行编、解码。它可被设置成任何字符串。当两机此参数不同时,进行编、解码。

*NETWORKS节说明

       在单机配置时,此节略去。在多机时,此节必须。

       TUXEDO机器间通过主机地址和端口号传递ATMI数据,这些由NADDR按以下的规定定义:

       //lcspn1              主机名

                               分隔符

端口号

NLSADDR定义的是tlisten进程的主机地址和端口号。

BRIDGE用于和其他TUXEDO机器通讯的网络设备由BRIDGE定义。

 

分布式事务处理Distributed TransactionProcessing


 

简介

       分布式事务处理(DistributedTransation Processing-DTP)是运行一组需要访问一定量资源的交易或工作的必须的功能。要求保证交易动作必须全部成功或者全部失败,不能存在‘部分成功’的情况。

       TUXEDO系统使用XA协议在本地与远程机器间协同事务活动。


 

本节要点

l  定义

l  XA

l  2段式提交协议

l  ATMI事务API

l  过程

l  ubbconfig

创建格式化事务日志

用ATMI交易API写程序


分布式事务处理和XA接口

分布式事务处理(Distributed Transation Processing-DTP)有能力处理多数据库间、全局事务而不必考虑交易各方及其资源的位置。

服务使用嵌入式SQL接口去访问数据库。在一个“全局交易”中TM和RM使用XA接口保证执行所有的资源访问动作。

全局事务通常最初被ATMI调用,包含一个以上的组;由客户端和服务端启动、提交或撤消。TUXEDO通过全局事务标识符(Global TransactionIdentifier-GTRID)控制所有参与部分。

RM               资源管理者(Resource Manager),本例中是一个数据库。

XA                控制RM提交或回滚所有动作的协议。

TMS                    TUXEDO的事务管理服务(Transaction Management Server),能够按XA协议与RM联系。TMS负责协调系统范围内事务相关资源管理。应用程序员可以通过ATMI事务API与TMS联系。

GTRID         全局事务标识符(Global TransactionIdentifier)。

TLOG           事务日志,用于跟踪交易所有部分。

 

 

 

二段式提交(2 Phase Commit)

 


 

分布式事务处理的UBBCONFIG

 

分布式事务处理的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节说明

       MAXGTT限制了一台机器上同时可以提供的GTRID数。最大值是2048,最小是0,缺省100;

       CMTRET设成LOGGED时表示tpcommit()在所有部分都成功预提交时返回;设成COMPLETE时表示tpcommit()在所有部分都成功提交才返回。

*MACHINES节说明

       TLOGDEVICE指出了该机器包含事务日志(TLOG)的文件系统。

       TLOGNAME指出了该机器的事务日志名字。

       TLOGSIZE指出了该机器事务日志的大小,单位是物理页数。最大值是2048,最小是0,缺省100

*GROUPS节说明

       TMSNAME是事务管理服务的可执行文件名

       TMSCOUNT是TMS启动的数量(最小2,最大10,缺省3)

       OPENINFO是一个用于打开RM的信息的字符串

       CLOSEINFO是一个用于关闭RM的信息的字符串

       AUTOTRAN设成N则该交易初始化成无事务方式,Y则反之。

       TRANTIME事务创建的超时时间,单位为秒。

创建事务日志的脚本

tmadmin <<!

crdl –b 500 –z /usr/apps/atmapp/logs/TLOG–O 0

crlog –m STIE1

!

为支持分布式事务处理,必须创建一个格式化的设备记录事务信息。上文是用tmadmin命令的脚本生成此种设备的例子。

 


 

ATMI 事务API

事务API通过ATMI给应用提供了以下操作

² 通过tpbegin(),tpcommit(),tpabort()控制事务的开始和结束。

int tpbegin(int timeout, long flags)

int tpcommit(long flags)

int tpabort(long flags)

² 通过tpsuspend(),tpresume()管理多个并发的事务。

int tpsuspend(TPTRANID *tranid, longflags)

int tpresume(TPTRANID *tranid, longflags)

² 通过tpscmt()设定提交返回方式为”logged”或”complete”

int tpscmt(long flags)

TP_CMT_LOGGED-在第一段后返回

TP_CMT_COMPLETE-在第二段后返回

² 通过tpgetlev()决定当前事务模式

int tpgetlev(void)

² 通过tpopen(),tpclose()为服务组打开或关闭RM

int tpopen(void)

int tpclose(void)

使用ATMI事务API的代码范例

/* 确保交易TRANSFER没有设成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事务API;本例使用了TUXEDO的NULL TMS配置。当TRANSFER被调用,首先起一个事务,调用交易WITHDRAWAL,然后调用交易DEPOSIT。如果一切都运行成功,TRANSFER调用tpcommit()结束事务。任何错误都将导致RM回滚事务。

 

 

 

 

 

 


管理类API AdminAPI(MIB)


 

 

 

本节要点

l  定义

l  过程

l  代码例子

l  错误处理和管理类API域


简介

       在TUXEDO下管理应用有很多手段,如下:

²  tmadmin

²  tmadmin的脚本

²  调用ATMI

²  X-Windows GUI

²  JAVA applet Web GUI

²  Admin API (MIB)

每一种方法都有其优点和适用场合。Admin API提供访问TUXEDO信息的控制方法和结构。这些信息被分类成组,称为管理信息库(Management Information Base—MIB)。通过Admin API可以访问MIB。使用AdminAPI有以下优势:

²  可访问的TUXEDO系统信息更多

²  管理应用有更高的灵活度

²  可以集成到外部系统工具中


 

AdminAPI(MIB)

       TUXEDO系统组成的各个部分都有自己的MIB,每部分的MIB是一组相关的类,每个类代表一个MIB可管理的实体或项目,有其自身的属性、许可权限和语义。TUXEDO系统的MIB有5部分,如下:

² TM_MIB

² EVENT_MIB

² APPQ_MIB

² WS_MIB

² ACL_MIB

下边的例子是访问TM_MIB并显示了/T部分的管理信息库。


 

范例

       AdminAPI使用了一些预定义的FML32的域,这些数据组织存放在文件$TUXEDO/udataobj/tpadm中。环境变量必须设置如下:

       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);

}

因为Admin API是基于FML32类型的数据,所以要包含TUXEDO系统头文件“fml32.h”。

因为Admin API要用一些预定义的域去访问MIB信息,如TA_OPERATION和TA_CLASS,所以要包含TUXEDO系统头文件“tpadm.h”。

用tpinit()连接TUXEDO系统。

分配一个FML32数据缓冲。

在本例中,我们通过“GET(ing)”得到“MACHINE”的信息。

用tpcall()调用.TMIB服务。

显示结果。

释放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域和错误处理

 

       除基本的域外,其他一些Admin API域在管理MIB信息时也非常有用。如:

在一个大应用中,server节会包含很多条目,以下3个域在取得这些信息时很有用。

 

TA_OCCURS

在请求时,表示需要得到信息的行数。

在返回结果后,表示成功得到信息的行数。

TA_CURSOR

表示上一次GET操作停止的位置。配合TA_OPERATION的GETNEXT属性,可以顺序遍历MIB。

TA_FILTER

客户端程序可以通过该域得到一个特定域信息

 

       使用AdminAPI发生错误时,在回应缓冲中会带回来自MIB的错误信息

 

TA_ERROR

返回一个长整形操作结果值,参见诊断信息

TA_STATUS

用文本格式描述错误

TA_BADFLD

如果有一个域发生错误,用一个长整形值描述出错的FML32域

 

代码范例

/* 得到前3项 */

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);

/* 如果出错打印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项*/

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一个NEW T_RESOURCE类,然后定义一个初始配置给应用

Unbooted App

Configured App

在有权限的UID/GID情况下,GET并SET任何TM_MIB(5)中任何类的任何属性。

Booted App

Unattached Process

在有权限的UID/GID情况下或用户是管理员,当返回值不是ACTIVE时,可以GET任何TM_MIB(5)中有合适权限的任何类的任何属性。

Booted App

Attached Process

权限在tpinit()时由授权key决定,可以GET任何TM_MIB(5)中有合适权限的任何类的任何属性。

 

 

代码范例:

 

#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在其系统框架中集成了进程间通讯安全功能。在商业应用中可以由用户决定安全级别。

       本节中,我们将讨论TUXEDO提供的不同的安全保障能力和应用实现的必要步骤。

 

 

 

 


 

本节要点

l  概念

l  管理文件和命令

l  ubbconfig

l  API使用说明

l  代码范例


概念

       TUXEDO系统在第一次ATMI调用时——tpinit()就进行安全工作。

       安全级别信息先传入tpinit(),在公告牌上进行校验,然后用AUTHSVR进行二次检查。如果验证通过,tpinit()允许客户端连上TUXEDO系统。

       TUXEDOAPI tpchkauth()用来决定应用的安全级别。下表是各安全级别认证需要的资源。

tpchkauth()的返回值

管理文件设置

UBBCONFIG的设置

TPNOAUTH

 

 

TPSYSAUTH

 

SECURITY APP_PW

TPAPPAUTH

tpusr

tpgrp

tpacl

SECURITY USERAUTH

ACL

MANDATORY_ACL

AUTHSVC AUTHSVC

 

 

 

 

 

 

相关管理命令

组命令

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

简要说明

       以上管理命令维护AUTHSVR的安全入口。只有安全级别要求到ACL(Access Control List)时,这些操作过程才是必须的。

       AUTHSVR对每一个用户进行认证。当客户端进程调用tpinit()去连接应用时,发生以下过程:

AUTHSVR校验用户名,客户端名和密码

当成功,AUTHSVR提供一不可伪造的应用key

每次交易请求时,客户端都要提交此应用key


 

ubbconfig有关安全的部分

*RESOURCES

AUTHSVC  “..AUTHSVC”

SECURITY “ACL”

*SERVERS

AUTHSVR  SVRGRP=”AUTHGRP”SRVID=100

                     RESTART=YMAXGEN=2 GRACE=0

                     CLOPT=”-A”

AUTHSVR提供的交易名字叫“..AUTHSVC”

SECURITY设置了安全的级别


 

客户端代码范例

#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或错误用以决定加密强度。

tpalloc()将分配一个TPINIT结构,存储与公告牌对比的密码。

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()还将根据TPINITNEED()分配一段空间存储用户密码。

       用tpinit()与TUXEDO连接。

 

 

 

 


事件代理       Event Broker


简介

       在事件代理出现前,所有的通讯由用户发起。通过事件代理,TUXEDO系统增加了另一种进程间通讯方式——通讯可以由事件发起。事件可以独立于客户端,促使其他活动发生。

       事件代理搜寻并报告一些预定义的事件,如系统错误和用户定义错误。

       在本节中,我们将研究事件监视模块,练习TUXEDO的’publish’和’subscribe’事件模块的程序设计。

      


 

本节要点

l  ubbconfig范例

tpsubscribe和tpunsubscribe的代码范例

tppost的范例


概念

       事件代理提供了这样一种通讯方式:一些进程可以发布消息给订阅了这些消息的进程或客户端。例如:服务可以在价格发生变化时发布信息,所有连接系统的客户端都可以收到信息。

       事件代理只能执行一些该事件预定动作,这些动作包括:

²  调用交易(tpacall)

²  将请求送入一个可靠队列(tpenqueue)

²  用户通知之类(tpnotify)

²  记录日志到ULOG.mmddyy

²  执行系统调用

主要有2类事件:

²  系统             TUXEDO系统内部活动引起,如网络故障等

²  用户定义     应用中与业务流程有关的

触发事件的ATMI API是tppost()。

订阅和取消订阅的ATMI API是tpsubscribe(),tpunsubscribe()。


 

 

Subscribing&  Unsubscribing ATMI

 

longtpsubscribe(char *eventexpr, char *filter, TPEVCTL *ctl, long flags)

 

进行订阅。返回订阅句柄,-1失败

char *eventexpr       表示事件的字符串,可以含有通配符*

char *filter          一个布尔表达式,决定是否收到消息。

TPEVCTL ctl     一个描述事件代理将进行的动作

flags                   可以是[TPNOTIME|TPSIGRSTRT|TPNOBLOCK]

 

inttpunsubscribe(long subscription, long flags)

 

取消订阅

long eventexpr tpsubscribe()返回的句柄

flags                   可以是[TPNOTIME|TPSIGRSTRT|TPNOBLOCK]

 

struct TPEVCTL

 

 {

       longflags;

       charname1[32];

       charname2[32];

       TPQCTLqctl;

}

调用另一个交易

ctl->flags=TPEVSERVICE;

strcpy(ctl->name1,”SERVICENAME”);

进入队列

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系统——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”);

       }

}

建立一个服务调用订阅事件,被调用服务是BANK_MANAGER,当交易BANK_TLR_WITHDRAWAL的AMOUNT域的值大于300.00触发。

       用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中分离交易金额;增加交易过滤规则:金额>300.00,给FML域赋值;调用tppost()。

 

 

 

 

 

 

 


 

Ubbconfig相应改变

*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              系统事件代理服务进程

TMUSREVT      用户事件代理服务进程

-f     指定了包含订阅信息的数据文件

-S   表示有第二事件代理,-p决定其轮循时间(单位:秒)

 

 


消息队列    Queued Message


 

本节要点

l  定义

l  基本队列

l  队列设定—qmadmin

l  高级队列

l  交易和管道

l  ubbconfig

l  代码范例


 

可靠队列

       当进程通过消息方式进行通讯时,消息在被取用前存储的地方称为消息队列。这些队列是一些存储空间,或者是内存(IPC消息队列),或在硬盘上。内存中的队列在写硬盘前可以清除;这样,在主机故障时,就有丢失信息的风险。基于硬盘的队列可以在主机或网络瘫痪时可靠地保存信息,代价是读写硬盘的开销。

       商业上用队列方式使任务可以同步完成。一般地,商业系统需要保证系统总是稳定可靠,良好地完成任务。传统上是使用昂贵的容错系统达到此目标,花费主要是在冗于硬件上,使用队列,往往只要复制部分系统就能达到此效果。

 

 

 

 


 

概念

       作为请求/应答通讯方式的一种替代,可靠队列允许商业应用通过同步或时序方式使用可靠存储队列进行通讯。BEA TUXEDO /Q提供了这种机制。

       其特性提供优点如下:

² 可靠传递

² 同步的、*处理

² 审计、恢复

/Q ATMI通过按照2段式XA事务协议操作,保证可靠的传输,并且有内建的错误处理能力处理意外情况。

 


 

基本队列

       /Q提供的API简单而功能强大,有以下两个函数:

² tpenqueue() – 将消息置入队列

² tpdequeue() – 从队列中得到消息

       队列由BEATUXEDO管理员创建,定义队列并指定大小。队列全部位于队列空间,队列空间的名字是函数参数之一。每个队列都有一个名字,函数通过名字调用队列。

tpenqueue()参数如下:

² 队列空间名

² 队列名

² 包含置入队列信息的结构

² 置入队列的数据缓冲

² 长度

² 控制标志

tpenqueue(qspace,qname,control_info,buffer,len,flags)

tpdequeue()参数如下:

² 队列空间名

² 队列名

² 包含取队列信息的结构

² 取队列的数据缓冲

² 长度

² 控制标志

tpdequeue(qspace,qname,control_info,buffer,len,flags)

 

 

qmadmin范例

       qmadmin是一个命令行工具,TUXEDO /Q的一个部分,使管理员可以建立基于硬盘的的队列;qmadmin用于在设备上建立、初始化、列出和删除队列和队列空间。

$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上建立一个400页的设备

用qspacecreate命令在设备上建立一个100页的队列空间QSPACE,有6个队列。

用qopen命令打开队列空间QSPACE。

用qcreate命令在队列空间QSPACE上建立队列DEPOSIT,FIFO方式,消息可以取出2次。同样建立队列REPLYQ。

 


 

高级队列

       每个队列都有与之相关的一些控制信息;其中绝大多数内容由应用设定,但是有些由BEA TUXEDO队列软件直接设定。

队列次序

       缺省的,消息进出队列的次序由管理员确定,一般是先入先出(FIFO-first in first out);但有时消息不需要立即处理,这样就需要其他的队列次序。BEA TUXEDO提供了几种方案解决之,有:

²  按优先级

²  按时序

²  先进先出

²  后进先出

管理员甚至可以合并使用上述几种方式决定队列次序。

按时释放

       当一个消息进队列时,程序员可以决定其在某时间前不可出队列。这个时间可以是一个定值(如:1月7号下午2点)或相对于入队列的时间。当程序试图出队列时,那些‘还没到时间’的消息是不可见的。例:

control_info->deq_time=3600;/* 3600秒后才可以出队列*/

control_info->flags=TPQTIME_REL;/* 表示相对时间值被设定*/

TPQCTL结构

TPQCTL结构用来控制一个消息如何进/出队列

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]

本节中有定义:

typedef struct tpqctl TPQCTL;

优先级

       一条消息可以被设置一个优先级;优先级决定消息相对于队列中其他消息的位置。高优先级的消息较靠近队列头,可以较早出队列。例:

control_info->priority=100;  /*设入队列优先级为**/

control_info->flags=TPQPRIORITY;      /* 表示优先级的值已经设定*/

返回和错误队列

       在将消息入队列前,程序可以定义两个队列:返回队列和错误队列。当消息出队列时,这些队列中存有原消息的处理结果:返回或错误消息。

相关标识

       应用可以在消息上加一个‘标记’,当消息被从一个队列移动到另一个队列并被应用的不同部分处理时可以识别它。这些标记被称为‘相关标识’。

超次序

       虽然队列被定义了一个固定的出/入次序,但有时应用需要超越这个次序。BEA TUXEDO的队列工具允许管理员配置程序入队列时可以超越次序的队列。

² 可以将一条消息置于队列头

² 可以将一条消息置于特定消息前

错误诊断

如果tperrno被设成TPEDIAGNOSTIC,则TPQCTL结构中的诊断域将被设成一个错误状态,有以下:

² QMEINVAL              调用时使用了非法标志值

² QMEDADMSGID    非法错误消息ID

² QMENOMSG    队列没有可以取出的消息

² QMEINUSE              队列中有消息,但现在不可用

 

事务和管道

事务

       事务是一种保证一系列操作全部成功或全部失败的机制;通常用来保证对数据库的多次操作全部完成。

       BEATUXEDO可以协调本队列修改、其他队列修改和数据库系统操作。当程序调用tpdequeue()将一条消息出队列时,事实上消息仅在程序事务确认时才从队列中除去。如果事务回滚或超时,消息仍在队列中;可以再次操作。系统从而有效地保障该消息仅被处理一次。

       TMQUEUE是一个BEATUXEDO系统提供的当程序调用tpenqueue()和tpenqueue()时将消息入、出队列的服务。tpenqueue()和tpenqueue()的第一个参数是队列空间名;该名字必须由TMQUEUE的一个交易发布过。

管道

       TMQFORWARD是BEATUXEDO提供的将消息通过调用tpenqueue()将消息前转的服务。

       消息将被发送到一个有与读出队列名匹配的交易的服务。消息将在一个事务中出队列并送给服务。如果交易失败,事务回滚、消息将被送回队列,可以重试的次数决定于队列配置;如果达到了限制次数,消息将送入队列空间的错误队列。

ubbconfig的相应改变

*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”

说明:

       每个队列空间需要单独创建一个组,本例中为QUE1。TMSNAME是事务管理服务的名字。TMCOUNT决定最少启动几个TMS_QM服务。

       TMQUEUE是处理tpenqueue()将请求置入队列的/Q服务。TMQFORWARD是将请求出队列并通过tpcall()将请求送相应的交易。-i决定再次读队列前应该延迟的秒数。-q决定前转请求的来源队列。

客户端代码范例

#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);

}


会话 Conversations


 

本节要点

l  简介

l  定义

l  ATMI

l  UBBconfig


简介

       作为对呼叫/应答方式的补充,TUXEDO提供了一种称为会话的通讯方式。该方式用于客户端和服务端需要进行大量、多次数据传输并保持连接时。在一个会话过程中双方会有多次发送和接收。例如,一对客户端/服务端之间传诵一个大的数据库查询结果游标时,需要进行几次传输。

       在呼叫/应答方式中,所有的数据必须在一次通讯中传递,不保留任何中间状态信息。在会话模式中,通讯双方使用了一种“半双工”协议。一个进程只能处于发送数据或接收数据状态之一。该通讯协议中,状态信息与数据一同传送。

       会话被用来传送大量数据,如:

²  报表

²  数据/图形文件传输

²  大型数据库查询

此模式必须进行另外的ATMI编程才能实现。以下函数协助实现此种连接:

² tpconnect() 建立连接

² tpsend() 发送信息

² tprecv() 接收信息

² discon() 撤消连接(出错时)

在会话持续期间,客户端被绑定在服务上。不利之处是服务在会话期间不能响应其他请求。

 

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应作的改动

*RESOURCES MAXCONV        域内缺省最大会话数

MACHINES       MAXCONV        本机器上最大会话数,可以超越*RESOURCES节定义的域内缺省最大会话数

*SERVERS              CONV=Y           定义该服务是一个会话方式的服务。

ubbconfig的例子

*RESOURCES

 MAXCONV      20

*MACHINES

 lcspn1              TUXDIR=”/usr/tuxedo”

                     MAXCONV=25

*SERVERS

 audit          SRVGRP=BANKB1      SRVID=1

                     CONV=Y

                     CLOPT=”-A”

会话方式的客户端源程序

main(int argc, char *argv[])

{

int   ret,cd;   /* 循环计数器 */

char *buf;    /* 数据指针 */

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域;

分配一个1K的ATMI缓冲;

使用tpconnect()连接名为’AUDIT’的一个会话交易;

客户端通过TPSENDONLY将通讯控制权交给服务端。此时无数据传送。返回的通讯描述符存储于cd,用来跟踪绑定在会话上的唯一服务过程;

数据首先被复制到ATMI缓冲中;

数据被发送到会话服务上;

第二部分数据被复制到ATMI缓冲中;

用tpsend()发送到会话服务上;

客户端用TPRECVONLY标志放弃控制权。此处调用tpsend()没有发送数据,客户端准备接收数据;

客户端用tprecv()接收数据。

会话方式的服务端源程序

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

以上宏定义在程序中用到;

当客户端刚连接交易时,状态被设为RECEIVE;

此部分代码是会话交易在RECEIVE状态中;

tprecv()用来接收客户端数据;

协议在以下情况把状态由RECEIVE转成SEND:

tprecv()返回-1

tperrno被设成TPEEVNT

revent被设成TPEV_SENDONLY

在状态变成SEND后,服务可以调用tpsend();

如果协议有“部分”失败,服务切断客户端连接去处理错误;

代码将会话交易状态转成SEND;

使用tpsend()发送数据;

在一次数据传送后,服务状态被设成DONE;

注意tpreturn用来结束一个成功的会话;tpdiscon()用于出错时结束会话。


广播通知Unsolicited Notification


 

本节要点

l  定义

l  ATMI


简介

       一般情况下,客户端发起并控制通讯。TUXEDO额外提供了一种允许客户端接收消息的通讯方式。该通讯方式的发起方可以是其他客户端或服务。我们称之为广播通知。

       有两种方式的广播通知:目标是一个客户端(通知);目标是多个客户端(广播)。

       为接收此种非主动请求信息,客户端必须指定处理此种信息的回应函数。客户端通常使用信号传递处理信息。而不使用此种方式的客户端可以通过tpchkunsol(),或DIPIN方法处理此种信息。当任何TUXEDO ATMIAPI 被调用时,DIPIN被定义成此类信息的检查标志。

       管理员使在系统出错时用此类信息通知客户端。此外,该类信息还有其他许多用途。

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中的相应信息

*RESOURCES NOTIFY       DIPIN

TUXEDO 将用DIPIN方法与客户端进行广播通知方式的通讯。

客户端使用广播通知方式通讯的源代码

#include <atmi.h>

void main()

{

/*作为一个柜员客户端连接TUXEDO——tpinit()*/

if ( tpsetunsol(unsolfunc)==TPUNSOLERR)

{

       printf(“tpsetunsol():%s\n”,tpstrerror(tperrno));

}

tpchkunsol();/*在一个轮循中*/

tpterm();

}

void unsolfunc(char *data,long len,longflag)

{

       printf(“Unsolicitedmessage is %s”,data);

       return;

}

客户端连接TUXEDO域;

客户端登记回应函数,unsolfunc,当收到广播通知的信息时触发;

客户用tpchkunsol()端轮循处理信息;

接下来是回应函数的定义;

在本例中,广播通知的信息是一个字符串,客户端将其打印出来。

 

服务端广播通知消息的源代码

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缓冲,所以,先分配一个ATMI缓冲。

用tpnotify()发送消息给请求了UNSOL交易的客户端。

服务使用tpbroadcast()将同一消息发送到SITE1上所有以TELLER登录的用户。

 

 

 

 

 

 工作站的客户端workstation Client


简介

BEA TUXEDO 的/WS部分实际上是工作站扩展件。此前,所有的客户端平台都是运行着TUXEDO系统的UNIX,这就限制了TUXEDO的客户端只能运行于UNIX平台。在今天是不可思议的。

       /WS通过以下几点突破了以上限制:

² 允许远端不需公告牌即可运行

² 不需要TUXEDO系统域资源

² 不限制客户端的平台

² 服务器上无进程对客户端的一对一的限制

突破这些限制后,服务器不再考虑客户端的表示,不必管理大量的客户端进程而专注于TUXEDO和应用服务,大大扩展了系统的可伸缩性。

本节中,我们开始研究/WS应用。


 

 本节要点

l  定义

l  过程

l  改变ubbconfig

l  网络阻塞

l  buildclient


概念

       远程/WS客户端(WSC)可以是UNIX或WINDOWS客户端。所有的客户端与TUXEDO通过工作站监听进程(WSL-Workstation Listener)和工作站处理进程(WSH-WorkstationHandler)进行通讯。

       当客户端进行tpinit()或tpchkauth()调用时,进程读取本地环境变量WSNADDR。该变量应该与监听连接请求的WSL进程的地址相符。地址值设定在WSL可执行服务的CLOPT的参数中。

       WSL进程处理请求,将WSC的网络地址通知WSH进程。WSH进程处理WSC与TUXEDO系统的进一步通讯。

       WSH将请求发给合适的服务并将结果返回WSC。如果交易在远程机器上,WSH将请求发给BRIDGE,由它将请求前转到合适的节点。

      

      


 

ubbconfig的相应变化

*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”

通知客户端的方式设为“DIPIN”,使用Windows的消息仿UNIX信号,若消息为WM_TIMER则对应tpchkunsol()。

MAXWSCLIENTS表示该机最多允许连接的工作站数目。

工作站监听进程启动参数如下:

-n   指定交易请求连接TUXEDO应用环境的监听进程的主机名和端口号。格式如下:

       //lcspn1              主机名

       :                 间隔符

       3060            端口号

-d    WSL和WSH用于传递ATMI数据的的设备

-m tmboot最少启动的WSH进程数

-M   tmboot最多启动的WSH进程数

-x    每个WSH支持的工作站数

-I     工作站连接应用许可的最大耗时

-T    无响应连接许可时间

 


 

PC上的环境变量设置

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可以是一些由逗号隔开的使用相同端口的地址,或由竖线隔开*选择端口。例:

WSNADDR=//lcspn1:3050,//lcspn2:3050  

WSNADDR=(//lcspn1:3050|//lcspn2:3050)

 

TUXDIR                    TUXEDO系统软件位置

WSNADDR                     WSL网络地址

WSDEVICE                    网络设备

WSENVFILE            环境变量文件

WSTYPE                  机器类型,控制编、解码

TMPDIR                    存储返回的目录

WSRPLYMAX         应用返回缓冲内存大小

APP_PW                  应用密码

编译:

buildclient –w –v –o atmclt –f atmclt.c

-w 表示是WS客户端,Windows将通过一个DLL去访问ATMI。

简介

 

/Domain作为TUXEDO的一组件,使独立的TUXEDO应用可以进行通讯和共享资源。每个应用环境视作一个’domain’。这种结构有以下优点:

l  仍然可以访问远程其他域的数据

l  应用管理工作可以分散进行

l  资源可以根据计算的需要合适地分配

一个域可以跨越多台(个)机器或处理器。所有的客户端通过BB(Bulletin Board)了解所有的机器上提供的交易。BB间的一致性通过DBBL(DistinguishedBulletin Board Liaison)来保证。

通过/Domain,可以维护独立于主域的BB,可以设定那些交易可以响应其他机器。当一个远程域提出一个合法的交易请求时,/Domain将请求发送到被请求域并把返回送到请求进程。

以下介绍进行域间通讯时需修改的配置。


 本节要点

l  概念解释

l  配置过程

——环境变量

——ubbconfig

——dmconfig

——dmloadcf

 

使用TUXEDO组件/DOMAINS时,需要对管理配置作一些改变。在以下例子中,会创建一个独立的测试应用环境(DOMAINIDTEST),它可以读取/请求另一个应用的交易(ProdCust)的数据。

服务GWTDOMAIN(GWT)负责响应域间通讯。GWADMDMADM是处理管理交易和域服务的管理服务。这些服务必须配置在UBBCONFIG文件中。配置信息必须在远程和本地应用环境中定义。

服务GWTDOMAIN通过TCP/IP协议与其他域进行通讯。物理上远程的域的应用位置是透明的。

服务GWTDOMAIN是双向的:可以处理远程域发来的请求也可以向远程域发出请求。

除UBBCONFIG外,配置/DOMAINS还需要一些信息。这些信息在DMCONFIG文件中。DMCONFIG的文本文件通过BDMCONFIG编译成二进制文件。


 过程

第一步:UBBCONFIG应作相应改动

       为/DOMAIN建立的新组应该和其他应用组隔离开。其一用于管理,其他是网关服务。

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



第二步:为域间请求创建DMCONFIG

       下文的ASCII数据存在的文件一般称为DMCONFIG,由此生成的二进制格式文件称为BDMCONFIG。以下的DMCONFIG存在于“TEST“域,用来请求远程的”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

第三步:创建DMCONFIG指定对域外提供的交易

下文的DMCONFIG位于域’prod’,该域将向其他域提供可调用交易:ProdCust。

域‘prod’上的DMCONFIG

#本地域信息

*DM_LOCAL_DOMAINS

                            #LMID

production         GWGRP=LGWGRP

                            #域描述:TDOMAIN即TUXEDODOMAINS

                            TYPE=TDOMAIN   

                            #域的唯一标识符

                            DOMAINID=”prod”

                            #交易的日志

                            DMTLOGDEV=”/usr/apps/atmapp/logs/DLOG”

#远程域信息

*DM_REMOTE_DOMAINS

test               TYPE=TDOMAIN

                            DOMAINID=”TEST”

*DM_TDOMAIN

                            #地址和设备名

prod                    NWADDR=”//lcspn1:3070”

                            NWDEVICE=”/dev/xti/tcp”

TEST                  NWADDR=”//lcspn2:3070”

                            NWDEVICE=”/dev/xti/tcp”

*DM_REMOTE_SERVICES

*DM_LOCAL_SERVICES

#远程域可以使用的交易

 ProdCust

 第四步:设定环境变量

/DOMAIN进程需要额外的环境变量去访问/DOMAINS配置信息

exportBDMCONFIG=/usr/apps/atmapp/atmapp.bdm

 第五步:编译ubbconfig

本过程是从两个域中相同的UBBCONFIG生成二进制文件TUXCONFIG。在本例中,UBBCONFIG的信息位于’ubbconfig’。

tmloadcf –y ubbconfig 

第六步:编译dmconfig

本过程是创建二进制DOMAINS配置文件,BDMCONFIG,在两个域中相同;而两者都有的文件‘dmconfig’内容是不同的。

dmloadcf –y dmconfig