AJP
协议是面向包的协议,采用二进制形式代替文本形式,以提高性能。
Web Server
一般维持和
Web Container
的多个
TCP Connecions
,即
TCP
连接池,多个
request/respons
循环重用同一个
Connection
。但是当
Connection
被分配(
Assigned
)到某个请求时,该请求完成之前,其他请求不得使用该连接。
Tcp Connection
具有两种状态:
(1). Idle
没有请求正使用该连接。
(2). Assigned
当前连接正在处理某个请求
.
数据类型
:
AJP
协议中包括四种数据类型:
Byte,
Boolean
,
Integer
and String
.
Byte:
一个字节
Boolean
:
一个字节,
1 = true, 0 =
false
。
Integer
:两个字节,无符号整数,高位字节在前。
String:
可变字符串,最大长度为
2^16.
字符串的前而会有二个字节(
Integer
型)表示字符串的长度,
-1
表示
null
。字符串后面会跟上
终结符
”\0”
,而且字符串长度不包括这个终结符。
AJP
的包结构
,
图表
1
:
包方向
|
0
|
1
|
2
|
3
|
4…(n+3)
|
Server->Container
|
0x12
|
0x34
|
数据长度
(n)
|
数据
(payload)
|
Container->Server
|
A
|
B
|
数据长度
(n)
|
数据
(payload)
|
图表
1
可以看出,从
apache
发向
tomcat
包都带有
0x1234
头,而从
tomcat
发向
apache
的包都带有
AB(ascii
码
)
头,随后二字节代表数据的长度(不包括前四个字节)
.
所认
AJP
包的最大长度可以接近
2^16
,但目前的版本支持的最大包长度为
2^13
,即
8K
。
再看数据部分
(payload),
除
Server->Container
的请求体包外,其他包的数据部分的首字节为其消息类型
(code)
,如下表(描述部分是原文,译成中文本人认为更难理解,英文表义比中文是好一些)
:
方向
|
code
|
包类型
|
描述
|
Server->Container
|
2
|
Forward Request
|
Begin the request-processing cycle with
the following data
。
|
7
|
Shutdown
|
The web server asks the container to shut
itself down
|
8
|
Ping
|
The web server asks the container to take
control (secure login phase).
|
10
|
Cping
|
The web server asks the container to
respond quickly with a CPong
|
none
|
Data
|
Size (2 bytes) and corresponding body
data.
|
Container->Server
|
3
|
Send Body
Chunk
|
Send a
chunk of the body from the servlet container to the web server
|
4
|
Send
Headers
|
Send the
response headers from the servlet container to the web server
|
5
|
End
Response
|
Marks the
end of the response
|
6
|
Get Body
Chunk
|
Get
further data from the request if it hasn't all been transferred yet
|
9
|
CPong
Reply
|
The reply
to a CPing request
|
Forward
Request
包数据部分(
payload
)结构:
AJP13_FORWARD_REQUEST :=
prefix_code
(byte) 0x02 = JK_AJP13_FORWARD_REQUEST
method
(byte)
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
|
---------------------------------------------------------------------------------------------------------------------------------
req_header_name :=
sc_req_header_name | (string)
[see below for how this is parsed]
|
---------------------------------------------------------------------------------------------------------------------------------
sc_req_header_name := 0xA0xx (integer)
req_header_value := (string)
|
---------------------------------------------------------------------------------------------------------------------------------
attribute_name := sc_a_name | (sc_a_req_attribute string)
attribute_value := (string)
|
(1)
prefix_code
所有的
Forward
Request
包都是
0x02.
(2)
Method:
一个字节,对方法的编码,其对应如下(只列了部分):
Command Name
|
code
|
POST
|
4
|
OPTIONS
|
1
|
PUT
|
5
|
GET
|
2
|
DELETE
|
6
|
HEAD
|
3
|
TRACE
|
7
|
(
参考:
http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html)
(3)
protocol, req_uri, remote_addr,
remote_host, server_name, server_port, is_ssl
:
每个请求包都有这几个字段,格式都是
长度+字符串值
+\0
结束符。
(4)
num_headers:
请求头的个数,两个字节。
(5)
request_headers:
请求头名称分化为两类,
一类请求头被转换为
0xA0xx
格式(如下表所示),其他请求头仍然用原字符串编码。
请求头
|
Code
值
|
Code
名称
|
accept
|
0xA001
|
SC_REQ_ACCEPT
|
accept-charset
|
0xA002
|
SC_REQ_ACCEPT_CHARSET
|
accept-encoding
|
0xA003
|
SC_REQ_ACCEPT_ENCODING
|
accept-language
|
0xA004
|
SC_REQ_ACCEPT_LANGUAGE
|
authorization
|
0xA005
|
SC_REQ_AUTHORIZATION
|
connection
|
0xA006
|
SC_REQ_CONNECTION
|
content-type
|
0xA007
|
SC_REQ_CONTENT_TYPE
|
content-length
|
0xA008
|
SC_REQ_CONTENT_LENGTH
|
cookie
|
0xA009
|
SC_REQ_COOKIE
|
cookie2
|
0xA00A
|
SC_REQ_COOKIE2
|
host
|
0xA00B
|
SC_REQ_HOST 0xA00C
|
pragma
|
0xA00C
|
SC_REQ_PRAGMA
|
referer
|
0xA00D
|
SC_REQ_REFERER
|
user-agent
|
0xA00E
|
SC_REQ_USER_AGENT
|
(6)
Java
代码读取头两个字节的整数型,如果高位字节为
”0xA0”
,则第二字节为上在列表的索引。如果高位字节不是
”0xA0”
,则这两个字节为随后请求头名称的长度。
(7)
Attributes
:很少用,直接看
tomcat
文档吧。
(8)
request_terminator:
一个字节
0xFF,
请求结束符。
响应包数据部分
(payload)
结构
:
AJP13_SEND_HEADERS :=
prefix_code
4
http_status_code
(integer)
http_status_msg
(string)
num_headers
(integer)
response_headers
*(res_header_name header_value)
res_header_name :=
sc_res_header_name |
(string)
[see below for how this is
parsed]
sc_res_header_name := 0xA0 (byte)
header_value := (string)
AJP13_SEND_BODY_CHUNK :=
prefix_code
3
chunk_length
(integer)
chunk
*(byte)
AJP13_END_RESPONSE :=
prefix_code
5
reuse
(boolean)
AJP13_GET_BODY_CHUNK :=
prefix_code
6
requested_length
(integer)
|
1.
response_headers:
和请求头一样,一类响应头被转换为
0xA0xx
格式(如下表所示),其他响应头名称采用原字符串编码。
请求头
|
Code
值
|
Code
名称
|
Content-Type
|
0xA001
|
SC_RESP_CONTENT_TYPE
|
Content-Language
|
0xA002
|
SC_RESP_CONTENT_LANGUAGE
|
Content-Length
|
0xA003
|
SC_RESP_CONTENT_LENGTH
|
Date
|
0xA004
|
SC_RESP_DATE
|
Last-Modified
|
0xA005
|
SC_RESP_LAST_MODIFIED
|
Location
|
0xA006
|
SC_RESP_LOCATION
|
Set-Cookie
|
0xA007
|
SC_RESP_SET_COOKIE
|
Set-Cookie2
|
0xA008
|
SC_RESP_SET_COOKIE2
|
Servlet-Engine
|
0xA009
|
SC_RESP_SERVLET_ENGINE
|
Status
|
0xA00A
|
SC_RESP_STATUS
|
WWW-Authenticate
|
0xA00B
|
SC_RESP_WWW_AUTHENTICATE
|
2.
reuse:
如果为
1,
表示该连接可以被子重用,否则这个连接应该关闭。
下面我们来看一个简单
AJP
请求过程中抓到的请求包:
http://localhost/test/testCluster.jsp
请求:
1
,
2
字节是上文所说的
Server->Container
包头,
3
,
4
字节表示包长度
(0x01b0=432),
即从第
5
个字节到最后的一个字节(
ff
)的长度。第
5
个字节(
02
)代表是
”Forward
Request”
包。
第
6
个字节
(02)
代表是
Get
请求。第
7
,
8
字节
(0x0008)
代表
protocol
字符串的长度,后
8
个字节为
protocol
字符串
(HTTP/1.1),
第
9
个字节为
protocol
字符串的终结符“
\0
”。
18-41
字节
代表
req_uri
字符串
(0x15+2+1=24
个
)
。
42-53
字节代表
remote_addr
字符串
(0x09+2+1=12
个
)
54-55
两字节
(0xffff=-1)
代表
null
字符串
,
即
remote_host
不存在。
56-67
两字节
代表
server_name
字符串
(0x09+2+1=12
个
)
68-69
两字节
(0x0050=80)
代表
server_port
70
字节
(0x00)
代表
is_ssl
为
false
71-72
两字节
(0x0009)
代表该请求有
9
个请求头
,
如图中的前
9
个红色
椭圆
.
第
10
个红色椭圆
(0x06)
代表
Attributes
的
route.
第
11
个红椭圆之后,代表
AJP_REMOTE_PORT
与
JK_LB_ACTIVATION
两个请求属性
.
最后一个字节
0xFF
表示请求结束。
响应头数据包:
和请示头比较类似,不再细描述。其中第
5
个字节
0x04
代表
”Send Headers”
响应。
并且没有终结符字节
0xFF.
响应正文数据包
:
响应结束
End Response:
其中最后一个字节
(01)
,代表当前连接仍然可用。
(完)

