레이블이 apache인 게시물을 표시합니다. 모든 게시물 표시
레이블이 apache인 게시물을 표시합니다. 모든 게시물 표시

Apache/IHS 성능 튜닝: MaxRequestWorkers

"서버가 자주 죽어요", "사용자가 몰리면 응답이 없어요." 이런 문제의 상당수는 Apache/IHS의 동시 접속자 처리 설정, 즉 MPM(Multi-Processing Module) 설정과 관련이 깊습니다. 이 가이드에서는 서버의 물리적 한계 내에서 최대 성능을 끌어내는 MPM 튜닝, 특히 MaxRequestWorkers 설정을 정복하는 방법을 단계별로 안내합니다.

(참고: Apache 2.2의 MaxClients는 2.4 버전부터 MaxRequestWorkers로 이름이 변경되었습니다. 기능은 동일합니다.)

Busy server rack with many network cables

서버의 성능은 올바른 설정에서 시작됩니다.


1. 모든 것의 시작: 핵심 공식

MaxRequestWorkers 튜닝은 감으로 하는 것이 아니라, 서버의 물리적 RAM을 기준으로 한 명확한 계산에서 시작해야 합니다.

MaxRequestWorkers = (총 RAM - OS 및 다른 프로세스 사용 RAM) / (Apache 프로세스 1개의 평균 메모리 사용량)

이 공식의 목표는 간단합니다. 메모리 부족으로 인한 스왑(Swap) 발생을 막아, 서버가 급격히 느려지는 재앙을 피하는 것입니다.


2. 3단계 계산법: 내 서버의 한계값 찾기

최적의 MaxRequestWorkers 값을 찾기 위해 아래 3단계를 순서대로 진행합니다.

1단계: Apache 프로세스 평균 메모리 측정

먼저, httpd(또는 apache2) 프로세스 하나가 실제 사용하는 메모리(RSS) 평균을 구합니다.

# SSH로 서버에 접속하여 아래 명령어를 실행합니다.
ps -ylC httpd --sort:rss | awk '{sum+=$8; ++n} END {print "Average RSS: " sum/n/1024 " MB"}'

결과로 Average RSS: 45.5 MB 와 같이 나옵니다. 이 값이 공식의 분모가 됩니다.

2단계: Apache가 사용할 수 있는 RAM 산정

서버의 전체 RAM에서 OS, DB 등 다른 서비스가 사용하는 메모리를 제외하여 Apache가 독점적으로 사용할 수 있는 RAM을 계산합니다.

# 사용 가능한 메모리를 MB 단위로 확인합니다.
free -m

예시: 총 16GB RAM 서버에서 DB가 4GB, OS 및 기타 서비스가 2GB를 사용한다면, Apache를 위해 할당할 수 있는 RAM은 16 - 4 - 2 = 10GB (10240 MB) 입니다. 이것이 공식의 분자가 됩니다.

3단계: 최종 값 계산

이제 1, 2단계에서 구한 값들을 공식에 대입합니다.

  • 계산: 10240 MB / 45.5 MB = 225.05
  • 결론: 소수점 이하는 버리고, MaxRequestWorkers의 최적값은 225로 산출할 수 있습니다.

3. 보이지 않는 벽: Limit 지시어 이해하기

MaxRequestWorkers 값을 계산했더라도, 이 값이 제대로 동작하려면 ServerLimitThreadLimit이라는 '보이지 않는 벽'을 이해해야 합니다. 이들은 각각 MaxRequestWorkersThreadsPerChild의 설정 가능한 최댓값을 제한하는 '하드 리밋'입니다.

  • 규칙 1: MaxRequestWorkers <= ServerLimit * ThreadsPerChild
  • 규칙 2: ThreadsPerChild <= ThreadLimit

만약 이 Limit 지시어들이 설정 파일에 보이지 않는다면, Apache는 내부 기본값(보통 ServerLimit 16, ThreadLimit 64)을 사용합니다. 계산된 MaxRequestWorkers 값이 이 기본 한계를 초과한다면, 반드시 설정 파일에 ServerLimitThreadLimit을 명시적으로 추가해야 합니다.


4. 최적의 튜닝 전략: 안정성 vs 효율성

더 많은 요청을 처리하기 위해 ServerLimit(프로세스 수)과 ThreadsPerChild(프로세스당 스레드 수) 중 무엇을 늘려야 할까요?

ServerLimit (프로세스 증가) ThreadsPerChild (스레드 증가)
안정성 높음 (프로세스 독립, 하나가 죽어도 나머진 생존) 낮음 (스레드 메모리 공유, 하나가 죽으면 프로세스 전체 다운)
메모리 효율 낮음 (프로세스마다 독립적인 메모리 필요) 높음 (메모리 공유로 자원 절약)
권장 사항 적극 권장 신중한 접근 필요 ⚠️

결론은 명확합니다. 서버의 안정성을 최우선으로 고려해야 하므로, ThreadsPerChild는 25와 같이 검증된 값으로 고정하고, 성능 확장은 ServerLimit을 늘려서 대응하는 것이 표준적인 모범 사례입니다.


