nginx+tomcat搭建负载均衡集群
前提nginx已经搭建好nginx-1.10.1.tar.gz
所需软件包:
apache-tomcat-7.0.37.tar.gz ##tomcat安装包
jdk-7u79-linux-x64.tar.gz ##tomcat需要运行在jdk的环境下
至少准备两台虚拟机
一、配置tomcat
这是两台虚拟机都要做的
1.解包到/usr/local
# tar zxf apache-tomcat-7.0.37.tar.gz -C /usr/local
# tar zxf jdk-7u79-linux-x64.tar.gz -C /usr/local
2.在/usr/local下制作软连接
# ln -s jdk1.7.0_79 java
#ln -s apache-tomcat-7.0.37 tomcat
3.设置环境变量
# vim /etc/profile
export JAVA_HOME=/usr/local/java
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/bin
# source /etc/profile
4.做一个小测试看我们的环境变量是否设置好了
# echo $PATH
# echo $CLASSPATH
# vim test.java
public class test {
public static void main(String[] args) {
System.out.println("hello,java");
}
}
# javac test.java
# java test
5.开启tomcat
# /usr/local/tomcat/bin/startup.sh
此时可以通过访问8080端口来查看是否启动了tomcat
实验:通过网页访问.jsp文件
在nginx.conf中添加
意思是,当访问的是jsp文件时,全部都转交给172.25.0.1的8080端口处理
在nginx的发布目录下编写文件test.jsp
server1 time is : <%-new java.util.Date()%>
通过网页访问:
命令jps:
jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。
二、搭建nginx+tomcat的负载均衡集群
1.修改nginx.conf,在http段添加upstream来定义后端的tomcat的集群
2.重启nginx
# nginx -s reload
3.在tomcat中写测试页文件
这一步两台虚拟机上都要做
/usr/local/tomcat/webapps/ROOT
server1'time is <%=new java.util.Date()%>
第二台虚拟机的测试页这样写
server2'time is <%=new java.util.Date()%>
3.通过网页访问该文件,刷新多遍,会发现一会儿显示server1,一会儿显示server2
做到这我们可以想一下,负载均衡可以在哪里在做?
1.DNS服务,域名解析时,就直接解析到不同的服务器上
2.ip_hash 将不同的客户端ip分配到不同的服务器上
3.cookie,服务器给客户端下发一个cookie,具有特定cookie的请求会分配给它的发行者
三、nginx的sticky模块
http://blog.****.net/yu870646595/article/details/52056340
Sticky就是基于cookie的一种负载均衡解决方案,通过cookie实现客户端与后端服务器的会话保持, 在一定条件下可以保证同一个客户端访问的都是同一个后端服务器。请求来了,服务器发个cookie,并说:下次来带上,直接来找我。
Sticky工作原理 Sticky是nginx的一个模块,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上。sticky的处理过程如下(假设cookie名称为route):
1.客户端首次发起请求,请求头未带route的cookie。nginx接收请求,发现请求头没有route,则以轮询方式将请求分配给后端服务器。
2.后端服务器处理完请求,将响应头和内容返回给nginx。
3.nginx生成route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值。
4.客户端接收请求,并创建route的cookie。
5.客户端再次发送请求时,带上route。
6.nginx接收到route,直接转给对应的后端服务器。
配置过程:
1.需要nginx-goodies-nginx-sticky-module-ng-c78b7dd79d0d.tar.gz,解包
2.重新编译nginx
编译完之后可能会因为nginx的版本过高而导致无法成功,所以需要下载一个较低的nginx版本来编译
3.修改nginx.conf
重启nginx
4.测试
在网页上访问
在命令行访问,就会出现1.和2会轮询出现,而浏览器一只都是1,因为sticky是基于cookies的
四、tomcat和memcache
Tomcat-1 (T1) 将 session 存储在 memcached-2 (T2)上。只有当 M2 不可用时,T1 才将 session 存储在 memcached-1 上(M1 是 T1 failoverNode)。使用这种配置的好处是,当 T1 和 M1 同时崩溃时也不会丢失 session 会话,避免单点故障。T1和T2的会话都会在自己的内存里保留一份,所以加入当T1宕掉,M1的内的数据没了,但是T2自己的内存有一份,而且M2中保存的是T1的会话,所以会话不会丢失。
配置过程:
两台虚拟机上都要做
1.在/usr/local/tomcat/webapps/ROOT下编写测试页test.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</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="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>
2.用网页访问
现在把1的tomcat关掉,再次访问,会发现以前的信息不见了
现在开始配置能让他保留下来的
# cd /usr/local/tomcat/lib
下载下面这些包到/usr/local/tomcat/lib
asm-3.2.jar
kryo-1.04.jar
kryo-serializers-0.10.jar
memcached-session-manager-1.6.3.jar
memcached-session-manager-tc7-1.6.3.jar
minlog-1.2.jar
msm-kryo-serializer-1.6.3.jar
reflectasm-1.02.jar
spymemcached-2.7.3.jar
修改文件/usr/local/tomcat/conf/context.xml,在Contest内添加
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:172.25.90.1:11211,n2:172.25.90.2:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
虚拟机2应该把上面修改一个地方,failoverNodes=‘n2’
重启tomcat
# cat logs/catalina.out
若有跟下面截图一样的信息,说明tomcat已经成功配好交叉存储的memcached了
接下来去网页上验证一下结果:
此时我们关掉2上面的tomcat,再去添加信息,会发现响应的是1,而且,以前在2上保存的信息依然存在
扩展:nginx的五种负载均衡算法:
http://blog.****.net/gzh0222/article/details/8095994
nginx 负载均衡5种配置方式
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
例如:
upstream bakend {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}
3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
例如:
upstream bakend {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend {
server server1;
server server2;
fair;
}
5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
upstream backend {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
tips:
upstream bakend{#定义负载均衡设备的Ip及设备状态
ip_hash;
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}
在需要使用负载均衡的server中增加
proxy_pass http://bakend/;
每个设备的状态设置为:
1.down 表示单前的server暂时不参与负载
2.weight 默认为1.weight越大,负载的权重就越大。
3.max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
4.fail_timeout:max_fails次失败后,暂停的时间。
5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
nginx支持同时设置多组的负载均衡,用来给不用的server来使用。
client_body_in_file_only 设置为On 可以讲client post过来的数据记录到文件中用来做debug
client_body_temp_path 设置记录文件的目录 可以设置最多3层目录
location 对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