domain将tuxedo应用融合在一起,在解决多应用的分布系统时,是一个很好的选择.
domain和WSL的区别
当client和tuxedo服务不在同一主机上的时候,在服务器端运行wsl使客户端能能够获取服务端的服务.
当两个tuxedo服务在不同的主机上,要相互调用时,使用domain,就是说两个主机上的server是对等的.
所以wsl是为了client->server,domain是为了server<->server.
下面举一个例子来说明domain的最基本的用法.
环境:
A主机:linux,tuxedo8.1,ip=192.168.1.113
B主机:winxp,tuxedo8.1,ip=192.168.1.113
应用概述
在A主机上面有一个tuxedo服务DOMAIN_TEST,现在有一个客户端,只能访问B主机上面的tuxedo服务,客户端为了得到A主机上的DOMAIN_TEST服务.
有两种办法:
一)在B主机上面建到A主机的DOMAIN_TEST服务路由,可以通过访问B主机的DOMAIN_TEST服务来达到访问A主机的DOMAIN_TEST服务的目的,可以采用配置domain来解决.
二)在B主机上面提供一个通用的服务DOMAIN_TEST,根据客户端的请求参数,决定在A的DOMAIN_TEST服务程序中采用tpcall来调用相应A主机上的tuxedo服务.也可以采用domain来解决.
A主机配置
A主机的ubbconfig,内容如下:
# (c) 2003 BEA Systems, Inc. All Rights Reserved.
#ident "@(#) samples/atmi/simpapp/ubbsimple $Revision: 1.5 $"
#Skeleton UBBCONFIG file for the TUXEDO Simple Application.
#Replace the <bracketed> items with the appropriate values.
*RESOURCES
#Example:
IPCKEY 123456
DOMAINID server_240
MASTER chenli
MAXACCESSERS 1000
MAXSERVERS 1000
MAXSERVICES 2500
MAXGTT 5
MODEL SHM
LDBAL N
BLOCKTIME 10
*MACHINES
DEFAULT:
APPDIR="/home/dev/app/src/bin"
TUXCONFIG="/home/dev/app/src/bin/tuxconfig"
TUXDIR="/home/dev/app/tuxedo8.1"
TLOGSIZE=500
MAXWSCLIENTS=50
#Example:
# APPDIR="/home/me/simpapp"
# TUXCONFIG="/home/me/simpapp/tuxconfig"
# TUXDIR="/usr/tuxedo"
#<Machine-name>
chenli_linux LMID=chenli
#Example:
#beatux LMID=chenli
*GROUPS
GROUP1
LMID=chenli GRPNO=1 OPENINFO=NONE
GROUP2
LMID=chenli GRPNO=2 OPENINFO=NONE
GROUP3
LMID=chenli GRPNO=3 OPENINFO=NONE
GROUP4
LMID=chenli GRPNO=4 OPENINFO=NONE
GROUPWSL
LMID=chenli GRPNO=6 OPENINFO=NONE
LGWGRP LMID=chenli GRPNO=7 OPENINFO=NONE
LDMGRP LMID=chenli GRPNO=8 OPENINFO=NONE
*SERVERS
DEFAULT:
CLOPT="-A -p" RESTART=N GRACE=86400
#=======================domain===========================================#
DMADM SRVGRP=LDMGRP SRVID=200
GWADM SRVGRP=LGWGRP SRVID=310
GWTDOMAIN SRVGRP=LGWGRP SRVID=320
#======================= GROUP1 servers Define ==========================#
simpserv SRVGRP=GROUP2 SRVID=200 MIN=1 MAX=2 REPLYQ=Y RQADDR="simpserv" MAXGEN=5
#WSL SRVGRP=GROUP1 SRVID=700 MIN=1 MAX=1 REPLYQ=Y MAXGEN=2 RESTART=Y CLOPT = "-A -t -- -n //192.168.1.201:3195 -H //192.168.1.201:3195 -m 5 -M 20 -x 3 -T 120 -I 30"
WSL SRVGRP=GROUPWSL SRVID=2 MAXGEN=2 CLOPT=" -A -- -n //192.168.1.113:3195 -m 2 -M 6 -x 10"
*SERVICES
SERV_TEST
TOUPPER
DOMAIN_TEST
#===================================================#
配置dmconfig,内容如下:
*DM_LOCAL_DOMAINS
TDOM02 GWGRP=LGWGRP
TYPE=TDOMAIN
DOMAINID="TDOM02"
DMTLOGDEV="/home/dev/app/src/bin/logs/DLOG"
*DM_REMOTE_DOMAINS
TDOM01 TYPE=TDOMAIN
DOMAINID="TDOM01"
*DM_TDOMAIN
TDOM02 NWADDR="//192.168.1.113:3071"
TDOM01 NWADDR="//192.168.1.100:3070"
*DM_REMOTE_SERVICES
*DM_LOCAL_SERVICES
DOMAIN_TEST
同设置好TUXCONFIG,BDMCONFIG环境变量.
执行tmloadcf -y ubbconfig,dmloadcf -y dmconfig编译配置文件,生成TUXCONFIG和BDMCONFIG二进制文件.
A主机上的服务程序simpserv.c,内容如下:
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <ctype.h>
#include <atmi.h>
#include <userlog.h>
#include "data.h"
extern "C"
{
int tpsvrinit(int argc, char *argv[])
{
argc = argc;
argv = argv;
userlog("Welcome to the simple server");
return(0);
}
}
#ifdef __cplusplus
extern "C"
#endif
void
#if defined(__STDC__) || defined(__cplusplus)
SERV_TEST(TPSVCINFO *rqst)
#else
SERV_TEST(rqst)
TPSVCINFO *rqst;
#endif
{
int i;
int x;
trans_data_t buf_data;
char *data = "how are you?";
char *ref;
int len = strlen(data) + 1;
userlog("start proccess SERV_TEST service");
ref = (char *)malloc(len);
strcpy(ref, data);
userlog("rqst->len=%d\n", rqst->len);
memcpy(&buf_data, rqst->data, sizeof(trans_data_t));
userlog("receive string:%s", rqst->data);
userlog("receive name:%s", buf_data.name);
userlog("receive age:%d", buf_data.age);
buf_data.age += 100;
memcpy(rqst->data, &buf_data, sizeof(trans_data_t));
//data = rqst->data;
tpreturn(TPSUCCESS, 0, rqst->data, sizeof(trans_data_t), 0);
free(ref);
}
#ifdef __cplusplus
extern "C"
#endif
void
#if defined(__STDC__) || defined(__cplusplus)
TOUPPER(TPSVCINFO *rqst)
#else
TOUPPER(rqst)
TPSVCINFO *rqst;
#endif
{
int i;
for(i = 0; i < rqst->len-1; i++)
rqst->data[i] = toupper(rqst->data[i]);
tpreturn(TPSUCCESS, 0, rqst->data, 0L, 0);
}
#ifdef __cplusplus
extern "C"
#endif
void
#if defined(__STDC__) || defined(__cplusplus)
DOMAIN_TEST(TPSVCINFO *rqst)
#else
DOMAIN_TEST(rqst)
TPSVCINFO *rqst;
#endif
{
int i;
for(i = 0; i < rqst->len-1; i++)
rqst->data[i] = toupper(rqst->data[i]);
printf("DOMAIN_TEST==============================\n");
tpreturn(TPSUCCESS, 0, rqst->data, 0L, 0);
}
编译以上程序,生成tuxedo的可执行server程序simpserv
主机B配置
B主机的ubbconfig,内容如下:
# (c) 2003 BEA Systems, Inc. All Rights Reserved.
#ident "@(#) samples/atmi/simpapp/ubbsimple $Revision: 1.5 $"
#Skeleton UBBCONFIG file for the TUXEDO Simple Application.
#Replace the <bracketed> items with the appropriate values.
*RESOURCES
#Example:
IPCKEY 123456
DOMAINID chenli
MASTER chenli
MAXACCESSERS 500
MAXSERVERS 200
MAXSERVICES 100
MAXGTT 50
MODEL SHM
LDBAL N
*MACHINES
DEFAULT:
APPDIR="D:\bea\tuxedo8.1\apps\simpapp"
TUXCONFIG="D:\bea\tuxedo8.1\apps\simpapp\tuxconfig"
TUXDIR="D:\bea\tuxedo8.1"
ULOGPFX="D:\bea\tuxedo8.1\apps\simpapp\log.txt"
MAXWSCLIENTS=40
#Example:
# APPDIR="/home/me/simpapp"
# TUXCONFIG="/home/me/simpapp/tuxconfig"
# TUXDIR="/usr/tuxedo"
#<Machine-name>
CHENLI LMID=chenli
#Example:
#beatux LMID=chenli
*GROUPS
GROUP1 LMID=chenli GRPNO=1 OPENINFO=NONE
LGWGRP LMID=chenli GRPNO=2 OPENINFO=NONE
LDMGRP LMID=chenli GRPNO=3 OPENINFO=NONE
*SERVERS
simpserv CLOPT="-A" SRVGRP=GROUP1 SRVID=1 MIN = 1 MAX = 5
DMADM SRVGRP=LDMGRP SRVID=200
GWADM SRVGRP=LGWGRP SRVID=310
GWTDOMAIN SRVGRP=LGWGRP SRVID=320
*SERVICES
SERV_TEST
TOUPPER
LDOMAIN_TEST
B主机上的dmconfig配置,内容如下:
*DM_LOCAL_DOMAINS
TDOM01 GWGRP=LGWGRP
TYPE=TDOMAIN
DOMAINID="TDOM01"
DMTLOGDEV="D:\bea\tuxedo8.1\apps\simpapp\dlog.txt"
*DM_REMOTE_DOMAINS
TDOM02 TYPE=TDOMAIN
DOMAINID="TDOM02"
*DM_TDOMAIN
TDOM02 NWADDR="//192.168.1.113:3071"
TDOM01 NWADDR="//192.168.1.100:3070"
*DM_REMOTE_SERVICES
DOMAIN_TEST
#*DM_LOCAL_SERVICES
#DOMAIN_TEST
编译ubbconfig和dmconfig,执行如下命令:
tmloadcf -y ubbconfig,dmloadcf -y dmconfig
B主机的服务端程序simpserv.c,内容如下:
#include <stdio.h>
#include <ctype.h>
#include <atmi.h>
#include <userlog.h>
#include "data.h"
#if defined(__STDC__) || defined(__cplusplus)
tpsvrinit(int argc, char *argv[])
#else
tpsvrinit(argc, argv)
int argc;
char **argv;
#endif
{
argc = argc;
argv = argv;
userlog("Welcome to the simple server");
return(0);
}
#ifdef __cplusplus
extern "C"
#endif
void
#if defined(__STDC__) || defined(__cplusplus)
SERV_TEST(TPSVCINFO *rqst)
#else
SERV_TEST(rqst)
TPSVCINFO *rqst;
#endif
{
int i;
int x;
trans_data_t buf_data;
char *data = "how are you?";
char *ref;
int len = strlen(data) + 1;
userlog("start proccess SERV_TEST service");
ref = (char *)malloc(len);
strcpy(ref, data);
userlog("rqst->len=%d\n", rqst->len);
memcpy(&buf_data, rqst->data, sizeof(trans_data_t));
userlog("receive string:%s", rqst->data);
userlog("receive name:%s", buf_data.name);
userlog("receive age:%d", buf_data.age);
buf_data.age += 100;
memcpy(rqst->data, &buf_data, sizeof(trans_data_t));
//data = rqst->data;
tpreturn(TPSUCCESS, 0, rqst->data, sizeof(trans_data_t), 0);
free(ref);
}
#ifdef __cplusplus
extern "C"
#endif
void
#if defined(__STDC__) || defined(__cplusplus)
TOUPPER(TPSVCINFO *rqst)
#else
TOUPPER(rqst)
TPSVCINFO *rqst;
#endif
{
int i;
for(i = 0; i < rqst->len-1; i++)
rqst->data[i] = toupper(rqst->data[i]);
tpreturn(TPSUCCESS, 0, rqst->data, 0L, 0);
}
#ifdef __cplusplus
extern "C"
#endif
void
#if defined(__STDC__) || defined(__cplusplus)
LDOMAIN_TEST(TPSVCINFO *rqst)
#else
LDOMAIN_TEST(rqst)
TPSVCINFO *rqst;
#endif
{
int i;
char *sendbuf, *rcvbuf;
long sendlen, rcvlen;
int ret;
rcvlen = sendlen = strlen(rqst->data);
if((sendbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
(void) fprintf(stderr,"Error allocating send buffer\n");
tpterm();
exit(1);
}
if((rcvbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
(void) fprintf(stderr,"Error allocating receive buffer\n");
tpfree(sendbuf);
tpterm();
exit(1);
}
(void) strcpy(sendbuf, rqst->data);
ret = tpcall("DOMAIN_TEST", (char *)sendbuf, 0, (char **)&rcvbuf, &rcvlen, (long)0);
if(ret == -1) {
(void) fprintf(stderr, "Can't send request to service DOMAIN_TEST\n");
(void) fprintf(stderr, "Tperrno = %d\n", tperrno);
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
exit(1);
}
(void) strcpy(rqst->data, rcvbuf);
tpreturn(TPSUCCESS, 0, rqst->data, 0L, 0);
}
编译服务端程序:
buildserver -o simpserv -f simpserv.c -s SERV_TEST -s TOUPPER -s LDOMAIN_TEST
B主机上的两个客户端程序client3.c和client4.c
client3.c内容如下:
#include <stdio.h>
#include "atmi.h"
#if defined(__STDC__) || defined(__cplusplus)
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{
char *sendbuf, *rcvbuf;
long sendlen, rcvlen;
int ret;
if(argc != 2) {
(void) fprintf(stderr, "Usage: client2 string\n");
exit(1);
}
if (tpinit((TPINIT *) NULL) == -1) {
(void) fprintf(stderr, "Tpinit failed\n");
(void) fprintf(stderr, "Tperrno = %d\n", tperrno);
exit(1);
}
sendlen = strlen(argv[1]);
if((sendbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
(void) fprintf(stderr,"Error allocating send buffer\n");
tpterm();
exit(1);
}
if((rcvbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
(void) fprintf(stderr,"Error allocating receive buffer\n");
tpfree(sendbuf);
tpterm();
exit(1);
}
(void) strcpy(sendbuf, argv[1]);
ret = tpcall("DOMAIN_TEST", (char *)sendbuf, 0, (char **)&rcvbuf, &rcvlen, (long)0);
if(ret == -1) {
(void) fprintf(stderr, "Can't send request to service DOMAIN_TEST\n");
(void) fprintf(stderr, "Tperrno = %d\n", tperrno);
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
exit(1);
}
(void) fprintf(stdout, "Returned string is: %s\n", rcvbuf);
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
return(0);
}
client4.c内容如下:
#include <stdio.h>
#include "atmi.h"
#if defined(__STDC__) || defined(__cplusplus)
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{
char *sendbuf, *rcvbuf;
long sendlen, rcvlen;
int ret;
if(argc != 2) {
(void) fprintf(stderr, "Usage: client2 string\n");
exit(1);
}
if (tpinit((TPINIT *) NULL) == -1) {
(void) fprintf(stderr, "Tpinit failed\n");
(void) fprintf(stderr, "Tperrno = %d\n", tperrno);
exit(1);
}
sendlen = strlen(argv[1]);
if((sendbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
(void) fprintf(stderr,"Error allocating send buffer\n");
tpterm();
exit(1);
}
if((rcvbuf = (char *) tpalloc("STRING", NULL, sendlen+1)) == NULL) {
(void) fprintf(stderr,"Error allocating receive buffer\n");
tpfree(sendbuf);
tpterm();
exit(1);
}
(void) strcpy(sendbuf, argv[1]);
ret = tpcall("LDOMAIN_TEST", (char *)sendbuf, 0, (char **)&rcvbuf, &rcvlen, (long)0);
if(ret == -1) {
(void) fprintf(stderr, "Can't send request to service LDOMAIN_TEST\n");
(void) fprintf(stderr, "Tperrno = %d\n", tperrno);
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
exit(1);
}
(void) fprintf(stdout, "Returned string is: %s\n", rcvbuf);
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
return(0);
}
编译客户端程序
buildclient -v -o client3 -f client3.c
buildclient -v -o client4 -f client4.c
测试
分别在A主机和B主机上编译server源程序,然后执行tmboot -y启动服务,然后在B主机上分别运行client4 www和client3 www都会返回Returned string is: WWW
程序解释
由上面配置可以看到A主机上才有真正的DOMAIN_TEST服务,通过在A主机B主机上分别配置domain来,是B主机能在server中访问A主机的DOMAIN_TEST���务.
客户端程序client3.c是直接访问B主机的DOMAIN_TEST服务,在这儿B主机是将对DOMAIN_TEST服务的请求转发到A主机,并将结果返回给客户端程序.
客户端程序client4.c是访问B主机的LDOMAIN_TEST服务,在LDOMAIN_TEST服务中,请求A主机的DOMAIN_TEST服务,并将A主机的DOMAIN_TEST服务返回的结果转发给客户端程序.