适用于 Microsoft IIS 的 ISAPI 重定向器操作指南

简介

本文档解释了如何设置适用于 IIS 的 ISAPI 重定向器以与 Tomcat 协作。

通常,IIS 无法执行 Servlet 和 Java Server Pages (JSP)。配置 IIS 使用 ISAPI 重定向器插件将使 IIS 能够将 Servlet 和 JSP 请求发送到 Tomcat(从而将它们提供给客户端)。

建议您同时阅读 Worker 操作指南 文档,以了解如何在您的 Web 服务器和 Tomcat 引擎之间设置工作实体。有关更详细的配置信息,请查阅 workers.propertiesuriworkermapIIS 的参考指南。

文档约定和假设

${tomcat_home} 是 Tomcat 的根目录。您的 Tomcat 安装应包含以下子目录

  • ${tomcat_home}\conf - 您可以放置各种配置文件的地方
  • ${tomcat_home}\webapps - 包含示例应用程序
  • ${tomcat_home}\bin - 您放置 Web 服务器插件的地方

在本文档中的所有示例中,${tomcat_home} 将是 c:\tomcat。Worker 被定义为接受来自 IIS 服务器工作的 Tomcat 进程。

支持的配置

IIS 到 Tomcat 重定向器支持:

  • 运行在任何当前支持的 Windows 版本上的 IIS
  • 所有当前支持的 Tomcat 版本

该重定向器可能与运行在较旧、不受支持的 Windows 版本和/或 Tomcat 上的 IIS 配合使用,但此类配置不受支持。

AJP 协议?

该重定向器使用 AJP 协议将请求发送到 Tomcat 容器。使用的 AJP 版本是 ajp13。所有当前版本的 Tomcat 都支持 ajp13 协议。其他 Servlet 引擎,例如 JettyJBoss,也支持 ajp13 协议。

ajp12 协议已弃用,您不应再使用它。ajp14 协议被认为是实验性的。

它是如何工作的?

  1. ISAPI 重定向器是一个 Microsoft IIS 插件(过滤器 + 扩展)。IIS 加载重定向器插件并为每个传入请求调用其过滤器函数。
  2. 过滤器随后根据 uriworkermap.properties 中保存的 URI 路径列表测试请求 URL。如果当前请求与 URI 路径列表中的某个条目匹配,则过滤器将请求传输到扩展。
  3. 扩展收集请求参数并使用定义的协议(如 ajp13)将其转发给相应的 Worker。
  4. 扩展从 Worker 收集响应并将其返回给浏览器。

安装

ISAPI 重定向器插件 isapi_redirect.dll 的预构建版本(适用于 32 位和 64 位环境)可从 Apache Tomcat 连接器下载 页面获取。您也可以从 Tomcat 连接器源代码分发包中本地构建副本。ISAPI 重定向器需要三个实体:

  • isapi_redirect.dll - 适用于 Microsoft IIS 的 ISAPI 重定向器插件,您可以获取预构建的 DLL 或自行构建(参见构建部分)。
  • workers.properties - 描述 Worker(Tomcat 进程)使用的主机和端口的文件。您可以在 conf 目录下找到一个 workers.properties 示例。
  • uriworkermap.properties - 将 URL 路径模式映射到 Worker 的文件。您也可以在 conf 目录下找到一个 uriworkermap.properties 示例。

安装包括以下部分:

  • 使用默认的 /examples 上下文配置 ISAPI 重定向器,并检查您是否可以使用 IIS 提供 Servlet。
  • 向配置中添加更多上下文。

配置 ISAPI 重定向器

这些说明基于 Windows Server 2012 R2 编写,并已在所有支持的 Windows 操作系统(最高 Windows 11 / Windows Server 2022)上进行测试。

