概述
最近工作中开发了一款应用服务器,使用http协议+json技术。功能上都能满足要求,最后没有重视压力测试这块,导致最后被嫌弃。
介绍
Nginx - 高性能web server,这个不用多说了,大家都知道。
FastCGI程序 - 常驻型CGI程序,它是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。
Nginx要调用FastCGI程序,需要用到FastCGI进程管理程序(因为nginx不能直接执行外部的cgi程序,我们可使用lighttpd中的spawn-fastcgi来让nginx可支持外部cgi运行。也有其他方法安装nginx-fcgi来让nginx支持cgi,这里是使用spawn-fastcgi的方法),来达到调用FastCGI程序的目的。Nginx本身没有集成类似的模块,而Apache具备该功能模块,所以不需要额外安装FastCGI进程管理程序。
工作原理
Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket(这个socket可以是文件socket,也可以是ip socket)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。
当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接收到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端。这就是Nginx+FastCGI的整个运作过程,如图
FastCGI接口方式在脚本解析服务器(CGI应用程序服务器)上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是FastCGI进程管理器,或者称为FastCGI引擎。 spawn-fcgi与PHP-FPM都是FastCGI进程管理器(支持PHP和C/C++)。
环境部署
3.1.Nginx的编译安装。(不再啰嗦)
Nginx配置:
location ~ /application.cgi {
root /usr/local/nginx/cgi_bin;
fastcgi_pass 127.0.0.1:8888;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME fcgi$fastcgi_script_name;
include fastcgi_params;
}
注意:开通防火墙8888端口。
3.2.spawn_fastcgi的安装、部署与配置
spawn_fastcgi https://github.com/lighttpd/spawn-fcgi
这里使用的是1.6.4的版本 https://github.com/lighttpd/spawn-fcgi/releases/tag/v1.6.4
下载以后解压并安装(请记得看README)
如果没有configure,请先执行./autogen.sh,生成configure
./configure
make
编译好以后,将可执行文件移动到nginx的sbin目录下
cp ./src/spawn-fcgi /usr/local/nginx/sbin/ (cp到nginx的安装目录下)
4.Application的编译安装。
编写cgi程序,生成demo
4.2.启动发布
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf (指定配置文件启动)
/usr/local/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 8088 -f /usr/local/nginx/cgibin/demo
5, 打开浏览器访问一下吧
http://localhost/demo.cgi
测试
我的机器是i3双核四线程+8G内存。
刚开始吞吐量throughput只有200,吓我一跳,原因是服务器部署在远端,上传带宽只有300kb,这里成为瓶颈。在本地搭建服务器+数据库mysql开始测试。
1,先测试加心跳业务+fcgi的http请求,每一次心跳请求都会insert一下mysql。结果只能到1000个请求每秒。
2,经过各种尝试,原来要改nginx和fcgi的工作进程数,我开了4个nginx的worker进程+8个fcgi应用进程,并发数量一下子到达了9000每秒。
3,然后测试nignx只转发静态的html的性能情况,不加fcgi,不加业务。结果:能达到每秒处理4万个请求。
4,然后,测试下nginx+fcgi框架,不加数据库,不叫任何业务,只返回空的json数据。最终结果能达到20000个请求每秒。这说明fcgi框架的速度损耗将近50%。
5,最后,我在nignx+fcgi框架上加上了mysql操作,每个请求insert一次数据路,优化sql语句,最终测试结果如下:能达到14000左右的并发。
测试结果如下:
我的jmeter配置如下: