为 Apache HTTP 服务器配置 mod_jk

配置指令

大多数指令在 Apache HTTP 服务器配置的全局部分和每个 <VirtualHost> 元素中允许使用一次。此规则的例外情况在下表中明确列出。

大多数值从主服务器继承到虚拟主机。从版本 1.2.20 开始,它们可以在虚拟主机中被覆盖。此规则的例外情况在下表中再次明确列出。请特别注意 JkMountCopy。

警告:如果 Apache 和 Tomcat 被配置为从同一文件系统位置提供内容,则必须注意确保 Apache 无法提供不当内容,例如 WEB-INF 目录的内容或 JSP 源代码。

如果 Apache DocumentRoot 与 Tomcat 主机的 appBase 或任何上下文的 docBase 重叠,则可能会发生这种情况。当使用 Apache Alias 指令与 Tomcat 主机的 appBase 或任何上下文的 docBase 时,也可能会发生这种情况。

以下是 Apache 支持的所有指令

属性 描述
JkWorkersFile

Tomcat servlet 容器的工作进程文件名称。
此指令仅允许使用一次。它必须放在配置的全局部分中。
如果您不使用 JkWorkerProperty 指令,则必须使用有效的 JkWorkersFile 定义您的工作进程。没有默认值。

JkWorkerProperty

允许在 Apache 配置文件中设置工作程序属性。语法与 JkWorkersFile(通常为 workers.properties)中的语法相同。只需在每行前加上“JkWorkerProperty”前缀,即可将其直接放入 Apache 配置文件中。
此指令允许多次使用。它必须放入配置的全局部分。
如果您不使用 JkWorkerProperty 指令,则必须使用有效的 JkWorkersFile 定义您的工作进程。没有默认值。
此指令在 jk1.2.7 及更高版本中可用。

JkShmFile

共享内存文件名。仅在 Unix 平台上使用。shm 文件由平衡器和状态工作程序使用。
此指令仅允许使用一次。它必须放在配置的全局部分中。
默认值为 logs/jk-runtime-status。强烈建议将 shm 文件放在本地驱动器上,而不是 NFS 共享中。

共享内存包含负载平衡器工作程序及其成员的配置和运行时信息。所有 Apache 子进程都需要它

  • 共享负载平衡成员的相同状态信息(正常、错误,...),
  • 共享各个工作程序承担的负载信息,
  • 共享状态工作程序在运行时可更改的配置部分信息。

JkShmSize

共享内存文件的大小。
此指令仅允许使用一次。它必须放在配置的全局部分中。
默认值取决于平台。通常小于 64KB。

JkMountFile

包含从上下文到 Tomcat 工作程序的多重映射的文件。它通常称为 uriworkermap.properties。
有关继承规则,请参见:JkMountCopy。
没有默认值。

JkMountFileReload

此指令以秒为单位配置重新加载检查间隔。系统会定期检查 JkMountFile 是否有更改。更改后的文件会自动重新加载。如果将此指令设置为“0”,则会关闭重新加载检查。
默认值为 60 秒。
此指令已添加到 mod_jk 的 1.2.20 版本中。

JkMount

从上下文到 Tomcat 工作程序的装载点。
此指令允许多次使用。它允许在全局配置和 VirtualHost 中使用。
您也可以在 Location 中使用它,但语法不同。在 Location 中,省略第一个参数(路径),它从 Location 参数中逐字继承。虽然 匹配以 "/myapp" 开头的任何 URI,但嵌套在这样的 Location 块中的任何 JkMount 仅匹配 URI 为 /myapp 的请求。因此,通常不建议在 Location 中嵌套 JkMount。
默认情况下,JkMount 条目不会从全局服务器继承到其他 VirtualHost 或在 VirtualHost 之间继承。有关完整的继承规则,请参阅:JkMountCopy。
您可以将规则扩展追加到工作程序名称。扩展与工作程序名称之间用分号 ";" 分隔,使用与 uriworkermap.properties 文件中相同的语法。

JkUnMount

从上下文到 Tomcat 工作程序的排除挂载点。在将请求映射到 Tomcat 工作程序后,将检查所有排除挂载。如果请求也映射到排除,则不会将其转发到 Tomcat,而是将其本地提供。
此指令允许多次使用。它允许在全局配置和 VirtualHost 中使用。
您也可以在 Location 中使用它,但语法不同。在 Location 中,省略第一个参数(路径),它从 Location 参数中逐字继承。虽然 匹配以 "/myapp" 开头的任何 URI,但嵌套在这样的 Location 块中的任何 JkUnMount 仅匹配 URI 为 /myapp 的请求。因此,通常不建议在 Location 中嵌套 JkUnMount。
有关继承规则,请参见:JkMountCopy。
此指令在 jk1.2.7 及更高版本中可用。

JkAutoAlias

自动将 Web 应用程序上下文目录别名化为 Apache 文档空间。
应注意确保仅通过 Apache 提供静态内容,这是使用此指令的结果。Apache 提供的任何静态内容都将绕过应用程序的 web.xml 中定义的任何安全约束。
有关继承规则,请参见:JkMountCopy。
没有默认值。

JkMountCopy

如果此指令在某个虚拟服务器中设置为“On”,则全局服务器中的挂载将复制到此虚拟服务器,更准确地说,是 JkMount 或 JkUnMount 定义的所有挂载。仅当 VirtualHost 未定义自己的 JkMountFile 或 JkAutoAlias 时,才将 JkMountFile 和 JkAutoAlias 定义的挂载继承下来。
如果您希望所有 vhost 继承主服务器中的挂载,则可以在主服务器中将 JkMountCopy 设置为“All”。
此指令仅允许在 VirtualHost(值为“On”)和全局服务器(值为“All”)中使用。
默认值为 Off,因此不会从全局服务器继承任何挂载到任何 VirtualHost。
从 1.2.26 版本开始,您还可以在全局虚拟服务器中将其设置为“All”。这会将默认值切换为 On。

JkWorkerIndicator

Apache 环境变量的名称,可用于结合 SetHandler jakarta-servlet 设置工作程序名称。
每个虚拟服务器仅允许此指令出现一次。它在全局配置和 VirtualHost 中均被允许。
默认值为 JK_WORKER_NAME。

JkWatchdogInterval

此指令配置看门狗线程间隔(以秒为单位)。后台线程会定期维护工作进程,该线程每隔 watchdog_interval 秒运行一次。工作进程维护会检查空闲连接、更正负载状态,并能检测后端运行状况。
仅当距离上次维护已过去至少 worker.maintain 秒时,才会进行维护。因此,将 JkWatchdogInterval 设置得比 worker.maintain 小很多是没有用的。
默认值为 0 秒,这意味着不会创建看门狗线程,而是会与正常请求结合进行维护。
此指令仅允许使用一次。它必须放在配置的全局部分中。
此指令已添加到 mod_jk 的 1.2.27 版本中。它仅适用于使用 APR 库(包括线程支持)的 Apache 2.x 及更高版本。

JkLogFile

mod_jk 日志文件的完整路径或相对于服务器的路径。它还可与管道配合使用,方法是使用 "| ..." 形式的值。
默认值为 logs/mod_jk.log。
仅从 1.2.16 版本开始,Apache 1.3 才支持管道。默认值仅从 1.2.20 版本开始存在。

JkLogLevel

mod_jk 日志级别,可以是 debug、info、warn、error 或 trace。
默认值为 info。

JkLogStampFormat

mod_jk 日期日志格式,使用扩展的 strftime 语法。此格式将用于 JkLogFile 中的时间戳。格式的最大长度为 63 个字符。
从 mod_jk 的 1.2.24 版本开始,您还可以使用 %Q 为日志添加毫秒,使用 %q 为日志添加微秒。这些转换说明符是 strftime 的扩展。它们仅适用于具有 gettimeofday() 函数的平台。您只能在模式中使用 %Q 和 %q 一次,也不能在同一模式中同时使用它们。
默认值为 "[%a %b %d %H:%M:%S %Y] ",从 1.2.24 版本开始,在具有 gettimeofday() 函数的平台上,默认值为 "[%a %b %d %H:%M:%S.%Q %Y] "。

JkRequestLogFormat

请求日志格式字符串。请参见下面的详细说明。
没有默认值。如果不定义值,则请求日志记录将关闭。

JkExtractSSL

启用 mod_jk 的 SSL 处理和信息收集
默认值为 On。
为了让 Apache 中的 SSL 数据可供 mod_jk 使用,您需要设置 SSLOptions +StdEnvVars。对于证书信息,您还需要添加 SSLOptions +ExportCertData

具体来说,mod_jk 会根据 Servlet 规范 3.0 第 3.8 节,将以下环境变量从 Apache 导出到 Tomcat,并作为请求属性。

环境变量请求属性名称类型示例
SSL_CIPHER
(或 JkKEYSIZEIndicator)
javax.servlet.request.cipher_suite java.lang.String DHE-RSA-AES256-SHA
SSL_CIPHER_USEKEYSIZE
(或 JkKEYSIZEIndicator)
javax.servlet.request.key_size java.lang.Integer 256
SSL_SESSION_ID
(或 JkSESSIONIndicator)
javax.servlet.request.ssl_session java.lang.String 905...32E(十六进制字符串)
SSL_CLIENT_CERT_CHAIN_n
(或 JkCERTCHAINPrefixn)
javax.servlet.request.X509Certificate java.security.X509Certificate[] (证书链按信任度升序排列,第一个是客户端证书,第二个是该证书的签名者,依此类推)

此外,mod_jk 还发送 SSL 协议名称,作为名为 AJP_SSL_PROTOCOL 的专有请求属性。现代 Tomcat 版本会以 org.apache.tomcat.util.net.secure_protocol_version 名称公开此属性。此功能已添加到 mod_jk 的 1.2.41 版本中。另请参见 JkSSLPROTOCOLIndicator。