这些安装说明已在干净、完全打补丁的操作系统安装上进行了测试,其中 IIS 及其 ISAPI 扩展和筛选器默认安装,Tomcat 9 安装在 C:\Program Files\Apache Software Foundation\Tomcat 9.0。在本文档的其余部分,这被称为 ${tomcat_home}。

  1. 创建目录 ${tomcat_home}\isapi
  2. 允许 IIS 进程创建 ISAPI 重定向器日志文件。如果日志文件要写入不同的目录,请根据需要修改路径。在命令提示符下输入以下内容:
    >icacls "C:\Program Files\Apache Software Foundation\Tomcat 9.0\isapi" /grant "IIS APPPOOL\DefaultAppPool":(OI)(CI)M
    
    在启用了用户账户控制 (UAC) 的客户端操作系统上,必须使用“以管理员身份运行”打开命令提示符,上述命令才能成功完成。
  3. 下载适用于您的操作系统的相应 (32 位或 64 位) isapi_redirect.dll,并将其放置在 ${tomcat_home}\isapi 中。
  4. 设置 isapi_redirect.dll 的权限。在 Windows Server 2019 上,似乎需要显式设置此 DLL 的权限。在命令提示符下输入以下内容:
    >icacls "C:\Program Files\Apache Software Foundation\Tomcat 9.0\isapi\isapi_redirect.dll" /grant "Everyone":RX
    
  5. 创建 ${tomcat_home}\isapi\isapi_redirect.properties 文件以配置 ISAPI 重定向器。配置也可以通过注册表设置完成——见下文。此文件的内容应为:
    extension_uri=/jakarta/isapi_redirect.dll
    log_file=C:\Program Files\Apache Software Foundation\Tomcat 9.0\isapi\isapi_redirect.log
    log_level=info
    worker_file=C:\Program Files\Apache Software Foundation\Tomcat 9.0\isapi\workers.properties
    worker_mount_file=C:\Program Files\Apache Software Foundation\Tomcat 9.0\isapi\uriworkermap.properties
    
    请注意,以防 Windows 为文件添加 .txt 扩展名。
  6. 创建 ${tomcat_home}\isapi\workers.properties 文件以配置请求将被传递到的 Tomcat 实例。对于本地机器上的单个 Tomcat 实例,此文件的内容应为:
    worker.list=tomcat01
    worker.tomcat01.type=ajp13
    worker.tomcat01.host=localhost
    worker.tomcat01.port=8009
    
  7. 创建 ${tomcat_home}\isapi\uriworkermap.properties 文件以配置哪些请求将被传递到 Tomcat。为了公开示例 Web 应用程序,此文件的内容应为:
    /examples/*=tomcat01
    
  8. 使用 IIS 管理控制台,向您的 IIS 网站添加一个新的虚拟目录。在全新安装中,这将是“默认网站”。虚拟目录的名称必须是 jakarta。其物理路径应为您放置 isapi_redirect.dll 的目录。
  9. 在管理控制台中选择新创建的虚拟目录,然后双击“处理程序映射”。选择(当前禁用的)ISAPI-dll 条目,然后在操作窗格中点击“编辑功能权限”。在弹出的对话框中,选择“执行”,以便所有三个权限都被选中。点击“确定”后,ISAPI-dll 应处于已启用状态。
  10. 再次使用 IIS 管理控制台,将 ISAPI 重定向器添加为您的网站的过滤器。选择您的网站,然后双击“ISAPI 筛选器”。从操作窗格中,点击“添加...”。过滤器名称使用 tomcat,可执行文件应为 isapi_redirect.dll 的完整路径。配置完成后,点击“确定”
  11. 仍使用 IIS 管理控制台,将 ISAPI 重定向器配置为允许。选择您的服务器(而不是网站),然后双击“ISAPI 和 CGI 限制”。从操作窗格中,点击“添加...”。选择 isapi_redirect.dll,添加描述(例如 tomcat),然后选择“允许扩展路径执行”,然后点击“确定”
  12. 重启 IIS(停止 + 启动 IIS 服务)。

就这样,您现在应该启动 Tomcat 并让 IIS 为您提供 /examples 上下文。例如,尝试访问 http://localhost/examples/ 并执行一些 Servlet 或 JSP 示例。

如果这未能成功运行,请参阅下面的“故障排除”部分以获取纠正问题的帮助。

IIS 日志记录

如果 IIS 访问日志显示诸如 /jakarta/isapi_redirect.dll 而不是 /examples/servlets 的条目,则可以通过 IIS 管理控制台进行更正。选择您的服务器(而不是网站),然后双击“模块”。在“操作”窗格中,点击“查看有序列表...”,选择 IsapiFilterModule 并将其上移,直到它位于 HttpLoggingModule 之上。

注册表配置

作为使用 isapi_redirector.properties 文件的替代方案,ISAPI 重定向器可以通过注册表进行配置。为此,请按照以下步骤操作:

  1. 在注册表中,创建一个名为 "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0" 的新注册表项。
  2. 添加一个名为 extension_uri 的字符串值,其值为 /jakarta/isapi_redirect.dll
  3. 添加一个名为 log_file 的字符串值,其值指向您希望日志文件所在的位置(例如 c:\tomcat\logs\isapi.log)。
  4. 添加一个名为 log_level 的字符串值,其值为您的日志级别(可以是 debug、info、error 或 emerg)。
  5. 添加一个名为 worker_file 的字符串值,其值为您的 workers.properties 文件的完整路径(例如 c:\tomcat\conf\workers.properties)。
  6. 添加一个名为 worker_mount_file 的字符串值,其值为您的 uriworkermap.properties 文件的完整路径(例如 c:\tomcat\conf\uriworkermap.properties)。

64 位注意事项

在 64 位环境中,IIS 应用程序池的“启用 32 位应用程序”应设置为“False”。要检查此项,请在 IIS 管理控制台中选择“应用程序池”,然后右键单击您正在使用的池并选择“设置应用程序池默认值...”“启用 32 位应用程序”可在“常规”部分找到。如果此项配置不正确,则不会调用重定向器,IIS 将返回 HTTP 404 错误代码。

在 64 位操作系统上,您必须使用 64 位版本的 ISAPI 重定向器。如果您尝试使用 32 位版本,则每个请求都将收到 HTTP 500 错误代码,因为该库无法加载到 64 位 IIS 中。

添加额外的上下文

examples 上下文对于验证您的安装很有用,但您还需要添加自己的上下文。添加新上下文需要两个操作:

  1. 将上下文添加到 Tomcat(此处不讨论)。
  2. 将上下文添加到 ISAPI 重定向器。

将上下文添加到 ISAPI 重定向器很简单,您只需编辑 uriworkermap.properties 并添加一行类似如下的内容:

/context/*=worker_name

Worker 及其名称在 workers.properties 中定义。例如,如果您想添加一个名为“shop”的上下文,并由名为“tomcat01”的 Worker 提供服务,那么您应该添加到 uriworkermap.properties 中的行将是:

/shop/*=tomcat01
保存 uriworkermap.properties 后,重启 IIS,它将提供新的上下文。

以上应该是 IIS 将对应于 Tomcat 上下文 (webapp) 的任何 URI 的任何请求传递给 Tomcat 所需的全部内容。

高级上下文配置

如果您的网站非常繁忙(每秒超过 100 个请求,或超过 100 个同时客户端连接),有时可能希望 IIS 直接提供静态内容(html、gif、jpeg 等),即使这些文件是 Tomcat 提供服务的上下文的一部分。允许 IIS 直接提供此类文件可以避免通过重定向器将请求传递给 Tomcat 的少量开销,并且可以通过仅使用 Tomcat 处理只有 Tomcat 才能处理的请求(例如,对 JSP 页面和 Java Servlet 的请求)来稍微释放 Tomcat 的负担。

例如,考虑 examples 上下文中的 html 和 gif 文件:您可以直接使用 IIS 提供这些文件;没有必要从 Tomcat 进程中提供它们。

然而,在实现以下配置方式时应非常小心,因为这样做实际上是为 IIS 提供了一个“后门”,允许它在 Tomcat 不知情的情况下提供 Tomcat 上下文中的文件,从而绕过 Tomcat 本身和 Tomcat 上下文 (webapp) 可能对这些文件施加的任何安全限制。

使 IIS 提供作为 Tomcat 上下文一部分的静态文件需要以下操作:

  1. 配置 IIS 以了解 Tomcat 上下文
  2. 配置重定向器将静态文件留给 IIS

将 Tomcat 上下文添加到 IIS 需要添加一个新的 IIS 虚拟目录,该目录覆盖 Tomcat 上下文。例如,添加一个覆盖 c:\tomcat\webapps\examples 目录的 /example IIS 虚拟目录。

配置重定向器有些困难,您需要指定您希望 Tomcat 处理的精确 URL 路径模式(通常只有 JSP 文件和 Servlet)。这需要对 uriworkermap.properties 进行更改:

For the examples context it requires to replace the following line
/examples/*=tomcat01
with the following two lines
/examples/*.jsp=tomcat01
/examples/servlet/*=tomcat01

如您所见,第二种配置更明确,它实际上指示重定向器仅重定向对 /examples/servlet/ 下资源和 /examples/ 下名称以 .jsp 结尾的资源的请求。

您甚至可以更明确地提供以下行:

/example/servlets/chat=tomcat01

这指示重定向器将所有 URL 路径与前导字符串“/example/servlets/chat”匹配的请求重定向到名为 tomcat01 的 Worker。

保护您的 Tomcat 上下文内容

再次提醒,请注意,通过允许 IIS 直接访问您的 Tomcat 上下文内容,您可能会绕过 Tomcat 对该内容的保护。因此,如果需要,您应确保通过使用相应的 IIS 管理控制台功能在 IIS 级别保护此内容。

特别是,每个 Servlet 应用程序(上下文)都有一个名为 WEB-INF 的特殊目录,其中包含敏感的配置数据和 Java 类,并且应始终对 Web 用户隐藏。使用 IIS 管理控制台可以保护 WEB-INF 目录免受用户访问,但考虑到这是一项普遍要求,并且考虑到在 IIS 级别很容易忘记实施此保护,ISAPI 重定向器插件会自动为您完成此操作,它将拒绝其 URL 路径中包含 WEB-INF 的任何请求。它还将拒绝其 URL 路径中包含 META-INF 的任何请求。

高级 Worker 配置

有时,您可能希望使用不同的 Tomcat 进程来提供不同的上下文(例如,将负载分散到不同的机器上)。要实现此目标,您需要定义多个 Worker 并将每个上下文分配给其自己的 Worker。

定义额外的 Worker 在 workers.properties 文件中完成。此文件包含两种类型的条目:

# An entry that lists all the workers defined
worker.list=worker1, worker2
# Entries that define the host and port associated with each of these workers
worker.worker1.host=localhost
worker.worker1.port=8009
worker.worker1.type=ajp13
worker.worker2.host=otherhost
worker.worker2.port=8009
worker.worker2.type=ajp13

上述示例定义了两个 Worker,现在我们可以使用这些 Worker 来提供两个不同的上下文,每个上下文都有自己的 Worker:

example uriworkermap.properties fragment
/examples/*=worker1
/webpages/*=worker2

如您所见,examples 上下文由 worker1 提供服务,而 webpages 上下文由 worker2 提供服务。

有关 Worker 使用和配置的更多信息,请参见 Worker 操作指南worker.properties 配置参考

构建 ISAPI 重定向器

要构建 ISAPI 重定向器,您将需要 Mladen 的自定义 Microsoft 编译器。本文档的其余部分假设其已安装到 c:\cmsc。

构建 ISAPI 重定向器的步骤如下:

  • 将源代码下载为 zip 文件并解压。
  • 切换到 ISAPI 重定向器源代码目录。
  • c:\cmsc\setenv.bat x86
    nmake -f Makefile.vc
    c:\cmsc\setenv.bat x64
    nmake -f Makefile.vc
    

生成的文件 isapi_redirect.dll(以及调试符号文件 isapi_redirect.pdb)位于“x86_RELEASE”或“x64_RELEASE”子目录中。

故障排除

ISAPI 重定向器在您首次尝试安装时很容易不工作。

如果发生这种情况,以下是一些您可以尝试纠正问题的步骤。

这些步骤不能保证涵盖所有可能的问题,但它们应该有助于发现常见的错误。

如果您在这些步骤中进行了任何更正,请按照安装的最后一步所述重启 IIS 服务,然后重试该步骤。

注意:这些步骤基于安装说明中使用的配置,该配置将对 examples Web 应用程序的请求代理到一个单个 Tomcat 实例。同时假设如果您直接访问 Tomcat,“/examples”上下文能正常工作。

诊断步骤

如果存在 ISAPI 重定向器日志文件,请删除(或移至其他位置)它。

启动 IIS 服务和 Tomcat。

检查指定位置是否存在 ISAPI 重定向器日志文件。如果未找到,则表明 ISAPI 重定向器未正确启动。这通常是由不正确的配置设置引起的。

  • 根据安装说明仔细检查您的配置,特别是 ${tomcat_home}\isapi\isapi_redirect.properties 文件的位置、名称和内容。
  • 如果使用基于注册表的配置,请检查注册表项的路径、名称和值。注册表名称不区分大小写。
  • 检查为日志文件指定的目录是否存在,并且文件权限已按照安装说明进行配置。
如果上述设置正确,ISAPI 重定向器应该能够创建日志文件。

在浏览器中调用 URL http://localhost/examples/。URL 中大小写很重要。URL 中“localhost”后面的字符必须是小写。如果页面未出现,请停止 IIS 服务(需要查看 IIS 日志文件)。然后检查位于 C:\inetpub\logs\LogFiles\W3SVC1 的 IIS 日志文件中的最后一行。

如果最后一行包含

GET "/examples/ HTTP/1.1" 404
则 ISAPI 重定向器未识别出它应该处理对“/examples”上下文的请求。

如果最后一行包含类似以下内容:

GET "/jakarta/isapi_redirect.dll HTTP1.1"
则 ISAPI 重定向器识别出它应该处理该请求,但未能成功让 Tomcat 提供请求服务。

检查以下内容:

  • 根据安装说明仔细检查您的配置,特别是虚拟目录的名称以及 ${tomcat_home}\isapi\uriworkermap.properties${tomcat_home}\isapi\workers.properties 文件的位置、名称和内容。
  • 如果这些设置正确,ISAPI 重定向器应该能够识别出它应该处理对“/examples”上下文的请求。

如果浏览器显示 503 错误页面,则表示 ISAPI 重定向器已识别出应处理该请求,但未及时收到来自 Tomcat 的响应。请检查以下内容:

  • 根据安装说明仔细检查您的配置,特别是 ${tomcat_home}\isapi\workers.properties 文件的位置、名称和内容。
  • 检查 Tomcat 中的 AJP 连接器配置是否与 ${tomcat_home}\isapi\workers.properties 文件中的配置匹配。

如果浏览器显示 500 错误页面,则表示在尝试提供请求时 IIS 或 ISAPI 重定向器内部发生了错误。页面顶部应有错误的文本描述,页面末尾应有一个 8 位十六进制错误代码。最后四位应是与问题相关的标准 Windows 错误代码。

500 错误的一个常见原因是 Windows 创建了带有隐藏“.txt”文件扩展名的配置文件,这些文件在 Windows 资源管理器中不显示。即使其他文件显示文件扩展名,也要仔细检查以确保 Windows 资源管理器配置为显示所有文件的文件扩展名。

如果错误消息是“对 ISAPI 过滤器 ‘...isapi_redirect.dll’ 调用 GetFilterVersion 失败”,并且代码是 0x8007047e,则该代码转换为错误代码 0x047e 或 1150,即“指定的程序需要更高版本的 Windows”。这些共同表明 ISAPI 重定向器的初始化失败,因为无法读取配置——无论是从 ${tomcat_home}\isapi\isapi_redirect.properties 还是从注册表。请根据需要检查 ${tomcat_home}\isapi\isapi_redirect.properties 文件的名称、位置和内容或注册表项。

如果上述设置正确,index.html 页面应显示在您的浏览器中。您也应该能够点击链接执行一些 Servlet 或 JSP 示例。