厚积薄发

不忘初心,方得始终!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Nginx介绍

nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好.目前中国大陆使用nginx网站用户有:新浪、网易、 腾讯等。

nginx的负载均衡策略可以划分为两大类:内置策略和扩展策略。

内置策略包含加权轮询和ip hash,在默认情况下这两种策略会编译进nginx内核,只需在nginx配置中指明参数即可。

扩展策略有很多,如fair、通用hash、consistent hash,sticky(支持Session sticky) 等,默认不编译进nginx内核。

Nginx环境安装

CentOS6.3安装

[如果已安装略过该步骤]

1. 可以使用安装盘centos6.3(可以从网上下载最新的镜像文件刻录成光盘)进行linux-centos的安装,安装后设置IP等网络信息可以参考svn地址

http://192.168.1.4/svn/product_repos/AtmanDoc/TechStudy/NetWork/ Centos6.3静态IP设置.docx

JDK1.7安装

[如果已安装略过该步骤]

1. 下载lrzsz,可以通过Xshell客户端进行拖拽上传到服务器任意目录下

yum install lrzsz

2. 查看老jdk版本并卸载

#rpm -qa | grep jdk

java-1.6.0-openjdk-1.6.0.0-1.45.1.11.1.el6.x86_64

卸载

#yum remove java-1.6.0-openjdk-1.6.0.0-1.45.1.11.1.el6.x86_64

# rpm -qa | grep gcj

java-1.5.0-gcj-1.5.0.0-29.1.el6.x86_64

libgcj-4.4.6-4.el6.x86_64

#yum remove java-1.5.0-gcj-1.5.0.0-29.1.el6.x86_64

#yum remove libgcj-4.4.6-4.el6.x86_64

3. 上传jdk1.7,安装包并安装

#rpm -ivh jdk-7u10-linux-x64.rpm

4. 配置环境变量

JAVA_HOME=/usr/java/jdk1.7.0_10

PATH=$JAVA_HOME/bin:$PATH

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export JAVA_HOME

export PATH

export CLASSPATH

5. 立即生效

source /etc/profile

6. 检查jdk安装情况

#echo $JAVA_HOME

#echo java -version

TOMCAT7安装

[如果已安装略过该步骤]

1. 下载apache-tomcat-7.0.34.tar.gz

2. 上传并解压

tar -zxvf apache-tomcat-7.0.34.tar.gz

3. 复制并重新命名

cp -R apache-tomcat-7.0.34 /usr/local/tomcat7

4. 配置环境变量(见红色字体部分)

JAVA_HOME=/usr/java/jdk1.7.0_10

PATH=$JAVA_HOME/bin:$PATH

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

TOMCAT_HOME=/usr/local/tomcat7

CATALINA_HOME=/usr/local/tomcat7

export JAVA_HOME

export PATH

export CLASSPATH

export TOMCAT_HOME

export CATALINA_HOME

5. 启动/停止服务

#cd /usr/local/tomcat7/bin

#./startup.sh

#./shutdown.sh

Nginx1.2.7安装

1. 安装nginx的基础环境,如c编译环境等

yum install gcc gcc-c++ gcc-g77 pcre-devel openssl-devel bison autoconf automake make cmake libcurl-devel gd-devel zlib* fiex* libxml* ncurses-devel libmcrypt* libtool-ltdl-devel*

2. [nginx依赖]上传pcre,解压,安装pcre

#./configure --prefix=/usr/local/pcre-8.32

#make && make install

3. [nginx依赖]上传zlib,解压,安装zlib

#./configure --prefix=/usr/local/zlib-1.2.7

#make && make install

4. [nginx扩展]-黏性session模块(备注:如果不需要黏性session,该步骤可以掠过)

4.1和4.2两种黏性session方案可选1种,建议选择第二种。具体原因请看后面分析。

4.1 nginx_upstream_jvm_route

#tar -zxvf nginx-1.2.7.tar.gz

#svn checkout http://nginx-upstream-jvm-route.googlecode.com/svn/trunk/ /usr/local/nginx-jvm-route

#cd nginx源码路径

#patch -p0 < /usr/local/nginx-jvm-route/jvm_route.patch