对于所有其他与 SSL 相关的变量,请为每个所需的变量使用 JkEnvVar。请注意,与 JkEnvVar 一样,这些变量可从请求属性中获取,而不是作为环境变量或请求头。

JkRequestIdIndicator

Apache 环境变量的名称,其中包含唯一请求 ID。环境变量的值将添加到大多数 mod_jk 错误日志行中,并且通过在其中也添加该环境变量,可以轻松地与 Apache 日志进行关联。
默认值为“UNIQUE_ID”。加载模块“mod_unique_id”将自动以该名称提供唯一的请求 ID。

此功能已添加到 mod_jk 的 1.2.49 版本中。

如果请求 ID 是由客户端或其他反向代理通过 HTTP 请求头发送的,则可以通过使用 mod_setenvif 将其复制到环境变量中,从而使此 ID 可用于 mod_jk
SetEnvIf X-REQUEST-ID-HEADER "(.+)" X-REQUEST-ID=$1
将传入标头 X-REQUEST-ID-HEADER 的值复制到环境变量 X-REQUEST-ID 中。mod_jk 可以通过 JkRequestIdIndicator X-REQUEST-ID 从那里获取它。

JkHTTPSIndicator

包含 SSL 指示的 Apache 环境变量的名称。
默认值为“HTTPS”。

JkSSLPROTOCOLIndicator

包含 SSL 协议名称的 Apache 环境变量的名称。
默认值为“SSL_PROTOCOL”。
此指令已在 mod_jk 的 1.2.41 版本中添加。

JkCERTSIndicator

包含 SSL 客户端证书的 Apache 环境变量的名称。
默认值为“SSL_CLIENT_CERT”。

JkCIPHERIndicator

包含 SSL 客户端密码的 Apache 环境变量的名称。
默认值为“SSL_CIPHER”。

JkCERTCHAINPrefix

包含 SSL 客户端链证书的 Apache 环境(前缀)的名称。
默认值为“SSL_CLIENT_CERT_CHAIN_”。

JkSESSIONIndicator

包含 SSL 会话的 Apache 环境变量的名称。
默认值为“SSL_SESSION_ID”。

JkKEYSIZEIndicator

包含正在使用的 SSL 密钥大小的 Apache 环境变量的名称。
默认值为“SSL_CIPHER_USEKEYSIZE”。

JkLocalNameIndicator

可用于覆盖已转发的本地名称的 Apache 环境变量的名称。仅在需要调整数据时使用(请参阅 代理 文档)。
默认值为“JK_LOCAL_NAME”。
此指令已在 mod_jk 的 1.2.28 版本中添加。

JkIgnoreCLIndicator

强制忽略现有 Content-Length 请求标头的 Apache 环境变量的名称。这可用于使 mod_jk 与 mod_deflate 请求正文扩充兼容(请参阅 下方)。
默认值为“JK_IGNORE_CL”。
此指令已在 mod_jk 的 1.2.41 版本中添加。

JkLocalAddrIndicator

可用于覆盖已转发的本地 IP 地址的 Apache 环境变量的名称。仅在需要调整数据时使用(请参阅 代理 文档)。
默认值为“JK_LOCAL_ADDR”。
此指令已在 mod_jk 的 1.2.41 版本中添加。

JkLocalPortIndicator

可用于覆盖已转发的本地端口的 Apache 环境变量的名称。仅在需要调整数据时使用(请参阅 代理 文档)。
默认值为“JK_LOCAL_PORT”。
此指令已在 mod_jk 的 1.2.28 版本中添加。

JkRemoteHostIndicator

可用于覆盖已转发的远程(客户端)主机名的 Apache 环境变量的名称。仅在需要调整数据时使用(请参阅 代理 文档)。
默认值为“JK_REMOTE_HOST”。
此指令已在 mod_jk 的 1.2.28 版本中添加。

JkRemoteAddrIndicator

可用于覆盖已转发的远程(客户端)IP 地址的 Apache 环境变量的名称。仅在需要调整数据时使用(请参阅 代理 文档)。
默认值为“JK_REMOTE_ADDR”。
此指令已在 mod_jk 的 1.2.28 版本中添加。

JkRemotePortIndicator

可用于覆盖已转发的远程(客户端)IP 地址的 Apache 环境变量的名称。仅在需要调整数据时使用(请参阅 代理 文档)。
默认值为“JK_REMOTE_PORT”。
此指令已在 mod_jk 的 1.2.32 版中添加。

JkRemoteUserIndicator

Apache 环境变量的名称,可用于覆盖转发用户名。仅在需要调整数据时使用(请参阅代理文档)。
默认值为“JK_REMOTE_USER”。
此指令已在 mod_jk 的 1.2.28 版本中添加。

JkAuthTypeIndicator

