您的位置:首页 > 运维架构 > Nginx

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

2013-05-08 10:25 393 查看
当前比较流行的负载均衡前端服务器主要有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以上,升级可能有兼容性问题,故只能作罢。

转而研究nginx:Nginx (”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

#css|js|ico|gif|jpg|jpeg|png|txt|html|htm|xml|swf|wav这些都是静态文件,但应分辨,js、css可能经常会变,过期时间应小一些,图片、html基本不变,过期时间可以设长一些

location ~* ^.+\.(ico|gif|jpg|jpeg|png|html|htm)$ {

root /var/www/poseidon/root/static;

access_log off;

expires 30d;

}

location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {

root /var/www/poseidon/root/static;

access_log off;

expires 24h;

}

#注: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;

gzip on;

gzip_comp_level 7;

gzip_min_length 1100; #需要压缩的最小长度

gzip_buffers 4 8k;

gzip_types text/plain application/javascript text/css text/xml application/x-httpd-php; #指定需要压缩的文件类型

output_buffers 1 32k;

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. }

#设定查看Nginx状态的地址(非默认安装模块,需要在编译时加上–with-http_stub_status_module)

location /NginxStatus {

stub_status on;

access_log on;

auth_basic “NginxStatus”;

auth_basic_user_file /var/www/poseidon/root/passwd;

}

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. }

#强大的rewrite模块:

#文档:http://wiki.codemongers.com/NginxHttpRewriteModule

#经典示例:rewrites http://www.mydomain.nl/foo => http://mydomain.nl/foo
if ($host ~* www\.(.*)) {

set $host_without_www $1;

rewrite ^(.*)$ http://$host_without_www$1 permanent; # $1 contains ‘/foo’, not ‘www.mydomain.nl/foo’

}

#我们的应用:rewrites 所有非www.popovivi.com的访问 => http://www.popovivi.com/xxx
if ($host != “www.popovivi.com”) {

rewrite ^(.*)$ http://www.popovivi.com$1 permanent;

}

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

#nginx+fastcgi+php-cgi套路:

wget lighttpd1.4.19(or later)

wget php5.2.6(or later)

./configure –prefix=/usr/local/lighttpd

make & make install

./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

make & make test & make install(php.ini的默认读取位置为[prefix]/lib)

cp php.ini-dist /usr/local/php-5.2.6/lib/php.ini

/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

#修改nginx的配置文件,使用fastcgi_pass http://127.0.0.1:10005作为后端
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;

#Catalyst自带文档:

#http://dev.catalyst.perl.org/wiki//gettingstarted/howtos/deploy/lighttpd_fastcgi.view?rev=22

#以上文档介绍的是lighttpd和catalyst的结合,本质是一样的

#实际上也就是用自动生成的script/[myapp]_fastcgi.pl来启动,剩下的事,就随意啦(只是用什么来做前端而已)

#首先安装FCGI模块

cpan

install FCGI

install FCGI::ProcManager

cd /var/www/project/script

chmod 755 project_fastcgi.pl

./project_fastcgi.pl -listen 127.0.0.1:3003 -nproc 10 -pidfile /var/run/fcgi_catalyst.pid -daemon

#nginx中,配置:

location / {

fastcgi_pass 127.0.0.1:3003;

include /var/www/project/root/fastcgi.conf;

}

#fastcgi.conf详细(注意点:将SCRIPT_NAME替换成PATH_INFO即可)

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_param QUERY_STRING $query_string;

fastcgi_param REQUEST_METHOD $request_method;

fastcgi_param CONTENT_TYPE $content_type;

fastcgi_param CONTENT_LENGTH $content_length;

#fastcgi_param SCRIPT_NAME $fastcgi_script_name;

fastcgi_param PATH_INFO $fastcgi_script_name;

fastcgi_param REQUEST_URI $request_uri;

fastcgi_param DOCUMENT_URI $document_uri;

fastcgi_param DOCUMENT_ROOT $document_root;

fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;

fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;

fastcgi_param REMOTE_PORT $remote_port;

fastcgi_param SERVER_ADDR $server_addr;

fastcgi_param SERVER_PORT $server_port;

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

#!/bin/sh

#

# description: Starts, stops nginx

#

#chkconfig: 2345 20 80

#dscription: Startup script for nginx webserver on CentOS. Place in /etc/init.d

#

# Author: Touya

set -e

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

DESC=”nginx daemon”

NAME=nginx

DAEMON=/usr/local/nginx/sbin/$NAME

CONFIGFILE=/var/www/poseidon/root/nginx.conf

PIDFILE=/var/run/$NAME.pid

SCRIPTNAME=/etc/init.d/$NAME

# Gracefully exit if the package has been removed.

test -x $DAEMON || exit 0

d_start() {

echo “Starting $DESC: $NAME”

$DAEMON -c $CONFIGFILE || echo “already running”

}

d_stop() {

echo “Stopping $DESC: $NAME”

test -f $PIDFILE && kill -QUIT `cat $PIDFILE`

}

d_reload() {

echo “Reloading $DESC configuration…”

kill -HUP `cat $PIDFILE` || echo “can’t reload”

}

case “$1″ in

’start’)

d_start

echo “started.”

;;

’stop’)

d_stop

echo “stoped.”

;;

‘reload’)

d_reload

echo “reloaded.”

;;

‘restart’)

echo “Restarting $DESC: $NAME …”

d_stop

# One second might not be time enough for a daemon to stop,

# if this happens, d_start will fail (and dpkg will break if

# the package is being upgraded). Change the timeout if needed

# be, or change d_stop to have start-stop-daemon use –retry.

# Notice that using –retry slows down the shutdown process somewhat.

sleep 3

d_start

echo “done.”

;;

‘list’)

ps auxf | egrep ‘(PID|nginx)’ | grep -v grep

;;

‘test’)

$DAEMON -t -c $CONFIGFILE

;;

*)

echo “Usage: $SCRIPTNAME {reload|list|test|start|stop|restart}” >&2

exit 3

;;

esac

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)、启动脚本等等,希望对大家有帮助,少走歪路。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: