大部分一开始接触WEB服务器的人可能和我一样对为什么有Apache又有Tomcat服务器感到奇怪(它们还都是Apache开发的呵呵),其实他们不是冗余的服务器,虽然他们都能对外提供WEB服务器,但总的来说还是各有侧重点。下面做个简单介绍。

1.       Apache是世界排名第一的Web服务器;在Apache基金会里其永远被第一支持。而开源的Apache Tomcat也非常关注,由于开源,用户最支持。

2.       Apache支持静态页面,Tomcat支持动态页面(servlet, JSP);一般在使用Apache + Tomcat的配置下,Apache都是实现对JSP的转发,交给Tomcat来处理。Apache可以支持PHP,但如果要支持JAVA,就需要Tomcat来处理。

3.       Apache是Web服务器,Tomcat是应用(Java)服务器,它只是一个servlet容器,是Apache的扩展,但可以独立于Apache运行;如果以独立方式运行,功能与Apache等效,但对静态页面的处理不太理想。

通过上面分析,可以知道:

1.       Apache能有很好的静态页面处理能力,如果搭配Tomcat能同时支持静态和动态页面

2.       Tomcat能够承担性能要求较低的WEB应用。

负载均衡

为了提高整个系统的可用性和性能,常常会用到负载均衡,而Apache和Tomcat经常联合在一起来实现负载均衡技术。

主机Apache作为前段负载平衡服务器对用户进行分配,后端不同的Tomcat服务器最终处理请求,其中根据侧重点不同可以有两种不同的配置。

1.       增加系统可用性

保证多台Tomcat服务器之间会话的同步,确保任何一台当机都不会影响系统的运行,从而提高系统的可用性。

2.       提高系统性能

在负责负载平衡的Apache主机上记录每个请求的Session ID(这个ID是由Tomcat分配的)及回应Session的Tomcat Server对应关系,在下一个请求到来时先判断每个Session ID,如果有标识连接已经建立,那么转到对应服务器;负责就是新的连接,根据每个后台Tomcat服务器的状态分配一个服务器并记录Session ID.

如下图:

Apache + Tomcat配置

正如上面中看到的可以通过Apache +Tomcat来配置来达到较高WEB服务器同时,也能高正较高的可用性和系统性能。这些是通过Apache与Tomcat之间的通讯来完成的。Apache和Tomcat之间的通讯基本有三种方式:

1.       Mod_Jk

2.       HTTP_Proxy

3.       AJP_Proxy

这里主要介绍Mod_JK方式,其也是最流行的方式,并且官方的文档也非常全。

Mod_JK

Mod_JK是Apache的一个模块,其通过AJP协议实现Apache与Tomcat之间的通讯,而Tomcat默认监听AJP连接器的8009端口来接受AJP的连接请求;一般这些请求来自前端的Apache服务器。

由于Mod_JK已经被设计成Apache的一个模块,因此可以通过一些相对简单的配置就能达到Apache和Tomcat之间通讯的目的;同样包含负载均衡。

配置步骤安装

1.       安装Apache HTTP服务器,从Apache官方网站下载;我安装的是Apache2.0.64

2.       安装Apache Tomcat,可以安装在Apache同一个机器,也可以在其他的机器,版本要与Mod_JK匹配

3.       下载Mod_Jk;这里注意要与Apache Tomcat匹配。

配置加在Mod_Jk

Mod_Jk是在Apache HTTP服务器上被加载的,需要将下载下来的Mod_Jk.so放到Apache/Modules目录下,并修改httpd.conf,增加下面一行:

Include conf/mod_jk.conf

使用include命令包含mod_jk.conf,这个是我们自己添加的关于mod_jk的配置文件。

新建Mod_jk.conf,并添加如下内容:

#Load mod_jk module.

LoadModule jk_module modules/mod_jk.so

#Where to find workers.properties

JkWorkersFile conf/workers2.properties

JkMountFile conf/urimap.properties

#Where to put jk logs

JkLogFile logs/mod_jk.log

#Set the jk log level[debug/error/info]

JkLogLevel info

#Select the log format

JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"

#JkRequestLogFormat set the request format

JkRequestLogFormat "%w %V %T"

JkMount /* loadbalancer

上面包含了两个properties文件,分别是workers2.properties和urimap.properties。

Workers2.properties用于说明Tomcat服务器的负载均衡配置方法,具体如下:#worker.list=loadbalancer

worker.list=loadbalancer,tomcat1,tomcat2  #server 列表

 

#define the first node

worker.tomcat1.port=8009

worker.tomcat1.host=10.224.70.57

worker.tomcat1.type=ajp13

worker.tomcat1.lbfactor=1

 

#define the first node

worker.tomcat2.port=8009

worker.tomcat2.host=10.224.70.57

worker.tomcat2.type=ajp13

worker.tomcat2.lbfactor=1

 

#Now we define the load-balancing behavior

worker.loadbalancer.type=lb

worker.loadbalancer.balance_workers=tomcat1, tomcat2

 

worker.loadbalancer.sticky_session=true

 

worker.loadbalancer.sticky_session_force=true

在Mod_jk.conf中有JkMount /* loadbalancer,这个loadbalancer正好对应上面worker.list一行的loadbalancer。

另外tomcat1和tomcat2是配置的后台tomcat服务器;当然这里只有一台服务器,所以两个worker都是同样的地址。lbfactor表示在负载均衡算法中采用的权重。

另外在urimap.properties文件中说明了哪些请求会转交给Tomcat服务器,配置项为:

!/*.htm=loadbalancer

注意这里的表示*.htm的请求都到loadbalancer;这个loadbalancer是上文中的loadbalancer。

至此Apache和Tomcat之间的负载均衡已经被配置好了。

运行时观察

这里主要观察session的stickiness是如何被实现的;已经Apache服务器如何了解到关于Session ID相关的信息。

实际上对于负载均衡来说,如果上面的例子中你配置了两个Tomcat,那么关闭sticky_session的情况下,每个Tomcat服务器将轮流收到请求。

其实在试验的时候发现session ID是Tomcat服务器分配创建的,Apache服务器只是用来管理其与Tomcat服务器之间的关系;当然Apache服务器需要检查每次请求中的Session ID。这个ID是由Tomcat分配的;Tomcat对于每个第一次请求的动态页面都会生成JSESSIONID;而对于静态页面是不会生成JESSIONID的。

具体运行过程:

1.       Apache服务器接收到来自client的请求,检查HTTP请求是否包含SESSIONID

2.       如果不包含,采用负载均衡算法选择一个Tomcat服务器

3.       Apache服务器将这个client请求转发到选定Tomcat服务器的8009端口,数据包的格式是AJP协议

4.       Tomcat解析AJP协议,生成SESSION ID并且取得响应,将结果发送给Apache服务器,这个是通过之前的8009连接过来的链接发送回去的。

5.       Apache服务器解析AJP包,并得到SESSION ID信息,并将其与对应的服务器(和会话)关联起来。

6.       Apache将SESSION ID转发给client

7.       Client将Session ID保存到Cookie中用于下次使用。

Packet No

Apache

Tomcat:8009

1

2:REQ:GET /index.jsp HTTP/1.1 à

2

ß2:RSP:send headers:200 OK

3

ß2:RSP:SEND BODY CHUNK

4

ß2:RSP:END RESPONSE

通常这个连接建立好了之后短时间是不会断,不过这是可以通过参数来配置的。

在上面的包交互过程中:第2个包包含了SESSION ID的信息;内容类似于下面:

Set-Cookie..3JSESSIONID=955AAE2AA22B074BD1824395B6E4835A; Path=/...Content-Type...text/html...Content-Length...141.AB.....

AJP(Apache JServer Protocol)

AJPv13协议是面向包的。WEB服务器和Servlet容器通过TCP连接来交互;为了节省SOCKET创建的昂贵代价,WEB服务器会尝试维护一个永久TCP连接到servlet容器,并且在多个请求和响应周期过程会重用连接。

一旦一个连接被分配给特定的请求,在请求处理周期结束之前这个连接不能被重用;换句话说,请求不是连接多工的。这样编码比较简单。

一旦连接被分配给特定的请求,基本请求信息(HTTP头)以压缩的个性(通常字符串会编码为整数);如果有请求实体,会随后立即发送。

这个时候,servlet容器已经准备好了处理请求并发送西面的信息回WEB服务器:

1.       SEND_HEADERS:发回浏览器的响应头

2.       SEND_BODY_CHUNK:将实体发送给浏览器

3.       GET_BODY_CHUNK:获取更多的请求数据,这些数据没有被发送。

4.       END_RESPONSE:表示请求处理周期结束。

WEB服务器发送给Servlet容器的请求包括:

1.       转发请求开始

2.       关闭

3.       Ping

4.       CPing

AJP13_FORWARD_REQUEST的格式

AJP13_FORWARD_REQUEST :=

Magic:            (word)

Length:           (word)

prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST

method           (byte)       HTTP请求方法的字节编码

protocol         (string)

req_uri          (string)

remote_addr      (string)

remote_host      (string)

server_name      (string)

server_port      (integer)

is_ssl           (boolean)

num_headers      (integer)

request_headers *(req_header_name req_header_value)

attributes      *(attribut_name attribute_value)

request_terminator (byte) OxFF

AJP13_SEND_HEADERSAJP13_SEND_HEADERS :=  prefix_code       4  http_status_code  (integer)  http_status_msg   (string)  num_headers       (integer)  response_headers
*(res_header_name header_value)

更多信息,参见:http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html#header_encoding

Apache Tomcat AJP 实现负载均衡的更多相关文章

  1. Apache+Tomcat+mod_jk实现负载均衡

    最近公司提出了负载均衡的新需求,以减轻网站的高峰期的服务器负担.趁空闲时间我就准备了一下这方面的知识,都说有备无患嘛.网上相关资料很多,但是太散.我希望可以通过这篇随笔,系统的总结. 一.Tomcat ...

  2. Apache + Tomcat集群 + 负载均衡

    Part I: 取经处: http://www.ramkitech.com/2012/10/tomcat-clustering-series-simple-load.html  http://blog ...

  3. ngnix apache tomcat集群负载均衡配置

    http://w.gdu.me/wiki/Java/tomcat_cluster.html 参考: Tomcat与Apache或Nginx的集群负载均衡设置: http://huangrs.blog. ...

  4. Linux中Apache+Tomcat+JK实现负载均衡和群集的完整过程

    人原创,一个字一个字地码的,尊重版权,转载请注明出处! http://blog.csdn.net/chaijunkun/article/details/6987443 最近在开发的项目需要承受很高的并 ...

  5. 搭建nginx+tomcat+Java的负载均衡环境

    转载  未测 供参考 另外这篇文章也不错.http://blog.csdn.net/wang379275614/article/details/47778201 一.简介: Tomcat在高并发环境下 ...

  6. 【转】搭建nginx+tomcat+Java的负载均衡环境

    一.简介: Tomcat在高并发环境下处理动态请求时性能很低,而在处理静态页面更加脆弱.虽然Tomcat的最新版本支持epoll,但是通过Nginx来处理静态页面要比通过Tomcat处理在性能方面好很 ...

  7. Nginx+Tomcat+Redis实现负载均衡、资源分离、session共享

    Nginx+Tomcat+Redis实现负载均衡.资源分离.session共享 CentOS安装Nginx http://centoscn.com/CentosServer/www/2013/0910 ...

  8. keepalived+nginx+tomcat+redis实现负载均衡和session共享(原创)

    keepalived+nginx+tomcat+redis实现负载均衡和session共享 直接上链接,码了一天,就不再重写了,希望能帮到大家,有问题欢迎留言交流.

  9. 基于mod_proxy+Apache 2.2.16+Tomcat 7的负载均衡与集群配置

    第一章. 背景简介 对于大多数企业应用,都希望能做到7*24小时不间断运行.要保持如此高的可用性并非易事,比较常见的做法是将系统部署到多台机器上,每台机器都对外提供同样的功能,这就是集群.系统变为集群 ...

  10. Ubuntu下基于Nginx实现Tomcat集群负载均衡

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   Nginx是一款HTTP和反向代理服务器,有关它的介绍可以到网上搜一下,很多很多,不再累述.这里,我们记录一下Nginx ...

随机推荐

  1. docker高级篇第二章-分布式存储之实战案例:主从容错切换迁移案例

    在上一篇,学会了3主3从的Redis集群搭建.那么接下来,我们就来学习Redis集群主从容错切换迁移案例 本次案例从模拟两个场景 1:数据读写存储 a:一个新key数据来了,是否会按照预设的进入槽中? ...

  2. DB\redis\zookeeper分布式锁设计

    redis 参考目录: 生产级Redis 高并发分布式锁实战1:高并发分布式锁如何实现 https://www.cnblogs.com/yizhiamumu/p/16556153.html 生产级Re ...

  3. LCD屏幕显示PNG图像

    正点原子LCD屏幕显示PNG图像 本文概要 这段时间在学习正点原子的IMX6ULL开发板,在应用编程中有一个代码练习是需要在LCD屏幕上显示PNG图像,但由于我的屏幕参数和教程中的有些出入,于是经过自 ...

  4. HTML——基础标签

    基础标签    图片.音频.视频标签    src:资源路径 1.绝对路径 2.相对路径 ./ 表示本级目录 (可以省略) ../ 表示上级目录 超链接标签       列表标签    表格标签    ...

  5. Atcoder Beginner Contest 367

    A.Shout Everyday \(\text{Diff }43\) 给你 \(24\) 小时制下的 \(A,B,C\) 三个时刻,问 \(A\) 是否在 \([B,C]\) 范围内 考虑到先将 \ ...

  6. 一些rand()的测试

    rand()生成的伪随机数已经足够我们实用,为了跟好的理解rand()跟seed的关系,做了一些测试! rand()函数种子默认为1,在每一次程序运行中,随机数相同,在一次运行中,可将生成数看做随机 ...

  7. 深入理解 Nuxt.js 中的 app:error:cleared 钩子

    title: 深入理解 Nuxt.js 中的 app:error:cleared 钩子 date: 2024/9/28 updated: 2024/9/28 author: cmdragon exce ...

  8. 左值 <->右值

    左值引用指向左值 右值引用指向右值 int a = 5; int &ref_a = a; // 左值引用指向左值,编译通过 int &ref_a = 5; // 左值引用指向了右值,会 ...

  9. NET Core 基础 - 删除字符串最后一个字符的七大类N种实现方式

    今天想通过和大家分享如何删除字符串最后一个字符的N种实现方法,来回顾一些基础知识点. 01.第一类.字符串方式 这类方法是通过string类型自身方法直接实现. 1.Substring方法 相信大多数 ...

  10. pip下载太慢,换源

    1.安装pqi pip install pqi 2.改变pip源 比如换成清华源: pqi use tuna 3.显示当前源