압력 테스트
압력 테스트 결과에 영향을 미치는 요인?
- 압력 발생기와 서버 간의 네트워크 지연 (내부망 또는 로컬에서 압력 테스트 권장)
- 압력 발생기와 서버 간의 대역폭 (내부망 또는 로컬에서 압력 테스트 권장)
- HTTP keep-alive가 활성화되어 있는지 여부 (활성화 권장)
- 동시 접속 수가 충분한지 여부 (외부망 압력 테스트의 경우 가능한 더 큰 동시 접속을 활성화할 것)
- 서버 프로세스 수가 합리적인지 여부 (helloworld 비즈니스 프로세스 수는 CPU 수와 동일하게, 데이터베이스 비즈니스 프로세스 수는 CPU의 4배 이상 권장)
- 비즈니스 자체 성능 (예: 외부망 데이터베이스 사용 여부)
HTTP keep-alive란 무엇인가?
HTTP Keep-Alive 메커니즘은 단일 TCP 연결에서 여러 HTTP 요청 및 응답을 전송하는 기술로, 성능 테스트 결과에 큰 영향을 미칩니다. keep-alive를 비활성화하면 QPS가 기하급수적으로 감소할 수 있습니다.
현재 대부분의 브라우저는 기본적으로 keep-alive를 활성화하고 있습니다. 즉, 브라우저가 특정 HTTP 주소에 접속한 후 연결을 일시적으로 닫지 않고, 다음 요청 시 해당 연결을 재사용하여 성능을 향상시킵니다.
압력 테스트 시 keep-alive를 활성화하는 것이 좋습니다.
또한, keep-alive를 비활성화한 압력 테스트의 경우, 클라이언트 로컬 포트가 빠르게 timewait 상태로 소진되며, 총 요청 수가 일정 수(약 28,000 회)를 초과하면 실패하는 요청이 발생합니다.
압력 테스트 시 HTTP keep-alive를 활성화하는 방법은?
ab 프로그램으로 압력 테스트를 하는 경우 -k
매개변수를 추가해야 합니다. 예: ab -n100000 -c200 -k http://127.0.0.1:8787/
apipost는 반환 헤더에 gzip 헤더를 반환해야 keep-alive를 활성화할 수 있습니다 (apipost의 버그, 아래 참고).
기타 압력 테스트 프로그램은 일반적으로 기본적으로 활성화되어 있습니다.
외부망에서 압력 테스트 시 QPS가 낮은 이유는?
외부망의 지연으로 인해 QPS가 낮아지는 것은 정상적인 현상입니다. 예를 들어, baidu 페이지를 압력 테스트 할 경우 QPS가 수십에 불과할 수 있습니다.
내부망 또는 로컬에서 압력 테스트를 권장하여 네트워크 지연의 영향을 배제할 수 있습니다.
외부망에서 압력 테스트를 해야 할 경우, 동시 접속 수를 증가시켜 처리량을 늘릴 수 있습니다(대역폭이 충분한 경우).
nginx 프록시를 거친 후 성능이 저하되는 이유는?
nginx 실행은 시스템 자원을 소모합니다. 또한, nginx와 webman 간의 통신도 일정량의 자원을 소모합니다.
그러나 시스템 자원은 제한적이며, webman은 모든 시스템 자원을 사용할 수 없기 때문에 전체 시스템 성능이 저하될 수 있는 것은 정상적인 현상입니다.
nginx 프록시로 인한 성능 영향을 최대한 줄이기 위해 nginx 로그를 비활성화(access_log off;
)하고, nginx와 webman 간의 keep-alive를 활성화하는 것을 고려할 수 있습니다. nginx 프록시 참고.
또한 HTTPS는 HTTP보다 더 많은 자원을 소모합니다. HTTPS는 SSL/TLS 핸드셰이크, 데이터 암호화 및 복호화, 패킷 크기 증가로 인해 더 많은 대역폭을 사용하게 되어 성능이 저하될 수 있습니다.
압력 테스트에 단기 연결(HTTP keep-alive 비활성화)을 사용하는 경우 매 요청마다 추가적인 SSL/TLS 핸드셰이크 통신이 필요하고, 성능이 크게 저하됩니다. HTTPS에 대한 압력 테스트는 HTTP keep-alive를 활성화하는 것이 좋습니다.
시스템이 성능의 한계에 도달했는지 어떻게 알 수 있나요?
일반적으로 CPU가 100%에 도달하면 시스템 성능이 한계에 도달했다는 것을 나타냅니다. CPU에 여유가 있다면 아직 한계에 도달하지 않은 것이고, 이때 적절히 동시 접속을 늘려서 QPS를 증가시킬 수 있습니다.
동시 접속을 증가시켜도 QPS가 향상되지 않는다면 webman 프로세스 수가 부족할 수 있으므로 적절히 webman 프로세스를 늘려야 합니다. 그래도 개선되지 않는다면 대역폭이 충분한지 확인해야 합니다.
왜 내 압력 테스트 결과에서 webman의 성능이 go의 gin 프레임워크보다 낮은가?
techempower의 압력 테스트 결과에 따르면 webman은 순수 텍스트, 데이터베이스 쿼리, 데이터베이스 업데이트 등 모든 지표에서 gin보다 약 두 배 이상 우수합니다.
결과가 다르다면 webman에서 ORM을 사용하여 상당한 성능 손실이 발생했을 수 있으므로 webman+원시 PDO와 gin+원시 SQL을 비교해 보시기 바랍니다.
webman에서 ORM을 사용할 때 성능 손실은 얼마인가?
다음은 압력 테스트 데이터 세트입니다.
환경
서버: 알리 클라우드 4코어 4G, 로컬 MySQL 데이터베이스, 10만 개 레코드 중 랜덤으로 데이터 1개 조회 후 JSON 반환, 로컬 압력 테스트.
원시 PDO 사용 시
webman QPS는 1.78만
laravel의 Db::table() 사용 시
webman QPS는 0.94만으로 감소
laravel의 Model 사용 시
webman QPS는 0.72만으로 감소
thinkORM의 결과도 유사하며 큰 차이는 없습니다.
팁
ORM을 사용할 때 성능이 저하되기는 하지만, 99%의 비즈니스에 대해 성능은 이미 상당히 과잉입니다. 만약 당신이 그 1%에 해당된다면 CPU 또는 서버를 증설하여 쉽게 해결할 수 있습니다.
우리는 개발 효율성, 유지 보수성, 성능 등 여러 지표에서 균형점을 찾아야 하며, 성능만을 추구해서는 안 됩니다.
왜 apipost로 압력 테스트를 하면 QPS가 낮은가?
apipost의 압력 테스트 모듈에는 버그가 있어, 서버가 gzip 헤더를 반환하지 않으면 keep-alive를 유지할 수 없어 성능이 크게 저하됩니다.
해결 방법은 응답 시 데이터를 압축하고 gzip 헤더를 추가하는 것입니다. 예:
<?php
namespace app\controller;
class IndexController
{
public function index()
{
return response(gzencode('hello webman'))->withHeader('Content-Encoding', 'gzip');
}
}
이 외에도, apipost는 특정 상황에서 만족스러운 압력을 생성하지 못할 수 있으며, 이는 동일한 동시 접속에 대해 apipost가 ab보다 약 50% 낮은 QPS를 보이는 형태로 나타납니다.
압력 테스트는 ab, wrk 또는 기타 전문적인 압력 테스트 소프트웨어를 사용하는 것이 좋으며 apipost를 피하는 것이 좋습니다.
적절한 프로세스 수 설정
webman은 기본적으로 cpu*4 프로세스를 활성화합니다. 실제로 네트워크 I/O가 없는 helloworld 비즈니스의 경우 프로세스 수를 CPU 코어 수와 일치시키는 것이 성능 최적화에 가장 좋습니다. 왜냐하면 프로세스 전환 오버헤드를 줄일 수 있기 때문입니다.
데이터베이스, redis와 같은 차단 I/O 비즈니스의 경우 프로세스 수는 CPU의 3-8배로 설정할 수 있습니다. 이 경우 더 많은 프로세스가 동시 처리를 늘려야 하며, 프로세스 전환 오버헤드는 차단 I/O에 비해 거의 무시할 수 있습니다.
압력 테스트의 일부 참조 범위
클라우드 서버 4코어 4G 16 프로세스, 로컬/내부망 압력 테스트
- | keep-alive 활성화 | keep-alive 비활성화 |
---|---|---|
hello world | 8-16만 QPS | 1-3만 QPS |
데이터베이스 단일 조회 | 1-2만 QPS | 1만 QPS |
압력 테스트 명령 예시
ab
# 100000 요청 200 동시 접속 keep-alive 활성화
ab -n100000 -c200 -k http://127.0.0.1:8787/
# 100000 요청 200 동시 접속 keep-alive 비활성화
ab -n100000 -c200 http://127.0.0.1:8787/
wrk
# 200 동시 접속 10초 압력 테스트 keep-alive 활성화(기본값)
wrk -c 200 -d 10s http://example.com