죽지 않는 서버를 만드려면...

kang0203의 이미지

안녕하세요...
지금 서버를 만들고 있는데여...
죽지 않는 서버를 만들때 어떤것들을 염두해 두고 개발을 해야 하는지여?
지금은 Unix Network programming책을 보구 간단하게 만들어 봤는데여..
너무 허접한것 같아서여...
물리적인 것 말구여 프로그래밍상에서 염두해두어야 할 부분에 대해 고수님들의 의견을 듣고 싶습니다.
그럼 좋은 하루되세요..

s0me의 이미지

대부분의 경우 프로그램이 죽는일은 메모리 침범일것 같은데요.
서버에 요청된 페이지의 입력값이 요구되는 형식과 다른 경우..
문자열 파싱도중 잘못된 매칭으로 프로세서가 죽는것 같습니다.
integer 에 string 혹은..이런 경우가 되겠죠
먼저 프로세서에 메모리 누수 부분이 없는지 확인이 된다면..
다양한 스트링으로 서버에 요청을 하여 걸러내지 못하는 부분이 있는지 테스트해보세요.
..다른문제로 죽는일은 없더군요.

sjang의 이미지

죽지 않는 대몬을 만든다라는 것이 프로그램 내부 동작과 함께
동작 모델도 중요하지요.

fork
prefork
thread

하나의 연결요청에 대해서 독립된 프로세스가 생겨서 동작한다면
fork 된 프로세스는 내부오류로 인해 죽더라도,
main 프로세서는 죽지않고 계속 서비스 되지요.
이 방법이 새로운 클라이언트에게는 죽지않고 계속 서비스 되는 것으로
보이지요.
thread 방식은 단일 프로세스 안에서의 동작이므로, thread 하나에서
메모리 참조 에러가 발생하면 프로세스 자체가 죽어 버립니다.

아시다시피, 모델에 따른 장단점은 있습니다.
말씀하신 책에 잘 나와 있지요.

The Future !!!

sunyzero의 이미지

일반적으로 윗분의 말씀대로 메모리침범을 막기 위해서 모든 데이터는 기록시 길이를 항상 체크하여야 하며, 쓰레드 사용시에는 thread safety한지 확인해야 하며, 메모리의 할당/해제시 확실하게 해야 합니다.

그럼에도 불구하고 서버가 죽을 경우를 대비하여 재실행 및 복구가능한 루틴은 꼭 있어야 합니다.

========================================
* The truth will set you free.

낙엽의 이미지

program이 비정상적으로 동작한다면 core를 내고 죽어야 하는것이 당연한 수순입니다. 그리고 나서 그 처리를 해주고 거기에 따라 재실행 하는 것이 낳겠죠.

죽지않는 서버를 만들수는 있겠지만 어떤 오류가 발생할 지 모르는 상황에서 무작정 안죽는것만이 능사는 아니겠죠.

서버 오동작 -> core 발생 -> 종료 -> 처리 -> 재실행

이런 수순을 밟는것이 낳을것같은데요..

choissi의 이미지

서버의 기능을 보면 네트워크 입출력을 관리하는 부분과
서버 본래의 업무를 처리등으로 나뉘어 지는데,
이 둘을 분리해서 구성하는게 좋다고 봅니다.

업무로직은 여러명이서 작업을 하는 경우가 많은데,
그러면, 구성원의 이해도나 능숙도의 차이에 의해서
버그가 존재하기 마련입니다.

하지만 아래와 같은 구조라면,
업무서버만 오류로 죽고 이 오류는 접속서버가 알아채고
클라이언트에 무리없이 오류를 전달할수 있게 됩니다.
또, 업무 서버는 이 들 프로세스를 관리하는 프로세스가 존재해서
다시 재시작 할수 있겠죠.

Quote:

클라이언트(1) <----> 접속서버 <---> 업무서버(1)
클라이언트(2)            업무서버(2)
클라이언트(3)            업무서버(n)
....
클라이언트(n)

접속서버 입장에서는 순수하게 네트워크에 관련된 코드만
있으면 구조가 간단해지면서 버그에 대한 위험도 줄어 들껍니다.
그리고, 로드의 분배도 구현이 쉬워 지구요..

