- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
Apereo CAS 默认以嵌入式 Apache Tomcat 作为 Servlet 容器运行,而 Apache Portable Runtime(APR)为 Tomcat 提供原生级 socket 处理、OpenSSL 支持与更高并发吞吐能力。本文围绕 CAS 嵌入式 Tomcat 的 APR 启用方式展开,结合仓库中cas-server-webapp-init-tomcat模块的源码实现,讲解 JVM 启动参数、原生库加载、连接器协议选择及配套的 HTTP/AJP/HTTP2 调优配置,帮助你为生产环境部署出高性能的 CAS 登录服务。
1. 背景:CAS 的嵌入式 Tomcat 容器
CAS 的 Web 应用默认采用"嵌入式容器"模式,即不需要单独安装外部 Tomcat,而是把 Tomcat 作为依赖直接嵌入到 Spring Boot 应用中。这一能力由webapp/cas-server-webapp-init-tomcat模块提供,其核心装配入口是 CasEmbeddedContainerTomcatConfiguration.java,该配置类在类路径存在 Tomcat 且功能开关ApacheTomcat开启时生效(@ConditionalOnClass({Tomcat.class, Http2Protocol.class})与@ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.ApacheTomcat)),并注册两个关键 Bean:
CasTomcatServletWebServerFactory:继承 Spring Boot 的TomcatServletWebServerFactory,负责构建 Tomcat 实例,同时在 postProcessContext 中关闭热加载(setReloadable(false))、启用资源缓存,并可按需注入会话集群复制(SimpleTcpCluster)能力;CasTomcatServletWebServerFactoryCustomizer:负责在容器启动前对连接器(Connector)、Valve、安全约束等做统一定制,具体逻辑见 CasTomcatServletWebServerFactoryCustomizer.java 的customize方法:依次配置 AJP、HTTP 端口、HTTP 代理、扩展访问日志、Rewrite Valve、SSL Valve、Basic 认证、Remote-User Valve 与错误页 Valve。
因此,任何针对嵌入式 Tomcat 的底层优化——包括启用 APR——都发生在这个模块之上,相关的可配置项统一收敛在cas.server.tomcat.*属性前缀下(对应配置模型类 CasEmbeddedApacheTomcatProperties.java)。
2. 什么是 APR,CAS 为什么要用它
Apache Portable Runtime(APR)是 Apache 软件基金会提供的一套跨平台原生运行时库。Apache Tomcat 在默认的 Java 纯网络栈(NIO/NIO2)之外,还提供了一条基于 APR 的通道:当 Tomcat 通过tomcat-native(又称 tcnative)库加载 APR 后,即可获得:
- 原生 socket 与内存池:底层网络 I/O 由 C 实现,减少 JVM 到 OS 之间的拷贝与对象开销,在大并发连接场景下表现更好;
- 更好的可扩展性(scalability):APR 连接器能够更高效地支撑大量并发长连接;
- 与原生服务器技术更紧密的集成:例如基于 OpenSSL 的 TLS/SSL 处理、对 Unix 域套接字等平台能力的利用,便于与 Apache httpd、Nginx 等原生服务器保持一致的运维生态。
需要说明:以上收益属于 Tomcat 官方对 APR 的通用定位(原文即强调 APR 带来"superior scalability, performance, and better integration with native server technologies")。具体性能收益与部署环境、连接模式强相关,应以自身压测数据为准,不宜一概而论。
对 CAS 而言,嵌入式 Tomcat 同样遵循这一机制:只要在 JVM 启动时正确指定 APR 原生库的加载路径,容器在初始化阶段就会自动完成 APR 的探测与装载,连接器即可选用 APR 协议实现。
3. 启用 APR 的最小配置:JVM 系统属性
启用 APR 的关键一步,是告诉 JVM 去哪里寻找 APR 库的二进制文件(即tomcat-native编译产物,包含libtcnative.so/libtcnative.dylib/tcnative-1.dll等)。需要设置如下 JVM 系统属性:
-Djava.library.path=/path/to/tomcat-native/lib其中/path/to/tomcat-native/lib应替换为实际安装路径。文档给出的典型示例路径为 macOS 下通过 Homebrew 安装的目录:
-Djava.library.path=/usr/local/opt/tomcat-native/lib3.1 在常见启动方式中注入该属性
不同部署方式注入 JVM 属性的位置不同,以下是几种典型场景:
场景一:使用 CAS 的bin启动脚本或catalina.sh风格脚本
在启动脚本中显式加入:
JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/opt/tomcat-native/lib"场景二:Spring Boot 打包的 fat-jar 直接启动
java -Djava.library.path=/usr/local/opt/tomcat-native/lib -jar cas.war场景三:容器化部署(Docker/Kubernetes)
在镜像或 Pod 的 JVM 环境变量中配置(不同镜像对 JVM 参数注入方式不同,常见为JAVA_OPTS或JAVA_TOOL_OPTIONS):
JAVA_TOOL_OPTIONS="-Djava.library.path=/usr/local/opt/tomcat-native/lib"3.2 前置条件:原生库本身必须存在
设置属性只是"告诉 JVM 去哪找",前提是环境中确实安装了tomcat-native。通常需要通过操作系统的包管理器或源码编译安装,例如:
- Debian/Ubuntu:
apt-get install libtcnative-1 - macOS(Homebrew):
brew install tomcat-native - 源码编译:从 Tomcat 发布页获取
tomcat-native源码,通过configure && make && make install生成并安装到目标lib目录
安装完成后,可通过-Xlog(JDK9+)或-verbose:jni观察 JVM 是否成功加载了tcnative库。若库缺失或路径错误,Tomcat 通常会回退到纯 Java 实现并在日志中给出 APR 不可用的提示,服务本身仍可启动,但 APR 特性不会生效——这一点在排错时需要特别留意。
4. 源码视角:连接器协议如何与 APR 衔接
APR 是否真正生效,最终取决于连接器(Connector)使用的协议处理器。在 CAS 嵌入式 Tomcat 中,连接器由 CasTomcatServletWebServerFactoryCustomizer.configureHttp 创建,其核心代码为:
val connector = new Connector(http.getProtocol());也就是说,CAS 把配置属性cas.server.tomcat.http[].protocol的值直接当作 Tomcat 协议处理器类名传入Connector构造器。配置模型类 CasEmbeddedApacheTomcatHttpProperties.java 中该字段的默认值是:
private String protocol = "org.apache.coyote.http11.Http11NioProtocol";即默认走 Java NIO 实现。这意味着:
- 若希望使用 APR 协议,可以将该属性覆盖为 Tomcat 提供的 APR 协议处理器类名(如
org.apache.coyote.http11.Http11AprProtocol); - 由于协议名是以字符串形式注入的,任何 Tomcat 支持的协议类都可以在此启用,这为运维方保留了充分的灵活性。
4.1 CAS 已支持的协议族(源码可证)
从 CasTomcatServletWebServerFactoryCustomizer.java 的configureConnectorForProtocol方法可以看到,CAS 在 HTTP 反向代理场景下原生支持以下协议选择:
| 配置值 | 实际使用的协议处理器 |
|---|---|
HTTP/1.1 | org.apache.coyote.http11.Http11NioProtocol(NIO) |
HTTP/1.2 | org.apache.coyote.http11.Http11Nio2Protocol(NIO2) |
HTTP/2 | 在连接器上附加Http2Protocol升级协议 |
AJP/2 | org.apache.coyote.ajp.AjpNio2Protocol |
| 其他(默认) | org.apache.coyote.ajp.AjpNioProtocol |
而configureHttp还会无条件为每个 HTTP 连接器附加Http2Protocol升级支持(见 源码 L229-L230),这解释了为何 CAS 默认即具备 HTTP/2 over TLS 的升级能力。
当启用 APR 时,协议选择与上述 NIO 家族是平行关系:APR 使用 Tomcat 的AprProtocol实现族(如Http11AprProtocol)。从代码结构看,CAS 的协议选择机制是"字符串直通",因此将protocol属性设置为 APR 类名即可让连接器走 APR 通道,这与默认 NIO 的实现路径保持一致。
5. 与 APR 配套的连接器与 Socket 调优
APR 连接器对底层 socket 参数非常敏感,CAS 为此提供了细粒度的配置。在 CasTomcatServletWebServerFactoryCustomizer.finalizeConnectors 中,以下属性会被写入连接器:
配置项(cas.server.tomcat.socket.*) | 对应 Connector 属性 | 说明 |
|---|---|---|
bufferPool | socket.bufferPool | socket 缓冲区池大小 |
appReadBufSize | socket.appReadBufSize | 应用层读缓冲区 |
appWriteBufSize | socket.appWriteBufSize | 应用层写缓冲区 |
performanceBandwidth | socket.performanceBandwidth | 带宽优化模式 |
performanceConnectionTime | socket.performanceConnectionTime | 连接时间优化模式 |
performanceLatency | socket.performanceLatency | 延迟优化模式 |
源码注释明确说明:NIO 与 NIO2 实现支持这些 Java TCP socket 属性(见 CasEmbeddedApacheTomcatProperties.java)。在启用 APR 后,这些参数同样适用于原生 socket 层面的调优。
一个完整的application.properties/cas.properties示例(注意协议类名按需替换为 APR 实现):
# ---- 嵌入式 Tomcat 基础 ---- cas.server.tomcat.server-name=Apereo CAS # ---- 附加 HTTP 连接器(默认 NIO,可按需改为 APR 协议类名)---- cas.server.tomcat.http[0].enabled=true cas.server.tomcat.http[0].port=8080 cas.server.tomcat.http[0].protocol=org.apache.coyote.http11.Http11NioProtocol cas.server.tomcat.http[0].scheme=http cas.server.tomcat.http[0].secure=false cas.server.tomcat.http[0].redirect-port=8443 # ---- Socket 调优 ---- cas.server.tomcat.socket.buffer-pool=100 cas.server.tomcat.socket.app-read-buf-size=1024 cas.server.tomcat.socket.app-write-buf-size=1024 cas.server.tomcat.socket.performance-bandwidth=0 cas.server.tomcat.socket.performance-connection-time=0 cas.server.tomcat.socket.performance-latency=0说明:属性名遵循 CAS 的松散绑定(relaxed binding)规则,
redirectPort、bufferPool等驼峰写法与redirect-port、buffer-pool等价。
5.1 更多连接器维度(AJP / 代理 / SSL Valve)
APR 往往与生产环境的代理架构配合使用,CAS 的嵌入式容器还提供以下相关开关(均由同一个 Customizer 驱动):
- AJP 连接器:
cas.server.tomcat.ajp.enabled=true、cas.server.tomcat.ajp.port=8009、cas.server.tomcat.ajp.secret=...,支持与 Apache httpd 的mod_proxy_ajp对接。代码见 configureAjp。 - HTTP 反向代理:
cas.server.tomcat.httpProxy.enabled=true及scheme、proxyPort、redirectPort、protocol等,用于在 CAS 自身不做 SSL 终止、由前端代理承担 TLS 的场景下校正连接器元数据。 - SSL Valve:
cas.server.tomcat.sslValve.enabled=true,用于从代理转发头中提取客户端证书与加密信息,详细配置可参考同目录文档 Servlet-Container-Embedded-Tomcat-SslValve.md。 - Basic 认证、Rewrite Valve、Remote-User Valve、扩展访问日志:分别对应
cas.server.tomcat.basicAuthn.*、rewriteValve.*、remoteUserValve.*、extAccessLog.*,均在 Customizer 的customize流程中按条件装配。
6. 验证 APR 是否生效
容器启动后,可通过以下方式确认 APR 通道是否真正启用:
- 观察启动日志:Tomcat 初始化 APR 时,
AprLifecycleListener会输出加载tcnative库的信息;若 APR 可用,连接器初始化日志中会出现 APR 协议相关条目;若不可用,日志会提示 APR 库缺失并回退到 Java 实现。 - 查看连接器协议:通过 Tomcat 的 JMX 或管理接口查看 Connector 的
protocolHandlerClassName,应为 APR 协议实现类而非 NIO 类。 - 检查 JVM 属性:确认启动命令中确实包含了
-Djava.library.path,且路径下的原生库文件存在、权限可读、位数与 JVM 匹配(32/64 位不一致会导致加载失败)。
仓库中的 CasTomcatServletWebServerFactoryCustomizerTests.java 展示了如何以 Spring Boot 测试方式驱动 Customizer 对连接器的定制流程(execCustomize会真实执行customize并断言不抛异常),可作为自行编写容器调优回归测试的参考模板。
7. 常见问题与注意事项
- 库路径与架构不匹配:
java.library.path中的原生库必须是当前 JVM 架构(x86_64/aarch64)与位数的对应版本,否则 JNI 加载会失败。 - 属性仅影响"查找路径":
-Djava.library.path只是定位库文件;APR 特性的最终生效还取决于连接器协议是否选择了 APR 实现。建议同时完成第 3 节(JVM 属性)与第 4 节(协议类名)两步。 - 与 HTTP/2 的关系:CAS 会默认附加
Http2Protocol升级;在启用 APR 的场景下,HTTP/2 的协商仍遵循 Tomcat 的既有机制,需确认所用 Tomcat 版本对 APR 与 HTTP/2 组合的支持情况。 - SSL 终止位置:若由前端代理(如 Apache httpd、Nginx、HAProxy)承担 TLS,CAS 侧无需重复配置证书,但应配合
httpProxy或 SSL Valve 让 CAS 正确识别协议与客户端信息,避免跳转或审计信息失真(相关背景可参见 Troubleshooting-Guide.md 中关于代理后部署的说明)。
8. 小结
CAS 的嵌入式 Tomcat 容器为生产调优预留了完整的扩展点:通过-Djava.library.path指定 APR 原生库路径、通过cas.server.tomcat.http[].protocol切换连接器协议、通过cas.server.tomcat.socket.*调优底层 socket 参数,三者配合即可让 CAS 的登录服务跑在原生级网络通道上。实际收益与部署形态强相关,建议在启用前后做同环境压测对比,用数据决定是否在生产环境全面切换到 APR。相关实现细节可继续阅读 CasTomcatServletWebServerFactoryCustomizer.java 与配置模型 CasEmbeddedApacheTomcatProperties.java 深入理解。
- 后端
- 认证鉴权
- 单点登录
【免费下载链接】cas
Apereo CAS - Identity & Single Sign On for all earthlings and beyond.
相关推荐
Apereo CAS 嵌入式 Tomcat HTTP 连接器与代理模式配置指南
Apereo CAS 嵌入式 Tomcat HTTP 连接器与代理模式配置指南 导读 Apereo CAS 默认以内嵌的 Apache Tomcat 作为 Se
后端认证鉴权单点登录Apereo CAS 嵌入式 Tomcat 容器 Rewrite Valve(URL 重写)配置指南
Apereo CAS 嵌入式 Tomcat 容器 Rewrite Valve(URL 重写)配置指南 导读 本文聚焦 Apereo CAS 内嵌 Apache
后端认证鉴权单点登录Apereo CAS 嵌入式 Servlet 容器配置指南:从零启动嵌入式 Tomcat/Jetty 并深入源码
Apereo CAS 嵌入式 Servlet 容器配置指南:从零启动嵌入式 Tomcat/Jetty 并深入源码 CAS 本身自带多个嵌入式 Servlet 容
后端认证鉴权单点登录
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考