5. 최종 설정 예시 (Event MPM 기준)

위의 모든 내용을 종합하여, MaxRequestWorkers1000으로 설정하는 경우의 최종 httpd.conf (또는 mpm.conf) 설정 예시입니다.

# /etc/httpd/conf.d/mpm_event.conf

<IfModule mpm_event_module>
    # 1. ThreadsPerChild는 25로 고정 (ThreadLimit 기본값 64보다 작으므로 생략 가능)
    ThreadsPerChild         25

    # 2. 필요한 ServerLimit 계산 (1000 / 25 = 40). 기본값 16보다 크므로 반드시 명시
    ServerLimit             40

    # 3. 목표 MaxRequestWorkers 설정 (40 * 25 = 1000 이므로 유효)
    MaxRequestWorkers       1000

    # 4. 기타 옵션은 서버 상황에 맞게 설정
    StartServers            4
    MinSpareThreads         75
    MaxSpareThreads         250
    MaxConnectionsPerChild  0
</IfModule>

Apache 보안 취약점 조치 - 버전 정보 노출 방지

Apache 웹 서버는 기본 설정으로 버전 정보 및 모듈 정보를 외부에 노출합니다. 이 정보는 공격자가 취약점을 탐지하는 데 활용될 수 있으므로, 보안 강화를 위해 노출을 최소화해야 합니다.

1. ServerTokens 설정

항목 기본값 변경값 설명
ServerTokens Full Prod Apache 버전, OS, 모듈 정보까지 모두 노출 → "Apache"로만 표시되도록 제한
ServerTokens Prod

2. ServerSignature 설정

항목 기본값 변경값 설명
ServerSignature On Off 에러 페이지 하단에 Apache 버전 정보 노출 → 정보 비표시
ServerSignature Off

3. Server 헤더 제거 (선택 사항)

mod_headers 모듈 사용 시 HTTP 헤더 내의 Server 정보를 완전히 제거할 수 있습니다.

Header unset Server

참고: 클라이언트나 일부 시스템에서 호환성 문제가 발생할 수 있으므로 사전 테스트 권장

4. 설정 적용

설정 변경 후 Apache를 재시작하여 적용합니다.

# CentOS / RHEL
systemctl restart httpd

# Ubuntu / Debian
systemctl restart apache2

참고

  • 추가 보안을 위해 X-Content-Type-Options, X-Frame-Options, Content-Security-Policy 등의 보안 헤더 설정도 함께 고려하세요.

apache 설치 가이드

실 사용 환경에서 필요한 내용만 정리


Test environment

OS : CentOS 7 3.10.0-957.el7.x86_64

사전 작업

Install APR (Apache Protable Runtime)

컴파일방식으로 설치 하기 때문에 사전에 APR을 다운로드

최신 Apache HTTP Server 사용하기 위해서는 버전에 맞는 APR 설치가 필요.

  • 패키지 사전 설치 확인

    yum -y install gcc make gcc-c++ pcre-devel

apr

Download link : https://apr.apache.org/download.cgi

[root@was11 apr]$ ./configure --prefix=/SW/web/tools/apr
[root@was11 apr]$ make && make install

apr-util

#압축 해제
[root@was11 apr-util]$ ./configure --prefix=/SW/web/tools/apr-util --with-apr=/SW/web/tools/apr
[root@was11 apr-util]$ make && make install

PCRE

https://www.pcre.org/

[root@was11 pcre]# ./configure --prefix=/SW/web/tools/pcre
[root@was11 pcre]# make && make install

openssl

Download link : https://www.openssl.org/source/


[root@was11 openssl]# ./config --openssldir=/SW/web/tools/openssl

make

make uninstall

주요 내용

[root@was11 httpd24]$ tar -zxvf httpd-2.4.41.tar.gz
[root@was11 openssl]# make && make install

configure command

[root@was11 httpd24]# ./configure -prefix=/SW/web/httpd24 -enable-so -enable-rewrite --enable-proxy -enable-ssl -enable-mods-shared=all -enable-modules=shared -enable-mpms-shared=all --with-mpm=worker --with-apr=/SW/web/tools/apr --with-apr-util=/SW/web/tools/apr-util --with-pcre=/SW/web/tools/pcre --with-ssl=/SW/web/tools/openssl --enable-ssl -enable-unique-id

[root@was11 httpd24]# make && make install

start

/SW/web/httpd24/bin/apachectl start

indexpage

Set Non-Domain Access Processing

Set Non-Domain Access Processing


Test Environment

  • Test OS : CentOS 7.2
  • Test Version : IBM HTTPServer v8.5

apache httpd.conf setting

tip You can set it up on the web server of the Apache class.

Forward to the virtual host that is error-handling for non-domain specified.
The point is not to give a serverName value to a dummy virtual host.

Listen 80
Listen 4958

NameVirtualHost *:80
NameVirtualHost *:4958

<VirtualHost *:80>
    DocumentRoot /app/was/htdocs
    ErrorDocument 403 "해당 방식은 접근이 허용되지 않은 방식입니다."
    ErrorDocument 404 "해당 방식은 접근이 허용되지 않은 방식입니다."
    ErrorDocument 500 "해당 방식은 접근이 허용되지 않은 방식입니다."
