문제

웹 서버를 벤치마킹하기 위해 'ab'를 사용할 때마다 많은 요청을 보낸 후 잠시 정지되고 20초 정도 후에 계속됩니다.

Ruby로 작성된 다음 HTTP 서버 시뮬레이터를 고려해보세요.

require 'socket'

RESPONSE = "HTTP/1.1 200 OK\r\n" +
           "Connection: close\r\n" +
           "\r\n" +
           "\r\n"

buffer = ""
server = TCPServer.new("127.0.0.1", 3000)  # Create TCP server at port 3000.
server.listen(1024)                        # Set backlog to 1024.
while true
    client = server.accept             # Accept new client.
    client.write(RESPONSE)             # Write a stock "HTTP" response.
    client.close_write                 # Shutdown write part of the socket.
    client.read(nil, buffer)           # Read all data from the socket.  
    client.close                       # Close it.
end

그런 다음 다음과 같이 ab를 실행합니다.

ab -n 45000 -c 10 http://127.0.0.1:3000/

처음 몇 초 동안 ab는 예상대로 작업을 수행하고 100% CPU를 사용합니다.

Benchmarking 127.0.0.1 (be patient)
Completed 4500 requests
Completed 9000 requests
Completed 13500 requests

약 13500개의 요청 후에는 시스템 CPU 사용량이 0%로 떨어집니다.ab는 뭔가에 얼어붙은 것 같아요.현재 서버가 accept()를 호출하고 있기 때문에 문제는 서버에 있는 것이 아닙니다.약 20초 후에 ab는 아무 일도 일어나지 않은 것처럼 계속되고 CPU를 다시 100% 사용하게 되며 몇 초 후에 다시 정지됩니다.

커널의 무언가가 연결을 제한하고 있는 것 같습니다. 그런데 무엇과 그 이유는 무엇입니까?저는 OS X Leopard를 사용하고 있습니다.Linux에서도 유사한 동작을 보았지만 정지는 훨씬 더 많은 수의 요청에서 발생하고 자주 발생하지는 않습니다.

이 문제로 인해 대규모 HTTP 벤치마크를 실행할 수 없습니다.

도움이 되었습니까?

해결책

당신이 부족한 것 같아요 임시 포트.확인하려면 netstat 명령을 내리고 수천 개의 포트를 찾으십시오. TIME_WAIT 상태.

Mac OS X에서 기본 임시 포트 범위는 49152~65535이며 총 포트 수는 16384개입니다.이 내용은 다음을 통해 확인할 수 있습니다. sysctl 명령:

$ sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535

임시 포트가 부족해지면 일반적으로 다음이 나올 때까지 기다려야 합니다. TIME_WAIT 특정 포트 번호를 재사용할 수 있을 때까지 상태가 만료됩니다(2 * 최대 세그먼트 수명).Linux 및 Solaris의 기본값인 32768에서 시작하도록 범위를 변경하여 포트 수를 두 배로 늘릴 수 있습니다.(최대 포트번호는 65535 이므로 하이엔드를 늘릴 수 없습니다.)

$ sudo sysctl -w net.inet.ip.portrange.first=32768
net.inet.ip.portrange.first: 49152 -> 32768

참고 IANA가 지정한 공식 범위 49152~65535이며 일부 방화벽에서는 동적으로 할당된 포트가 해당 범위에 속한다고 가정할 수 있습니다.로컬 네트워크 외부의 더 넓은 범위를 사용하려면 방화벽을 재구성해야 할 수도 있습니다.

최대 세그먼트 수명을 줄이는 것도 가능합니다(sysctl net.inet.tcp.msl Mac OS X의 경우), 지속 시간을 제어합니다. TIME_WAIT 그러나 이는 이전 연결이 동일한 포트 번호를 사용하는 새 연결과 혼동될 수 있으므로 위험합니다.또한 특정 포트에 바인딩하는 것과 관련된 몇 가지 트릭이 있습니다. SO_REUSEADDR 옵션 또는 SO_LINGER 옵션이지만 이전 연결과 새 연결이 혼동될 수도 있으므로 일반적으로 나쁜 생각으로 간주됩니다.

다른 팁

포트 수를 늘리는 대신 길이를 변경하십시오. TIME_WAIT Mac OS X에서.

이것은 개발에서만 작동하지만 이제 물어볼 수 있습니다. ab 시간 초과 없이 원하는 만큼 요청을 처리할 수 있습니다.

다음과 같이 기본 시간 제한을 1000ms로 설정합니다.

$ sudo sysctl -w net.inet.tcp.msl=1000
net.inet.tcp.msl: 15000 -> 1000

다른 답변에 언급된 brianp.net 페이지는 더 이상 사용할 수 없습니다.에서 검색할 수 있습니다. 인터넷 아카이브.

문제를 해결하는 또 다른 옵션은 다음을 추가하여 HTTP KeepAlive를 활성화하는 것입니다. "-k" 옵션.이렇게 하면 ab가 TCP 연결을 재사용하게 되고 결과적으로 사용 가능한 모든 포트가 소진되지 않습니다.예를 들어:

ab -n 45000 -c 10 -k http://127.0.0.1:3000/

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