Apache 环境变量的名称,可用于覆盖转发认证类型。仅在需要调整数据时使用(请参阅代理文档)。
默认值为“JK_AUTH_TYPE”。
此指令已在 mod_jk 的 1.2.28 版本中添加。

JkOptions

设置一个或多个选项以配置 mod_jk 模块。有关此指令的详细信息,请参见下文。
每个虚拟服务器可以使用此指令多次。
自 1.2.24 版起,默认值为“ForwardURIProxy”。在 1.2.23 版中为“ForwardURICompatUnparsed”,在 1.2.22 版及之前版本中为“ForwardURICompat”。

JkEnvVar

添加环境变量的名称和可选默认值,该变量应作为请求属性发送到 servlet 引擎。如果未明确给出默认值,则仅当在运行时设置该变量时才发送该变量。
默认值为空,因此不会发送其他变量。
每个虚拟服务器可以使用此指令多次。设置将在全局服务器和任何虚拟服务器之间合并。
您可以通过 request.getAttribute(attributeName) 以请求属性的形式在 Tomcat 上检索变量。请注意,通过 JkEnvVar 发送的变量不会列在 request.getAttributeNames() 中。
自 1.2.20 版起支持空默认值。在 1.2.21 版中引入了不发送具有空默认值和空运行时值的变量。

JkStripSession

如果在某个虚拟服务器中将此指令设置为 On,则对于未转发而是由本地服务器处理的 URL,将删除会话 ID ;jsessionid=...
此指令仅允许在 VirtualHost 内使用。
默认情况下为关闭。
此指令已在版本 1.2.21 中引入。
从版本 1.2.27 开始,此指令可以具有可选会话 ID 标识符。如果未指定,则默认为 ;jsessionid

配置指令类型

我们将在此处讨论 mod_jk 指令类型。

定义工作进程

JkWorkersFile 指定 mod_jk 查找工作进程定义的位置。请参阅 工作进程文档 以获取详细说明。

JkWorkersFile     /etc/httpd/conf/workers.properties

日志记录

JkLogFile 指定 mod_jk 放置其日志文件的位置。

JkLogFile     /var/log/httpd/mod_jk.log

自 Apache 2.x 的 JK 1.2.3 和 Apache 1.3 的 JK 1.2.16 以来,此功能也可用于管道日志记录

JkLogFile     "|/usr/bin/rotatelogs /var/log/httpd/mod_jk.log 86400"

JkLogLevel 设置日志级别

  • info 日志将包含标准 mod_jk 活动(默认)。
  • warn 日志将包含非致命错误报告。
  • error 日志还将包含错误报告。
  • debug 日志将包含有关 mod_jk 活动的所有信息
  • trace 日志将包含有关 mod_jk 活动的所有跟踪信息
JkLogLevel    info

info 应为正常操作的默认选择。

JkLogStampFormat 将配置 mod_jk 日志文件中找到的日期/时间格式。有关详细信息,请参见上文。

JkLogStampFormat "[%Y-%m-%d %H:%M:%S.%Q] "

您可以使用 Apache 标准模块 mod_log_config 记录 mod_jk 信息。该模块在 Apache 注释表中设置了多个注释。其中大多数仅与负载平衡器工作进程结合使用时才有用。

属性 描述
JK_WORKER_NAMEURI 映射选择的 worker 的名称
JK_WORKER_TYPEURI 映射选择的 worker 的类型
JK_WORKER_ROUTEURI 映射选择的实际 worker 名称(通常是负载平衡器的成员)。
在版本 1.2.26 之前,仅在设置了 JkRequestLogFormat 时才可用。
JK_REQUEST_DURATION以秒和微秒为单位的请求持续时间。
在版本 1.2.26 之前,仅在设置了 JkRequestLogFormat 时才可用。
JK_LB_FIRST_NAME负载平衡器:尝试的第一个 worker 的名称
JK_LB_FIRST_TYPE负载平衡器:尝试的第一个 worker 的类型
JK_LB_FIRST_ACCESSED负载平衡器:尝试的第一个 worker 的访问计数
JK_LB_FIRST_SESSIONS负载平衡器:尝试的第一个 worker 创建的会话数
JK_LB_FIRST_READ负载均衡器:尝试的第一个工作进程读取的字节数
JK_LB_FIRST_TRANSFERRED负载均衡器:尝试的第一个工作进程传输的字节数
JK_LB_FIRST_ERRORS负载均衡器:尝试的第一个工作进程的错误计数
JK_LB_FIRST_BUSY负载均衡器:尝试的第一个工作进程的忙碌计数
JK_LB_FIRST_ACTIVATION负载均衡器:尝试的第一个工作进程的激活状态
JK_LB_FIRST_STATE负载均衡器:尝试的第一个工作进程的错误状态
JK_LB_LAST_NAME负载均衡器:尝试的最后一个工作进程的名称
JK_LB_LAST_TYPE负载均衡器:尝试的最后一个工作进程的类型
JK_LB_LAST_ACCESSED负载均衡器:尝试的最后一个工作进程的访问计数
JK_LB_LAST_SESSIONS负载均衡器:尝试的最后一个工作进程创建的会话计数
JK_LB_LAST_READ负载均衡器:尝试的最后一个工作进程读取的字节数
JK_LB_LAST_TRANSFERRED负载均衡器:尝试的最后一个工作进程传输的字节数
JK_LB_LAST_ERRORS负载均衡器:尝试的最后一个工作进程的错误计数
JK_LB_LAST_BUSY负载均衡器:尝试的最后一个工作进程的忙碌计数
JK_LB_LAST_ACTIVATION负载均衡器:尝试的最后一个工作进程的激活状态
JK_LB_LAST_STATE负载均衡器:尝试的最后一个工作进程的错误状态
LogFormat     "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n \
               %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log
