十万级以上的网络引擎

由于libevent的多线程限制,以及性能方面原因。  本人重新从底层写了一套网络引擎。 性能超10万以上。  先上图 :  有图有真相: 


测试环境:

服务器:

虚拟机: centos 7.2,

虚拟机: cpu, 4核

内存:    8G

客户端:

操作系统: win10

测试工具 :  vcClient客户端

每个 客户端开启 10000的模拟终端,  不间断发送应答请求, 未收到应答, 报错。

本次测试, 分为  网关 gateway 和  游戏服务器 gameserver。

gateway 承载 5万在线,数据转发给gameserver, 由gameserver处理后,再经过gateway发送给  每个终端链接。

数据流: user-> gateway -> gameserver(处理及应答) -> gateway  -> user  闭环。


描述:   上图,客户机 开启 5万模拟终端,  虚拟机中  gateway 占用cpu: 31.6.   内存  1.5G * 10%


由于单台客户端 ,能开启的客户端有限, 未能进一步测试 10万级数据。

但 5万用户的测试,足以说明, 在数据接收,应答等,  足够 承载10万以上  数据!!!

由于代码量比较大, 只能打包下载了。

上传部分代码:

#include "DataManager.h"
#include <stdio.h>
#include "NodeManager.h"
#include "CircularQueue.cpp"
//中间层数据格式定义: head[14]  ####(4),midNum(1),type(1),seq(2),len(2),fd(4)
//中间层 是由 gateway进行封装。
//midNum:表示 经过几层 中转。
//type :表示 数据包类型,0 中转包 1 请求,2 应答,3 通知(无应答), 4 ACK, 5 SNIFF。(逻辑层的)
//seq:  表示 数据包流水号,
//ACK:  网络层应答包, 仅仅指 底层确保 数据被收到。
//SNIFF: 网络测试包(心跳), 服务器  ACK应答.
//session: 由登陆服务器生成, 保存到 游戏服务器的redis中。
#define GATEWAY
extern CNodeManager* g_pNodeManager;
DataManager::DataManager()
{
}
void DataManager::Init()
{
 for (int i = 0; i < 10; i++)
 {
  thData[i].threadID = -1;
  thData[i].m_objClientQueue = new CircularQueue<user_data*>(200000);
 }
}
DataManager::~DataManager()
{
 for (int i = 0; i < 10; i++)
 {
  while (thData[i].m_objClientQueue->length() > 0)
  {
   user_data* pdata = NULL;
   thData[i].m_objClientQueue->PopQueue(pdata);
   delete pdata;
  }
  delete thData[i].m_objClientQueue;
 }
}
int DataManager::PushRecvData(int threadID, int fd, char* buff, int len, bool isClient)
{
 if (isClient)
 {
  user_data* pdata = new user_data();
  memcpy(pdata->line, buff, len);
  pdata->fd = fd;
  pdata->iType = 1;
  pdata->n_size = len;
  thData[threadID].m_objClientQueue->PushQueue(pdata);
  printf("recv client: head: ++ \n");
 }
 else
 {
  user_data* pdata = new user_data();
  memcpy(pdata->line, buff, len);
  pdata->fd = fd;
  pdata->n_size = len;
  pdata->iType = 2;
  thData[threadID].m_objClientQueue->PushQueue(pdata);
  printf("recv Server: head: ++ \n");
 }
 return 0;
}
int DataManager::InitThreadData(int threadID)
{
 thData[threadID].threadID = threadID;
 return 0;
}
int DataManager::CreatePage(char* buff, char midNum, char iType, short seq, short lenth, int fd)
{
 sprintf(buff, "####");
 buff[4] = midNum;
 buff[5] = iType;
 memcpy(&(buff[6]), &seq, 2);
 memcpy(&(buff[8]), &lenth, 2);
 memcpy(&(buff[10]), &fd, 4);
 return 0;
}
int DataManager::ProcDataPage()
{
 for (int i = 0; i < 10; i++)
 {
  
  if(thData[i].threadID > -1)
  {
   char head[14] = { 0 };
   sprintf(head, "####");
   char midNum = 1;//
   char iType = 0;//中转
   static short seq = 0;
   seq++;
   short len = 0;
   int cliFD = 0;
   //------------------------------
   user_data* pdata = NULL;
   //user_data* pMidData = new user_data();
   //pMidData->pData = new char[2048];
   thData[i].m_objClientQueue->PopQueue(pdata);
   while (pdata != NULL)
   {   
    //printf("DataManager::ProcDataPage: fd: %d pdata: %d iType: %d \n", pdata->fd, pdata, pdata->iType);
    g_pNodeManager->PushRecvData(pdata->fd, pdata);/
    
    //printf("DataManager::ProcDataPage: fd: %d pdata: %d iType: %d \n", pdata->fd, pdata, pdata->iType);
    pdata = NULL;
    thData[i].m_objClientQueue->PopQueue(pdata);
   }
  }
 }
 
 g_pNodeManager->ProcRecvData();
 g_pNodeManager->Senddata();
 return 0;
}
int DataManager::PushRequstData(int fd, char* buff, int len)
{
 return 0;
}
int DataManager::PushAnswerData(int fd, char* buff, int len)
{
 return 0;
}
int DataManager::PushMidTranData(int fd, char* buff, int len)
{
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值