문제

Tomcat에서 maxSpare, minSpare 및 maxThreads, acceptCount 등의 최상의 수를 어떻게 결정합니까?기존 모범 사례가 있습니까?

나는 이것이 하드웨어를 기반으로 해야 한다는 것을 이해합니다(예:코어당) 특정 하드웨어에 대한 추가 성능 테스트 및 최적화의 기반이 될 수 있습니다.

도움이 되었습니까?

해결책

"스레드 수 문제"는 상당히 크고 복잡한 문제이며 간단한 경험 법칙으로는 대답할 수 없습니다.

보유하고 있는 코어 수를 고려하는 것은 숫자 처리 등과 같이 많은 CPU를 소비하는 경향이 있는 멀티 스레드 애플리케이션에 유용합니다.일반적으로 CPU가 아닌 다른 요인에 의해 부하가 걸리는 웹 앱의 경우에는 이런 경우가 거의 없습니다.

한 가지 일반적인 제한 사항은 사용자와 다른 외부 시스템, 특히 DB 간의 지연입니다.요청이 도착할 때마다 데이터베이스에 여러 번 쿼리할 것입니다. 즉, JDBC 연결을 통해 일부 바이트를 스트리밍한 다음 해당 바이트가 데이터베이스에 도착할 때까지 기다립니다(localhost에 있더라도 여전히 약간의 지연이 있습니다). 그런 다음 DB가 요청을 고려할 때까지 기다린 다음 데이터베이스가 이를 처리할 때까지 기다립니다(데이터베이스 자체는 디스크가 특정 지역을 검색할 때까지 기다립니다).

이 시간 동안 스레드는 유휴 상태이므로 다른 스레드가 해당 CPU 리소스를 쉽게 사용하여 유용한 작업을 수행할 수 있습니다.DB 응답을 기다리는 데 소요되는 시간의 40~80%를 보는 것은 매우 일반적입니다.

연결 반대편에서도 마찬가지입니다.스레드가 브라우저에 출력을 쓰는 동안 CLIENT 연결 속도로 인해 브라우저가 특정 패킷이 수신되었음을 승인할 때까지 스레드가 유휴 상태로 유지될 수 있습니다.(이것은 몇 년 전에 꽤 문제가 되었습니다. 최근 커널과 JVM은 스레드가 그런 식으로 유휴 상태가 되는 것을 방지하기 위해 더 큰 버퍼를 사용합니다. 그러나 웹 응용 프로그램 서버 앞에 있는 역방향 프록시(간단히 httpd라도)는 사람을 피하는 데 정말 유용할 수 있습니다. 인터넷 연결이 좋지 않아 DDOS 공격으로 행동합니다 :) )

이러한 요소를 고려하면 일반적으로 스레드 수는 보유하고 있는 코어 수보다 훨씬 많아야 합니다.단순한 듀얼 코어나 쿼드 코어 서버에서도 최소한 수십 개의 스레드를 구성해야 합니다.

그렇다면 구성할 수 있는 스레드 수를 제한하는 것은 무엇입니까?

우선, 각 스레드는 (예전에는) 많은 리소스를 소비합니다.각 스레드에는 RAM을 소비하는 스택이 있습니다.더욱이 각 스레드는 작업을 수행하기 위해 실제로 힙에 항목을 할당하고 RAM을 다시 소비하며 스레드 간 전환(컨텍스트 전환) 작업은 JVM/OS 커널에 대해 상당히 무겁습니다.

이로 인해 수천 개의 스레드가 있는 서버를 "부드럽게" 실행하기가 어렵습니다.

이 그림을 보면 여러 가지 기술이 있습니다(주로:시도, 실패, 조정, 다시 시도) 앱에 필요한 스레드 수를 어느 정도 결정합니다.

1) 스레드가 어디에 시간을 소비하는지 이해하려고 노력하십시오.좋은 도구가 많이 있지만 jvisualvm 프로파일러도 훌륭한 도구이거나 요약 타이밍 통계를 생성하는 추적 측면이 될 수 있습니다.외부 무언가를 기다리는 데 더 많은 시간을 소비할수록 유휴 시간 동안 CPU를 사용하기 위해 더 많은 스레드를 생성할 수 있습니다.

2) RAM 사용량을 결정합니다.JVM이 사용하는 스레드 수와 관계없이 특정 양의 메모리(주로 permgen 공간, 일반적으로 최대 100MB, 다시 jvisualvm이 알려줌)를 사용한다는 점을 고려하면 하나의 스레드로 실행한 다음 10개로 실행한 다음 다음으로 실행해 보세요. 100, jmeter 등으로 앱에 스트레스를 가하면서 힙 사용량이 어떻게 증가하는지 확인하세요.이는 엄격한 제한을 초래할 수 있습니다.

3) 목표를 정해보세요.각 사용자 요청을 처리하려면 스레드가 필요합니다.평균 응답 시간이 "get"당 200ms인 경우(이미지, CSS 및 기타 정적 리소스 로드를 고려하지 않는 것이 더 좋음) 각 스레드는 초당 4/5페이지를 제공할 수 있습니다.각 사용자가 3/4초마다 "클릭"할 것으로 예상되는 경우(브라우저 게임인지 아니면 긴 텍스트가 많은 사이트인지에 따라 다름), 의미에 관계없이 하나의 스레드가 "20명의 동시 사용자에게 서비스를 제공"합니다.사용량이 가장 많은 시간에 500명의 단일 사용자가 1분 안에 사이트를 방문하는 경우 이를 처리하려면 충분한 스레드가 필요합니다.

4) 상한 충돌 테스트.jmeter를 사용하여 예비 가상 머신에 많은 스레드로 서버를 구성하고 특정 제한을 초과하면 응답 시간이 어떻게 악화되는지 확인하십시오.여기서는 하드웨어보다 기본 OS의 스레드 구현이 중요합니다. 그러나 CPU가 실제로 실행하는 것보다 실행할 스레드를 파악하는 데 더 많은 시간을 소비하는 지점에 도달하게 되면 그 숫자는 그렇게 믿을 수 없을 정도로 많지 않습니다. 높은.

5) 스레드가 다른 구성 요소에 어떤 영향을 미치는지 고려하십시오.각 스레드는 데이터베이스에 대해 하나(또는 둘 이상)의 연결을 사용할 것입니다. 데이터베이스가 50/100/500개의 동시 연결을 처리할 수 있습니까?NoSQL 서버의 샤드 클러스터를 사용하는 경우에도 서버 팜이 해당 시스템 간에 충분한 대역폭을 제공합니까?웹앱 서버가 있는 동일한 시스템에서 또 무엇이 실행됩니까?아나쉬 httpd?오징어?데이터베이스 자체?mongos 또는 memcached와 같은 데이터베이스에 대한 로컬 캐싱 프록시?

프로덕션에서 스레드 4개 + 예비 스레드 4개만 있는 시스템을 본 적이 있습니다. 해당 서버에서 수행한 작업은 단지 이미지 크기를 조정하는 것뿐이어서 거의 100% CPU 집약적이었고 다른 시스템은 거의 동일한 하드웨어에 구성되어 있었습니다. 수백 개의 스레드로 인해 웹앱이 외부 시스템에 대해 많은 SOAP 호출을 수행하고 대부분의 시간을 응답을 기다리는 데 소비했기 때문입니다.

대략적인 값을 결정했습니다.웹앱에 최적인 최소 및 최대 스레드를 선택했다면 일반적으로 다음과 같이 구성합니다.

1) RAM의 제약, 기타 외부 리소스 및 컨텍스트 전환에 대한 실험을 기반으로 도달해서는 안되는 절대 최대값이 있습니다.따라서 maxThreads를 사용하여 해당 숫자의 약 절반 또는 3/4로 제한하십시오.

2) 애플리케이션이 상당히 빠른 경우(예를 들어 일반적으로 몇 밀리초 동안 응답을 보내는 REST 웹 서비스를 노출하는 경우) 최대 동일한 수의 maxThreads까지 큰 acceptCount를 구성할 수 있습니다.웹 애플리케이션 서버 앞에 로드 밸런서가 있는 경우 작은 acceptCount를 설정하십시오. 로드 밸런서는 이미 바쁜 서버에 사용자를 대기시키는 것보다 승인되지 않은 요청을 확인하고 다른 서버로 전환하는 것이 더 좋습니다.

3) 스레드를 시작하는 것은 (여전히) 무거운 작업으로 간주되므로 minSpareThreads를 사용하여 사용량이 많은 시간대에 도달할 때 몇 개의 스레드를 준비하십시오.이는 예상되는 부하의 종류에 따라 달라집니다.minSpareThreads, maxSpareThreads 및 maxThreads 설정을 통해 정확한 수의 스레드가 항상 준비되고 회수되지 않으며 성능을 예측할 수 있도록 하는 것이 합리적입니다.전용 시스템에서 tomcat을 실행하는 경우 다른 프로세스를 부담할 위험 없이 minSpareThreads 및 maxSpareThreads를 올릴 수 있습니다. 그렇지 않으면 스레드가 대부분의 OS에서 실행되는 나머지 프로세스와 공유되는 리소스이므로 조정하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top