ajp 定向包协议 二进制代替文本提高性能 简介

article/2025/8/30 5:19:41

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 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),代表当前连接仍然可用。


http://chatgpt.dhexx.cn/article/DDWZ6uQP.shtml

相关文章

Java高级自我介绍

先放个大招&#xff0c;哈哈&#xff0c;相信很多朋友准备了很久技术方面的内功&#xff0c;但是在真正与HR交锋的时候&#xff0c;有时还是败下阵来&#xff0c;究其原因之一&#xff0c;竟然是第一招错了&#xff0c;我自己也是&#xff0c;&#xff0c;所以&#xff0c;周末…

java开发自我介绍范文(合集)

java开发自我介绍范文3篇 java开发自我介绍范文篇一&#xff1a; Good morning ! It is really my honor to have this opportunity for a interview, I hope i can make a good performance today. Im confident that I cansucceed. Now i will introduce myself briefly I am…

Java面试中如何介绍自己的项目经验?

&#x1f447;&#x1f447;关注后回复 “进群” &#xff0c;拉你进程序员交流群&#x1f447;&#x1f447; 作者: hsm_computer 来源: https://www.cnblogs.com/JavaArchitect/p/7586949.html 在面试时&#xff0c;经过寒暄后&#xff0c;一般面试官会让介绍项目经验 。常见…

Java程序员面试时,如何进行自我介绍呢?

现在不管什么面试都会面对的一个环节&#xff0c;就是“自我介绍”。这个环节是很多企业作为选拔人才的一个方式与标准。那么&#xff0c;Java程序员面试自我介绍部分讲什么内容&#xff1f;小千给你详细解答下。 Java程序员自我介绍要有一条清晰的线索&#xff0c;便于组织自…

Java面试自我介绍怎么说?Java面试技巧!

自我介绍可谓是面试中最讨厌的环节了&#xff0c;许多程序员自身技术水平相当不错&#xff0c;但不善于表达&#xff0c;在自我介绍环节往往容易给面试官一个不好的印象。但这又是不可避免的&#xff0c;想要别人知道你是谁&#xff0c;你会什么&#xff0c;你做过什么&#xf…

JAVA面试技巧之自我介绍

【如何进行自我介绍】 自我介绍这个问题&#xff0c;不用多说了&#xff0c;面试必定会问&#xff01;如果想要在自我介绍的时候就能够打动面试官&#xff0c;吸引面试官对我们的兴趣&#xff0c;那么像我们这种接受过Java培训的程序员的自我介绍当然不能和应届生或者其他非技术…

AIOP简介

AIOP&#xff1a;AI for IT Operations

AIOps,让金融智能化运维化繁为简

前言 数字化转型是今天金融企业保持竞争力、拓展业务边界的必经之路。这让企业数据中心运维工作不得不面对海量数据压力的挑战。显然&#xff0c;传统运维方法已经无法满足企业数字化时代的新需求&#xff0c;构建面向未来的智能运维体系成为金融企业转型的关键。 2022年银保…

AIOps产品与架构浅析

【摘要】 本文简要介绍AIOps系统主要组成部分&#xff0c;介绍该系统在企业级IT运维场景下的作用和地位。 我们已经成功地应用了人工智能和机器学习来自动化传统的人工任务和IT操作过程。从异常检测到自动修复&#xff0c;现在将前沿算法融入到易于使用的工具中&#xff0c;允…

AIOps变革

图片摘自灵犀官网 目前稍微有点规模的公司都走到了2.0和3.0&#xff0c;之后4.0会逐渐普及 AIOps目前主要是应用数据发现故障&#xff0c;由于AI目前无法理解业务&#xff0c;所以很多故障处理依然需要依靠人工完成。深度的AI自动发现和故障处理需要智能AI组件的加入&#xf…

AIoT是什么?

