本文介绍了Apache 背后的 Tomcat 使用 ajp 进行 Spring Boot 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用使用嵌入式 Tomcat 的 Spring Boot 应用程序配置 Apache Web 服务器.在 Spring Boot 之前,我曾经创建一个 ajp.conf 文件,如:

I've been trying to configure Apache web server with a Spring Boot app that uses embedded Tomcat. Before Spring Boot I used to create an ajp.conf file like:

<VirtualHost *:80>
   ServerName localhost
   <Proxy *>
      AddDefaultCharset Off
      Order deny,allow
      Allow from all
   </Proxy>

   ProxyPass /app ajp://localhost:8009/app
   ProxyPassReverse /app ajp://localhost:8009/app

 </VirtualHost>

并包含在 httpd.conf 文件中,如

And include in the httpd.conf file like

Include /opt/lampp/apache2/conf/ajp.conf

而在Tomcat的server.xml文件中,我是用来配置监听8009端口的

And in the Tomcat's server.xml file, I used to configure it to listen to port 8009

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" connectionTimeout="5000"

此设置有效.但是,现在使用 Spring Boot,我正在尝试使用嵌入式 tomcat 实现类似的功能.我读了 Spring Boot 文档 在这里并在我的 application.yml 文件中添加了以下属性:

This setup works. But, now with Spring Boot I am trying to achieve something similar with an embedded tomcat. I read Spring Boot Documentation here and added the following propertied on my application.yml file:

server:
    port: 8080
    tomcat:
        remote_ip_header: x-forwarded-for
        protocol_header: x-forwarded-proto

我的 ajp.conf 文件如下所示:

My ajp.conf file looks like so:

<VirtualHost *:80>
   ServerName localhost
   <Proxy *>
      AddDefaultCharset Off
      Order deny,allow
      Allow from all
   </Proxy>

   ProxyPass /app ajp://localhost:8009/
   ProxyPassReverse /app ajp://localhost:8009/

 </VirtualHost>

我的 spring boot tomcat 配置类为

I have my spring boot tomcat configuration class as

@Configuration
public class TomcatConfiguration {

private final Logger log = LoggerFactory.getLogger(TomcatConfiguration.class);

@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
    tomcat.addAdditionalTomcatConnectors(createConnector());
    tomcat.addContextValves(createRemoteIpValves());
    return tomcat;
}

private RemoteIpValve createRemoteIpValves(){
    RemoteIpValve remoteIpValve = new RemoteIpValve();
    remoteIpValve.setRemoteIpHeader("x-forwarded-for");
    remoteIpValve.setProtocolHeader("x-forwarded-protocol");
    return remoteIpValve;
}

private Connector createConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
    connector.setScheme("ajp");
    connector.setProtocol("AJP/1.3");
    connector.setRedirectPort(8443);
    //connector.setSecure(true);
    connector.setPort(8009);
    return connector;
}

在我的 apache 错误日志中,我看到:

On my apache error logs I see:

AH01080: ajp_msg_check_header() got bad signature 4854
[proxy_ajp:error] [pid 24073] AH01031: ajp_ilink_receive() received bad header
[proxy_ajp:error] ajp_read_header: ajp_ilink_receive failed
[proxy_ajp:error] (120007)APR does not understand this error code: [client xx.xx.xx.xx:60916] AH00878: read response failed from (null) (*)

不知道这里发生了什么.我在网上搜索了很多,但找不到关于如何使用 Spring Boot 应用程序在 apache 后面服务 tomcat 的好的文档.最后,我也想对多个 tomcat 实例进行负载均衡.

Not sure what's going on here. I searched a lot online, but could not find a good documentation on how to serve tomcat behind apache with spring boot apps. Eventually, I would like to load balance multiple tomcat instances too.

推荐答案

从上面的评论推导出:

@Configuration
public class TomcatAjpConfig {

@Bean
@SuppressWarnings("static-method")
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
    tomcat.addAdditionalTomcatConnectors(createConnector());
    tomcat.addContextValves(createRemoteIpValves());
    return tomcat;
}

private static RemoteIpValve createRemoteIpValves() {
    RemoteIpValve remoteIpValve = new RemoteIpValve();
    remoteIpValve.setRemoteIpHeader("x-forwarded-for");
    remoteIpValve.setProtocolHeader("x-forwarded-proto");
    return remoteIpValve;
}

private static Connector createConnector() {
    Connector connector = new Connector("AJP/1.3");
    connector.setPort(8009);
    return connector;
}

}

这篇关于Apache 背后的 Tomcat 使用 ajp 进行 Spring Boot 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 19:48
查看更多