본문 바로가기

CentOS7/Apache

mod_jk를 이용한 아파치 로드밸런싱 ( 설치부터 적용까지 ) - 삽질중인 개발자

반응형

운영을 하다 보면 로드밸런싱을 적용해서 부하를 분산시켜야 하는 경우가 있는데 L4, L7 같은 장비를 사용하여 로드밸런싱을 하기에는 비용이 상당히 많이 들어 도입하기가 어려운 경우가 있다.

 

이런 경우에 아파치를 이용하여 톰캣(was)을 로드밸런싱을 할 수 있다. 

 

우선 로드밸런싱 방법 중 몇가지 방법(mod_jk, proxy, 기타 등등)이 존재 하는데 proxy 방법은 httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html 해당 사이트의 examples of a balancer configuration 칸을 보고 따라 하면 바로 적용될 정도로 쉽기에 이 포스팅에서는 mod_jk를 이용해서 적용하는 방법을 포스팅한다. ( 각각의 방식에 장단점이 있다. )

 

우선 mod_jk는 AJP 프로토콜을 사용하여 통신을 한다. 따라서 AJP 포트를 열어줘야 한다. 해당 포스트에서는 맨 아래 Spring boot 버전으로 코드를 추가해놨다.

 

테스트 환경

CentOS 7

httpd 2.4.47 

 

1. mod_jk 설치 여부 확인

cd /etc/httpd/modules
ls | grep jk

 

mod_jk는 아파치 설치시에 기본적으로 들어오는 모듈이 아니라 아마 존재하지 않을 것이다.

 

2. mod_jk 설치

아래의 커맨드를 따라 설치한다.

만약 http://mirror.navercorp.com/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.48-src.tar.gz 파일이 없다면 

http://mirror.navercorp.com/apache/tomcat/tomcat-connectors/jk/ 여기로 접속해서 최신 버전을 확인한 후 다운로드 하자.

	# mod_jk 설치 방법

	wget -c http://mirror.navercorp.com/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.48-src.tar.gz
	
	tar -xvzf tomcat-connectors-1.2.48-src.tar.gz
	
	cd tomcat-connectors-1.2.48-src/native

	# 없으면 설치
	yum install httpd-devel

	./configure --with-apxs=/usr/bin/apxs
	
	make
	
	cp apache-2.0/mod_jk.so /usr/lib64/httpd/modules/

 

 

위의 커맨드를 다 실행 했다면 mod_jk.so 파일이 /usr/lib64/httpd/modules/ 에 있을 것이다.

 

 

3. mod_jk 세팅 

cd /etc/httpd/conf.d

vi mod_jk.conf

아래의 내용을 복붙한다.

mod_jk.conf

		LoadModule jk_module modules/mod_jk.so
		<ifModule jk_module>
		    JkWorkersFile           conf/workers.properties
		    JkLogFile               logs/mod_jk.log
		    JkLogLevel              info
		    JkShmFile               /var/log/httpd/jk-runtime-status
		    JkWatchdogInterval      30
            

    
		</ifModule>

위에 있는 LoadModule로 mod_jk의 모듈을 불러온다. 

 

 

4. worker 세팅

 

cd /etc/httpd/conf

vi workers.properties

 

workers.properties

		#워커 세팅 
		worker.list=jk-status
		worker.jk-status.type=status
		worker.jk-status.read_only=true
		#JK manager
		worker.list=jk-manager
		worker.jk-manager.type=status
		
		#워커 그룹 명 같음
		worker.list=load_balancer
		
		#워커 타입 로드 밸런스로 세팅
		worker.load_balancer.type=lb
        
		#해당 워커는 아래의 tomcat1,tomcat2를 참조한다.
		worker.load_balancer.balance_workers=tomcat1,tomcat2
		
		# 워커의 상세 설정1
		worker.tomcat1.type=ajp13
		worker.tomcat1.host=127.0.0.1
		worker.tomcat1.port=18009
		#retries를 0으로 꼭 세팅하자
		worker.tomcat1.retries=0
		worker.tomcat1.secretkey=test
		worker.tomcat1.socket_timeout=0
				
		# 워커의 상세 설정2
		worker.tomcat2.type=ajp13
		worker.tomcat2.host=127.0.0.1
		worker.tomcat2.port=18008
		#retries를 0으로 꼭 세팅하자
		worker.tomcat2.retries=0
		worker.tomcat2.secretkey=test
		worker.tomcat2.socket_timeout=0

 

worker.tomcat1.port=18009 의 포트는 AJP 포트이다. 잘 확인하자.

 

retries를 0으로 세팅을 안 하면 통신 실패 시아파치에서 자동으로 디폴트 값인 1회를 추가로 보내주는데 이 옵션으로 인하여 두 번 통신되면 안되는 API가 (ex ) 결제하는 API ) 두번 통신되는 경우가 있어서 필수적으로 0으로 세팅한다.

 

 

5. virtualhost 컨피그 파일에 JkMount 추가

 

<VirtualHost *:80>
	DocumentRoot /www/example1
	ServerName www.example.com

	JkMount /* load_balancer

</VirtualHost>

 

JKMount에 있는 /* path 밑으로 4번에 있는 worker.properties 파일에 worker.list=load_balancer 를 참조하여 로드밸런싱을 해준다.

 

 


Spring boot에서의 AJP 포트 세팅

 

TomcatContainerConfig.java

import org.apache.catalina.connector.Connector;
import org.apache.coyote.ajp.AjpNioProtocol;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.InetAddress;
import java.net.UnknownHostException;

@Configuration
class TomcatContainerConfig {
	@Value("${tomcat.ajp.protocol}")
	String ajpProtocol;
	
	@Value("${tomcat.ajp.port}")
	int ajpPort;
	
	
	@Bean
	public ServletWebServerFactory servletContainer() throws UnknownHostException {
		TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
		tomcat.addAdditionalTomcatConnectors(createAjpConnector());
		
		return tomcat;
	}
	
	private Connector createAjpConnector() throws UnknownHostException {

		
		Connector ajpConnector = new Connector(ajpProtocol);
		ajpConnector.setPort(ajpPort);
		ajpConnector.setSecure(true);
		ajpConnector.setAllowTrace(false);
		ajpConnector.setScheme("http");
		ajpConnector.setRedirectPort(8443);
		
		AjpNioProtocol protocol= (AjpNioProtocol)ajpConnector.getProtocolHandler();
		protocol.setSecret("test"); 
		protocol.setSecretRequired(false);
		protocol.setRequiredSecret(null);   // 톰캣 버전을 타는 옵션인데 이거 세팅 안하면 버그 난다.  AJP13 protocol: Reuse is set to false tomcat
		protocol.setAddress(InetAddress.getByName("0.0.0.0"));      // 이거 세팅 안하면 ajp_send_request::jk_ajp_common.c (1724): (tomcat2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=111) 에러
		
		return ajpConnector;
	}
	
}

 

application.yml

tomcat:
  ajp:
    protocol: AJP/1.3
    port: 18009
    enabled: true

 

위에 과정을 잘 따라 하면 로드밸런싱이 적용이 될 것이다.

 

 

 

반응형

'CentOS7 > Apache' 카테고리의 다른 글

Apache http2 적용 방법 (mod_http2)- 삽질중인 개발자  (0) 2021.05.02