LoginSignup
2
5

More than 3 years have passed since last update.

Apache httpd + Spring Boot

Posted at

はじめに

Apache httpdとSpring Boot (Tomcat)連携のための設定、必要なクラスなどのメモ。

バージョン

Apache httpd 2.4.39

$ /usr/local/bin/apachectl -v
Server version: Apache/2.4.39 (Unix)
Server built:   Apr 19 2019 17:53:55

Spring Boot v2.1.6.RELEASE

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

AjpによるApache httpdとTomcatの連携

httpd.conf

LoadModule proxy_module lib/httpd/modules/mod_proxy.so
LoadModule proxy_ajp_module lib/httpd/modules/mod_proxy_ajp.so

 <IfModule proxy_ajp_module>
 Include /usr/local/etc/httpd/extra/httpd-proxy.conf
 </IfModule>

LoadModule unique_id_module lib/httpd/modules/mod_unique_id.so

<IfModule unique_id_module>
 RequestHeader set unique_id %{UNIQUE_ID}e
 </IfModule>

unique_id_moduleはリクエストを識別するIDを生成する。これをHTTPヘッダunique_idで共有。

httpd-proxy.conf

<Location /api/>
    ProxyPass ajp://XXXXX:8090/
    ProxyPassReverse ajp://XXXXX:8090/
</Location>

Tomcat Ajp設定

TomcatCustomizer.java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class TomcatCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Value("${tomcat.ajp.port:0}")
    private int ajpPort;

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        if (ajpPort != 0) {
            factory.setProtocol("AJP/1.3");
            factory.setPort(ajpPort);
        }
    }
}

SLF4J MDC設定

Apache httpdからHTTPヘッダで渡されたリクエストIDをMDCに格納。
もしなければ、代わりにランダムな文字列を生成する。

MdcConfig.java
import java.util.Base64;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.MDC;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

@Configuration
public class MdcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptorAdapter() {
            private Random random = new Random();
            private static final String MDC_KEY_REQUEST_ID = "request_id";
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                    throws Exception {
                String requestId = request.getHeader("unique_id");
                if (requestId == null) {
                    requestId = generateRequestId();
                }
                MDC.put(MDC_KEY_REQUEST_ID, requestId);
                return true;
            }

            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                    ModelAndView modelAndView) throws Exception {
                MDC.remove(MDC_KEY_REQUEST_ID);
            }

            private String generateRequestId() {
                byte[] bytes = new byte[18];
                random.nextBytes(bytes);
                return Base64.getEncoder().encodeToString(bytes);
            }
        }).addPathPatterns("/*");
    }
}

リクエストIDをログに含めるため、ログメッセージパターンに%X{request_id}を指定する。

logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE logback>

<configuration>

    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <appender name="MDC" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
        <pattern>%date{yyMMdd HH:mm:ss.SSS},%X{request_id},%m%n</pattern>
      </encoder>
    </appender>

    <logger name="MDC" level="INFO">
        <appender-ref ref="MDC" />
    </logger>

</configuration>

Apache httpdアクセスログに含めるには、%{unique_id}e

httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{unique_id}e\"" combined
CustomLog "/usr/local/var/log/httpd/access_log" combined
2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5