spring-以 Apache 和 AJP 为前端的启动

spring-boot fronted with Apache and AJP

有很多文档说明您应该使用各种其他东西(包括简单的代理),但 AJP 灵活且快速,它确实帮助我集成了我们的 SAML2 SSO,而无需担心任何网络应用程序关于这些。

我现在正试图让一个 spring-boot 应用程序以同样的方式工作,但它真的很糟糕。主要症状是 "Bad Gateway",错误消息如下:

[error] ajp_get_reply::jk_ajp_common.c (2126): (boot_worker_1) Tomcat is down or refused connection. No response has been sent to the client (yet)

[info] ajp_service::jk_ajp_common.c (2623): (boot_worker_1) sending request to tomcat failed (recoverable), because of protocol error (attempt=1)

[error] ajp_connection_tcp_get_message::jk_ajp_common.c (1289): wrong message format 0x4854 from 127.0.0.1:8092

最后一个好像有点线索,但一直找不到。

spring 引导手册似乎建议如果你只有一个连接,你可以在 application.properties 中设置它 - 这是我最想做的,但我没有'找不到这方面的任何例子。不过,从分发的角度来看,这似乎很理想——发布一个 jar,为用户提供一个文档化的属性文件。

由于这不起作用,我尝试像这样以编程方式进行:

@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
    Connector ajpConnector = new Connector();
    ajpConnector.setProtocol("AJP/1.3");
    ajpConnector.setPort(8092);
    ajpConnector.setSecure(false);
    ajpConnector.setAllowTrace(false);
    ajpConnector.setScheme("http");
    tomcat.addAdditionalTomcatConnectors(ajpConnector);
    return tomcat;
}

(我真的不想为本地主机连接配置 SSL,因为它只会让事情变得复杂,一旦你花时间在 zookeeper、kafka 等不安全的世界中,你就会放弃一段时间后发现您的 ESB 是 RFC1918 并且有防火墙)。

我的问题是:

1) 这一切真的可以用属性文件完成吗?如何做?

2) 通过上面的硬编码配置,我可以远程登录到端口 8092 并发出 GET 请求......我不确定为什么我可以这样做,因为这些 GET 是 http 并且我已经配置了协议到 AJP/1.3 所以我不认为它应该工作。但这是 Apache 遇到的问题吗?我找不到 "wrong message format 0x4854" 或错误“-11”的任何解释。“

--克里斯

我遇到了同样的问题并通过添加连接器实现解决了它。

例如:

Connector ajpConnector = new Connector("org.apache.coyote.ajp.AjpNioProtocol");

可用实现列表: https://tomcat.apache.org/tomcat-8.0-doc/config/ajp.html#Common_Attributes (协议)

或仅指定协议(AJP 而不是 HTTP):

Connector ajpConnector = new Connector("AJP/1.3");

有关从属性文件动态读取值的完整示例,请参阅 https://blog.swdev.ed.ac.uk/2015/06/24/adding-embedded-tomcat-ajp-support-to-a-spring-boot-application/