您的位置:首页 > 其它

用libevent 写高性能的服务器

2016-01-23 18:19 281 查看
前面写过用 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<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<event2/event.h>   // 必须包含   libevent的核心头文件
#include<event2/evhttp.h> // libevent 提供的http 服务的头文件
#include<event2/buffer.h>
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 为例
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: