前面写过用 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 为例