高性能服务器C代码,高性能服务器c开发库-minac工作笔记

背景

Gleasy部分高性能中间件(比如分布式nosql集群cloudRedis,使用JAVA),经过线上一段时间的验证,发现在CPU占用方面始终偏高,而且nosql集群本身并无复杂的业务逻辑,多数情况下都是直接PROXY到后端的redis。出于对性能的的严苛要求,决定使用C对cloudRedis进行重构。在重构的过程中,由于cloudRedis的java版基于mina2,特别是codec环节大量依赖于IoBuffer和IoSession这两个类,确实十分好用。因此衍生出来使用c语言实现完整的mina2接口的想法,借鉴MINA2本身的优秀设计,避免了很多弯路,最终实现了一套完整的开发库,为了对mina2致敬,取名为minac。

minac介绍

minac基于epoll,使用event-loop-per-thread结构,IO thread个数默认为Cpu的核数。

熟悉mina2的同学基本上拿过来就可以直接使用,没有任何学习成本。

以下是提供的一些基本类库

1. iobuffer

完整实现了java的IoBuffer类,所有方法跟java版兼容(所有写入buf的基本类型会被被转换为big endian的,读出时会转换回系统支持的endian模式)提供了以下方法:

extern iobuffer_t *iobuffer_create(int32_t);

extern void iobuffer_destroy(iobuffer_t *);

extern void iobuffer_set_auto_expend(iobuffer_t *,int flag);

extern void iobuffer_set_auto_shrink(iobuffer_t *,int flag);

extern void iobuffer_set_increment(iobuffer_t *,int32_t);

extern void iobuffer_flip(iobuffer_t *);

extern void iobuffer_compact(iobuffer_t *);

extern void iobuffer_clear(iobuffer_t *);

extern int32_t iobuffer_set_position(iobuffer_t *,int32_t);

extern int32_t iobuffer_get_position(iobuffer_t *);

extern int32_t iobuffer_set_limit(iobuffer_t *,int32_t);

extern int32_t iobuffer_get_limit(iobuffer_t *);

extern void iobuffer_skip(iobuffer_t *,int32_t);

extern int32_t iobuffer_remaining(iobuffer_t *);

extern int32_t iobuffer_put_int(iobuffer_t *,int32_t);

extern int32_t iobuffer_get_int(iobuffer_t *,int32_t *);

extern int32_t iobuffer_put_double(iobuffer_t *,double);

extern int32_t iobuffer_get_double(iobuffer_t *,double *);

extern int32_t iobuffer_put_long(iobuffer_t *,int64_t);

extern int32_t iobuffer_get_long(iobuffer_t *,int64_t *);

extern int32_t iobuffer_put(iobuffer_t *,char *,int32_t);

extern int32_t iobuffer_get(iobuffer_t *,char *,int32_t);

extern int32_t iobuffer_put_by_read(iobuffer_t *,int fd,int32_t);

extern int32_t iobuffer_get_and_write(iobuffer_t *,int fd,int32_t);

/**

* 从src中获取内容写入另一个www.111com.net dest

* 注意:此函数不支持src和dest为同一个iobuffer的情况

*/

extern int32_t iobuffer_put_iobuffer(iobuffer_t *dest,iobuffer_t *src);

2. iosession

实现了mina2的IoSession基本功能,主要接口如下:

extern iosession_t *iosession_create(int connfd, mina_session_config_t *sessionConfig);

extern void iosession_destroy(iosession_t *session);

extern int iosession_write(iosession_t *session, iobuffer_t *buf);

extern int iosession_write_wait(iosession_t *session, iobuffer_t *buf,int seconds);

extern int iosession_close(iosession_t *session);

extern int iosession_flush(iosession_t *session);

3. socket_acceptor

实现了mina2的IoSocketAcceptor类,主要接口如下

extern mina_socket_acceptor_t* mina_socket_acceptor_create();

extern void mina_socket_acceptor_destroy(mina_socket_acceptor_t *acceptor);

extern int mina_socket_acceptor_bind(mina_socket_acceptor_t *acceptor,struct sockaddr_in *addr);

extern void mina_socket_acceptor_unbind(mina_socket_acceptor_t *acceptor);

4. socket_connector

实现了mina2的IoSockectConnector类,主要接口如下:

extern mina_socket_connector_t* mina_socket_connector_create();

extern void mina_socket_connector_destroy(mina_socket_connector_t *acceptor);

extern iosession_t *mina_socket_connector_connect(mina_socket_connector_t *acceptor,struct sockaddr *addr);

extern void mina_socket_connector_stop(mina_socket_connector_t *acceptor);

5. socket_handler