- 大小: 122.2 KB

- 大小: 39.3 KB

- 大小: 165 KB

- 大小: 6.1 KB
分享到:
相关推荐
总结,"tomcat-connectors-1.2.26-src.tar.gz"不仅是一个开源的软件包,更是学习和研究AJP协议、Apache Web服务器与Tomcat集成的关键资源。通过阅读和理解源码,开发者能够更好地掌握Web服务器与应用服务器间的交互...
2. modules/proxy_ajp/*.c:AJP协议的实现代码。 3. conf/*:包含配置文件模板,如workers.properties,定义了Apache与Tomcat之间的worker(即连接器)关系。 4. Makefile.am:Automake的配置文件,用于构建过程。 ...
Coyote则是处理网络连接的部分,如HTTP和AJP协议;Jasper则是JSP编译器,负责将JSP转换为Servlet。 在源码分析部分,作者孙卫琴带领读者深入Tomcat的源代码,解析关键类和方法,这对于开发者提升对Tomcat工作原理的...
在深入分析Tomcat的架构之前,需要了解Tomcat是Apache Jakarta项目中的一个核心项目,是一个免费的开源Servlet容器。它主要用于作为独立服务器或集成到Web服务器中,如Apache和IIS等。作为Web服务器,Tomcat负责解析...
5. **使用AJP协议**:在负载均衡场景下,使用AJP协议代替HTTP协议可以减少网络传输开销。 ### 五、总结 《深入剖析 Tomcat》这一资料为读者提供了深入理解Tomcat架构、内部机制及优化方法的机会。通过对Tomcat的...
Tomcat启动分析与配置详解 Tomcat是一款广泛使用的开源Java Servlet容器,它实现了Java EE的Web应用程序规范。理解Tomcat的启动过程和配置对于优化服务器性能和管理Web应用至关重要。本文将深入解析Tomcat的组成...
#### 知识点一:背景介绍与需求分析 在企业级应用开发环境中,经常需要将不同类型的Web服务进行整合,以便在一个统一的平台上提供服务。本文档旨在说明如何在Windows 2003服务器上整合IIS6和Tomcat6,使其共同使用...
### 三大Web服务器对比分析:Apache、Lighttpd与Nginx #### 一、概述 随着互联网技术的发展,Web服务器成为了构建网站不可或缺的核心组件之一。本文将对三种流行的Web服务器——Apache、Lighttpd与Nginx进行深入...
总结起来,Tomcat Connectors是Tomcat的核心组件,负责网络通信和协议处理。"tomcat-connectors-1.2.27-src.tar.gz"提供了一个深入了解其工作原理和优化策略的机会,对于Java Web开发者来说,研究这个源代码能够极大...
总结来说,Tomcat 8.5源码分析不仅有助于提升开发者的技能,还能帮助优化应用性能,解决复杂问题。通过深入学习,我们可以更好地理解和利用这个强大的Java Web服务器,从而构建更高效、安全的Web应用。
例如,HTTP/1.1 Connector负责处理HTTP请求,而AJP Connector则用于与Apache HTTP服务器进行通信。 1. Container组件 Container是处理请求和生成响应的主体,它包含了Servlet容器的概念。Container有多个层次,包括...
- 可以与Apache HTTP Server通过AJP协议集成,提高静态内容的处理速度。 - 与数据库如MySQL、Oracle等集成,实现动态数据处理。 总结,Apache Tomcat 8.0.21 for Linux提供了一个强大而灵活的平台来部署和管理...
部署时,应禁用ajp协议,因为在8.5.51之前的版本默认开启,但后续版本已默认禁用。此外,合理配置线程池可以有效控制资源使用,提高并发处理能力。Tomcat支持三种运行模式:bio、nio、apr,根据应用场景选择最适合的...
Connector将请求解析成内部表示,并传递给Coyote处理器,这是一个抽象层,它与具体的协议(如HTTP/1.1或AJP)解耦。处理器将请求数据包装成Request对象,然后交给相应的Executor执行。Executor管理一组线程,这些...
- 上述配置将两个Tomcat实例分别命名为`worker1`和`worker2`,并通过AJP协议与Apache通信。 ##### 3. **数据库连接池优化** - 为了进一步提高系统的响应速度,需要对数据库连接池进行优化。考虑到DBCP在某些情况...
这个库主要负责处理连接器(Connector)部分,连接器是Tomcat与外部世界交互的桥梁,包括HTTP、AJP等协议的处理。1.2.15版本是一个稳定版,修复了之前的许多问题,增强了兼容性和安全性。 源码包jakarta-tomcat-...
1. **禁用AJP连接器**:如果不需要使用AJP协议,则可以在`server.xml`中注释掉相关的Connector配置。 2. **优化线程池设置**:通过调整`maxThreads`、`minSpareThreads`等参数来优化线程池性能。 3. **启用压缩**:...
##### 2.2 启动与初始化流程 当启动Tomcat时,首先会加载配置文件,然后初始化各个组件。具体步骤如下: 1. **读取配置文件**:读取`conf/server.xml`等配置文件,解析配置信息。 2. **创建Server**:根据配置文件...
本文将详细介绍Tomcat与JDK版本之间的对应关系,并深入分析各版本的主要特性和关键改进。 #### 二、Tomcat与JDK版本对应关系 在选择Tomcat版本时,确保其与JDK版本兼容至关重要。以下是不同版本的Tomcat与推荐的...