Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring-boot fronted with Apache and AJP

There are a lot of documents out there explaining that you should use various other things (including simple proxying) but AJP is flexible and fast, and it really helps me integrate our SAML2 SSO without any of the webapps having to worry about any of that.

I am now trying to get a spring-boot application working the same way and having a really terrible time of it. The main symptom is "Bad Gateway" with error messages like:

[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

The last one seemed like a clue but I have not been able to find it.

The spring boot manual seems to suggest that if you only have a single connection you can set it up in application.properties - this is what I would ideally like to do, but I haven't been able to find any examples of this. From a distribution point of view, though, this seems ideal - publish a jar, give the user a documented properties file.

Since that didn't work, I tried doing it programmatically like this:

@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;
}

(I'd really rather not get into having to configure SSL for a localhost connection because it just complicates things, and once you spend time in the unsecured worlds of zookeeper, kafka, etc. you kind of give up after a while and figure your ESB is RFC1918 and firewalled anyway).

My questions are:

1) Can this all really be done with the properties file, and how?

2) With the above hard-coded configuration, I can telnet to port 8092 and issue GET requests ... I'm not sure why I can do this, because these GETs are http and I have configured the protocol to AJP/1.3 so I don't THINK it should work. But is that the problem Apache is having? I can't find any explanation of "wrong message format 0x4854" or error "-11."

--Chris

like image 207
wz2b Avatar asked Apr 05 '15 13:04

wz2b


People also ask

Can Spring Boot run on Apache?

Spring Boot can run as a standalone server, but putting it behind an Apache web server has several advantages, such as load balancing and cluster management. Now with LetsEncrypt it's easier than ever (and free) to secure your site with SSL.

What is Reverse Proxy in Spring Boot?

define: reverse proxy. In computer networks, a reverse proxy is the application that sits in front of back-end applications and forwards client requests to those applications. Reverse proxies help increase scalability, performance, resilience and security.


1 Answers

i had the same problem and resolve it by adding the connector implementation.

for example :

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

list of available implementations : https://tomcat.apache.org/tomcat-8.0-doc/config/ajp.html#Common_Attributes (protocol)

or simply specify the protocol (AJP instead of HTTP):

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

For complete example to dynamically read values from properties file please see https://blog.swdev.ed.ac.uk/2015/06/24/adding-embedded-tomcat-ajp-support-to-a-spring-boot-application/

like image 65
Y.M. Avatar answered Oct 04 '22 03:10

Y.M.