实现了mina2的IoSocketHandlerAdaptor,定义如下:

typedef void (*_messageReceived)(iosession_t *,iobuffer_t *);

typedef void (*_messageSent)(iosession_t *,iobuffer_t *);

typedef void (*_sessionCreated)(iosession_t *);

typedef void (*_sessionOpened)(iosession_t *);

typedef void (*_sessionClosed)(iosession_t *);

typedef void (*_exceptionCaught)(iosession_t *,mina_exception_t *);

typedef void (*_sessionIdle)(iosession_t *,mina_iosession_idle_t );

typedef struct mina_socket_handler_t{

_messageReceived messageReceived;

_messageSent messageSent;

_sessionCreated sessionCreated;

_sessionOpened sessionOpened;

_sessionClosed sessionClosed;

_exceptionCaught exceptionCaught;

_sessionIdle sessionIdle;

}mina_socket_handler_t;

6. session_config

实现了mina2的SessionConfig,主要接口如下:

typedef struct mina_session_config_t{

int readBufferSize;

int minReadBufferSize;

int maxReadBufferSize;

int writeBufferSize;

int minWriteBufferSize;

int maxWriteBufferSize;

int tcpNoDelay;

int sendBufSize;

int revBufSize;

int readerIdleTime;//time in sec

int writerIdleTime;//time in sec

}mina_session_config_t;

extern mina_session_config_t *mina_session_config_create();

extern void mina_session_config_destroy(mina_session_config_t *);

7. 使用例子:

用几句代码就轻松实现服务器程序:

#include "minac.h"

#include "common.h"

#include

static void messageReceived(iosession_t *session,iobuffer_t *buf){

//dzlog_info("接收到一行,size:%d",iobuffer_remaining(buf));

int32_t remaining = iobuffer_remaining(buf);

if(remaining>0){

iobuffer_t *rbuf = iobuffer_create(remaining);

iobuffer_compact(rbuf);

iobuffer_put_iobuffer(rbuf,buf);

iobuffer_flip(rbuf);

iosession_write(session,rbuf);

iobuffer_destroy(rbuf);

}

}

static void messageSent(iosession_t *session,iobuffer_t *buf){

//dzlog_info("写了www.111Cn.net数据,size:%d",iobuffer_remaining(buf));

}

static void sessionClosed(iosession_t *session){

//dzlog_info("session is closed.%d",session->connfd);

}

static void sessionOpened(iosession_t *session){

//dzlog_info("session is opened.%d",session->connfd);

}

static void exceptionCaught(iosession_t *session,mina_exception_t *exception){

dzlog_info("exception met, code:%d, messag:%s",exception->errorCode,exception->errorMessage);

iosession_close(session);

}

static void sessionIdle(iosession_t *session,mina_iosession_idle_t idleType){

//dzlog_info("session idle, fd:%d, idleType:%d",session->connfd,idleType);

}

static void exit_handler(void *arg){

mina_socket_acceptor_t *acceptor = (mina_socket_acceptor_t *)arg;

mina_socket_acceptor_unbind(acceptor);

}

extern void test_acceptor(){

mina_socket_acceptor_t *acceptor = mina_socket_acceptor_create();

acceptor->sessionConfig->tcpNoDelay = 1;

acceptor->sessionConfig->readerIdleTime = 2;

acceptor->sessionConfig->writerIdleTime = 2;

acceptor->socketHandler->messageReceived = messageReceived;

acceptor->socketHandler->messageSent = messageSent;

acceptor->socketHandler->sessionOpened = sessionOpened;

acceptor->socketHandler->sessionClosed = sessionClosed;

acceptor->socketHandler->exceptionCaught = exceptionCaught;

acceptor->socketHandler->sessionIdle = sessionIdle;

register_exit_handler(exit_handler,(void *)acceptor);

struct sockaddr_in servaddr;

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(6666);

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

mina_socket_acceptor_bind(acceptor,&servaddr);

}

熟悉mina2的人,基本上对上面的代码极为熟悉了。

性能如何

功能上面是好用了,性能如何呢?以echo server为例,性能测试结果如下:

熟悉mina2的人,基本上对上面的代码极为熟悉了。

性能如何

功能上面是好用了,性能如何呢?以echo server为例,性能测试结果如下:

1. 实验1(400客户端)

16f0504073adfe586b5c3d5861274132.png

400并发客户端,TPS最大41万,平均18万,CPU占用164%

2. 实验2(1000客户端)

f0119b3f250dbee1b623ed22ae88860d.png

bf5766f1618037384c65326ffb9a23e9.png

1000并发客户端,TPS最大55万,平均30万,CPU占用169%

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值