Nginx
实现负载均衡

实验环境:RHEL6.0

Server
Server3.example.com

    IP
192.168.0.3

1.
安装配置Nginx

 
所需源码包:

pcre

nginx:

gperftools
:(优化nginx

openssl
zlib
  
 
 
# yum install gcc make gcc-c++  -y

解压zlibpcreopensslgperftools源码包!

 
1.1
安装所需组件——pcre(提供rewrite模块)

 
【系统默认自带有pcre,如若提前卸载,则无法编译安装】

【源码包安装完毕后请勿删除,因为安装nginx时需要使用】

 
# tar zxf pcre-8.32.tar.gz

# cd pcre-8.32

# ./configure \

> --prefix=/usr/local/pcre-8.32 \

> --libdir=/usr/local/lib/pcre \

> --includedir=/usr/local/include/pcre

# make && make install

# vim /etc/ld.so.conf

***********************************

添加:

/usr/local/lib/pcre

***********************************

# ldconfig                  #
载入动态函数库

 
1.2
安装google-perftools

google-perftools
包含四个工具:TCMallocheap-checkerheap-profilercpu-profilerTCMallocgoogle-perftools的其中一个工具,用于优化内存分配的效率和速度,帮助在高并发的情况下很好的控制内存的使用。

# tar zxf gperftools-2.0.tar.gz

# cd gperftools-2.0

# ./configure

# make&&make install

# echo "/usr/local/lib" >>/etc/ld.so.conf

# ldconfig

1.3
安装Nginx

# useradd -M -s /sbin/nologin www

# cd nginx-1.3.14

# ./configure \

> --user=www \

> --group=www \

> --prefix=/usr/local/nginx \

> --pid-path=/usr/local/nginx/logs/nginx.pid \

> --error-log-path=/usr/local/nginx/logs/error.log \

> --http-log-path=/usr/local/nginx/logs/access.log \

> --with-http_stub_status_module \        #
取得一些nginx的运行状态

> --with-http_ssl_module \

> --http-client-body-temp-path=/tmp/nginx_client \#
客户端请求临时文件

> --http-proxy-temp-path=/tmp/nginx_proxy \

> --http-fastcgi-temp-path=/tmp/nginx_fastcgi \

> --with-http_gzip_static_module \        #
启用时需要zlib

> --with-google_perftools_module \        #
该模块能优化nginx

> --with-ld-opt='-l tcmalloc_minimal'  \  #
该模块能优化nginx

> --with-ipv6 \

> --with-pcre=/root/source/pcre-8.32/  \   #
指定pcre的源码位置

> --with-openssl=
/root/source/openssl-1.0.1e \ #
指定openssl源码位置

> --with-zlib=/root/source/zlib-1.2.5  \   #
指定zlib的源码位置

> --with-http_flv_module    \             #
支持对FLV文件的拖动播放

> --with-http_realip_module     \          #
支持显示真实来源IP地址

> --with-mail     \          #
允许POP3/IMAP4/SMTP代理模块

> --with-mail_ssl_module    \#
允许POP3IMAPSMTP可以使用SSLTLS

#make

#make install

 
1.4
配置Nginx

# vim /usr/local/nginx/conf/nginx.conf

********************************************************************

user  www;

worker_processes  1;

error_log  logs/error.log;

 
pid        logs/nginx.pid;

 
google_perftools_profiles /var/tmp/tcmalloc;

 
worker_rlimit_nofile 1024;

events {

    use epoll;

    worker_connections  1024;

}

 
http {

    include       mime.types;

default_type  application/octet-stream;

 
upstream  server3.example.com {

    server  192.168.0.4:80

    weight=1 max_fails=3 fail_timeout=60s;

    server  192.168.0.5:80

    weight=1 max_fails=3 fail_timeout=60s;

    }

 
    access_log  off;

    error_log /dev/null;

 
    sendfile        on;

    server_names_hash_bucket_size  128;

    client_header_buffer_size 32k;

    large_client_header_buffers 4 32k;

    client_max_body_size 8m;

    tcp_nopush on;

    tcp_nodelay on;

    keepalive_timeout  120;

 
    gzip  on;

    gzip_min_length  1k;

    gzip_buffers  4  16k;

    gzip_http_version  1.0;

    gzip_comp_level  2;         #
压缩等级

    gzip_types  text/plain  application/x-javascript  text/css  application/xml;

    gzip_vary   on;

 
    server {

        listen       80;

        server_name  Server3.example.com;

        #access_log  logs/host.access.log;

 
        location / {

            root   html;

            index  index.html index.htm;

        }

     

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

          }

        }

  include   vhost/*.conf;

 }

1.5
配置nginx代理

# cd /usr/local/nginx/conf/

# vim proxy.conf

*********************************************************************

proxy_redirect          off;

proxy_set_header        Host $host;

proxy_set_header        X-Real-IP $remote_addr;

proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;

client_max_body_size    50m;

client_body_buffer_size 256k;

proxy_connect_timeout   30;

proxy_send_timeout      30;

proxy_read_timeout      60;

 
proxy_buffer_size       4k;

proxy_buffers           4  32k;

proxy_busy_buffers_size 64k;

proxy_temp_file_write_size      64k;

proxy_next_upstream     error timeout invalid_header http_500 http_503 http_404;

proxy_max_temp_file_size        128m;

 
#Nginx cache

client_body_temp_path   client_body 1 2;

proxy_temp_path proxy_temp 1 2;

#client_body_temp_path  /tmpfs/client_body_temp 1 2;

#proxy_temp_path        /tmpfs/proxy_temp 1 2;

#fastcgi_temp_path      /tmpfs/fastcgi_temp 1 2;

*********************************************************************

 
1.6
建立Ningx虚拟主机目录

# mkdir -p /usr/local/nginx/conf/vhost

# mkdir /home/www

# chmod 755 -R /home/www

# chown -R www.www  /home/www/

# chown www /usr/local/nginx/conf/

 
1.7
启动、关闭Nginx

# cp /usr/local/nginx/sbin/nginx  /etc/init.d/nginx

# /etc/init.d/nginx                #
启动Nginx

# /etc/init.d/nginx  -s reload     #
重启Nginx

# /etc/init.d/nginx  -s stop       #
关闭Nginx

 
1.8 Nginx
启动脚本

# vim /etc/init.d/nginx

********************************************************************

#! /bin/sh

# chkconfig: 2345 55 25

# Description: Startup script for nginx webserver on RHEL. Place in /etc/init.d and

# run 'update-rc.d -f nginx defaults', or use the appropriate command on your

# distro. For CentOS/Redhat run: 'chkconfig --add nginx'

 
### BEGIN INIT INFO

# Provides:          nginx

# Required-Start:    $all

# Required-Stop:     $all

# Default-Start:     2 3 4 5

# Default-Stop:      0 1 6

# Short-Description: starts the nginx web server

# Description:       starts nginx using start-stop-daemon

### END INIT INFO

 
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=/usr/local/nginx/conf/$NAME.conf

PIDFILE=/usr/local/nginx/logs/$NAME.pid

SCRIPTNAME=/etc/init.d/$NAME

 
set -e

[ -x "$DAEMON" ] || exit 0

 
do_start() {

 $DAEMON -c $CONFIGFILE || echo -n "nginx already running"

}

 
do_stop() {

 kill -INT `cat $PIDFILE` || echo -n "nginx not running"

}

 
do_reload() {

 kill -HUP `cat $PIDFILE` || echo -n "nginx can't reload"

}

 
case "$1" in

 start)

 echo -n "Starting $DESC: $NAME"

 do_start

 echo "."

 ;;

 stop)

 echo -n "Stopping $DESC: $NAME"

 do_stop

 echo "."

 ;;

 reload|graceful)

 echo -n "Reloading $DESC configuration..."

 do_reload

 echo "."

 ;;

 restart)

 echo -n "Restarting $DESC: $NAME"

 do_stop

 do_start

 echo "."

 ;;

 *)

 echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2

 exit 3

 ;;

esac

 
exit 0

********************************************************************

# chmod +x /etc/init.d/nginx

# chkconfig  --add nginx

# chkconfig  nginx on

 
1.9
虚拟主机的建立

# cd /usr/local/nginx/conf/vhost/

# vim default.conf

*********************************************************************

server       

{

listen  80;

#
本机域名或IP

server_name  server3_3.example.com              

index  index.html  index.php;

root    /home/www;

 
location  /nginx{

stub_status  on;

auth_basic  "NginxStatus";

#auth_basic_user_file  conf/htpasswd;  

#
密码是由apachehtpasswd工具产生

access_log off;

}

 
location  / {

location  ~ .*/.(php|php5)?$ {

index index.php;

root /home/www/;

proxy_pass  http://127.0.0.1:81;

}

 
include proxy.conf;

if ( !-e $request_filename){

proxy_pass  http://127.0.0.1:81;

}

 
location ~* /.(jpg|jpeg|gif|png|swf)$ {

if ( -f $request_filename ){

root  /home/www/;

expires  30d;

break;

}

}

 
location ~*  /.(jss|css)$ {

if (-f $request_filename){

root /home/www/;

expires  1d;

break;

}

}

}

 
error_page  500  502  503  504  /50x.html;

