所谓集群,就是把多台服务器集合起来,对外提供一个接口访问,对用户来说完全透明,常用的办法就是前端放一个服务器,将用户请求分发到不同的服务器,大致有以下几种方案
1)采取DNS轮询:将用户的连接解析到不同的服务器上,这会产生一个问题,如果一个服务器宕掉,DNS无法及时更新,就会出现问题
2)反向代理服务器:将用户的连接转发到不同的服务器上,这有两种方式,一个是修改HTTP头,让用户的连接转到固定的服务器,以后不再和代理服务器交互,这会修改用户浏览器里的地址,可能会不怎么友好;如果不修改地址,用户总是通过代理服务器转接,这个代理服务器可能会成为瓶颈。
3)MAC地址转发,所有的服务器IP地址相同,通过设备指向不同的机器。
对于代理问题,会产生Session共享的问题,有一种办法就是针对特定用户固定在一台服务器上,这样就不存在Session共享的问题了,这种方法最简单,但是其算法效率比较重要,需要自己选择。还有就是将所有服务器的Session共享,比如放在数据库里、共享目录里或者MemCached里等,但是这些实现方式都有一定的问题,比如保存的数据需要序列化、共享服务器会成为系统薄弱点;再有就是将Session复制,让所有的服务器保持相同的Session信息,这种情况如果需要服务器过多,会严重的影响性能。
系统配置
CentOS 7,192.168.1.14,Apache 80, Nginx 808, Tomcat8 8081, Tomcat8 8082

可选的方案
1)Nginx:固定服务器访问,这个非常简单,修改nginx.conf,采用ip_hash指令,如下
http {
.............
upstream tomcat_server_pool{
ip_hash;
server 192.168.1.14:8081 weight=4 max_fails=2 fail_timeout=30s;
server 192.168.1.14:8082 weight=4 max_fails=2 fail_timeout=30s;
}
server {
listen 808;
server_name localhost;

charset utf-8;

#access_log logs/host.access.log main;

if (-d $request_filename)
{
rewrite ^/(.*)([^/]) http://$host/$1$2/ permanent;
}
location / {
#root html;
index index.html index.htm index.do;

proxy_next_upstream http_502 http_504 error timeout invalid_header ;
proxy_pass http://tomcat_server_pool;
#proxy_set_header Host www.shiyq.com;
proxy_set_header X-Forwarded-For $remote_addr;
}

可以看出nginx将808端口转发到本机的8081/8082,创建一个spring mvc项目,虚拟目录为study,修改默认的文件,如下
HomeController.java,增加以下内容
@RequestMapping(value = "/index.do", method = RequestMethod.GET)
public String home_do(Locale locale, Model model,HttpServletRequest request) {
logger.info("Welcome home! The client locale is {}.", locale);

Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);

String formattedDate = dateFormat.format(date);

String host_str = ", the host is " + request.getLocalAddr() + ":" + request.getLocalPort();
HttpSession session = request.getSession();

String check = request.getParameter("check");
if(check != null && !check.equals("")){
session.setAttribute("name", "石永强");
}

logger.info("the name in session is {}", (String)session.getAttribute("name"));
String test_Str = (String) session.getAttribute("host_str");

model.addAttribute("serverTime", formattedDate + ", the host is "+ host_str);

model.addAttribute("name",session.getAttribute("name"));

model.addAttribute("sessionId",session.getId());

return "home";
}
修改home.jsp,内容如下
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>

<P> The time on the server is ${serverTime}. </P>
<P> The name in session is ${name}. </P>
<P> The session id is ${sessionId}. </P>
</body>
</html>
有时候会出现乱码的问题,修改如下内容
在web.xml中加上如下
<filter>
<filter-name>Encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

上述配置适合解决method=post的问题,如果需要get方式支持中文,如form用get方式提交,或者点击链接支持中文,则需要修改 Tomcat根目录的 conf/server.xml文件中,找<Connector port="8080" />,在里面加<Connector port="8080" uRIEncoding="utf-8" />
注意如果用于开发服务器,需要找到正确的位置,如Eclipse的Servers下的配置文件。
但是在地址栏输入中文,仍然无法支持,只能禁止这种方式。
在这种情况下,访问http://192.168.1.14:808/study/index.do?check=1
输出为
Hello world!
The time on the server is 2014年8月6日 上午11时39分48秒, the host is , the host is 192.168.1.14:8081.

The name in session is 石永强.

The session id is C318A769671490E6822C04752499380F.
刷新之后,可以看到访问的是固定的服务器,这样就能保证用户Session不会出问题
2)使用MemCache
这需要Nginx的session插件,还需要tomcat的memcache插件,可是code.google.com访问不了,虽然文档很多,也实现不了,看以后吧。
只能采用Session复制的方式
3)tomcat 8配置cluster非常简单,当然,这种集群方式采取广播的方式复制Session,当数量到了一定程度必然会引起广播风暴,不适合大型系统
最简单的设置方法:
A)将server.xml中<Cluster>标签注释去掉,默认如下
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
B)在需要复制Session的web-app中的web.xml增加一行:<distributable/>
C)关掉防火墙:service iptables stop,如果使用的是firewalld,使用命令service firewalld stop
设置Cluster需要注意的地方(官方文档)
a)所有的session属性必须实现java.io.Serializable
b)去掉server.xml中Cluster元素的注释
c)如果要定制valves,确保要设置ReplicationValve
d)确保在web.xml中增加<distributable/>
e)如果使用了mod_jk,在Engine中要设置jvmRoute属性为 workers.properties的worker名称一致
f)确保所有的时间都相同,经过NTP服务器的同步
g)确保你的负载均衡设置为会话粘连模式(sticky session mode)
在浏览器中访问http://192.168.1.104:808/study/index.do,会发现在设置了ip_hash的情况下,根据页面提示,会发现总是访问一个服务器,将这个tomcat关掉,再刷新页面,就会发现自动访问另一个tomcat,而session信息不变。
而且,如果去掉了ip_hash模式,nginx会自动按顺序依次访问系统,但其session ID不变。
如果要更好的测试可以,可以分别访问http://192.168.1.14:8081/study/index.do和http://192.168.1.14:8082/study/index.do,会发现是一致的session ID,而且还可以访问http://192.168.1.14:8081/study/index.do?check=1,这时候已经设置了session的属性值,然后访问http://192.168.1.14:8082/study/index.do,就可以知道确实发生了Session复制。
如果需要更复杂的定制效果,可以看一下文档
对于防火墙的问题,可以增加如下规则
iptables -A INPUT -i eth0 -d 224.0.0.4 -j ACCEPT
vim /etc/sysconfig/iptables
增加以下内容:
-A INPUT -p udp -m state --state NEW -m udp --dport 45564 -j ACCEPT
启动防火墙
service iptables save
service iptables start
3)Apache+mod_jk+tomcat方案
a)下载apache开发包
yum install httpd-*
b)下载mod_jk
wget http://mirrors.cnnic.cn/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.40-src.tar.gz
tar xvf tomcat-connectors-1.2.40-src.tar.gz
cd tomcat-connectors-1.2.40-src.tar.gz
cd native
./configure --with-apxs=/bin/apxs
make
make install
c)配置Apache
因为httpd.conf包含conf.module.d目录下文件,在此目录下新建00-add.conf,输入以下内容

