하나의 WAS로 정적 콘텐츠를 전달하고 동적인 기능도 제공하게 만들면 매우 간단한 애플리케이션을 빠르게 만들 수 있다.
이 생각이 과연 옳은가?
어느정도 규모의 서비스들은 프런트엔드를 위한 웹 서버를 따로 제공한다. 이는 프런트엔드와 백엔드를 분리하는 시작점이 된다.
웹 서버를 통해 로드 밸런싱도 할 수 있고, 정적 콘텐츠를 매우 빠르게 전달할 수 있으며 웹 서버에 SSL 인증서를 설치하여 적용하면 매우 쉬운 보안 구성이 진행된다. 또 웹 서버가 제공하는 여러 모듈의 기능도 이용할 수가 있다. 딱 웹서버까지를 DMZ로 사용하는 것이다.
그럼 이제 고민해야 한다. Apache와 Tomcat 간의 어떤 프로토콜을 사용할지 정해야 한다.
- HTTP
- AJP
Apache JServ Protocol은 익숙하지 않다. 이는 웹 서버에서 애플리케이션 서버로 요청을 프락시 하도록 설계된 프로토콜이다.
아 그렇구나 HTTP 요청은 클라이언트의 요청을 받고 그 요정이 동적인 기능이 필요하면 tomcat에 HTTP 요청을 보낸다. 반면 AJP 프로토콜로 통신하게 되면 웹 서버를 프락시 서버로 사용하는구나? 근데 정적 콘텐츠도 제공하면서? 어떤 모듈이 있는지 확인해봐야겠다.
일단 선택하는 방법은 단순성을 위해서라면 HTTP를 선호하고 그렇지 않고 성능 향상을 원하면 AJP를 선호한다.
오늘은 윈도우 운영체제에서 아파치와 내장 톰캣을 통해 연동을 하는 법을 알아보고 내일은 https를 웹 서버에 적용하고 플러터로 간단한 화면을 만들고 ec2에 배포하는 과정을 진행할 것이다.
이 과정에서 웹서버를 사용하지 않고 내장 톰켓으로 웹서버 역할까지 하는 와중에 플러터 코드를 static에 넣고 동작했을 때 spring security가 잘 동작하도록 하는 설정까지 해볼 것이다.
https://www.apachelounge.com/download/#google_vignette
https://opentutorials.org/course/3647/23838
웹 서버 아파치를 설치를 다했구 이제 스프링 부트의 설정을 해줄 차례다.
application.properties
server.port=8080
tomcat.ajp.protocol=AJP/1.3
tomcat.ajp.port=9090
tomcat.ajp.enabled=true
@Configuration
public class AJPConfig {
@Value("${tomcat.ajp.port}")
int ajpPort;
@Value("${tomcat.ajp.enabled}")
boolean ajpEnabled;
@Value("${tomcat.ajp.protocol}")
String ajpProtocol;
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
if (ajpEnabled) {
Connector ajpConnector = new Connector(ajpProtocol);
ajpConnector.setPort(ajpPort);
ajpConnector.setSecure(false);
ajpConnector.setScheme("http");
ajpConnector.setAllowTrace(false);
tomcat.addAdditionalTomcatConnectors(ajpConnector);
((AbstractAjpProtocol<?>)ajpConnector.getProtocolHandler()).setSecretRequired(false);
}
return tomcat;
}
}
작년인가 ajp 프로토콜 취약점이 발견되어 문제가 있었다. 아마 ghostcat이었나.. 그래서 ajp 프로토콜을 사용하는 경우 신뢰할 수 있는 네트워크일 경우만 setSecretRequired 값을 false로 해야 한다.
위 코드는 다른 포트에서 다른 프로토콜을 수신하도록 서블릿 컨테이너를 구성하는 코드입니다.
이제 포트 9090에서 AJP 요청을 수신하고 있는지 확인하러 배포하여 확인해보죠.
이제 확인도 했으니 Apache의 모듈을 확인해서 구성해야 합니다.
Apache가 AJP를 통해 Tomcat과 통신하도록 하려면 몇 가지 옵션이 필요한데 mod_jk 모듈, mod_proxy_ajp 모듈이 있습니다.
우리는 mod_proxy_ajp를 사용해보죠 이는 기존 mod_jk보다 더 쉽게 사용할 수 있도록 최근 추가되었답니다.
LoadModule proxy_mode modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
주석을 제거한 이후 아파치를 재시작해 문제가 없는지 확인해야 합니다.
httpd.config 파일에서 해당 섹션이 있는 곳까지 내려와서 다음 줄을 추가합니다.
<VirtualHost *:80>
serverName localhost
ProxyPass / ajp://localhost:9090/
ProxyPassReverse / ajp://localhost:9090/
</VirtualHost>
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html
위 공식문서를 통해 지시어를 보고 사용해야합니다. 이는 Apache가 80 포트에서 serverName(도메인)에 대한 연결을 수신하도록 지시하는 지시문입니다.
또한 연결을 수신하게 되면 AJP 프로토콜을 통해 포트 9090에서 실행 중인 Spring Boot 웹 앱으로 전달됩니다.
확인을 위해 index.html를 만들어 처리하도록 해야겠습니다.
여기까지 별다른 동작없이 80 요청으로 들어온 클라이언트 요청을 ajp 프로토콜을 통해 tomcat의 9090 포트로 전달하는 프락시 아파치를 구성하였다.
실제 윈도우환경에 서버를 배포하는 돈 많은 회사?는 거의 없기때문에 ec2 인스턴스를 프리티어로 생성해 아파치를 설치하고 https를 구성하는 부분을 알아보자
'Spring|Spring-boot' 카테고리의 다른 글
스프링 부트란? (0) | 2023.01.21 |
---|---|
도메인간 바운디드 컨텍스트 강결합의 대책 "이벤트" (0) | 2023.01.04 |
Spring Transaction Propagation (0) | 2022.10.16 |
Spring Transaction Option (0) | 2022.10.15 |
Spring DB (5) (0) | 2022.10.14 |
댓글