Linux에서 실행되며 TCP를 사용하는 푸시 기반 메시징 서비스를 구현하는 C++로 작성된 서버 프로그램이 있습니다. 푸시 방식으로 인해 더 긴 시간 동안 열어 두어야하는 많은 동시 연결 (약 1 백만 개를 계획 중)이있을 수 있습니다. 대부분의 경우 이러한 연결은 가끔씩 중단되어 유휴 상태가되며 전송은 대다수의 경우 동시에 발생합니다.많은 수의 파일 설명자와 함께 select()를 사용하는 외부 코드
대량의 소켓을 멀티플렉싱하기 위해 epoll
을 사용하고 RLIMIT_NOFILE
을 수정하여 실제로 많은 양의 소켓에서 잘 작동합니다.
내 문제는 동일한 프로그램에서 다른 유형의 연결, 특히 FastCGI (FastCGI SDK의 libfcgi 사용)가 내부 파일 설명자에 select()
을 사용하는 HTTP 요청을 받아들이는 것입니다. 이는 파일 설명자가 1024 (FD_SETSIZE
)보다 커지면 프로그램의 epoll
부분이 1024 이하의 대부분의 fd 숫자를 사용하면 발생합니다.
가장 좋은 방법은 무엇인지 궁금합니다. 이 문제를 처리 할 수 있습니다.
select()
을 사용하는 외부 코드를 모두 수정하고 poll()
을 대신 사용해야합니까?
내 epoll
기반 코드 (특히 accept()
호출)가 1024보다 큰 파일 설명자 만 사용하도록 유도 할 수 있습니까? 아래 내용은 select()
기반 코드입니다.
나는 FD_SETSIZE
의 가치를 어떻게 든 올릴 수 있다고 생각하지만, select()
이 작동하는 방식 때문에 성능이 많이 나빠질 것이라고 생각합니다. 실제 해결책이 아니라 해킹으로 생각합니다.
서버는 이미 여러 인스턴스로 실행되도록되어 있으며 클라이언트는 무작위로 또는로드에 따라 사용 가능한 서버 중 하나를 선택합니다. 다른 멀티플렉싱 레이어를 추가하는 것도 가능하지만 코드를 더 많이 변경해야하기 때문에 지금은이 방법을 사용하고 싶지 않습니다. dup2는 유망한 것으로 들립니다. 이제는'dup2'에 전달 된'newfd'가 다른 곳에서 이미 사용되지 않았는지 확인해야합니다. 왜냐하면'dup2'가 임의의 fds를 닫는 것을 원하지 않기 때문입니다. –
"처리하려는 연결 수가 너무 많아 단일 프로세스에서 처리 할 수 없습니다."정말 그렇게하니? 그들은 대부분의 시간 동안 유휴 상태이며 어떤 것이 옮겨지면 실제로 모든 사람들 (또는 그들 그룹)에게 동일한 데이터입니다. 나는 TCP 재전송이 많은 클라이언트들에게 문제가 될 것이라고 생각한다. (다른 VM을 사용하는 클라이언트와 동일한 물리적 인 머신상의 서버와 클라이언트로 대부분 테스트했다.) 그러나 서버가 모든 요청에 대해 내 유스 케이스에 충분히 빠르다. –
@AlemariusNexus 시작할 때, 설정 한도만큼 많은 파일 기술자를여십시오 (아마도'/ dev/null'을 열어서). 1,024 이하를 닫으십시오. 이제'dup2'에 파일 디스크립터 풀이 있습니다. 파일 디스크립터가 끝나면 파일 디스크립터를 닫지 않고 여분의 파일 디스크립터 중 하나를'dup2 '한다. –