Archive

Posts Tagged ‘nginx负载均衡’

强大的负载均衡+静态文件WEB服务器 nginx实战

March 24th, 2009 No comments

  当前比较流行的负载均衡前端服务器主要有apache(with mod_proxy),nginx,lighttpd,squid,perlbal,pound,或者如果你的域名服务商提供DNS级别的负载均衡,也可以(就是一个域名随机指向多个IP,定制性不高)。

    以前自己常用pound作为前端,它专注于负载均衡,支持https协议,配置还算简单,不过渐渐发现功能不够强大,转而研究其他一些既可以做负载均衡,又能做web服务器的高性能工具吧。Perlbal是第一个看的,大牛Danga的杰作,它们开发的memcached(分布式内存cache系统)非常好用,Perlbal也不差,虽然是基于Perl的,速度上比纯C开发的可能稍逊,但不得不说Danga大牛实力非凡。不过公司的机器都是perl5.8.5,而Perlbal必须perl5.8.8以上,升级可能有兼容性问题,故只能作罢。

    转而研究nginxNginx (“engine X”) 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。Igor 将源代码以类BSD许可证的形式发布。尽管还是测试版,但是,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。 

    中文维基地址:http://wiki.codemongers.com/NginxChs

模块依赖:
1 gzip支持,需要zlib http://www.zlib.net/ 下载最新版即可
2 rewrite module requires pcre library http://www.pcre.org/ 下载最新版即可
3 ssl 功能需要 openssl 库 http://www.openssl.org/ => http://www.openssl.org/source/ LASTEST版本即可

 

安装过程:

#下载以上source到/usr/local/src/nginx/目录下,解压,则该目录下情况如下:
[root@s16 nginx]# ls
nginx-0.6.32  nginx-0.6.32.tar.gz  openssl-0.9.8i  openssl-0.9.8i.tar.gz  pcre-7.8  pcre-7.8.tar.gz  zlib-1.2.3  zlib-1.2.3.tar.gz

cd nginx-0.6.32
./configure –with-pcre=../pcre-7.8 –with-zlib=../zlib-1.2.3 –with-openssl=../openssl-0.9.8i
make
make install

 

#OK,安装完成
#修改配置:
cd /usr/local/nginx
vi conf/nginx.conf
#例如,去掉例子中的8000端口的服务器配置的注释
sbin/nginx -t -c conf/nginx.conf (测试配置文件是否正确)
[root@s16 nginx]# sbin/nginx -t -c conf/nginx.conf  
2008/09/17 15:26:55 [info] 15879#0: the configuration file conf/nginx.conf syntax is ok
2008/09/17 15:26:55 [info] 15879#0: the configuration file conf/nginx.conf was tested successfully

 

sbin/nginx  (启动)
ps aux | grep nginx | grep -v grep (查看是否正常启动了)
#如果没有正常启动,查看errorlog,默认位置:/usr/local/nginx/logs/error.log

 

#经过apache bench测试,nginx在serve静态文件方面性能不比apache(with mod_perl)好多少,基本上,以65K为分界点,小文件时nginx性能好(最高可以达到3倍左右速度),大文件时apache性能好(不过差别有限),所以纯从速度上来讲,nginx并不比apache强,不过nginx小巧,消耗资源少,如果你有很多静态小文件需要serve,的确是个不错的选择哦。

     这里推荐一种架构:

     1 前端nginx,并serve静态文件,如图片,js,css等,nginx是支持gzip压缩的

     2 后端动态程序用fastcgi(lighttpd的spawn_fcgi即可),可以支持php,perl等多种脚本语言了

 

     下面介绍一下nginx的常用配置:

  1. 静态文件用nginx直接serve:
Nginx代码 复制代码
  1. #css|js|ico|gif|jpg|jpeg|png|txt|html|htm|xml|swf|wav这些都是静态文件,但应分辨,js、css可能经常会变,过期时间应小一些,图片、html基本不变,过期时间可以设长一些   
  2. location ~* ^.+\.(ico|gif|jpg|jpeg|png|html|htm)$ {   
  3.     root         /var/www/poseidon/root/static;   
  4.     access_log   off;   
  5.     expires      30d;   
  6. }   
  7. location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {   
  8.     root         /var/www/poseidon/root/static;   
  9.     access_log   off;   
  10.     expires      24h;   
  11. }   
  12. #注:location不包括?后面带的参数,所以以上正则可以匹配http://192.168.1.16/image/sxxx.jpg?a=xxx   
  1. 打开gzip,压缩传输
    Nginx代码 复制代码
    1. gzip on;   
    2. gzip_comp_level 7;   
    3. gzip_min_length  1100; #需要压缩的最小长度   
    4. gzip_buffers    4 8k;   
    5. gzip_types      text/plain application/javascript text/css text/xml application/x-httpd-php; #指定需要压缩的文件类型   
    6. output_buffers  1 32k;   
    7. postpone_output  1460;  

     

  1. 查看nginx的状态
    Nginx代码 复制代码
    1. #设定查看Nginx状态的地址(非默认安装模块,需要在编译时加上–with-http_stub_status_module)   
    2. location /NginxStatus {   
    3.     stub_status            on;   
    4.     access_log             on;   
    5.     auth_basic             “NginxStatus”;   
    6.     auth_basic_user_file   /var/www/poseidon/root/passwd;   
    7. }  

     

  2. 使用nginx的rewrite模块
    Nginx代码 复制代码
    1. #强大的rewrite模块:   
    2. #文档:http://wiki.codemongers.com/NginxHttpRewriteModule   
    3. #经典示例:rewrites http://www.mydomain.nl/foo => http://mydomain.nl/foo   
    4. if ($host ~* www\.(.*)) {   
    5.   set $host_without_www $1;   
    6.   rewrite ^(.*)$ http://$host_without_www$1 permanent; # $1 contains ‘/foo’, not ‘www.mydomain.nl/foo’  
    7. }   
    8.   
    9. #我们的应用:rewrites 所有非www.popovivi.com的访问 => http://www.popovivi.com/xxx   
    10. if ($host != “www.popovivi.com”) {   
    11.     rewrite ^(.*)$ http://www.popovivi.com$1 permanent;   
    12. }  

     

  3. 最常见的nginx+fastcgi+php的使用
    Shell代码 复制代码
    1. #nginx+fastcgi+php-cgi套路:   
    2. wget lighttpd1.4.19(or later)   
    3. wget php5.2.6(or later)   
    4. ./configure –prefix=/usr/local/lighttpd   
    5. make & make install   
    6. ./configure –prefix=/usr/local/php-5.2.6 –enable-fastcgi –enable-sockets –enable-force-cgi-redirect –with-gd –enable-mbstring –with-zlib –with-mysql –with-gettext –with-mcrypt –with-mime-magic –with-openssl    
    7. make & make test & make install(php.ini的默认读取位置为[prefix]/lib)   
    8. cp php.ini-dist /usr/local/php-5.2.6/lib/php.ini   
    9. /usr/local/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 10005 -u nobody -g nobody -f /usr/local/php-5.2.6/bin/php-cgi -P /var/run/fastcgi.pid -C 15  
    10.   
    11. #修改nginx的配置文件,使用fastcgi_pass http://127.0.0.1:10005作为后端   
    12. kill -HUP `cat /var/run/nginx.pid`  #重启nginx  

     

  4. nginx+fastcgi+catalyst(for perl users):
    Shell代码 复制代码
    1. #Catalyst自带文档:   
    2. #http://dev.catalyst.perl.org/wiki//gettingstarted/howtos/deploy/lighttpd_fastcgi.view?rev=22  
    3. #以上文档介绍的是lighttpd和catalyst的结合,本质是一样的   
    4. #实际上也就是用自动生成的script/[myapp]_fastcgi.pl来启动,剩下的事,就随意啦(只是用什么来做前端而已)   
    5. #首先安装FCGI模块   
    6. cpan   
    7. install FCGI   
    8. install FCGI::ProcManager   
    9.   
    10. cd /var/www/project/script   
    11. chmod 755 project_fastcgi.pl   
    12. ./project_fastcgi.pl -listen 127.0.0.1:3003 -nproc 10 -pidfile /var/run/fcgi_catalyst.pid -daemon   
    13.   
    14. #nginx中,配置:   
    15. location / {   
    16.     fastcgi_pass 127.0.0.1:3003;   
    17.     include /var/www/project/root/fastcgi.conf;   
    18. }   
    19. #fastcgi.conf详细(注意点:将SCRIPT_NAME替换成PATH_INFO即可)   
    20. fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;   
    21. fastcgi_param  QUERY_STRING       $query_string;   
    22. fastcgi_param  REQUEST_METHOD     $request_method;   
    23. fastcgi_param  CONTENT_TYPE       $content_type;   
    24. fastcgi_param  CONTENT_LENGTH     $content_length;   
    25. #fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;   
    26. fastcgi_param  PATH_INFO          $fastcgi_script_name;   
    27. fastcgi_param  REQUEST_URI        $request_uri;   
    28. fastcgi_param  DOCUMENT_URI       $document_uri;   
    29. fastcgi_param  DOCUMENT_ROOT      $document_root;   
    30. fastcgi_param  SERVER_PROTOCOL    $server_protocol;   
    31. fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;   
    32. fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;   
    33. fastcgi_param  REMOTE_ADDR        $remote_addr;   
    34. fastcgi_param  REMOTE_PORT        $remote_port;   
    35. fastcgi_param  SERVER_ADDR        $server_addr;   
    36. fastcgi_param  SERVER_PORT        $server_port;   
    37. fastcgi_param  SERVER_NAME        $server_name;  

     

     最后,因为nginx没有方便的控制命令可用,经常要ps,kill等直接控制,比较麻烦,可以为它写一个启动脚本,例子如下:

Shell代码 复制代码
  1. #!/bin/sh   
  2. #   
  3. # description: Starts, stops nginx   
  4. #   
  5. #chkconfig: 2345 20 80  
  6. #dscription: Startup script for nginx webserver on CentOS. Place in /etc/init.d    
  7. #   
  8. # Author: Touya   
  9. set -e   
  10.   
  11. PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin   
  12. DESC=nginx daemon”  
  13. NAME=nginx   
  14. DAEMON=/usr/local/nginx/sbin/$NAME   
  15. CONFIGFILE=/var/www/poseidon/root/nginx.conf   
  16. PIDFILE=/var/run/$NAME.pid   
  17. SCRIPTNAME=/etc/init.d/$NAME   
  18.   
  19. # Gracefully exit if the package has been removed.   
  20. test -x $DAEMON || exit 0  
  21.   
  22. d_start() {   
  23. echo “Starting $DESC: $NAME”  
  24. $DAEMON -c $CONFIGFILE || echo “already running”  
  25. }   
  26.   
  27. d_stop() {   
  28. echo “Stopping $DESC: $NAME”  
  29. test -f $PIDFILE && kill -QUIT `cat $PIDFILE`   
  30. }   
  31.   
  32. d_reload() {   
  33. echo “Reloading $DESC configuration…”  
  34. kill -HUP `cat $PIDFILE` || echo “can’t reload”  
  35. }   
  36. case “$1″ in   
  37. ‘start’)   
  38.     d_start   
  39.     echo “started.”  
  40. ;;   
  41. ‘stop’)   
  42.     d_stop   
  43.     echo “stoped.”  
  44. ;;   
  45. ‘reload’)   
  46.     d_reload   
  47.     echo “reloaded.”  
  48. ;;   
  49. ‘restart’)   
  50.     echo “Restarting $DESC: $NAME …”  
  51.     d_stop   
  52.     # One second might not be time enough for a daemon to stop,   
  53.     # if this happens, d_start will fail (and dpkg will break if   
  54.     # the package is being upgraded). Change the timeout if needed   
  55.     # be, or change d_stop to have start-stop-daemon use –retry.   
  56.     # Notice that using –retry slows down the shutdown process somewhat.   
  57.     sleep 3  
  58.     d_start   
  59.     echo “done.”  
  60. ;;   
  61. ‘list’)   
  62.     ps auxf | egrep ‘(PID|nginx)’ | grep -v grep   
  63. ;;   
  64. ‘test’)   
  65.     $DAEMON -t -c $CONFIGFILE   
  66. ;;   
  67. *)   
  68. echo “Usage: $SCRIPTNAME {reload|list|test|start|stop|restart}” >&2  
  69. exit 3  
  70. ;;   
  71. esac   
  72. exit 0  

保存文件,并chmod 755 /etc/init.d/nginx
用chkconfig –list nginx查看是否是一个可用后台启动服务,如果是的话,可以直接执行chkconfig –add nginx,这个后台服务搞定(代码中不可省略:#chkconfig: 2345 20 80)
接下可以用service nginx start|restart|stop来操作你的nginx服务器(restart时重新读入config)

怎么样?是不是方便多了?

 

     小结:本文是我自己实践nginx的整个经验总结,包括了前期准备、安装、配置、架构设计、和现有动态程序结合(公司使用的是Catalyst)、启动脚本等等,希望对大家有帮助,少走歪路

转载来源 http://touya.javaeye.com/blog/258480

  • Share/Bookmark
Categories: nginx Tags: ,