背景介绍
什么是负载均衡(loadbalance)
负载均衡是建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。负载均衡会将请求分摊到多个操作单元上进行执行。
本文介绍的应用是利用了Apache HTTP服务器作为代理服务器,将web请求转发,请求被转发给Tomcat服务器来处理,在这里我们利用Apache HTTP作为负载均衡服务器。
那么问题来了,作为java 开发者可能有的同学并没有使用过Apache HTTP服务器,什么是Apache HTTP服务器不在本文中讨论,有兴趣的同学可以自行查找相关资料或访问其官方网站:http://httpd.apache.org/
知识扩展:
Apache HTTP负载均衡属于软件负载均衡解决方案,相对的还有硬件负载均衡方案有兴趣的同学可以帮忙拓展下如何利用硬件实现负载均衡咯。
类似的负载均衡软件还有哪些?
Nginx?
IIS?
WebSphere?
国产东方红?(这东西用和Apache HTTP一样,没什么新鲜的,国人的拿来主义…)
什么是集群(clusters)
集群是一组相互独立的、通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理。一个客户与集群相互作用时,集群像是一个独立的服务器。集群配置是用于提高可用性和可缩放性。
这里的集群是指将多台(这里的多台必须大于等二,一台Tomcat服务器不是集群)Tomcat服务器组成一个独立的服务器群组,多台Tomcat服务器会互相通信,当我们访问Web服务的时候多台Tomcat服务器共同服务,理论上当我们需要扩展的时候可以添加或者减少任意台Tomcat服务器从而提高其可缩放性,而当某台服务器出现问题的时候其他正常的Tomcat可以立刻代替问题服务器使web服务可以不间断持续的服务从而提高其可用性。
特点
在现有网络结构之上,负载均衡提供了一种廉价有效的方法扩展服务器带宽和增加吞吐量,加强网络数据处理能力,提高网络的灵活性和可用性。集群系统 (Cluster)主要解决下面几个问题:高可靠性(HA):利用集群管理软件,当主服务器故障时,备份服务器能够自动接管主服务器的工作,并及时切换过去,以实现对用户的不间断服务。高性能计算(HP):即充分利用集群中的每一台计算机的资源,实现复杂运算的并行处理,负载平衡(load balance):即把负载压力根据某种算法合理分配到集群中的每一台计算机上,以减轻主服务器的压力,降低对主服务器的硬件和软件要求。
负载均衡集群适用的WEB应用(重点必读了解)
既然我们需要负载均衡集群就不得不说到WEB应用,传统的J2EE Web应用并不是简单直接部署到集群的Tomcat服务器上就可以完成应用的集群部署。不少传统的J2EE Web项目需要做到一些改造才能够支持集群,那么需要对项目改造的地方包括哪些呢?
1、 文件的上传和下载,文件被存放在当前Web工程目录下,如文件被存放在{WebRoot}这个目录下。
2、 使用的应用内部的缓存。如ehcache缓存,(独立的缓存服务Memcached,Redis等不受影响)。
3、 任务调度,如使用java定时器的使用(Timer),使用Quartz调度器的RAMJobStore。
4、 使用{WebRoot}目录下的文件数据,例如将一些运行时需要使用到的临时变量存放在文件中。
5、 在同一Tomcat下部署的多个Web应用,多个Web应用存互相调用服务引用服务的情况。
6、 省略。。。(未完待续,有熟悉的同学请帮忙补齐)
组建负载均衡集群
软件环境准备
1、 Apache HTTP 2.4下载地址: http://httpd.apache.org/download.cgi#apache24(注意这个地址下载的是源码,官方网站已经不在提供Windows环境编译好的软件,因此我们需要去第三方网站下载针对Windows环境编译好的软件,有兴趣的同学可以自己下载源码针对Linux 或者 Windows或者 Mac OS等操作系统环境编译)。
Windows系统第三方下载地址http://www.apachehaus.com/cgi-bin/download.plx下载文件httpd-2.4.18-x64-r2.zip。
2、 Tomcat7下载地址:http://tomcat.apache.org/download-70.cgi(目前tomcat7 最新的版本号是7.0.67尽量不要去下载tomcat6,8,9 因为太新和太旧在配置和稳定性不一定能保证,而且在配置方法上也有差异,本文介绍的方法就是Tomcat7的集群配置)我们选择下载64-bitWindows zip 这个版本就好了,不要去下载32位版本,为什么这样做这个后面下载的Tomcat连接器会提到。
3、 Tomcat Connectors连接器下载地址:http://mirror.bit.edu.cn/apache/tomcat/tomcat-connectors/jk/binaries/windows/
下载这个文件tomcat-connectors-1.2.40-windows-x86_64-httpd-2.4.x.zip这是一个Windows64位环境的Apache http与tomcat的连接器,64位的连接器也对应需要64位的Tomcat才能与之匹配。同时我们使用的是Apache2.4 64位,如果你使用的是Apache2.2.X 32位也就需要其他对应的连接器与之匹配。
Apache之所以能够和Tomcat通讯就是依靠了Tomcat连接器。而这个东西通讯协议就是AJP/1.3 ,这也是为什么我们每次启动Tomcat的时候除了我们常见的http通讯端口8080,但还有一个端口AJP 8009。其实多启动的这个8009端口就是为了与Apache通讯使用的,如果我们用不到Apache服务器那我们完全可以把Tomcat加载启动AJP服务关闭掉,减少内存占用提高效率。
配置Apache HTTP2.4
1、 解压刚才下载好的 httpd-2.4.18-x64-r2.zip文件。
2、 解压刚才下载好的 tomcat-connectors-1.2.40-windows-x86_64-httpd-2.4.x.zip将文件mod_jk.so拷贝到 {解压目录}\Apache24\conf\extra目录下。
3、 修改Apache配置文件 {解压目录}\Apache24\conf\http.conf。
第38行 Define SRVROOT "/Apache24" 将/Apache24 修改为当前文件绝对路径, 如: C:\Users\Woo\Desktop\apache-tomcat\Apache24 这是因为Apache HTTP期待的时候需要知道自己的运行目录在哪里.
第60行 Listen 80 这是Apache服务器Http的端口,如果原有的80端口被暂用了,那么Apache将无法启动。而如果你的机器上有多张网卡,可以指定网卡IP+端口来访问Apache HTTP。如 Listen 192.168.1.1:80
第170行 LoadModule ssl_module modules/mod_ssl.so 在这一句最前面加上# ,将这一行注释掉,这是因为apache HTTP在默认启动的时候会随带加载ssl(安全套阶层),安全Https协议需要使用到的,由于我们没有生成对应的证书文件,而且现在也暂时用不到它因此需要注解掉,否则你启动的时候Apache会因为找不到证书文件而启动失败。
在本文件最后加上下面一句话 Include conf/extra/mod_jk.conf 这句话代表引入配置文件mod_jk.conf,功能和 jsp的 include是一样的。需要注意的是该文件的存放位置在 {解压目录}\Apache24\conf\extra下面,如果你不想放在这个路径下面也没关系,只要修改下前面的相对路径就可以了。 |
4、 在{解压目录}\Apache24\conf\extra新建文件mod_jk.conf
#引入模块mod_jk.so LoadModule jk_module modules/mod_jk.so #配置 mod_jk conf #加载集群中的workers JkWorkersFile conf/workers.properties #加载workers的请求处理分配文件 JkMountFile conf/uriworkermap.properties #指定jk的日志输出文件 JkLogFile logs/mod_jk.log #指定日志级别 JkLogLevel info |
5、 在{解压目录}\Apache24\conf新建文件 workers.properties
# worker列表 worker.list=LB_worker,jkstatus
#第一个worker的配置,名为worker_A #tomcat的主机地址,如不为本机,请填写ip地址 worker.worker_A.host=localhost #ajp13 端口号,对应tomcat配置文件server.xml中Connector port="8009",默认8009 worker.worker_A.port=8009 worker.worker_A.type=ajp13 #负载的权重值,越高表示负载越大 worker.worker_A.lbfactor=1
#第二个worker的配置,名为worker_B worker.worker_B.host=localhost #ajp13 端口号,对应tomcat配置文件server.xml中Connector port="9009" worker.worker_B.port=9009 worker.worker_B.type=ajp13 worker.worker_B.lbfactor=1
#其他worker的配置,如果还有其他的Work重复以上的配置 #其他worker配置省略…..
#LB_worker,用于负载均衡分发的控制器 worker.LB_worker.type=lb #重试次数 worker.LB_worker.retries=3 #指定负载的worker列表,用逗号分隔 worker.LB_worker.balance_workers=worker_A,worker_B #配置session会话是否为粘性 #这样负载均衡器lb就会尽量保持一个session,也就是使用户在一次会话中跟同一个Tomcat进行交互 worker.LB_worker.sticky_session=false #如果sticky_session设为true时,此处一般设为false worker.LB_worker.sticky_session_force=false #设置运行状态的控制器 worker.jkstatus.type=status
|
6、 在{解压目录}\Apache24\conf新建文件 uriworkermap.properties
#所有请求都由LB_worker这个worker处理 /*=LB_worker #所有包含jkstatus请求的都由名称叫jkstatus的这个worker处理 /jkstatus=jkstatus |
配置Tomcat7服务器
1、 解压刚才下载好的 apache-tomcat-7.0.67-windows-x64.zip文件。我们需要分别解压2份,并分别将2份Tomcat重名为apache-tomcat-7.0.67_A与apache-tomcat-7.0.67_B,如果你需要更多的Tomcat服务器集群,可以解压或拷贝出多份Tomcat文件并重名文件夹。只要能保证文件夹名称唯一即可。
2、 如果你是水平集群,即在Tomcat分别是放在不同的电脑上的,可以不必修改Tomcat配置文件。
但是大家注意到了没有刚才我们在配置Apache HTTP 2.4 第5步骤的时候
worker.worker_A.host=localhost
worker.worker_B.host=localhost
我这里是在同一台电脑上安装两个tomcat,实现的是垂直集群方式,所以必须修改其中一个Tomcat的设置,在这里我们只修改apache-tomcat-7.0.67_B这份文件拷贝以避免TomcatB启动的时候端口冲突,修改的原则就是把原来以8开头的端口号改为以9开头端口号。这样修改简单又粗暴还能避免因为在一台机器上启动多个Tomcat而造成的端口重复问题。
apache-tomcat-7.0.67_B需要修改的配置文件如示
打开文件{Tomcat解压目录}\ conf\server.xml文件
第22行 <Server port="8005" shutdown="SHUTDOWN"> 将8005端口号修改为9005,这里解释下这个端口的用处,他是Tomcat监听shutdown命令端口.终止服务器运行时,必须在Tomcat服务器所在的机器上发出,如果没有了这个端口你将无法关闭Tomcat,好了那么问题来了。(见扩展知识点1)
第71-73行 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 修改为 <Connector port="9080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="9443" />
第93行 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 修改为 <Connector port="9009" protocol="AJP/1.3" redirectPort="9443" />
第105行 (特别注意这一段配置 Tomcat_A和Tomcat_B都需要操作) <Engine name="Catalina" defaultHost="localhost">
Tomcat_A修改为 <Engine name="Catalina" defaultHost="localhost" jvmRoute="worker_A"> Tomcat_B修改为 <Engine name="Catalina" defaultHost="localhost" jvmRoute="worker_B"> 这里填写的worker_A与 worker_B与配置Apache HTTP 第5步骤workers.properties里的worker_A与 worker_B对应一致。
第110-112行 (特别注意这一段配置 Tomcat_A和Tomcat_B都需要打开) <!— <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> 这一行的在源Tomcat文件中是注释掉的,现在因为需要集群需要将它重新打开 修改为如下 <!—--> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> |
到此为止我们的配置全部完毕。
部署TestCluster测试工程到Tomcat
由于我们配置的负载均衡集群需要测试是否配置成功,因此我们需要创建一个集群测试Web应用来验证的我们配置的环境。注意该WEB工程需要在Tomcat_A与Tomcat_B都要部署一模一样的工程
TestCluster工程如下:
新建文件在{Tomcat解压目录}\webapps\test\index.jsp
<%@ page contentType="text/html; charset=UTF-8" %> <%@ page import="java.util.*" %> <html><head><title>Cluster Test</title></head> <body> <% System.out.println(session.getCreationTime()); out.println("<br> SESSION ID:" + session.getId()+"<br>"); out.println("Session created time is :"+session.getCreationTime()+"<br>"); %> </body> </html> |
新建文件在{Tomcat解压目录}\webapps\test\WEB-INF\web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>test</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!—可以使用distributable元素来告诉servlet/JSP容器,编写的应用将在分布式Web容器中部署--> <distributable/> </web-app> |
启动Apache HTTP、Tomcat_A、Tomcat_B
1、 启动Apache HTTP。双击启动Apache24\bin\httpd.exe
2、 启动Tomcat_A。双击启动apache-tomcat-7.0.67_A\bin\startup.bat
3、 启动Tomcat_B。双击启动apache-tomcat-7.0.67_B\bin\startup.bat
正常启动后可以看到三个窗口分别是Tomcat_A与TomcatB 与Apache HTTP
测试负载均衡集群
打开浏览器访问http://localhost/test/index.jsp不断刷新可以看到
SESSION ID:990964A9238CC437099A163AA6321B00.worker_B Session created time is :1455433301447 |
或者
SESSION ID:990964A9238CC437099A163AA6321B00.worker_A Session created time is :1455433301447 |
worker_A 与 worker_B 不断交替变化,即负载均衡部署成功.