4.2 nginx-sticky-module

#上传、解压nginx-sticky-module-1.1.tar.gz

5.  [nginx安装]安装nginx(注意:pcre、zlib为源包路径,非安装后的路径)

选择nginx_upstream_jvm_route的configure命令

#./configure --prefix=/usr/local/nginx --with-pcre=/tmp/pcre-8.32  --with-zlib=/tmp/zlib-1.2.7 --with-http_stub_status_module --add-module=/usr/local/nginx-jvm-route/

选择/nginx-sticky-module的configure命令

#./configure --prefix=/usr/local/nginx --with-pcre=/tmp/pcre-8.32  --with-zlib=/tmp/zlib-1.2.7 --with-http_stub_status_module --add-module=/usr/local/nginx-sticky-module-1.1/

#make && make install

(备注:如果不需要黏性session,则“--with-http_stub_status_module --add-module=/usr/local/nginx-jvm-route/”参数可以去掉)

6. 启动/停止nginx服务

#cd /usr/local/nginx/sbin

#./nginx -c /usr/local/nginx/conf/nginx.conf (加载指定路径的配置文件)

#./nginx -s stop

Nginx负载均衡算法

轮训算法[内置]

默认情况下,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况

加权轮询的原理很简单,首先我们介绍一下轮询的基本流程。如下是处理一次请求的流程图:

wps566E.tmp

图中有两点需要注意,第一,如果可以把加权轮询算法分为先深搜索和先广搜索,那么nginx采用的是先深搜索算法,即将首先将请求都分给高权重的机器,直到该机器的权值降到了比其他机器低,才开始将请求分给下一个高权重的机器;第二,当所有后端机器都down掉时,nginx会立即将所有机器的标志位清成初始状态,以避免造成所有的机器都处在timeout的状态,从而导致整个前端被夯住。

这里处理请求时,用到了Nginx指令upstream,来实现负载均衡

nginx.conf文件:

upstream tomcat {

server 192.168.1.181:8080; //默认轮询(round robin)算法,加weight按权重排序

server 192.168.1.182:8080;

}

server{

listen       80;

server_name  192.168.1.181;

location / {

          proxy_pass http://tomcat;

          proxy_set_header        Host $http_host;

          proxy_set_header        X-Real-IP $remote_addr;

          proxy_set_header        REMOTE-HOST $remote_addr;

          proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

       }

}

配置介绍