location = /50x.html{

root html;

}

#
如果需要记录就把下面的注释去掉

# log_format  access '$http_x_forwarded_for  -  $remote_user [$time_local] "$request"'

# '$status  $body_bytes_sent  "$http_referer"'

# '"$http_user_agent" $remote_addr';

# access_log  logs/IP_access.log  access;

}

*********************************************************************

注意,配置文件中,每个“server”即就一台主机~

# /etc/init.d/nginx start   #
启动Nginx

此时,对应关系如下:

server3.example.com
——>/usr/local/nginx/html/index.html

server3_3.example.com
——>/home/www/index.html

虚拟主机OK了! 多个虚拟主机复制并修改以上内容即可~

 
顺便提一句:

可以利用tcmalloc优化mysql数据库喔!

# vim /etc/init.d/mysqld

添加:export LD_PRELOAD=/usr/local/lib/libtcmalloc.so

重启mysql数据库

#  lsof -n|grep tcmalloc 
可以查看mysql是否采用了该模块。

 
2.0 Nginx
实施负载均衡(必须配合反向代理才能实现)

主要利用ngx_http_upstream_hash_module模块和Nginx反向代理配置

# vim /usr/local/nginx/conf/nginx.conf

http花括号内,添加:

***************************************************************

upstream  servertest.example.com {

 
        server  192.168.0.1:80

        weight=1 max_fails=3 fail_timeout=60s;

 
        server  192.168.0.2:80

        weight=1 max_fails=3 fail_timeout=60s;

}

