TUXEDO在线监控浅谈(二):用MIB实时监控系统状况之SERVER篇
TUXEDO提供了一套可编程的管理员 API接口(Management Information Bases),简称为MIBS。通过MIBS,可以方便的监控TUXEDO运行时的所有系统资源,例如SERVER和SERVICE的运行状况、 SERVER队列和消息队列的资源情况、客户端的使用情况、域间通讯的连接情况、系统的资源配置等,所有的资源你都可以通过MIBS的API来获取或者动态的修改资源配置。例如对于某些关键的SERVER或者SERVICE,我们想监控它在多少秒之内的被调用情况,服务是否出现异常或者是被挂起,SERVER对应的消息队列是否出现了堵塞或者是队列空间紧张,当SERVER出现请求反应较慢需要增加进程时,通过MIBS动态的增加进程个数。对于消息队列,我们需要监控消息队列当前的请求总数,队列中的长度是否达到了危险程度需要告警。对于客户端使用者来说,我们需要监控有那些客户端调用超时或者是调用已经被系统给挂起了,某些客户端调用出现异常导致系统性能下降,我们可以自动先将这些客户端请求给消除或者杀掉,根据客户端请求的全过程来找出问题。如果系统和其它外围系统存在着连接或者是分布式的TUXEDO系统,我们需要监控系统和其它系统的域间通讯连接是否正常,远端的系统是否还在正常运行。用一句话来概括,TUXEDO所有的应用都可以通过MIBS进行实时监控。
MIB接口规定了系统管理员,系统操作员和其它用户,三者具有不同的操作权限。MIB接口将系统资源划分为三种类型,分别为Classes和 Attributes和States。Classes指资源的分组,例如SERVER、SERVICE、CLIENT、QUEUE、MSG等。 Attributes指Classes对应的属性,例如SERVER的属性有SERVERNAME、SRVGRP、SRVID和运行时的参数值等属性。 States指Classes在运行时的状态,以及在运行时可以更改的属性。MIB的操作类(OPERATION)分为GET和SET两种类型,即指查询和设置两种操作。
Classes的类型有T_MACHINE、T_GROUP、T_SERVER 、T_SERVICE 、T_SVCGRP、T_QUEUE、T_MSG T_DOMAIN、T_CLIENT等,下面逐一介绍怎么获取这些类型的属性和运行时的参数,重点介绍T_SERVER 、T_SERVICE 、T_SVCGRP、T_QUEUE、T_MSG 、T_DOMAIN、T_CLIENT等几个我们主要关心的类型。
用MIBS的API查询系统资源的接口比较简单,跟客户端调用SERVICE方法一样,都是用tpcall()或者tpacall()。只是服务名为.MIB。输入输出的缓冲区类型为FML32。在调用之前我们需要指定几个查询参数TA_OPERATION和TA_CLASS、TA_FLAGS,已经Classes对应的参数,例如我们在查询T_SERVER这个Classes,我们想根据LMID、SERVERNAME、SRVGRP、 SRVID、RQADDR等参数来查询对应,那么就在输入缓冲区中输入对应的参数值。
首先我们来介绍T_SERVER这个Classes。T_SERVER就是我们在TUXEDO配置文件的SERVER节中所定义的SERVER。用 MIBS来查询SERVER在运行状态下的数据,可以获取到SERVER的配置参数值,以及SERVER运行时的其它动态参数值,例如进程ID(操作系统的PID),请求消息队列的PID,回复消息队列的PID,队列名称,SERVER当前处于被请求服务的SERVICE,SERVER被调用的次数、已经完成的调用次数,还没有完成的请求数等。
代码简单如下:
obuf = (FBFR32 *)tpalloc("FML32",NULL,8000);
Finit32(obuf, (FLDLEN32)Fsizeof32(obuf));
Fchg32(obuf, TA_OPERATION, 0, "GET", 0);
Fchg32(obuf, TA_CLASS, 0, "T_SERVER", 0);
flags = MIB_LOCAL;
Fchg32( obuf, TA_FLAGS, 0, (char *)&flags, 0);
//根据查询参数设置想要查询的参数,例如服务名、服务ID、服务队列等。
if(strlen(t_SrvName)>0) Fchg32(obuf, TA_SERVERNAME, 0,t_SrvName, 0);
if(strlen(t_SrvGrp)>0) Fchg32(obuf, TA_SRVGRP, 0,t_SrvGrp, 0);
ret=tpcall(".TMIB",(char *)obuf,0,(char **)&obuf,&sendlen,TPNOTRAN);
if(ret == -1)
{
userlog("获取系统服务的状态失败:%s",tpstrerror(tperrno));
tpfree((char *)obuf);
Tuxedo_Return("-1","查询TUXEDO系统状态失败");
}
i=Foccur32(obuf,TA_SERVERNAME);
for(j=0;j<i;j++)
{
Fgets32(obuf,TA_SERVERNAME,j,t_ServerName);
Fgets32(obuf,TA_SRVID,j,t_SrvID);
Fgets32(obuf,TA_STATE,j,t_STATE);
Fgets32(obuf,TA_SRVGRP,j,t_SrvGrp);
Fgets32(obuf,TA_RQADDR,j,t_RQADDR);//SERVER队列名称
Fgets32(obuf,TA_TOTWORKL,j,t_TOTWORKL);//工作量。t_TOTREQC*负载因子=TA_TOTWORKL
..........................
//根据返回的数据进行其它操作。
..............................
}
从上面代码可以看到,我们可以获取到SERVER在运行状态下的所有参数值。例如假设有一个服务有异常,那么我们就可以根据获取的服务状态,来自动做一些处理。可以监控到SERVER被调用的频率,如果SERVER包含多个SERVICE,那么可以监控到某个SERVICE是否被调用次数过多而且影响到 SERVER中其它的SERVICE,那么就要考虑将这个SERVICE移到其它SERVER或者是单独成为一个SERVER。根据SERVER的 RPID,我们可以关联查询SERVER对应的REQUES消息队列,查看REQUES消息队列的排队率和占用率是否过高,自动��行处理或者是告警。
如果我们想在运行状态时动态的修改SERVER的配置参数,那么我们可以将TA_OPERATION改为SET,将需要修改的参数输入缓冲区,调用 MIBS的接口即可。修改某些参数有时需要将SERVER的状态改为INActive,相当是tmshutdown -s SERVER,然后才能修改。
下一篇文章我们将介绍跟SERVER密切相关的QUEUE和MSG QUEUE,分析如何通过SERVER的PID来查询对应的消息队列。因为我们知道,当系统的反应比较缓慢时,首先出问题的往往是消息队列。