IIS에서 호스팅되는 ServiceStack을 사용하여 구현 된 API가 있습니다. API의로드 테스트를 수행하는 동안 응답 시간은 좋지만 서버 당 약 3,500 명의 동시 사용자를 공격하자마자 빠르게 저하되는 것을 발견했습니다. 우리는 두 대의 서버를 보유하고 있으며 7,000 명의 사용자로 서버를 공격 할 때 모든 엔드 포인트에서 평균 응답 시간이 500ms 미만입니다. 박스는로드 밸런서 뒤에 있으므로 서버 당 3,500 개의 동시성을 얻을 수 있습니다. 그러나 총 동시 사용자 수를 늘리면 응답 시간이 크게 증가합니다. 동시 사용자를 서버 당 5,000으로 늘리면 엔드 포인트 당 평균 응답 시간이 약 7 초가됩니다.
서버의 메모리와 CPU는 응답 시간이 좋을 때와 성능이 저하 된 후 모두 낮습니다. 동시 사용자가 10,000 명일 때 CPU의 평균은 평균 50 % 미만이며 RAM은 16 개 중 3-4GB 정도입니다. 아래 스크린 샷은 총 10,000 명의 동시 사용자와 함께로드 테스트 중에 perfmon의 일부 주요 카운터를 보여줍니다. 강조 표시된 카운터는 초당 요청입니다. 스크린 샷의 오른쪽에서 초당 요청 수 그래프가 실제로 불규칙 해지는 것을 볼 수 있습니다. 응답 시간이 느린 주요 지표입니다. 이 패턴을 보자 마자 부하 테스트에서 응답 시간이 느립니다.
이 성능 문제를 해결하려면 어떻게해야합니까? 코딩 문제인지 구성 문제인지 확인하려고합니다. web.config 또는 IIS에이 동작을 설명 할 수있는 설정이 있습니까? 응용 프로그램 풀이 .NET v4.0을 실행 중이고 IIS 버전은 7.5입니다. 기본 설정에서 변경된 유일한 사항은 응용 프로그램 풀 큐 길이 값을 1,000에서 5,000 으로 업데이트하는 것 입니다. 또한 Aspnet.config 파일에 다음 구성 설정을 추가했습니다.
<system.web>
<applicationPool
maxConcurrentRequestsPerCPU="5000"
maxConcurrentThreadsPerCPU="0"
requestQueueLimit="5000" />
</system.web>
자세한 내용은:
API의 목적은 다양한 외부 소스의 데이터를 결합하고 JSON으로 반환하는 것입니다. 현재 데이터 계층에서 개별 외부 호출을 캐시하기 위해 InMemory 캐시 구현을 사용하고 있습니다. 리소스에 대한 첫 번째 요청은 필요한 모든 데이터를 가져오고 동일한 리소스에 대한 후속 요청은 캐시에서 결과를 얻습니다. 우리는 특정 설정된 간격으로 캐시의 정보를 업데이트하는 백그라운드 프로세스로 구현되는 '캐시 러너'를 가지고 있습니다. 외부 리소스에서 데이터를 가져 오는 코드 주위에 잠금을 추가했습니다. 또한 외부 소스에서 데이터를 비동기 방식으로 가져 오는 서비스를 구현하여 엔드 포인트가 가장 느린 외부 호출만큼 느려 야합니다 (물론 캐시에 데이터가없는 경우). 이것은 System.Threading.Tasks.Task 클래스를 사용하여 수행됩니다.프로세스에서 사용할 수있는 스레드 수의 측면에서 제한을 맞출 수 있습니까?