쓰레드를 이용하여 소켓 서버를 생성할 때...
글쓴이: inu111 / 작성시간: 월, 2005/08/01 - 8:04오후
제가 쓰레드를 이용하여 소켓 서버를 작성하고 있습니다.
제가 작성 중인 소켓 서버는 최소 300명 이상의 클라이언트가
매우 긴 시간 동안 접속을 유지하면서 주기적으로 전달하는
메시지를 처리할 수 있어야 합니다.
특별히 쓰레드 간에 공유할 데이터가 존재하지 않으며
연결이 끊어지면 다시 연결을 해서 통신 채널을 확보해야
하는 특징을 가지고 있습니다.
(쓰고 보니 특징이랄 것도 없네요 ;;)
처음에는 fork()/select()/poll()/thread() 중 여러 가지를
생각해보았는데, 많은 수의 접속을 오랜 시간동안 유지하기에는
어떤 기법이나 기법의 조합이 성능상 뛰어날지 잘 몰라서
일단 쓰레드로 만들어 보았습니다.
혹시 저처럼 많은 수의 접속(최소 동시 접속 300개 이상)을
처리해 보신 분이 계시면 어떤 기법이 가장 뛰어날 수 있는지
조언 부탁드립니다.
학교 과제로만 만들어 보던 소켓 프로그램을
성능까지 생각해보며 만들어 보려고 하니까
쉽지가 않네요...^^;;
Forums:
프로세스와 리눅스에서 지원하는 쓰래드는 단점이.. 커널의 자원을
프로세스와 리눅스에서 지원하는 쓰래드는 단점이.. 커널의 자원을
소모한다는데 있습니다.
많은 사용자의 접속을 받아들이면서도 시스템의 자원을 효율적으로
사용하는 방법중에.. 제가 사용하는 방법은..
pre-fork와 select 입니다
pre-fork는 접속이후에 fork를 하는방법이 아니라.. 이미
fork를 해놓는 상태입니다. 아파치를 생각하시면 됩니다.
그리고 select는 여러접속을 하나의 프로세스에 묶는데 사용을
합니다..
일반적으로 저는(설정파일에 의해 달라지지만..)
5~10명의 사용자를 하나의 프로세스에 묶습니다.
그리고 해당 프로세스를 일반적으로 20개 그리고 계속 추가적인
접속 증가에 따라 5개씩 증가하는 방법을 사용합니다.
한 프로세스가 10명의 사용자를 서비스 한다 설정후
초기 동작시 30개의 프로세스를 fork시킨다면
총 300명의 접속이 가능해 집니다.
증가치에 따라서 300접속이 가득찰 경우 5개의 프로세스를
추가적으로 fork한다면 50명씩 추가적으로 접속이 가능하겠지요.
제가 예전에 체팅을 구형장비에서 운영을 했었는데.
(팬1 133 64M Linux 였습니다.)
400여명의 접속을 무난하게 처리했었습니다.
(당시 제 기억으로.. CPU사용율은 20%정도였던것으로 기억합니다)
그 이상은 접속이 되었던 적이 없었습니다
접속단에서 업무처리단으로 보낼때는 m-queue를 사용하고
받을때는 domain소켓을 사용했었습니다.
물론 select처리시 가장중요한 점은. nonblock 소켓을 사용해야
한다는 점입니다. block소켓을 작동시키면 공격에 취약하게 됩니다
이 부분은 가만히 고민해 보시면 금방 알 수 있습니다.
여러명의 접속을 하나의 select호출로 묶고 있는 이상 반드시
필요한 부분이 될 것입니다.
당근 nonblock이므로 read및 write 스풀버퍼가 각 소켓마다
존재할 필요가 있겠지요.. (전 버퍼구현으로 리스트를 사용합니다)
오고가는 패킷이 그리 많지 않다면, 클라이언트 하나당 쓰레드물리는것보
오고가는 패킷이 그리 많지 않다면, 클라이언트 하나당 쓰레드
물리는것보다는 폴링방식이 낫지 않을까요?
yaws 라고 erlang 으로 만든 서버가 있습니다.병렬개념이 도입
yaws 라고 erlang 으로 만든 서버가 있습니다.
병렬개념이 도입된 함수형 언어정도로 알고 있습니다.
아파치보다 기술적으로 우수하고 우아하다고 합니다..
http://yaws.hyber.org/
-접속자수 : 수백(그리 많지 않은 수입니다. 한 4천은 넘겨야 좀 크다
-접속자수 : 수백(그리 많지 않은 수입니다. 한 4천은 넘겨야 좀 크다 보지요.)
-클라이언트간 서버를 통한 상호작용: 없음(프로그램을 단순화할 수 있지요)
-재접속 : 특별한 경우(네트워크 오류나 관리등) 외에 없음(포크등을 이용해도 무방한 경우, 재접속 비용이 전체에 비해 그리 비용이 많이 안든다는...)
-세션의 지속성: 가능한 무제한의 시간(화려한 테크닉보다 프로그램의 안정성이 더 필요한...)
이 경우라면, 그 어떤 방법론으로 작성해도 별 무리없어 보입니다.
다양한 네트워크 프로그램 제작방법론이 있으나, 이러한 경우라면, 제작자가 가장 잘 할 수 있는 방법을 사용하되 안정적으로 작성하는게 좋겠습니다.
가장 자신있는 방법론을 채택하세요.
가장 좋은 프로그램은 잘~ 돌면 되는 것이라는...
성능좋은 socket server 를 만드는 것은 정말이지 오랫동안 고민
성능좋은 socket server 를 만드는 것은 정말이지 오랫동안 고민되었던 부분 인 것 같습니다. 저두 이런 저런 방법으로 시도를 해봤구요... 일단은 구체적으로 server 의 임무가 어느 것이지 정확히 따져본 다음에 적합한 방법을 정하는 것은 당연합니다. 그러나 그러기 위해 참고할만한 좋은 글을 소개 하죠...
http://www.kegel.com/c10k.html
그리고 저의 경우는 libevent 라는 라이브러리를 사용해봤습니다. poll, select 등등을 cross platform (플래폼과 상관없이) 하게 사용할 수 있도록 만든 library 인데 아이디어도 괜찮구요... single thread non-block socket 으로 서버를 만들때 좋다고 봅니다.
지금 하신 방법도 좋을듯 싶습니다.
300명 정도의 클라이언트는 위에서 말씀하셨듯이 많은 수가 아닙니다.
따라서 프로세스를 여러개 생성해가면서 할 필요는 없을듯 싶네요
지금하신 멀티 스래드 방식이 괜찮을것 같네요...
저도 비슷한 규모의 서버를 구현한 적이 있는데 멀티 스래드 방식으로 해도 무지 잘 돌아갑니다.
스래드를 객체화 시켜서 구현해 보세요... 재미있는 작업이 될 것입니다.
/***************************************************
* 가장 심플한 것이 가장 아름다운 것이다.
***************************************************/
댓글 달기