</VirtualHost>

<VirtualHost *:4958>
    DocumentRoot /app/was/htdocs
    ErrorDocument 403 "해당 방식은 접근이 허용되지 않은 방식입니다."
    ErrorDocument 404 "해당 방식은 접근이 허용되지 않은 방식입니다."
    ErrorDocument 500 "해당 방식은 접근이 허용되지 않은 방식입니다."
</VirtualHost>

ProxyRequests Off
<VirtualHost *:80>
    ServerName test.apache.com
    ProxyPass / http://172.31.98.155/ Keepalive=on
    ProxyPassReverse / http://172.31.98.155/
   ProxyPreserveHost On
#LogLevel debug
   ErrorLog /app/was/HTTPServer/logs/test_proxy_error.log
   CustomLog /app/was/HTTPServer/logs/test_proxy_access.log combined
</VirtualHost>

<VirtualHost *:4958>
    ServerName test.httpserver.com
    ProxyPass / http://172.31.98.209/ Keepalive=on
    ProxyPassReverse / http://172.31.98.209/
    ProxyPreserveHost On
#LogLevel debug
    ErrorLog /app/was/HTTPServer/logs/http_proxy_error.log
    CustomLog /app/was/HTTPServer/logs/http_proxy_access.log combined
</VirtualHost>

##openssl로 사설 인증서 만들기

Test Environment

  • Test OS : CentOS 7.2
  • Test Version : apache

###command line

[root@lopdzmb-web01 test]# openssl genrsa -des3 -out test.vn.key 2048..........................+++e is 65537 (0x10001)Enter pass phrase for test.vn.key:[root@lopdzmb-web01 test]# openssl genrsa -des3 -out test.vn.key 2048..........................+++e is 65537 (0x10001)Enter pass phrase for test.vn.key:-----Country Name (2 letter code) [XX]:VNPlease enter the following 'extra' attributesto be sent with your certificate request#개인키 패스워드 지우기#인증서 생성#openssl x509 -req -days 365 -in test.vn.csr -signkey test.vn.key -out test.vn.crt#개인키 확인[root@lopdzmb-web01 test]# cat test.vn.key | head -3-----BEGIN RSA PRIVATE KEY-----MIIEpAIBAAKCAQEA9JYu6T71jmxqeu3rKhDL73sojqBSXJlmODPT3wEcdkoJwUl7#사설인증서 확인[root@lopdzmb-web01 test]# cat test.vn.csr | head -3-----BEGIN CERTIFICATE REQUEST-----MIIC3jCCAcYCAQAwZTELMAkGA1UEBhMCVk4xDjAMBgNVBAgMBUhhbm9pMQ4wDAYD#httpd.conf 설정SSLEngine on

openssl genrsa -des3 -out test.vn.key 2048

Generating RSA private key, 2048 bit long modulus
........+++
small:ui_lib.c:869:You must type in 4 to 8191 characters
Enter pass phrase for test.vn.key:
Verifying - Enter pass phrase for test.vn.key:
#openssl req -new -key test.vn.key -out test.vn.csr
Generating RSA private key, 2048 bit long modulus
........+++


140564056057760:error:28069065:lib(40):UI_set_result:result too small:ui_lib.c:869:You must type in 4 to 8191 characters
Enter pass phrase for test.vn.key:
Verifying - Enter pass phrase for test.vn.key:
[root@lopdzmb-web01 test]# openssl req -new -key test.vn.key -out test.vn.csr
Enter pass phrase for test.vn.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.


State or Province Name (full name) []:Hanoi
Locality Name (eg, city) [Default City]:lotte
Organization Name (eg, company) [Default Company Ltd]:admin
Organizational Unit Name (eg, section) []:admin
Common Name (eg, your name or your server's hostname) []:*.test.vn
Email Address []:


A challenge password []:Admin12#$
An optional company name []:Admin12#$

#cp test.vn.key test.vn.key.old
#openssl rsa -in test.vn.key.old -out test.vn.key

[root@lopdzmb-web01 test]# openssl rsa -in test.vn.key.old -out test.vn.key
Enter pass phrase for test.vn.key.old:
writing RSA key

[root@lopdzmb-web01 test]# openssl x509 -req -days 365 -in test.vn.csr -signkey test.vn.key -out test.vn.crt
Signature ok
subject=/C=VN/ST=Hanoi/L=lotte/O=admin/OU=admin/CN=*.test.vn
Getting Private key

KwyUN+98KhWkbxBKX8slvaGmOPU6IBQAam2vXJf9mpbREfMPjYAE4MaSs5G1sjiP
VQQHDAVsb3R0ZTEOMAwGA1UECgwFYWRtaW4xDjAMBgNVBAsMBWFkbWluMRYwFAYD
  • SSLCertificateFile /etc/httpd/conf/test.vn.crt
  • SSLCertificateKeyFile /etc/httpd/conf/test.vn.key

Apache, Tomcat VirtualHost setting

Apache, Tomcat Interlink Settings


Apache install guide