1. 这里的upstream的name=tomcat,与server中的,location指令中proxy_pass属性的值相对应(除http://部分)

2. 在一个http{…..}指令中可以配置多个upstream 和server 指令来处理多个端口和地址。

Server指令监听地址的端口号默认为:80,请求地址为:http://localhost/

3. 在upstream 中server可以监听TCP协议和Unix域套接字混合使用:

upstream backend {

    server backend1.example.com weight=5;

    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;

    server unix:/tmp/backend3; //这里unix: 为固定模式

}

参数:weight 表示权重,默认值是1,指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。;

max_fails=number,在一段时间内,允许与服务器之间请求连接失败的次数,超过设置的次数后,Nginx将视该服务器已宕机(这里的一段时间是由fail_timeout=time 属性决定),默认值为1,值设置为0时,将不统计尝试连接的次数;

fail_timeout=time 默认值为10秒;

backup 该属性表示这个服务器是用来备用的;

down  表示该服务器永远被禁用,通常与指令ip_hash一起使用。

IP_HASH算法[内置]

ip hash是nginx内置的另一个负载均衡的策略,流程和轮询很类似,只是其中的算法和具体的策略有些变化,如下图所示:

wps566F.tmp

从本质上说,ip hash算法是一种变相的轮询算法,如果两个ip的初始hash值恰好相同,那么来自这两个ip的请求将永远落在同一台服务器上,这为均衡性埋下了很深的隐患。

使用ip_hash指令来实现负载均衡和解决session问题。

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session 的问题

nginx.conf文件:

upstream tomcat {

        ip_hash;

server 192.168.1.181:8080;

server 192.168.1.182:8080;

}

server{

listen       80;

server_name  192.168.1.181;

location / {

          proxy_pass http://tomcat;

          proxy_set_header        Host $http_host;

          proxy_set_header        X-Real-IP $remote_addr;

          proxy_set_header        REMOTE-HOST $remote_addr;

          proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

       }

}

这里server监听了80端口,地址拦截是冲”/”开始,与上面例子的区别在于,这里的upstream指令中,引用一个指令ip_hash,只有所有请求这个端口的客户端,都会通过cookie来实现会话的保持。

[备注:如何客户端经常变化,那么ip_hash算法则不适合,所以ip_hash适合客户端ip不变化的场合]

location指令介绍:

语法规则: location [=|~|~*|^~] /uri/ { … }

= 开头表示精确匹配

^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。

~ 开头表示区分大小写的正则匹配

~*  开头表示不区分大小写的正则匹配

!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则

/ 通用匹配,任何请求都会匹配到。

黏性session算法[扩展]

nginx_upstream_jvm_route方式

原理:基于cookie的stickly session(JSESSIONID)的实现

参考网页:http://code.google.com/p/nginx-upstream-jvm-route/

Tomcat1 (修改conf/server.xml)

<Engine name="Catalina" defaultHost="localhost" jvmRoute="a">

Tomcat2 (修改conf/server.xml)

<Engine name="Catalina" defaultHost="localhost" jvmRoute="b">

nginx.conf文件:

upstream tomcat {

server 192.168.1.181:8080  srun_id=a;

server 192.168.1.182:8080  srun_id=b;

        jvm_route $cookie_JSESSIONID reverse;

}

server{

listen       80;

server_name  192.168.1.181;

location / {

          proxy_pass http://tomcat;

          proxy_set_header        Host $http_host;

          proxy_set_header        X-Real-IP $remote_addr;

          proxy_set_header        REMOTE-HOST $remote_addr;

          proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

       }

}

在两个tomcat部署两个测试工程,在一个测试的jsp分别打印出session和cookie信息

Tomcat1上的index.jsp

主机A </br>

session:<%out.print(request.getSession()) ;%></br>

cookie:<%out.println(request.getHeader("Cookie")); %>

Tomcat2上的index.jsp

主机B </br>

session:<%out.print(request.getSession()) ;%></br>

cookie:<%out.println(request.getHeader("Cookie")); %>

打开IE,地址栏输入http://192.168.1.181/test/index.jsp

可以看到第一次访问时,cookie为null,以后每一次cookie的值保持不变,按F5刷新,打印信息一直不变(说明所有的请求,访问的是后台tomcat是固定的)。

当关闭浏览器,重新敲入地址,访问到另外一台机器,一直刷新仍然是那个机器。

说明在一个session周期,访问的后台tomcat是固定的。下次session,可以到另外的tomcat,一旦确定,请求所访问的tomcat则固定。

只能通过JSESSIONID来实现,不能指定另外的key。而JSESSIOINID是会话cookie,当前浏览器关闭,重新开始。

nginx-sticky-module方式

原理:基于cookie的stickly session(用户自己指定的key,不能用JSESSIONID,默认为route)的实现

参考网页: https://code.google.com/p/nginx-sticky-module/wiki/Documentation

nginx.conf

upstream tomcat {

                sticky name=cookieD;

server 192.168.1.181:8080;

server 192.168.1.182:8080;

}

支持用户自己指定的key,stickly的用法请参考上述网页.

很显然对两种方式,应该采用该方式!

FAIR算法[扩展]

fair策略是扩展策略,其原理是根据后端服务器的响应时间判断负载情况,从中选出负载最轻的机器进行分流。这种策略具有很强的自适应性,但是实际的网络环境往往不是那么简单,因此要慎用。

通用HASH算法[扩展]

这两种也是扩展策略,在具体的实现上有些差别,通用hash比较简单,可以以nginx内置的变量为key进行hash,一致性hash采用了nginx内置的一致性hash环,可以支持memcache。

负载均衡算法比较

均衡性:是否能够将请求均匀的发送给后端

一致性:同一个key的请求,是否能落到同一台机器

容灾性:当部分后端机器挂掉时,是否能够正常工作

wps5680.tmp

posted on 2016-06-01 14:30  欢迎来到Java的世界  阅读(831)  评论(0编辑  收藏  举报