AIoT是AI人工智能与IoT物联网的缩写&#xff0c;指的是人工智能物联网&#xff0c;即通过物联网收集来自不同维度的海量数据&#xff0c;存储于云端、边缘端&#xff0c;再根据大数据分析以及AI等技术&#xff0c;实现万物数据化、万物智联化。 谈到物联网&#xff0c;出现频率…

AIops相关算法

文章目录 根因分析清华FOCUS&#xff1a;找影响系统性能瓶颈的原因Adtributor&#xff1a;根因定位MSRA iDice&#xff1a;多维指标突变定位清华Hotspot&#xff1a;多维根因定位 智能变更清华FUNNEL&#xff1a;评估变更影响 异常检测雅虎EGADS&#xff1a;KPI异常检测框架清华…

智能运维AIOps,aiops对比传统运维工具的优势

在智能化、智能化时代&#xff0c;IT从手工制作到完全自动化&#xff0c;从传统的运维流程管理到智能化。“运维智能”这将是行业的发展趋势。  目前&#xff0c;许多用户机房选择传统运维模式、日常运维服务、检查维护工作需要手工记录和报告&#xff0c;检查质量难以保证&a…

探索可观测性:AIOps中的时序数据应用

01. 背景 随着科技的发展&#xff0c;时序数据在我们的认知中占据越来越多的位置&#xff0c;小到电子元件在每个时刻的状态&#xff0c;大到世界每天的新冠治愈人数&#xff0c;一切可观测&#xff0c;可度量&#xff0c;可统计的数据只要带上了时间这个重要的因素就会成为时…

AIOps(智能运维)中的指标算法场景分享 | 内附视频ppt资料

本文转录自&#xff1a;北大博士后严川在云智慧AIOps社区举办的Meetup上进行的《AIOps指标相关算法体系》分享。 直播回放&#xff1a;戳此查看在线回放 PPT下载&#xff1a;戳此下载资料 智能运维算法场景概览 传统运维VS智能运维 传统运维&#xff1a; 特点&#xff1a;…

2022 AIOps挑战赛方案总结

文章目录 挑战赛赛题&#xff1a;微服务架构电商系统下的故障识别和分类一、赛季关键字二、赛题背景1、开源的微服务系统2、丰富的故障类型3、多模态监控数据 三、方法汇总1、特征工程&#xff08;1&#xff09;时序预处理&#xff08;2&#xff09;时序特征提取方案&#xff0…

AIOps:企业运维新力量!

摘要&#xff1a;企业运维需求及挑战&#xff0c;来看看华为AIOps如何解决&#xff01; 本文分享自华为云社区《【云驻共创】AIOps&#xff1f;企业运维新力量&#xff01;》&#xff0c;原文作者&#xff1a;启明。 国际惯例&#xff0c;我们先介绍一下AIOps的概念&#xff1…

智能运维(AIOps)系列之二:什么是人工智能

大众对人工智能认识的误区 很多计算机从业人员&#xff0c;对人工智能的理解 数据挖掘和深度学习。 另一部分对人工智能的理解&#xff0c;则多了知识图谱。 其实&#xff0c;人工智能的理论基础和技术分支&#xff0c;都极其广泛。具体详见下文。 揭开人工智能的神秘面纱 —…

运维数智化时代——京东数科AIOps落地实践(一)

一、背景 自从2016年Gartner提出AIOps概念以来&#xff0c;平台化和智能化已经成为了运维体系发展的大趋势。从整体来看&#xff0c;运维发展可以分为5个阶段&#xff0c;分别为手工及脚本运维、工具标准化运维、平台自动化运维、DevOps和AIOps。 自动化运维给手工及脚本运维…

智能运维(AIOps)系列之三:什么是智能运维

现阶段的研究方向 智能运维框架&#xff08;以质量保障为例&#xff09; 大家可以对照 系列二 的人工智能框架 以质量保障为例&#xff0c;详情 时序指标 根因分析 根因的场景可以区分为&#xff1a;实时场景、准实时场景、以及离线场景。具体取决于 技术限制、业务需求以及…