ajp 定向包协议 二进制代替文本提高性能 简介
AJP协议是定向包(面向包)协议,采用二进制形式代替文本形式,以提高性能。Web Server一般维持和Web Container的多个TCP Connecions,即TCP连接池,多个request/respons循环重用同一个Connection。但是当Connection被分配(Assigned)到某个请求时,该请求完成之前,其他请求不得使用该连接。
Tomcat服务器通过Connector连接器组件与客户程序建立连接,Connector组件负责接收客户的请求,以及把Tomcat服务器的响应结果发送给客户。默认情况下,Tomcat在server.xml中配置了两种连接器:
<!-- Define a non-SSL Coyote HTTP/1.1Connector on port 8080 --><Connector port="8080"maxThreads="150"minSpareThreads="25"maxSpareThreads="75"enableLookups="false"redirectPort="8443"acceptCount="100"debug="0"connectionTimeout="20000"disableUploadTimeout="true" /><!-- Define a Coyote/JK2 AJP 1.3Connector on port 8009 --><Connector port="8009"enableLookups="false"redirectPort="8443" debug="0"protocol="AJP/1.3" />
第一个连接器监听8080端口,负责建立HTTP连接。
一般Tomcat默认的SSL端口号是8443,但是对于SSL标准端口号是443,这样在访问网页的时候,直接使用https而不需要输入端口号就可以访问,如https://ip/
想要修改端口号,需要修改Tomcat的server.xml文件:
1.non-SSL HTTP/1.1 Connector定义的地方,一般如下:
<Connector port="80" maxHttpHeaderSize="8192" maxThreads="500" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" />
将其中的redirectPort端口号改为:443
2.SSL HTTP/1.1 Connector定义的地方,修改端口号为:443,如下:
<Connector port="443" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="conf/tomcat.keystore" keystorePass="123456" />
3.AJP 1.3 Connector定义的地方,修改redirectPort为443,如下:
<Connector port="8009" enableLookups="false" redirectPort="443" protocol="AJP/1.3" />
重新启动Tomcat就可以了。到这一步可以形成访问方式 https://ip/
4、强制https访问
在tomcat\conf\web.xml中的</welcome-file-list>后面加上这样一段:
<login-config> <!-- Authorization setting for SSL --> <auth-method>CLIENT-CERT</auth-method> <realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint> <!-- Authorization setting for SSL --> <web-resource-collection > <web-resource-name >SSL</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint>
</security-constraint>
注意:(如果对方使用的机器端口被占用)
需要切换端口来转换数据:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
AJP(Apache JServ Protocol)是定向包协议。因为性能原因,使用二进制格式来传输可读性文本。WEB服务器通过TCP连接和SERVLET容器连接。
Tcp Connection 具有两种状态:
(1). Idle
没有请求正使用该连接。
(2). Assigned
当前连接正在处理某个请求.
数据类型:
AJP协议中包括四种数据类型:Byte, Boolean, Integer andString.
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),代表当前连接仍然可用。
ajp 定向包协议 二进制代替文本提高性能 简介相关推荐
- 字符串 - 二进制和文本字符串 - 探究
1.应用场景 主要用于探究字符串中的二进制和文本字符串,以及它们的区别和应用场景. 2.学习/操作 1.文档阅读 重要来自于与chatgpt的对话问答 以及其他技术文章 2.整理输出 2.1 是什么 ...
- mysql源码包和二进制包_Linux软件包(源码包和二进制包)
Linux下的软件包众多,且几乎都是经 GPL 授权.免费开源(无偿公开源代码)的.这意味着如果你具备修改软件源代码的能力,只要你愿意,可以随意修改. GPL,全称 General Public Li ...
- 安卓修改软件安装时间_Linux软件包(源码包和二进制包)详细介绍
Linux下的软件包众多,且几乎都是经 GPL 授权.免费开源(无偿公开源代码)的.这意味着如果你具备修改软件源代码的能力,只要你愿意,可以随意修改. GPL,全称 General Public Li ...
- TCP数据包协议格式详解
出一个专栏把通信协议搞一下吧,万物互联的根本呀. IP 版本4位:4(二进制0100)表示IPv4,6(二进制0110)表示IPv6 报头长度(单位4byte):因为选项长度不确定,取值范围是5-15 ...
- R语言使用ggpubr包的ggarrange函数组合多张结论图:使用ggpubr包将图像、文本、表格组合在一起展示
R语言使用ggpubr包的ggarrange函数组合多张结论图:使用ggpubr包将图像.文本.表格组合在一起展示 目录 R语言使用ggpubr包的ggarrange
- [实战]前端wireshark抓包协议解密
前端wireshark抓包协议解密 废话不多说,先看看结果 该JSON文件是通过解密后的 HTTP 返回response结果再解密打开的新页面 有兴趣的小伙伴了解下之前的文章 Sha384解密[2] ...
- 在线二进制转文本工具
在线二进制转文本工具 在线二进制转文本工具 工具可以将空格分隔的二进制字符串转换为普通字符串,工具为实时转换,粘贴后即可完成转换. https://tooltt.com/bin2txt/
- 为什么爱奇艺会显示联通免流量服务器,联通爱奇艺流量定向包是怎么回事啊,是不是开通之后,这一个月里面看视讯免流量的...
联通爱奇艺流量定向包是怎么回事啊,是不是开通之后,这一个月里面看视讯免流量的以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧 ...
- 中文文本分类的java包_java实现中文文本分类
基于libsvm 的中文文本分类原型支持向量机(Support Vector M... 基于SSPP-KELM多标签文本分类算法的实现_电子/电路_工程科技_专业资料.文本数据分类后,根据类标签的个数 ...
最新文章
- LU 分解 (LU Decomposition)
- 中国量化投资将呈现三大发展趋势
- C++拷贝构造函数的调用时机
- pandas 读表格_pandas电子表格的读取(pandas中的read_excel)
- 技术应用丨DWS 空间释放(vacuum full) 最佳实践
- 最小费用最大流背诵用模板
- python程序-怎么用手机编写Python程序?
- 一个H264流,保存成多个文件需要注意的两个问题
- java 继承list_Java集合—List—继承关系
- 电气专业需要考什么计算机证书吗,电气自动化专业可以考什么证书
- 信息安全技术实验PGP邮件加密系统工具下载过程记录
- ffmpeg在低版本VS中的编译
- Occupancy Map(Occupancy Grid)的更新
- python推箱子游戏顶层设计子层设计_python实现推箱子游戏
- SSD202 驱动WIFI-ssw01b的AP模式
- Ipmitool工具安装以及常见使用方法
- 面向对象:想和你一起看夕阳,还有好多想去的地方,希望能与你同行
- 《Python编程:从入门到实践》读书笔记——第5章:if语句
- sudo: unable to resolove host iZ2ze7gg2o6tplktzc1le0Z问题的解决方法
- Linux(Ubuntu)下,生成C语言可执行文件和汇编文件
热门文章
- literal在程序語言中的意思(轉)
- 编程语言中字面常量(literal)的详细介绍(关键词:Java,文字量,直接量,常量,常值,字面量,字面值,实字)
- 用HackRF做一个私网LTE基站
- Linux-CentOS系统安装telnet服务和telnet-server服务器教程--解决telnet无法连接 Connection refused
- 机器视觉进行精密测量影响精度的因素有哪些?
- MACD柱堆形态指标公式
- 信息安全风险评估是什么?如何进行评估?
- PyTorch 报错:TypeError: exceptions must derive from BaseException
- http://www.cppblog.com/wsy6634/archive/2009/05/16/83115.aspx?opt=admin
- java Excel清除表格条件格式规则