CustomLog     logs/access_log     mod_jk_log

你还可以将请求协议记录在 mod_jk 日志文件中,而不是访问日志中。不推荐这样做,这主要是一个向后兼容性功能。指令 JkRequestLogFormat 将配置此协议的格式。它在每个虚拟主机基础上进行配置和启用。要为虚拟主机启用请求记录,只需添加一个 JkRequestLogFormat 配置。格式字符串的语法类似于 Apache LogFormat 命令,以下是可用请求日志格式选项的列表

属性 描述
%b发送的字节数,不包括 HTTP 头(CLF 格式)
%B发送的字节数,不包括 HTTP 头
%H请求协议
%m请求方法
%p为请求提供服务的服务器的规范端口
%q查询字符串(如果存在查询字符串,则以 ? 为前缀,否则为空字符串)
%r请求的第一行
%s请求 HTTP 状态代码
%T请求持续时间,以秒为单位处理请求的经过时间“.”微秒
%U请求的 URL 路径,不包括任何查询字符串。
%v处理请求的服务器的规范 ServerName
%V根据 UseCanonicalName 设置的服务器名称
%wTomcat 工作进程名称
%R实际工作进程名称
JkRequestLogFormat     "%w %V %T"

转发

JkOptions 指令允许你设置许多转发选项,这些选项将启用 (+) 或禁用 (-) 以下选项。如果没有任何前导符号,则将启用选项。

以下四个选项 +ForwardURIxxx 互斥。其中需要一个,不允许使用负号前缀。自 1.2.24 版本以来,默认值为“ForwardURIProxy”。在 1.2.23 版本中为“ForwardURICompatUnparsed”,在 1.2.22 版本之前为“ForwardURICompat”。你可以通过启用其他两个选项之一来关闭默认值。除非你有非常充分的理由更改它,否则你应该将其保留为默认值。

所有选项都从全局服务器继承到虚拟主机。支持启用(加号选项)和禁用(减号选项)的选项以以下方式继承
options(vhost) = plus_options(global) - minus_options(global) + plus_options(vhost) - minus_options(vhost)

使用 JkOptions ForwardURIProxy,转发 URI 将在 Apache 中处理后并转发到 Tomcat 之前部分重新编码。这将与 mod_rewrite 的本地 URL 操作和 URL 编码的会话 ID 兼容。

JkOptions     +ForwardURIProxy

使用 JkOptions ForwardURICompatUnparsed,转发 URI 将未解析。它符合规范且安全。它将始终转发原始请求 URI,因此使用 mod_rewrite 重写 URI 然后转发重写的 URI 将不起作用。

JkOptions     +ForwardURICompatUnparsed

使用 JkOptions ForwardURICompat,Apache 将解码转发 URI。将解码编码字符,并且显式路径组件(如“..”)将已解析。这不太符合规范,并且如果你正在使用前缀 JkMount,则不安全。此选项允许在转发之前使用 mod_rewrite 重写 URI。

JkOptions     +ForwardURICompat

使用 JkOptions ForwardURIEscaped,转发 URI 将是 ForwardURICompat 使用的 URI 的编码形式。显式路径组件(如“..”)将已解析。这将无法与 URL 编码的会话 ID 结合使用,但它允许在转发之前使用 mod_rewrite 重写 URI。

JkOptions     +ForwardURIEscaped

JkOptions RejectUnsafeURI 将阻止所有包含百分号“%”或反斜杠“\”的 URL(在解码之后)。

大多数 Web 应用程序不会使用此类 URL。通过使用 RejectUnsafeURI 选项,您可以阻止几种众所周知的 URL 编码攻击。默认情况下,此选项未设置。

您还可以使用功能更强大但稍显复杂的 mod_rewrite 实现此类检查。

JkOptions     +RejectUnsafeURI

自 1.2.44 起,JkOptions CollapseSlashesAll 已弃用,如果使用,将被忽略。

自 1.2.44 起,JkOptions CollapseSlashesUnmount 已弃用,如果使用,将被忽略。

自 1.2.44 起,JkOptions CollapseSlashesNone 已弃用,如果使用,将被忽略。

JkOptions ForwardDirectories 与 Apache 的 DirectoryIndex 指令结合使用。因此,mod_dir 应该以静态或动态 (DSO) 的方式供 Apache 使用。

配置 DirectoryIndex 时,Apache 将为指令中指定的每个本地 URL 创建子请求,以确定是否存在匹配的本地文件(通过对文件进行 stat 来完成此操作)。

如果 ForwardDirectories 设置为 false(默认值),并且 Apache 找不到任何匹配的文件,Apache 将提供目录的内容(如果指令 Options 为该目录指定了 Indexes)或 403 Forbidden 响应(如果指令 Options 未为该目录指定 Indexes)。

如果 ForwardDirectories 设置为 true,并且 Apache 找不到任何匹配的文件,请求将被转发到 Tomcat 以进行解析。在 Apache 由于各种原因无法在文件系统上看到索引文件时,将使用此功能:Tomcat 在不同的计算机上运行、JSP 文件已预编译等。

请注意,本地可见文件将优先于仅对 Tomcat 可见的文件(即如果 Apache 可以看到该文件,则将提供该文件)。如果 Tomcat 通常提供多种类型的文件,这一点非常重要,例如 Velocity 页面和 JSP 页面。

JkOptions     +ForwardDirectories

设置 JkOptions ForwardLocalAddress,您要求 mod_jk 发送 Apache HTTP 服务器的本地地址,而不是远程客户端地址。Tomcat 远程地址阀门可以使用此功能来仅允许来自已配置 Apache 服务器的连接。

JkOptions     +ForwardLocalAddress

设置 JkOptions ForwardPhysicalAddress,您要求 mod_jk 将物理对等 TCP IP 地址作为客户端地址发送。默认情况下,mod_jk 使用 Web 服务器提供的逻辑地址。例如,模块 mod_remoteip 将逻辑 IP 地址设置为客户端 IP,该 IP 由 X-Forwarded-For 标头中的代理转发。

JkOptions     +ForwardPhysicalAddress

JkOptions FlushPackets,您要求 mod_jk 在从 Tomcat 收到每个 AJP 数据包块后刷新 Apache 的连接缓冲区。此选项可能会对 Apache 和 Tomcat 造成严重的性能损失,因为写入操作执行的频率比通常需要的要高(即:在每个响应的末尾)。

JkOptions     +FlushPackets

JkOptions FlushHeader,您要求 mod_jk 在从 Tomcat 收到响应头后刷新 Apache 的连接缓冲区。

JkOptions     +FlushHeader

JkOptions DisableReuse,您要求 mod_jk 在使用连接后立即关闭连接。通常,mod_jk 使用持久连接并池化空闲连接以在需要将新请求发送到 Tomcat 时重用它们。

使用此选项会对 Apache 和 Tomcat 造成严重的性能损失。仅在无法解决的网络问题的情况下才将其作为最后手段使用。如果 Apache 和 Tomcat 之间的防火墙会静默关闭空闲连接,请尝试将 worker 属性 socket_keepalive 与操作系统中适当的 TCP 保活值结合使用。

JkOptions     +DisableReuse

JkOptions ForwardKeySize,当使用 ajp13 时,您要求 mod_jk 也转发 Servlet API 2.3 所需的 SSL 密钥大小。当 servlet 引擎为 Tomcat 3.2.x 时,不应设置此标志(默认情况下启用)。

JkOptions     +ForwardKeySize

JkOptions ForwardSSLCertChain,当使用 ajp13 时,您要求 mod_jk 转发 SSL 证书链(默认情况下关闭)。Mod_jk 仅将 SSL_CLIENT_CERT 传递给 AJP 连接器。对于自签名证书或直接由根 CA 证书签名的证书,这不是问题。但是,有大量由中间 CA 证书签名的证书,这是一个重大问题:servlet 将无法自行验证客户端证书。通过 AJP 连接器将 SSL_CLIENT_CERT_CHAIN 传递给 Tomcat 可以修复此错误。
此指令仅从 1.2.22 版本开始存在。

JkOptions     +ForwardSSLCertChain

指令 JkEnvVar 允许您将环境变量从 Apache 服务器转发到 Tomcat 引擎。您可以将默认值作为指令的第二个参数添加。如果未明确给出默认值,则仅当在运行时设置变量时才会发送该变量。
可以在 Tomcat 端通过请求属性 request.getAttribute(attributeName) 检索变量。请注意,通过 JkEnvVar 发送的变量不会列在 request.getAttributeNames() 中。
这些变量从全局服务器继承到虚拟主机。

JkEnvVar     SSL_CLIENT_V_START     undefined

将 URL 分配给 Tomcat

如果您已创建自定义或本地版本的 mod_jk.conf-local(如上所述),则可以更改设置,例如 worker 或 URL 前缀。

JkMount 指令为 Tomcat 分配特定的 URL。通常,JkMount 指令的结构为

JkMount [URL prefix] [Worker name]
# send all requests ending in .jsp to worker1
JkMount /*.jsp worker1
# send all requests ending /servlet to worker1
JkMount /*/servlet/ worker1
# send all requests jsp requests to files located in /otherworker will go worker2
JkMount /otherworker/*.jsp worker2

您可以在 httpd.conf 文件的顶级或 <VirtualHost> 部分中使用 JkMount 指令。

JkUnMount 指令与 JkMount 相反,它会阻止访问特定的 URL。其目的是能够从已装载的上下文中过滤出特定的内容类型。以下示例装载了 /servlet/* 上下文,但不会提供属于该上下文的任何 .gif 文件。

# send all requests ending with /servlet to worker1
JkMount /servlet/* worker1
# do not send requests ending with .gif to worker1
JkUnMount /servlet/*.gif worker1

JkUnMount 优先于 JkMount 指令,这意味着 JK 会先尝试装载,然后检查是否存在由 JkUnMount 定义的排除项。只有当 JkMount 和 JkUnMount 中的 worker 名称相同,JkUnMount 才会覆盖 JkMount。

以下示例将阻止所有 .gif 文件,尽管有针对它们的 JkMount

# do not send requests ending with .gif to worker1
JkUnMount /*.gif worker1
# The .gif files will not be mounted cause JkUnMount takes
# precedence over JkMount directive
JkMount /servlet/*.gif worker1

从 JK 1.2.26 版本开始,您可以通过在 JkUnMount 中使用星号字符 '*' 作为 worker 名称,将 JkUnMount 应用于任何 worker。JkUnMount worker 名称中不允许出现更复杂的模式。

# Mapping the webapps myapp1 and myapp2:
/myapp1/*=worker1
/myapp2/*=worker2
# Exclude the all subdirectories static for all workers:
!/*/static/*=*
# Exclude some suffixes for all workers:
!*.html=*

JkAutoAlias 指令会自动将 Webapp 上下文目录别名到 Apache 文档空间中。它使 Apache 能够提供静态上下文,而 Tomcat 提供动态上下文。此指令用于方便起见,这样您不必为 Tomcat 的 webapp 目录中的每个应用程序目录放置 Apache Alias 指令。出于安全原因,强烈建议默认情况下使用 JkMount 将所有请求传递给 Tomcat,并使用 JkUnMount 明确排除由 Apache 提供的静态内容。还应注意,由 Apache 提供的内容将绕过应用程序的 web.xml 中定义的任何安全约束。该指令仅适用于具有单个路径元素且没有版本标记的上下文的简单情况。它不支持

  • ROOT 上下文(即 .../webapps/ROOT)
  • 多级上下文(例如 .../webapps/foo#bar)
  • 并行部署(例如 .../webapps/foo##v00.05.12)

# enter the full path to the tomcat webapps directory
JkAutoAlias /opt/tomcat/webapps

以下示例演示了如何使用 Tomcat 提供动态上下文,并使用 Apache 提供静态上下文。Apache 必须能够访问 webapps 目录。

# enter the full path to the tomcat webapps directory
JkAutoAlias /opt/tomcat/webapps

# Mount 'examples' directory. It's physical location
# is assumed to be in the /opt/tomcat/webapps/examples
# ajp13w is a worker defined in the workers.properties
JkMount /examples/* ajp13w

# Unmount desired static content from examples webapp.
# This content will be served by the Apache directly.
JkUnMount /*.gif ajp13w

请注意,您可以在 httpd.conf 中为每个虚拟主机设置一个 JkAutoAlias 指令

JkWorkerProperty 是 JK 1.2.7 版本中提供的新指令。它是一种方便的方法,用于设置通常在 workers.propeties 文件中设置的指令。该指令的参数是 workers.properties 文件中的原始行。

# Just like workers.properties but exact line is prefixed
# with JkWorkerProperty

# Minimal jk configuration
JkWorkerProperty worker.list=ajp13w
JkWorkerProperty worker.ajp13w.type=ajp13
JkWorkerProperty worker.ajp13w.host=localhost
JkWorkerProperty worker.ajp13w.port=8009   

JkMountFile 是 JK 1.2.9 版本中提供的一项新指令。它用于在运行时动态更新装入点。当装入文件发生更改时,JK 将重新加载其内容。

# Load mount points

JkMountFile conf/uriworkermap.properties

如果装入点 URI 以感叹号“!”开头,则它会像 JkUnMount 一样定义一个排除项。如果装入点 URI 以减号“-”开头,则仅禁用装入点。可以通过删除减号并等待 JkMountFile 重新加载来重新启用已禁用的装入点。可以通过添加减号前缀来禁用排除项。

# Sample uriworkermap.properties file

/examples/*=ajp13w
# Do not map .gif files
!/*.gif=ajp13w
# Make jsp examples initially disabled  
-/examples/jsp/*=ajp13w

在运行时,您可以更改此文件的内容。例如,删除减号将启用先前禁用的 URI 映射。您可以在运行时添加任意数量的新条目,以反映新部署的应用程序。Apache 将在 60 秒间隔内重新加载文件并更新装入点。

无法通过动态重新加载删除条目,但您可以禁用或排除映射。

使用 SetHandler 和环境变量

除了 mod_jk 特定的指令外,您还可以使用 SetHandler 和环境变量来控制通过哪个工作进程转发请求。这为您提供了更大的灵活性,但结果可能更难理解。如果您混合使用这两种定义转发的方式,通常 mod_jk 指令会获胜。

SetHandler jakarta-servlet 强制由 mod_jk 处理请求。例如,您可以在 Location 块中或在 Apache 2.2 及更高版本中使用 SetHandler,也可以在 RewriteRule 中使用。

为了使用 SetEnvIfRewriteRule 控制工作进程以制定更复杂的规则,您可以将环境变量 JK_WORKER_NAME 设置为您选择的目标工作进程的名称。这使您能够以更灵活的方式决定所选工作进程,包括依赖于 cookie 值。此功能已添加到 mod_jk 的 1.2.19 版本中。此外,您还可以将规则扩展名附加到工作进程名称。扩展名通过分号“;”与工作进程名称分隔,使用与 uriworkermap.properties 文件中相同的语法。在工作进程名称中支持规则扩展名已添加到 1.2.33 版本中。

为了使用 JK_WORKER_NAME 之外的其他变量,您可以通过 JkWorkerIndicator 指令设置此变量的名称。

您还可以通过设置环境变量 no-jk 来定义 mod_jk 转发的排除项。

# Automatically map all encoded urls
<Location *;jsessionid=>
  SetHandler jakarta-servlet
  SetEnv JK_WORKER_NAME my_worker
</Location>

# Map all subdirs to workers via naming rule
# and exclude static content.
<Location /apps/>
  SetHandler jakarta-servlet
  SetEnvIf REQUEST_URI ^/apps/([^/]*)/ JK_WORKER_NAME=$1
  SetEnvIf REQUEST_URI ^/apps/([^/]*)/static no-jk
</Location>

高级环境变量

环境变量允许根据请求属性(例如请求 URI、标头值或 cookie)覆盖 mod_jk 的默认行为。这可以使用 SetEnvIfRewriteRule 指令来完成。

可以设置环境变量 JK_ROUTE 来明确选择负载平衡器工作进程的成员。该值必须等于成员的 route 属性,或者如果未使用该属性,则等于成员名称。请注意,仅当会话 ID 和路由在请求中以非标准方式编码时才需要这样做。默认情况下,支持使用 Java Servlet 兼容方式对 ID 进行编码的粘性。此功能自 1.2.33 版本起可用。

可以设置环境变量 JK_REPLY_TIMEOUT 来动态定义答复超时。该值必须以毫秒为单位给出。此功能自 1.2.27 版本起可用。

可以设置环境变量 JK_STICKY_IGNORE 来禁用单个请求的会话粘性。如果该变量被设置为一个空字符串或一个非零数字,则会话粘性将被禁用。将其设置为 0 将重置为由工作进程配置定义的行为。此功能自 1.2.33 版本起可用。

使用基于 Cookie 的会话粘性时,此功能可用于优化负载平衡。在这种情况下,只要用户保持浏览器处于打开状态,则由启动会话的用户发出的任何请求都将发送到同一 Tomcat 实例,即使用户离开了使用会话的应用程序部分。例如,当用户请求登录表单时,您可以设置此环境变量,以确保此初始会话请求以非粘性方式进行平衡。

环境变量 JK_STATELESS 可用于提高基于会话的平衡方法 SessionNext 的负载平衡。在这种情况下,通常任何不带会话 ID 的请求都算作新会话。如果在没有会话 ID 的情况下检索静态内容,则这可能会出现问题。如果您为请求设置环境变量 JK_STATELESS,则即使请求不带会话 ID,也不会将该请求算作新会话。此功能自版本 1.2.33 起提供。

可以设置环境变量 JK_IGNORE_CL 以强制忽略请求 Content-Length 标头(如果存在)。然后,mod_jk 将流式传输请求正文,直到 Web 服务器指示已读取完整正文。不会向后端发送 Content-Length 标头。此功能自版本 1.2.41 起提供。

此功能可用于使 mod_jk 与更改请求正文大小的过滤器兼容。其中一个过滤器是 mod_deflate,当用于对使用 gzip 编码正文的请求正文进行解压缩时。在这种情况下,mod_jk 默认会转发截断的正文,因为它从 Web 服务器获取了错误的正文大小。告知 mod_jk 忽略 Content-Length 标头将导致将所有可从 Web 服务器读取的请求正文数据流式传输到后端。

您应该仅为实际需要 JK_IGNORE_CL 环境变量的请求设置该变量。遗憾的是,mod_jk 无法自动检测到此需求。