쓰레드를 이용하여 소켓 서버를 생성할 때...

inu111의 이미지

제가 쓰레드를 이용하여 소켓 서버를 작성하고 있습니다.

제가 작성 중인 소켓 서버는 최소 300명 이상의 클라이언트가

매우 긴 시간 동안 접속을 유지하면서 주기적으로 전달하는

메시지를 처리할 수 있어야 합니다.

특별히 쓰레드 간에 공유할 데이터가 존재하지 않으며

연결이 끊어지면 다시 연결을 해서 통신 채널을 확보해야

하는 특징을 가지고 있습니다.
(쓰고 보니 특징이랄 것도 없네요 ;;)

처음에는 fork()/select()/poll()/thread() 중 여러 가지를

생각해보았는데, 많은 수의 접속을 오랜 시간동안 유지하기에는

어떤 기법이나 기법의 조합이 성능상 뛰어날지 잘 몰라서

일단 쓰레드로 만들어 보았습니다.

혹시 저처럼 많은 수의 접속(최소 동시 접속 300개 이상)을

처리해 보신 분이 계시면 어떤 기법이 가장 뛰어날 수 있는지

조언 부탁드립니다.

학교 과제로만 만들어 보던 소켓 프로그램을
성능까지 생각해보며 만들어 보려고 하니까
쉽지가 않네요...^^;;

kdoll의 이미지

프로세스와 리눅스에서 지원하는 쓰래드는 단점이.. 커널의 자원을

소모한다는데 있습니다.

많은 사용자의 접속을 받아들이면서도 시스템의 자원을 효율적으로

사용하는 방법중에.. 제가 사용하는 방법은..

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 스풀버퍼가 각 소켓마다

존재할 필요가 있겠지요.. (전 버퍼구현으로 리스트를 사용합니다)

kihongss의 이미지

오고가는 패킷이 그리 많지 않다면, 클라이언트 하나당 쓰레드
물리는것보다는 폴링방식이 낫지 않을까요?

무우의 이미지

yaws 라고 erlang 으로 만든 서버가 있습니다.
병렬개념이 도입된 함수형 언어정도로 알고 있습니다.
아파치보다 기술적으로 우수하고 우아하다고 합니다..
http://yaws.hyber.org/

익명 사용자의 이미지

-접속자수 : 수백(그리 많지 않은 수입니다. 한 4천은 넘겨야 좀 크다 보지요.)
-클라이언트간 서버를 통한 상호작용: 없음(프로그램을 단순화할 수 있지요)
-재접속 : 특별한 경우(네트워크 오류나 관리등) 외에 없음(포크등을 이용해도 무방한 경우, 재접속 비용이 전체에 비해 그리 비용이 많이 안든다는...)
-세션의 지속성: 가능한 무제한의 시간(화려한 테크닉보다 프로그램의 안정성이 더 필요한...)

이 경우라면, 그 어떤 방법론으로 작성해도 별 무리없어 보입니다.
다양한 네트워크 프로그램 제작방법론이 있으나, 이러한 경우라면, 제작자가 가장 잘 할 수 있는 방법을 사용하되 안정적으로 작성하는게 좋겠습니다.
가장 자신있는 방법론을 채택하세요.

가장 좋은 프로그램은 잘~ 돌면 되는 것이라는...

iamslash의 이미지

성능좋은 socket server 를 만드는 것은 정말이지 오랫동안 고민되었던 부분 인 것 같습니다. 저두 이런 저런 방법으로 시도를 해봤구요... 일단은 구체적으로 server 의 임무가 어느 것이지 정확히 따져본 다음에 적합한 방법을 정하는 것은 당연합니다. 그러나 그러기 위해 참고할만한 좋은 글을 소개 하죠...

http://www.kegel.com/c10k.html

그리고 저의 경우는 libevent 라는 라이브러리를 사용해봤습니다. poll, select 등등을 cross platform (플래폼과 상관없이) 하게 사용할 수 있도록 만든 library 인데 아이디어도 괜찮구요... single thread non-block socket 으로 서버를 만들때 좋다고 봅니다.

lovemyin의 이미지

300명 정도의 클라이언트는 위에서 말씀하셨듯이 많은 수가 아닙니다.
따라서 프로세스를 여러개 생성해가면서 할 필요는 없을듯 싶네요

지금하신 멀티 스래드 방식이 괜찮을것 같네요...

저도 비슷한 규모의 서버를 구현한 적이 있는데 멀티 스래드 방식으로 해도 무지 잘 돌아갑니다.

스래드를 객체화 시켜서 구현해 보세요... 재미있는 작업이 될 것입니다.

/***************************************************
* 가장 심플한 것이 가장 아름다운 것이다.
***************************************************/

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.