系统环境设置
- 准备三台redhat linux 5或 centos服务器:
- 负载均衡服务器:Apache安装自带的web发布服务(httpd服务) IP地址:192.168.0.100
- Tomcat发布服务器1:安装有两个发布服务tomcat1和tomcat2 IP地址:192.168.0.101
- Tomcat发布服务器2:安装有两个发布服务tomcat3和tomcat4 IP地址:192.168.0.102
- 统一对外部发布的地址是:http://192.168.0.100 (即负载均衡地址)
- 在设定完成IP之后,最好先设置主机名和IP的对应关系:
1css 2html 3前端 4java |
cat /etc/hosts node 192.168.0.100 web.example.com web #add linux 127.0.0.1 localhost.localdomain localhost nginx ::1 localhost6.localdomain6 localhost6 git |
Tomcat发布器的安装
JDK安装
- JDK软件最新版下载:http://www.oracle.com/technetwork/java/javase/downloads/index.html
- 点击排列的最左边一个大图标的“JDK”进入,
- 接下来选择服务器的版本(如linux),在“I agree”前面方框中打勾选中,再按“continue”下一步
- 选择下面一个版本进行下载,如jdk-6u24-linux-i586.bin
- 下载完成后上传到web服务器上的“/tools”目录下(本身建的目录)
- JDK软件的安装
1github 2web 3 4 5 6 7 8 9 10 11 12 |
# 先查看当前JDK的版本是多少 java –version # 进入下载目录,受权JDK文件的可执行权限 cd /tools/ chmod a+x jdk-6u24-linux-i586.bin # 执行JDK的安装解压缩,完成后按回车结束 . /jdk-6u24-linux-i586 .bin # 把解压出来的目录移动到/usr/local下面 mv jdk1.6.0_24 /usr/local/ |
- 配置JAVA的环境变量
- 新建环境变量文件java.sh
1 2 3 4 5 6 7 |
cat > /etc/profile .d /java .sh <<EOF # set java environment export JAVA_HOME= /usr/local/jdk1 .6.0_24 export CLASSPATH=.:\$JAVA_HOME /lib/dt .jar:\$JAVA_HOME /lib/tools .jar export PATH=\$JAVA_HOME /bin :\$PATH EOF chmod a+x /etc/profile .d /java .sh |
- 从新登陆终端,再次查询java的版本号是否升级了:
java -version
- Tomcat软件最新版下载:http://tomcat.apache.org/
(1)先选择Download下面的tomcat版本(如tomcat 7.0) (2)再点击“Core”下面的“tar.gz”进行下载,如apache-tomcat-7.0.12.tar.gz (3)下载完成后上传到web服务器上的“/tools”目录下(本身建的目录)
Tomcat安装
- 安装tomcat
1 2 3 4 5 6 7 8 9 10 |
# 进入下载目录,进行解压缩: cd /tools tar zxvf apache-tomcat-7.0.12. tar .gz # 复制并重命名目录到/usr/lcoal下面 ls -l cp apache-tomcat-7.0.12 /usr/local/tomcat1 #(web1服务器) cp apache-tomcat-7.0.12 /usr/local/tomcat2 #(web1服务器) cp apache-tomcat-7.0.12 /usr/local/tomcat3 #(web2服务器) cp apache-tomcat-7.0.12 /usr/local/tomcat4 #(web2服务器) |
- 配置tomcat发布器的端口
- web1服务器tomcat1:vi tomcat1/conf/server.xml(修改以下四个地方:)
1 2 3 4 5 |
< Server port = "8005" shutdown = "SHUTDOWN" > <!--'8005'改成'8001'端口--> < Connector port = "8080" protocol = "HTTP/1.1" > <!--'8080'发布端口改成'81'端口--> < Connector port = "8009" protocol = "AJP/1.3" redirectPort = "8443" /> <!--改成'8011'端口--> <!--Engine name="Catalina" defaultHost="localhost"--> < Engine name = "Catalina" defaultHost = "localhost" jvmRoute = "tomcat1" > |
- web1服务器tomcat2:port:8002, http:82, ajp:8012, jvmRote:tomcat2
- web1服务器tomcat3:port:8003, http:83, ajp:8013, jvmRote:tomcat3
- web1服务器tomcat4:port:8004, http:84, ajp:8014, jvmRote:tomcat4
- 在tomcat的server.xml配置参数据中增长session同步复制的设置
- vi server.xml (增长下列代码,增长Engine后面的cluster中去)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> <!--下面的代码是实现session复制功能--> < Cluster className = "org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions = "6" > < Manager className = "org.apache.catalina.ha.session.BackupManager" expireSessionsOnShutdown = "false" notifyListenersOnReplication = "true" mapSendOptions = "6" /> < Channel className = "org.apache.catalina.tribes.group.GroupChannel" > < Membership className = "org.apache.catalina.tribes.membership.McastService" address = "228.0.0.4" port = "45564" frequency = "500" dropTime = "3000" /> < Receiver className = "org.apache.catalina.tribes.transport.nio.NioReceiver" address = "192.168.100.63" <!—这里填写本机IP地址--> port="5000" selectorTimeout="100" /> < Sender className = "org.apache.catalina.tribes.transport.ReplicationTransmitter" > < Transport className = "org.apache.catalina.tribes.transport.nio.PooledParallelSender" /> </ Sender > < Interceptor className = "org.apache.catalina.tribes.group.interceptors.TcpFailureDetector" /> < Interceptor className = "org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor" /> < Interceptor className = "org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor" /> </ Channel > < Valve className = "org.apache.catalina.ha.tcp.ReplicationValve" filter = ".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;" /> < Valve className = "org.apache.catalina.ha.session.JvmRouteBinderValve" /> < Deployer className = "org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir = "/tmp/war-temp/" deployDir = "/tmp/war-deploy/" watchDir = "/tmp/war-listen/" watchEnabled = "false" /> < ClusterListener className = "org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener" /> < ClusterListener className = "org.apache.catalina.ha.session.ClusterSessionListener" /> </ Cluster > |
- 同时须要修改tomcat的web.xml配置参数才能真正实现session同步复制的设置
- web.xml
1 2 3 4 5 6 7 8 |
<!--....--!> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <distributable /> <!--在倒数第二行增长这个代码才能实现session同步复制功能--> </ web-app > |
- 设置Tomcat发布服务开机自启动
- 复制tomcat启动文件到开机目录下:
cp tomcat1/bin/catalina.sh /etc/rc.d/init.d/tomcat1
- 修改上面的tomcat1启动文件:vim /etc/rc.d/init.d/tomcat1(在文件的最顶上添加下列几行)
#chkconfig:35 85 15
#description:tomcat1 server
CATALINA_HOME=/usr/local/tomcat1
JRE_HOME=/usr/local/jdk1.6.0_24
- 添加tomcat1到开机启动服务
chkconfig --add tomcat1
chkconfig --list tomcat1
chkconfig tomcat1 on
service tomcat1 start
- 其它三个tomcat2 、tomcat3 、tomcat4 也都按上面三步来作
- 如何查看tomcat的启动过程
- 方法一:用catalina.sh来启动:
./catalina.sh run
- 方法二:若是用
./startup.sh
启动的话,查看启动日志tail –f /usr/local/tomcat4/logs/catalina.out
Apache Proxy负载均衡
- Apache发布器使用系统自带的httpd服务,在安装操做系统的时候先选择好服务器下面的web服务器组件。
- 修改配置web发布服务的参数文件:
- vim /etc/httpd/conf/httpd.conf (在最底下添加以下内容)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
ServerName localhost:80 #发布的端口说明 <VirtualHost *:80> ServerAdmin admin@china1168.com ServerName localhost ServerAlias localhost <proxy balancer: //testcluster > #testcluster可本身命名,没什么特别的意义 BalancerMember ajp: //192 .168.0.101:8011 loadfactor=1 route=tomcat1 #要与tomcat中的ajp对应 BalancerMember ajp: //192 .168.0.101:8012 loadfactor=1 route=tomcat2 BalancerMember ajp: //192 .168.0.102:8013 loadfactor=1 route=tomcat3 BalancerMember ajp: //192 .168.0.104:8014 loadfactor=1 route=tomcat4 < /proxy > ProxyRequests Off ProxyPass /server-status ! ProxyPass /balancer-manager ! ProxyPass / balancer: //testcluster/ stickysession=JSESSIONID #注意balancer前面有空格 ProxyPassReverse / balancer: //testcluster/ #注意balancer前面有空格 < /VirtualHost > <Location /server-status > #负载均衡服务器的状态查询,http://192.168.0.100/server-status SetHandler server-status < /Location > <Location /balancer-manager > #负载均衡服务器的管理查看,http://192.168.0.100/balancer-manager SetHandler balancer-manager < /Location > |
- 负载均衡集群测试实例
- 在tomcat目录下面的webapps文件夹中新建test测试文件:
- mkdir webapps/test
- vi test/index.jsp(文件内容以下)
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
request.setCharacterEncoding("UTF-8");
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>"); // 若是有新的 Session 属性设置
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
} out.print("<b>Session 列表</b>"); Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="index.jsp" method="POST">
名称:<input type=text size=20 name="dataName"><br>
值:<input type=text size=20 name="dataValue"><br>
<input type=submit>
</form>
</body>
</html>
- 对Apache负载均衡进行测试:
- 正常状况下,提交的测试内容会在四个tomcat之间轮循显示,实现负载均衡。
- 设置Apache发布服务开机自启动:
chkconfig httpd on
Nginx负载均衡
nginx安装
- 安装前必需要先下载相关联的配套软件包:
- 相关联软件的安装
- pcre套件的安装,进入下载目录,进行解压缩:
1 2 3 4 5 |
cd /tools tar zxvf pcre-8.12. tar .gz cd pcre-8.12 . /configure #默认是安装在/usr/local/目录下面,也可指定目录加参数 --prefix=/usr/local/ make && make install |
- openssl套件的安装,进入下载目录,进行解压缩(可选)
1 2 3 4 5 |
cd /tools tar zxvf openssl-1.0.0d. tar .gz cd openssl-1.0.0d . /configure # 默认是安装在/usr/local/目录下面,也可指定目录加参数 --prefix=/usr/local/ make && make install |
- Nginx软件的安装和配置
1 2 3 4 5 |
cd /tools tar zxvf nginx-1.0.0. tar .gz cd nginx-1.0.0 . /configure #默认是安装在/usr/local/目录下面,也可指定目录加参数 --prefix=/usr/local/ make && make install |
- 测试安装是否成功
1 2 3 4 5 |
cd /usr/local/nginx/sbin/ . /nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx .conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx .conf test is successful |
nginx负载配置
- vim /usr/local/nginx/conf/nginx.conf (修改增长下面的内容)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
pid logs /nginx .pid; upstream tomcat { # 负载均衡站点的名称为tomcat,能够本身取 ip_hash; # 可选,根据来源IP方式选择web服务器,省略的话按默认的轮循方式选择web服务器 server 192.168.0.101:81; # web服务器的IP地址及tomcat发布端口 server 192.168.0.101:82; server 192.168.0.102:83; server 192.168.0.102:84; } server { listen 80; # 站点侦听端口80 server_name localhost; # 站点名称 location / { root html; index index.html index.htm; proxy_pass http: //tomcat ; # 负载均衡指向的发布服务tomcat } |
- 注意:
upstream
部分要放在server { listen 80
这部分的前面,不能放到下面去,否则会出错
proxy_pass
部分要放在localtion这部分的括号里面,且http://
后面跟的名称要与上面upstream
中同样
- 启动负载均衡服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
cd /usr/local/nginx/sbin/ . /nginx -t # 测试配置有无错误 . /nginx # 启动服务 netstat -tlnp | grep :80 #查看nginx端口的进程号 kill -9 11274 #杀死nginx的主进程,11274是上面查询出来的主进程号,实际环境中不必定同样 # 在线修改配置参数(在nginx启动的状况),并让它从新加载,其间nginx不用中止服务。 vi nginx.conf kill -HUP ` cat /usr/local/nginx/logs/nginx .pid` # 设置Nginx开机自动启动 vim /etc/rc .d /init .d /nginx ,增长内容 #chkconfig:35 80 10 #description:Nginx server /usr/local/nginx/sbin/nginx chmod a+x nginx chkconfig --add nginx chkconfig nginx on |
Tomcat与Apache或Nginx链接和集群配置
Tomcat的链接方式
- 官方文档参考:http://tomcat.apache.org/tomcat-7.0-doc/connectors.html
- Tomcat与Web服务器的链接方式有两种:
- HTTP: HTTP链接器是Tomcat默认的方式,而且已经被使用。这种方式具备最低的延迟和最佳的总体性能。对于集群,须要一个支持粘性会话的web服务器在Tomcat前端。Tomcat支持mod_porxy(被默认包含在Apache HTTP Server 2.2)做为负载平衡器。值得注意的是,一般状况下HTTP proxy的性能低于AJP的性能,因此集群时AJP是优选。
- AJP: 单个服务器,一个本地WEB服务器和一个Tomcat实例链接的效率一般低于单个Tomcat使用其默认的HTTP链接的方式,即便web应用大部分都是静态内容。若是为了某种缘由,你须要整合一个本地WEB服务器,那么AJP链接将提供更好的效率。对于Tomcat集群,AJP链接是最有效的,其余功能和HTTP集群同样。
Tomcat7所支持的本地链接:
- JK 1.2 .x
- mod_proxy (Apache HTTP Server 2.2默认包含)
其余AJP链接器可能能够工做,但再也不维护。
Tomcat 与 Apache HTTP Server2.4链接
HTTP链接
从上面的说明能够看出,若是你只须要一个Tomcat,那就直接用就行了,不用和Apache HTTP Server链接。若是须要多个Tomcat集群,就是AJP链接。因此用HTTP链接Apache和Tomcat这种状况应该很少,简单说明一下怎么链接: 取消两个module的注释:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
在httpd.conf文件中添加如下两行:
ProxyPass /webappname http://ip:8080/webappname
ProxyPassReverse /webappname http://ip:8080/webappname
ip、端口号和webappname根据实际状况修改
说明:上述写法可能有安全隐患。不要使用ProxyRequests启用代理,除非对代理作了权限控制。不然对你的网络和互联网都是很大的危险。默认ProxyRequests为off。
参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#access
AJP链接
AJP链接官方支持两种方式JK 1.2.x和mod_proxy。
JK是老牌链接器,被普遍使用和验证,值得信任,可是配置比较复杂。
mod_proxy是Apache2.2之后的默认设置,配置简单,可是由于比较新,因此没有通过大范围的验证。
网上JK的文档比较多,这里咱们介绍一下mod_proxy的写法。其实跟HTTP的方式同样,只是把http://
修改成ajp://
就能够了。
取消两个module的注释
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
在httpd.conf文件中添加如下行:
ProxyPass /webappname ajp://ip:8009/webappname
ip、端口号和webappname根据实际状况修改
AJP链接一般不须要设置ProxyPassReverse。
参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy_ajp.html
Apache HTTP Server2.4集群配置
如文章开始所述,Apache Http Server和Tomcat集群要用AJP方式链接
一样集群能够用JK和mod_proxy两种方式,这里介绍mod_proxy的方式:
取消五个module的注释
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
根据负载均衡调度策略的不一样,取消以下module的注释
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
- 示例配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<Proxy balancer: //mycluster > #定义一个集群,起个名字 #定义集群成员。loadfactor是权重,数值越大权重越大被分配的请求约多。route和Tomcat中配置的jvmRoute一至。 #还有一些参数能够添加,好比:max=20 ttl=120 retry=300 timeout=15,详细参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass BalancerMember ajp: //ip :8019 loadfactor=1 route=tomcat7_a BalancerMember ajp: //ip :8029 loadfactor=2 route=tomcat7_b #热备服务器,只有在上面的BalancerMember都坏掉以后才会被启用。 BalancerMember ajp: //ip :8009 status=+H #现有3种负载均衡调度策略 #byrequests:请求计数(Request Counting) #bytraffic:流量加权计数(Weighted Traffic Counting) #bybusyness:挂起请求计数(Pending Request Counting) #默认是byrequests ProxySet lbmethod=bytraffic < /Proxy > ProxyPass /examples balancer: //mycluster/examples #设置代理链接 |
- 负载均衡器的粘性
当一个请求被代理到某个节点,接下来同一个用户的请求都将被代理到相同的节点。不少均衡器经过一张记录客户端ip和节点的关系表来实现这个特性。这种方式对客户端和节点都是透明的,可是存在一些问题:若是客户端藏在某些代理以后将致使负载分布不均,当客户端使用动态IP地址,并在请求间变动,将失去粘性,关系表溢出将致使错误等问题。
mod_proxy_balancer经过两种方式实现粘性:cookies和URL encoding。cookie能够被Apache服务器和节点使用,URL encoding一般在节点中使用。
下面的例子使用mod_headers提供负载均衡粘性,即便节点服务器没有设置合适的session cookie。
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster>
......
</Proxy>
ProxyPass /test balancer://mycluster
env变量有6种,参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html#environment
如下配置同时支持cookies和URL encoding
ProxyPass /test balacer://mycluuster stickysession=JSESSIONID|jsessionid scolonpathdelim=On
<Proxy balancer://mycluster>
BlancerMember http://192.168.1.50:80 route=node1
BlancerMember http://192.168.1.51:80 route=node2
</Proxy>
将集群的日志写到Apache服务器目录下的logs/balance_log文件中。
参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html#stickyness_troubleshooting
须要mod_status。管理页面能够动态更新集群成员,修改平衡器的属性和特定成员或使之离线。
<Location /balancer-manager>
SetHandler balancer-manager
Require ip 192.168
</Location>
你能够经过http://your.server.name/balancer-manager
访问管理页面。
注意,只有balancers在<Location ...>以外定义,才能使用管理页面。
Tomcat 与 Nginx链接
HTTP链接
1 2 3 4 5 6 7 8 |
server { #添加一个站点 listen 82; #设置端口 server_name localhost; #站点名称/域名 location / { #设置路径 proxy_pass http: //ip :8080; #http代理,指向tomcat http地址 } } |
在nginx.conf文件中添加一个server{},listen设置端口,server_name设置域名,location设置目录。
proxy_pass是http代理,指向tomcat地址。
修改后conf后,nginx -s reload就能够热更新了,很方便。
AJP链接
关于AJP链接,有一种说法是Nginx采用链接池,因此HTTP方式的链接不比AJP方式差。
有人的测试结果是Nginx经过HTTP链接Tomcat 性能略强于Apache经过AJP链接Tomcat。
参见:http://nginx.2469901.n2.nabble.com/AJP-td7582236.html
Nginx自己并不支持AJP链接,但有人写了一个nginx_ajp_module来支持ajp。因为是第三方控件,因此请在充分测试后使用。
先到nginx安装文件的目录下,打ajp补丁,从新配置configure,编辑,安装。
- 配置nginx.conf文件
1 2 3 4 5 6 7 8 9 |
server { listen 82; server_name localhost; location / { ajp_keep_conn on; #设置是否保持链接 ajp_pass ajp: //ip :8009; #Tomcat ajp链接地址和端口 } } |
其余配置详情参考:https://github.com/yaoweibin/nginx_ajp_module
Nginx集群配置
HTTP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
upstream tomcat_http { #用upstream定义一组服务器 #ip_hash经过记录客户端ip实现粘性session。有一个第三方的module能够用cookie实现粘性:https://code.google.com/p/nginx-sticky-module/ ip_hash; #经过server定义多个服务器 #weight是权重,默认为1。 #max_fails和fail_timeout配合使用,在fail_timeout时间内通讯失败达到max_fails的次数后,此服务器在fail_timeout时间内被认为不可用。 server 192.168.50.65:8090 weight=2; server 192.168.50.65:8091 max_fails=3 fail_timeout=30s; #keepalive为链接开启缓存,并设置缓存链接的最大数量。 keepalive 10; } server { listen 82; server_name localhost; location / { #将proxy_pass后的服务器地址,变为upstream的名字 proxy_pass http: //tomcat_http ; } } |
更多参数说明参考:http://nginx.org/en/docs/http/ngx_http_upstream_module.html
AJP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
upstream tomcat_ajp { # upstream定义一组服务器 #srun_id同Tomcat配置中Engine的jvmRoute。 server 192.168.50.65:8019 srun_id=tomcat7_a weight=2; server 192.168.50.65:8029 srun_id=tomcat7_b; #用cookie方式实现粘性session jvm_route $cookie_JSESSIONID reverse; keepalive 10; } server { listen 82; server_name localhost; location / { ajp_keep_conn on; ajp_pass tomcat_ajp; #指定链接到哪一个upstream上 } } |