LoadModule jk_module modules/mod_jk.so #加载模块
JkWorkersFile conf/worker.properties #加载mod_jk配置文件

JkMount /* worker3 #将根目录转发到worker3,worker3是一个负载均衡服务器,包含两台apache服务器

<IfModule dir_module>
DirectoryIndex index.jsp index.do
</IfModule>
d)在conf目录下建立workder.properties文件,内容如下
worker.list = worker3
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
worker.worker1.lbfactor=1
worker.worker1.connection_pool_timeout=600
worker.worker1.socket_keepalive=1
worker.worker1.socket_timeout=60

worker.worker2.type=ajp13
worker.worker2.host=localhost
worker.worker2.port=8010
worker.worker2.lbfactor=1
worker.worker2.connection_pool_timeout=600
worker.worker2.socket_keepalive=1
worker.worker2.socket_timeout=60

worker.worker3.type = lb
worker.worker3.balance_workers = worker1, worker2
可以看出worker1对应本机的8009端口,即前面配置过的tomcat8-1,worker2对应本机的8010端口,即之前配置过的tomcat8-2服务器,worker3代表负载均衡服务器,包括两个成员worker1,worker2
e)配置tomcat
vim /work/tomcat8-1/conf/server.xml
修改如下内容,在Engine标签增加jvmRoute="worker1"
<Engine name="Catalina" defaultHost="localhost" jvmRoute="worker1">
vim /work/tomcat8-2/conf/server.xml
修改如下内容,在Engine标签增加jvmRoute="worker2"
<Engine name="Catalina" defaultHost="localhost" jvmRoute="worker2">
f)重启Apache和tomcat,浏览器中输入http://192.168.1.14/study/index.do,可以看到类似的内容
The time on the server is 2014年8月6日 下午05时21分04秒, the host is , the host is 192.168.1.14:80.

The name in session is .

The session id is AE132D73152E74C043ED64ED6F27707E.worker2.
这里有一个有意思的事情,session id会增加一个i额后缀,即worker1或者workder2,应该是jvmRoute的作用,但本质来说还是一个session
用mod_jk的一个问题是不知道访问的是哪台机器,因为显示的apache的地址端口,通过session可以知道到底是哪台机器。
之前我们配置过nginx的均衡,浏览器输入http://192.168.1.14:808/study/index.do
会看到session id去掉后缀确实是一样的,而且运行http://192.168.1.14:808/study/index.do?check=1可以看到session信息是共享的。

总体来说,用nginx配置负载均衡要容易的多,mod_jk要麻烦一些,tomcat的session复制也非常容易,只不过要记住配置防火墙,如果出现问题,要第一时间关掉防火墙,有可能就好了。

CentOS 7 学习(三)配置Tomcat集群的更多相关文章

  1. 三种Tomcat集群方式的优缺点分析

    三种Tomcat集群方式的优缺点分析 2009-09-01 10:00 kit_lo kit_lo的博客 字号:T | T 本文对三种Tomcat集群方式的优缺点进行了分析.三种集群方式分别是:使用D ...

  2. linux下配置tomcat集群的负载均衡

    linux下配置tomcat集群的负载均衡 一.首先了解下与集群相关的几个概念集群:集群是一组协同工作的服务实体,用以提供比单一服务实体更具扩展性与可用性的服务平台.在客户端看来,一个集群就象是一个服 ...

  3. 九、配置Tomcat集群

    配置Tomcat集群所需服务器三台:192.168.1.5(调度服务器).192.168.1.10(WEB1),192.168.1.20(WEB2) 1.调度服务器设置 [root@proxy ~]# ...

  4. Apache配置tomcat集群

     APACHE 2.2.9+TOMCAT6.0配置负载均衡 目标: 使用 apache 和 tomcat 配置一个可以应用的 web 网站,要达到以下要求: 1. Apache 做为 HttpSe ...

  5. nginx配置tomcat集群

    显示nginx的核心配置 #user nobody;worker_processes 1; events { worker_connections 1024;    #并发连接数} http { in ...

  6. windows单机环境下配置tomcat集群

    场景:我们在平常联系中,需要涉及到tomcat中,但是电脑不够怎么办,肯定是在自己的电脑上模拟集群,就是装多个tomcat,这时候需要稍微配置下.如果是多个服务器,那不用配置,直接怼!!! 这里介绍的 ...

  7. windows下使用nginx配置tomcat集群

    转自:https://blog.csdn.net/csdn15698845876/article/details/80658599

  8. Tomcat集群---Cluster节点配置(转)

    <!-- Cluster(集群,族) 节点,如果你要配置tomcat集群,则需要使用此节点. className 表示tomcat集群时,之间相互传递信息使用那个类来实现信息之间的传递. cha ...

  9. Nginx+Tomcat集群配置

    Nginx+Tomcat集群配置 一台虚拟机作为Nginx服务 两太虚拟机配置Tomcat+jdk环境 Nginx测试 启动: cd usr/local/nginx/sbin ./nginx ---& ...

随机推荐

  1. [转载] PHP工作模型与运行机制

    转载自http://www.nowamagic.net/librarys/veda/detail/350 PHP的工作模型非常特殊.从某种程度上说,PHP和ASP.ASP.NET.JSP/Servle ...

  2. Python之多进程篇

    Process 创建子进程执行指定的函数 >>> from multiprocessing import Process,current_process >>> & ...

  3. [O]ORACLE物化视图的使用

    用于数据复制的物化视图 物化视图的一个主要功能就是用于数据的复制,Oracle推出的高级复制功能分为两个部分,多主复制和物化视图复制.而物化视图复制就是利用了物化视图的功能. 物化视图复制包含只读物化 ...

  4. POJ1082食物链

    加权并查集入门习题. 传送门http://poj.org/problem?id=1182 下面来记录一下做法: 并查集的作用是询问两个对象时候在同一集合以及将两个非空不相交集合合并. 本题涉及两点之间 ...

  5. c语言的字符串

    1. 字符串   1. 什么是字符串 ● 简单的字符串”itcast” ● 一个’i’是一个字符 ● 很多个字符组合在一起就是字符串了 2. 字符串的初始化 ● char a[] = “123”;   ...

  6. MongoDB中聚合工具Aggregate等的介绍与使用

    Aggregate是MongoDB提供的众多工具中的比较重要的一个,类似于SQL语句中的GROUP BY.聚合工具可以让开发人员直接使用MongoDB原生的命令操作数据库中的数据,并且按照要求进行聚合 ...

  7. TCP/IP协议栈 -----链路层

    这节说一下链路层和ARP RARP协议 链路层: 在协议栈中链路层的目的有三个:1. 为IP模块发送或接受数据包 2.为ARP模块发送或接受ARP请求 3. 为RARP模块发送或接受RARP请求. 让 ...

  8. Delphi 7中对StretchBlt, StretchDIBits, DrawDibDraw, BitBlt 的性能测试 - 原创

    我的天哪,上一篇博文是2年前的事情了.看来又虚度了2年光阴,继续学习... 本文算是副产品,正品是利用FFmpeg从任意视频中生成GIF片段的小程序,等写完了再发.不为别的,只是为了给儿子做动图,且看 ...

  9. 垃圾陷阱洛谷dp

    题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺. 卡门想把垃圾堆起来,等到 ...

  10. RBAC(Role-Based Access Control,基于角色的权限访问控制)—权限管理设计

    RBAC模型的核心是在用户和权限之间引入了角色的概念,将用户和权限进行解耦,采用用户确定角色,角色分配权限,进而间接达到给用户分配角色的目的 这样采用的方式优点在于 (1)降低管理成本--由于一个角色 ...