울랄라~ 호기심 천국~!!
http://www.ezdoum.com

MasterQ의 이미지

낙엽 wrote:
서버 오동작 -> core 발생 -> 종료 -> 처리 -> 재실행

이부분은 일반적으로 어떻게 구현하나요? (Monitoring 부분...)

조언바랍니다.

sunyzero의 이미지

일반적으로 어느정도까지 모니터할것인가에 따라서 다릅니다만, 가장 간단하고 쉬운 방법으로는 SHM메모리에 각종 프로세스 정보를 기록해두고 있다가, 죽게되면 signal을 받을테고, 이 경우 shm에 자신의 상태를 쓰고 죽어주면 되겠죠.

얼마나 많은 정보가 필요하는가에 따라서 조금씩 다릅니다. 특정 UDP를 받거나 쏘거나 하면서 체크하는 경우도 있고요.

========================================
* The truth will set you free.

xfmulder의 이미지

죽지않는 프로세스 혹은 죽지않는 서비스라면 inittab 에 등록하세요.

/etc/inittab 에 action 을 respawn 으로 두고 init q 하면 root 가 이 프로세스를 실행시켜 줍니다. 죽더라도 재실행 시키줍니다.

프로세스자체 오류때문에 죽을수 있기 때문에 프로세스 실행시 최초에 무조건 sleep(5) 하는 루틴을 넣으세요. 최악의 경우에 이 프로세스는 무한히 죽었다 살았다를 반복하게 될수도 있으니까!

int main()
{
    sleep(5) ;   // ----> 일단 5초 쉬었다 시작하도록 합니다. 
                      // ----> 아무리 잘짜여진 프로그램도 곧바로 죽을수 있음.

   //적당하게 시그널 처리부분 넣고요..
    signal(SIGSEGV, program_exit); --> 세그먼트폴트 (프로그램에러) 죽고나서 root가 재기동시켜준다. 
    signal(SIGTERM, SIG_IGN);  ------> kill 몀령 무시.
    signal(SIGHUP, SIG_IGN);   -----> SIGHUP 도 무시. 
    signal(SIGINT,   program_exit); ---> SIGINT 도 무시하거나 종료후 재실행. 

내 자식들도 나처럼 !!

낙엽의 이미지

MasterQ wrote:
낙엽 wrote:
서버 오동작 -> core 발생 -> 종료 -> 처리 -> 재실행

이부분은 일반적으로 어떻게 구현하나요? (Monitoring 부분...)

조언바랍니다.

Monitoring이라기 보다는 Loging에 가깝죠..
프로세스에서 오동작을 발생시에 나오는 시점의 exception과 시그널을 받아서 Loging 하신다고 생각하시면 맞겠네요. 그리고 Loging을 마치고 재기동을 하면 될 것 같네요.

MasterQ의 이미지

낙엽 wrote:
MasterQ wrote:
낙엽 wrote:
서버 오동작 -> core 발생 -> 종료 -> 처리 -> 재실행

이부분은 일반적으로 어떻게 구현하나요? (Monitoring 부분...)

조언바랍니다.

Monitoring이라기 보다는 Loging에 가깝죠..
프로세스에서 오동작을 발생시에 나오는 시점의 exception과 시그널을 받아서 Loging 하신다고 생각하시면 맞겠네요. 그리고 Loging을 마치고 재기동을 하면 될 것 같네요.

어떻게 시그널을 받으실건가요 (Monitoring 없이)? :wink: :wink:

towngo의 이미지

Quote:

하나의 연결요청에 대해서 독립된 프로세스가 생겨서 동작한다면

단순히 앞뒤 안가린다면 이분 의견에 강력히 한표.. ^^;

머.. 제 허접한 경험상으론 C로 만들었건 머건 첨에 버그 땜시 가끔 죽기도 하지만..
버그 좀 잡고 나면 소프트웨어가 잘못되서 죽는 경운 거의 없었네욤..
머 리소스 문제라든가 에러 핸들링만 잘 해 준다면 말이죠.. ^^

대게의 경우는 하드웨어가 맛탱이 가서.. -_- +
것두 꼭 주말이나 쉬는 날... 짜증..

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.