用libevent 写高性能的服务器

前面写过用 Node-Js 写的高并发服务器, 因为Node-Js 基于 异步 非阻塞的机制  ,优点是 容易实现高并发  缺点是 由于是 谷歌V8的引擎 JS 不适合做太大规模的计算操作。

所以 如果 服务器涉及到 大规模的计算操作 并且想 快速开发的话,基于HTTP / TCP IP 协议的话 推荐用 libevent 库   最直观的理解是  基于异步非阻塞的机制就是  都使用了 回调函数  

下面的代码是我从之前做过的工程里 找了一段 单独复制出来无法直接运行 我再 从网上找了点相关代码 加以修改

先告诉大家怎么在 Linux 下安装 和 配置 libevent 开发环境

http://download.csdn.net/detail/innovation_miracle/9411914  

这个链接是 libevent 的源代码,不要积分的 可以去下载

我的linux环境是 centos 7

把源代码压缩包解压出来

终端 cd 到 源码的目录下

1 . 输入  :  ./configure -prefix=/usr/libevent

2.  输入: make

3.  输入: make install

4.  检查是否安装成功  输入: ls -al /usr/lib | grep libevent  如果输出很多 xxxx.so  xxxx.3.3.so  代表安装成功了

5.  linux下 必须安装  libevent-devel  输入: yum install libevent-devel

6.  最好不要在 windows 平台下用libevent  我之前尝试把linux 平台的服务器代码 移植到 windows    白辛苦几天 不了了之了

7.  推荐一个  我感觉比 vi 好用的编辑器  sublime text 2  有需要的去下载一个 

下面 开始写 基于 http 协议的服务器代码

#include
#include
#include
#include
#include   // 必须包含   libevent的核心头文件
#include // libevent 提供的http 服务的头文件
#include 
void http_req(struct evhttp_request *req,void *arg)
{
char output[2048]="\0";
char tmp[1024];
	//获取 访问的请求链接 (使用 evhttp_request_uri  or  req->uri)
	const char *uri;
	uri = evhttp_request_get_uri(req);
	sprintf(tmp,"uri=%s\n",uri);
	strcat(output,tmp);


//  把请求的链接参数 解码
	char *decoded_uri;
	decoded_uri = evhttp_decode_uri(uri);
	

	//解析url的参数
	struct evkeyvalq params;
	evhttp_parse_query(decoded_uri,?ms);
	sprintf(tmp,"q=%s\n",evhttp_find_header(¶ms,"usrname"));
	strcat(output,tmp);
	sprintf(tmp,"s=%s\n",evhttp_find_header(¶ms,"password"));  // evhttp_find_header 是获取请求链接里特定的字段值
	strcat(output,tmp);
	free(decoded_uri);

	/*
	这里可以做很多操作 比如  数据库存储操作  比如memcatch 缓存操作等等
	*/

	// http 协议头
	evhttp_add_header(req->output_headers,"Content-Type","text/plain;charset=UTF-8");
	evhttp_add_header(req->output_headers,"Connection","hello world");

	
	struct evbuffer *buf;  // 字符缓冲区
	buf = evbuffer_new();
	evbuffer_add_printf(buf,"It works !\n%s\n",output);  // 把结果返回给客户端
	evhttp_send_reply(req,HTTP_OK,"OK",buf);
	evbuffer_free(buf);

}
int main(int argc, char *argv[])
{
	char *http_addr= "127.0.0.1";
	char *http_port = 8080;
	int http_daemon = 0;
  int http_timeout = 120;
	if (httpd_daemon)
  {
      pid_t pid;
      pid = fork();
      if (pid<0)
     	{
      	perror("fork failed");
      	exit(EXIT_FAILURE);
      }
     if (pid>0)
	   {
      exit(EXIT_SUCCESS);
     }
  }
	event_init();  // 初始化 event_init 环境  也可以用 struct event_base *base;
	struct evhttp *http;  // 也可以用 http = evhttp_new(base);   如果调用了 evhttp_new函数 则调用 evhttp_bind_socket 配套使用  我还没试过其他的方式 
	// 这里直接 调用启动 http 函数
	http= evhttp_start(http_addr,http_port);
	evhttp_set_timeout(http,http_timeout);
	evhttp_set_gencb(http,http_req,NULL); // 加载回调
	event_dispatch();
	evhttp_free(http);
	return 0;
}


编译运行

gcc libevent_http.c -levent

./a.out


上面的代码不是很完善  需要根据自己的需求进行修改

一般云服务器的带宽是 5MB,  运行上面的代码   可以用apache提供的那个服务器性能的测试工具来测试下    以后有时间讲下 集群部署  

下面我会宽泛的 写下 如何 使用 memcatch 和 如何使用 数据库交互  以 mongodb 或者 mysql 为例



你可能感兴趣的:(用libevent 写高性能的服务器)