www.pudn.com > 2003090514065121890.zip > spServerEB.h
#ifndef __SP_SERVER_EB_H_
#define __SP_SERVER_EB_H_
/*
实现负载均衡和故障检测:
首先实现了故障信息收集功能,然后添加负载均衡信息收集功能
所以在CErrorInfoCollect中,部分成员命名为添加Error或是Balance前缀,
未添加前缀的成员按照故障信息收集处理
关于所以已经建立的连接的处理:
所有建立的连接会存放到一个链表中,
对新创建的处理线程来讲,线程通过调用AddConnectionAndWait,AddBalanceConnectionAndWait,将自己添加到链表中
并且一直等待退出事件变为有信号。
线程分类:
1、Ping包添加线程 AddPingInfoThread,定期在待发送的数据链表内添加Ping包
2、故障信息发送线程 ErrorInfoSendThread 定期发送故障信息到所有已经连接的客户端
3、负载信息发送线程 BalanceInfoSendThread 定期发送负载信息到所有已经连接的客户端
关于Ping包,故障信息和负载信息数据发送的处理:
所有待发送的数据存放在链表中
发送线程定期从链表中读取数据,并通过连接链表读出已经建立的套接口信息并逐个发送
如果向已经建立连接的套接口发送失败,发送线程会将相应的线程的退出事件设置为有信号
关于数据同步的处理:
利用读写锁同步所有可能会别多线程同时访问的数据
*/
namespace spBase
{//定义名字空间
class CErrorInfoCollect;
class CConnectContainer;
class CEBSimpleDisplay;
//初始化服务器名称, exported
//该名称在系统内必须唯一,长度不能超过6字节
//此函数在系统启动时必须第一时间被调用,而且不能被第二次调用
void glo_spInitEBName(LPCSTR pszName);
//得到故障信息收集对象 exported
CErrorInfoCollect* glo_spGetErrorInfoObject(void);
//故障检查,服务器端回调函数
void ErrorMonitorCallback(CServerStatus* pS,CSocketChildThread* pC);
//回调函数,将故障数据发送给对方
void BalanceDataCallback(CServerStatus* pS,CSocketChildThread* pC);
//故障信息发送线程
DWORD ErrorInfoSendThread(LPVOID pD);
//Ping包发送线程
DWORD AddPingInfoThread(LPVOID pD);
//负载均衡数据发送线程
DWORD BalanceInfoSendThread(LPVOID pD);
}
namespace spBase
{
//////////////////////////
//基本的信息显示类
//////////////////////////
class CEBSimpleDisplay : public COutputDisplay
{//显示类
public:
CEBSimpleDisplay()
{};
~CEBSimpleDisplay(){};
public:
BOOL PutLine(ErrorLevel eLevel,LPCSTR pszOutput)
{
//char szDesc[20];
//GetErrorLevelString(eLevel,szDesc);
//printf("%d %s %s\n",(int)eLevel,szDesc,pszOutput);
return TRUE;
};
};
////////////////////////////////////////
//保存已经建立的连接的信息
////////////////////////////////////////
struct ConnectElement
{
int iID;
CSocketChildThread* pConnection;
HANDLE hEvent;
};
/////////////////////////////////////////
//用来保存所有连接
/////////////////////////////////////////
class CConnectContainer
{
public:
CConnectContainer(){};
~CConnectContainer()
{
while(m_arrElement.GetUpperBound()+1)
{
struct ConnectElement* pE = m_arrElement.ElementAt(0);
m_arrElement.RemoveAt(0);
CloseHandle(pE->hEvent);
delete pE;
}
};
public:
//将连接添加到数组中,并一直等待到被释放
void AddConnection(CSocketChildThread* pConnection,HANDLE hEvent,int iID)
{
struct ConnectElement* pE= new struct ConnectElement;
pE->iID = iID;
pE->hEvent = hEvent;
pE->pConnection=pConnection;
m_arrElement.Add(pE);
};
void DelConnection(int iID)
{
int iTotal = (int)m_arrElement.GetUpperBound()+1;
for(int i=0;iiID == iID)
{
m_arrElement.RemoveAt(i);
delete pE;
break;
}
}
};
public:
CArray m_arrElement;
};
//故障信息收集类
class CErrorInfoCollect
{
friend DWORD spBase::ErrorInfoSendThread(LPVOID pD);
friend DWORD spBase::AddPingInfoThread(LPVOID pD);
friend DWORD spBase::BalanceInfoSendThread(LPVOID pD);
public:
CErrorInfoCollect();
~CErrorInfoCollect();
public:
//启动服务,iPort为故障信息监听端口,iPort+1为负载信息监听端口
BOOL Start(LPCSTR pszLocalAddr,int iPort,BOOL fAutoPing=TRUE);
BOOL Stop(void);
public://关于故障信息收集的相关函数
BOOL AddPing(void);
/*
添加故障信息
故障类型:
0:不可恢复,服务器现为不可用状态。
1:无法接受请求,等待恢复。
5:普通故障,尚可以继续处理请求。
9:正常。
故障位置:故障类型为5时需要指明,否则此参数为Z
Z:正常情况
P:进程。
T:子线程。
O:外部服务。
N:网络。
F:存储系统。
D:数据库。
M:内存。
fSendNow:是否立即发送,如果为TRUE,则当前数据队列中待发送数据会被全部删除,本次数据会被放到第一位
*/
BOOL AddErrorInfo(int iCata=9,char cPos='Z',int iErrorCode=0,LPCSTR pszDesc="",BOOL fSendNow=FALSE);
//得到需要发送的信息
//如果当前无需要发送的信息,返回FALSE
BOOL PopErrorInfo(CString& szPop,CString *pszLastError=NULL);
//添加连接,添加连接后等待退出
void AddConnectionAndWait(CSocketChildThread* pConn);
protected:
//对待发送的故障信息数据的操作
void DeleteAllInfo(void);
void PushErrorInfo(LPCSTR pszPush,BOOL fIsPing=FALSE);
public://对于负载信息处理的函数
//添加CPU负荷
BOOL AddCPUBalance(int iPercent);
//添加当前等待的队列长
BOOL AddWaitingBalance(int iWaiting);
//添加已经处理的队列长
BOOL AddHandledBalance(int iHandled);
//添加正在处理的队列长
BOOL AddHandlingBalance(int iHandling);
//将数据添加到待发送的信息数据链表中
BOOL PopBalance(CString& szPop);
//添加连接,添加连接后等待退出
void AddBalanceConnectionAndWait(CSocketChildThread* pConn);
protected:
BOOL AddBanlanceInfo(LPCSTR pszType,LPCSTR pszPara);
void DeleteAllBalanceInfo(void);
void PushBalance(LPCSTR pszPush);
protected://Helper
//设置所有内部成员变量为空
void ResetMember(void);
//删除所有内部成员
void DeleteMember(void);
protected:
//是否自动发送Ping信息
BOOL m_fAutoPing;
//服务器是否在运行
BOOL m_fRunning;
//序号
CSequenceGenerator *m_pseqID;
//显示
CEBSimpleDisplay *m_pDisplay;
//保存所有待发送的故障数据
CStringList m_listErrorInfo;
//保存最后一次错误信息
CString m_szLastErrorInfo;
//发送线程与Ping线程的句柄
HANDLE m_hSendThread,m_hPingThread;
//保证故障数据读写安全
CRWAccessLock *m_pInfoLock;
//所有已经连接上的故障检测服务器的信息
CConnectContainer *m_pconnContainer;
//保证故障检测连接数据读写安全
CRWAccessLock *m_pConnLock;
//故障检测服务器线程
CSocketParentThread *m_pErrorServerThread;
//数据收集服务端存储
CSocketGlobalDataStorage *m_pstoreSvr;
//保存所有待发送的负载数据
CStringList m_listBalanceInfo;
//负载信息发送线程句柄
HANDLE m_hBalanceThread;
//保证负载数据读写安全
CRWAccessLock *m_pBalanceInfoLock;
//所有已经连接上的负载服务器的信息
CConnectContainer *m_pconnBalanceContainer;
//保证负载收集连接数据读写安全
CRWAccessLock *m_pBalanceConnLock;
//故障检测服务器线程
CSocketParentThread *m_pBalanceServerThread;
//数据收集服务端存储
CSocketGlobalDataStorage *m_pstoreBalanceSvr;
};
}//end namespace
#endif