#
其中weight是权重,决定服务器的优先级;

#max_fails
的值决定主server判断slave是否宕机的失败次数;

#faile_timeout
的值决定判定为宕机的时间(如:60秒内是宕机状态)

***************************************************************

 
2.1 Nginx
反向代理的设置

反向代理:多个客户端使用该服务器访问内部web服务器,从而提升静态网页的访问速度!代理服务其均匀发送请求 多台内部web服务器,达到较好的负载均衡效果!

 
反向代理的优势:

   
可以将负载均衡和代理服务器的高速缓存技术结合在一起,提供有益的性能,具备额外的安全性,外部用户不能直接访问真实的web服务器,并且可以实现较好的负载均衡策略,将负载可以非常均匀地分给内部服务器,不会出现负载集中到某个服务器的偶然现象。

# vim /usr/local/nginx/conf/nginx.conf

*********************************************************************

添加:

server

{

  listen       80;

  server_name  servertest.example.com;

  location / {

      proxy_pass  http://servertest.example.com;#
反向代理的地址池

      proxy_set_header   Host   $host; 

      proxy_set_header   X-Real-IP  $remote_addr;

       }

access_log  off;

}

#
当后端web服务器上也配置有多个虚拟主机时,需要用Header来区分反向代理哪个主机名;

#
如果后端web服务器上的程序需要获取用户IP,就从Header头获取!

*********************************************************************

对与缓存方面的设置,根据变更频率的不同而合适的设置即可~

Nginx
的配置文件对字体格式要求很严,出问题时请注意检查!

 
在其它slave机器安装nginx后进行测试!

 
 
遇到的问题及解决办法:

1.
报错:[emerg]directive "location" has no opening "{" in .....

解决方法:

   
由于对应行或者附近行的“{”前面缺少空格,导致该错误!

 
2.
无报错,但是就是无法打开80端口进行工作

解决方法:配置文件中,缺少“server......”项的配置!(就是监听80端口和根目录的相关配置)

 
3.
可以使用域名访问,但是无法使用IP访问

解决办法:我是因为在配置文件中有选项“include   vhost/*.conf;”,该选项应该放于文件末尾,否则会覆盖后面相应的配置!

 
4.
访问servertest.example.com是报错“502 Bad Gateway

解决办法:出现此问题说明已经正确配置了proxy,负载均衡的机器服务为开!

找到slave机器重新开启nginx服务即可!

 
5.
启动Nginx是报错:[emerg] unknown directive "" in nginx.conf

解决方法:nginx不识别的“}”是由于我的疏忽采用了中文输入法造成的!