aro dream

development, dream, human

이메일 서버 구축하기 (struct email server)

이번에 ucloud에 이메일 서버를 구축할 일이 있어서 진행하였는데…

생각보다 꽤 많은 일을 해야 했다. (귀찮게도…)

다음은 이메일 서버를 구축하기 위해 필요한 용어 정리~

  • DNS(Domain Name System):
    • DNS는 연결할 수 있는 서버 목록으로 acme.com과 같은 이름을 변환하고 특정 서버의 IP 주소를 찾기 위해 SMTP에서 사용하는 디렉토리이다. 발송 서버는 대상 서버의 주소를 DNS에서 찾아 수신인에게 메시지를 정확하게 라우트한다. DNS가 사용하는 두 종류의 레코드는 MX(Mail Exchanger) 레코드와 A 레코드이다.
  • A 레코드:
    • 호스트 이름을 서버의 IP 주소로 매핑한다.
  • MX(Mail eXchange) 레코드:
    • MX 레코드는 특정 도메인에 대한 메일을 수신하는 메일 서버를 지정하는 레코드이다.
      어떤 도메인에 MX 레코드로 받을 메일서버를 지정하면 그 도메인으로 오는 메일은 받을 메일서버로 전달된다. 메일을 받을 서버(MX record)명은 A레코드가 지정되어 있어야 한다. 따라서, MX 레코드를 설정하려면, 먼저 해당 메일 서버에 대한 A 레코드를 등록한 이후에 MX 레코드를 등록하고, MX 레코드의 데이터에 A레코드 호스트명을 입력하면 된다.
    • DNS 서비스의 표준에 의하면, 메일을 받을 서버(MX record)는 호스트이름이거나 도메인명이어야 한다. 표준대로라면 받을 메일서버로 IP 어드레스로 입력하는 것도 가능하지만, 이 경우 이를 IP 주소로 인식하는 것이 아닌 호스트명으로 인식하기 때문에, IP주소를 입력하면 실제로 메일을 받을 수가 없게 된다. 즉, 예를 들어 10.20.30.40 이라는 IP주소를 입력하게 되면, 메일을 보내는 서버는 DNS 정보에서 이 정보를 찾아와서 호스트명으로 인식하기 때문에, 10.20.30.40 의 맨 마지막 숫자인 40을 .com과 같은 도메인으로 인식하고, 이 40 도메인에 대하여, 메일서버 정보를 찾으나, 이러한 도메인은 존재하지 않으므로 결과적으로 메일을 받지 못하게 되는 것이다.
    • MX 레코드 즉, 메일 교환 레코드는 DNS(도메인 이름 시스템)의 리소스 레코드 유형이다. 이 레코드는 단순 메일 전송 프로토콜(SMTP)을 사용하여 인터넷 이메일을 라우팅해야 하는 방법을 지정한다. 각 MX 레코드에는 호스트 이름 및 선호도가 들어 있다. 호스트 이름은 이메일이 올바른 대상에 도착하도록 안내한다. 선호도는 여러 서버의 상대적 우선순위를 나타낸다.
    • 예를 들어, “alex@example.com” 같은 이메일 주소가 제대로 작동하도록 하려면, 도메인 “example.com”의 MX 레코드를 설정해야 한다. 이렇게 하려면 MX 레코드가 이메일 서버의 IP 주소나 도메인 이름을 가리키도록 해야 한다. 도메인 이름을 미리 등록한 경우, 해당 도메인 이름의 관리 콘솔(신청한 ISP업체 홈페이지에 있다)에서 이 설정을 수정할 수 있다.
  • 정방향 DNS:
    • 특정 DNS 레코드를 도메인 이름에 할당하는 프로세스. 이는 도메인 이름을 정확한 서버로 연결하는 것이다.
  • 역방향 DNS:
    • 역방향 DNS는 웹사이트의 숫자 주소(IP 주소)를 도메인/호스트 이름으로 변환하는 것을 말하며, 도메인/호스트 이름을 IP 주소로 변환하는 정방향 DNS 프로세스와 반대이다. 역방향 DNS는 지정한 IP 주소에 속한 도메인 이름/호스트를 찾는 것을 지칭하기도 한다. 이것이 이러한 프로세스를 역방향 DNS 조회라고도 하는 이유이다. 도메인 이름에 유효한 역방향 DNS가 있으면 IP 주소만 사용하여 접근할 수도 있다.
    • 역방향 DNS는 메일 시스템 실행을 위한 기본 요구 사항 중 하나이다. 역방향 DNS는 들어오는 메시지의 IP 주소가 인증된 도메인 이름과 일치하는지 확인하여 일치하지 않는 경우 해당 메시지를 차단하는 스팸 필터로 주로 사용된다. 메일 서버에 역방향 DNS를 설정하지 않으면, 메일 서버에서 보낸 메시지가 대부분의 주요 이메일 서비스에 의해 차단될 수 있다.
    • 역방향 DNS를 직접 설정할 수 없는데 계속해서 배달 문제가 발생하는 경우 정상적인 이메일 배달을 위해 다른 SMTP 서버를 추가하라. 이메일을 보낼 때 스패머로 취급되지 않도록 하려면 보다 더 잘 알려진 SMTP 서버를 사용하는 것이 좋다.

    • 일부 ISP는 zone의 일부를 사용자에게 위임할 수 있습니다. 따라서 사용자가 직접 자체 역방향 DNS를 호스팅할 수 있다. DNS 서버에서 PTR 레코드를 확인하여 역방향 DNS를 구성할 수 있다. PTR 레코드는 귀하에게 할당된 IP 주소를 제어하는 주체가 관리한다. 호스트가 하나 이상의 IP 주소가 포함된 IP 공간에 대한 역방향 DNS를 귀하에게 위임한 경우 이러한 주체는 귀하의 호스트 또는 귀하일 수 있다. 일반적으로 PTR 레코드는 in-addr.arpa 항목 앞에 오는 뒤에서부터 입력된 IP를 나타낸다. ISP와 함께 역방향 DNS 설정 — ISP 즉, 귀하의 IP 주소를 소유한 주체는 유일하게 적절한 PTR 레코드를 추가할 수 있다. 역방향 DNS 구성을 위해 ISP에 문의해야 할 수 있다.
  • SPF(Sender Policy Framework) 레코드:
    • 메일 서버 등록제라고도 불리는 이 설정 값은 메일을 이용하는 도메인에 설정하는 값이다. 발송한 메일서버의 IP와 DNS에서 설정되어 있는 TXT의 IP 값이 다를 경우에 수신 측에서 메일을 차단하는 방식을 말한다. 메일을 발송하는 서버의 IP와 도메인이 일치하는지 인증을 하며, 인증방법으로 SPF 레코드(TXT값)를 확인한다.
    • 주로 메일주소를 위장하여 스팸성 메일을 발송하는 것을 차단하기 위해 국내 주요 포탈사이트 및 기업 등에서 사용한다.
  • PTR 레코드 (Reverse DNS):
    • PTR 레코드 (Reverse Domain) 정책은 도메인이 아닌 IP를 질의하여 도메인을 확인하는 정책으로 수신측에서 메일 발송 서버의 IP를 조회하여 도메인이 등록된 PTR 레코드 값과 일치하면 정상메일로 판단하고 메일을 수신하겠다는 역방향 질의 방식이다. Reverse Domain의 일치 여부를 확인할 때 PTR 레코드를 조회하기 때문에 PTR 레코드와 Reverse Domain은 같은 의미로 통용된다.
    • SPF 레코드와 다른 점은 DNS 운영업체가 아닌 ISP업체 (KT, LG U+, SK, 하이라인넷 등)와 같이 IP 주소를 공급해준 업체에 등록을 해야 한다는 것이다. 따라서 자체적으로 메일시스템을 구축한 경우가 아니라면 메일 서비스를 제공하고 있는 업체에 연락해서 등록 요청을 하면 된다.
  • 화이트 도메인 (White Domain):
    • 공지, 안내 등 정상적으로 발송하는 대량 e메일이 스팸메일로 간주되어 RBL(Realtime Black List)에 등록되는 것을 방지하기 위해, 사전에 등록된 개인이나 사업자에 한하여 국내 주요 포탈사이트로의 email 전송을 보장해 주는 제도. 단, 화이트 도메인으로 등록되었다 하더라도 이후 모니터링을 통해 스팸 메일 발송 사실이 확인되면 즉각 차단 조치되며 화이트 리스트에서도 삭제될 수 있습니다.

국내의 경우 SPF 레코드가 스팸정책에 영향력이 높으며 해외의 경우 PTR 레코드가 스팸차단의 기준이 된다. 그래서 국내포탈이나 기업의 차단은 SPF 레코드 등록 및 화이트 도메인 등록을 중점적으로 체크해야 하며 해외메일 수신 차단의 경우는 PTR 레코드를 등록 후 체크해야 한다.

진행했던 일을 순서대로 정리해보면

  1. Domain을 구입한다.
    • 난 가격이 저렴한 hosting.kr에서 구매했다. communicationcloud.co.kr. 가격비교사이트에서 잘 비교해서 ISP를 고르면 된다.
  2. Domain을 산 ISP에 sub domain A 레코드를 등록한다.
    • Hosting.kr에서 ‘나의 서비스 관리/도메인 관리’ 페이지로 가서
    • communicationcloud.co.kr 도메인을 선택하고 나서
    • 아래로 내려가 ‘네임서버(서브도메인) 설정 관리’를 선택하고 나서 ‘신청하기’ 버튼을 누른다
    • ‘네임서버(서브도메인) 설정 관리’ 페이지에서 ‘서브도메인’ 항목에 ‘mail’을 넣고
    • ‘레코드타입’은 ‘서브도메인(A)’를 선택하고
    • ‘IP주소/레코드 값’ 항목에는 메일 서버의 IP (예: 111.222.333.444)를 넣고
    • ‘우선순위’ 항목에 적당한 값 (작을 수록 우선순위가 높다)을 넣고 ‘설정내용 추가’ 버튼을 누른다.
    • 내용이 잘 들어가 있는지 확인한 다음 ‘적용하기’ 버튼을 누른다.
    • nslookup 명령어를 통해 확인한다. 

      C:\Users\aro>nslookup mail.communicationcloud.co.kr
      서버: ns.xxxx.co.kr
      Address: 154.xxx.xxx.xxx

      권한 없는 응답:
      이름: mail.communicationcloud.co.kr
      Address: 111.222.333.444

  3. Domain을 산 ISP에 MX를 등록한다.
    • 마찬가지로 ‘네임서버(서브도메인) 설정 관리’ 페이지에서 ‘서브도메인’ 항목은 비워두고
    • ‘레코드타입’은 ‘MX레코드’를 선택하고
    • ‘IP주소/레코드 값’ 항목에는 메일 서버의 A 레코드 (mail.communicationcloud.co.kr)를 넣고
    • ‘우선순위’ 항목에 적당한 값 (작을 수록 우선순위가 높다)을 넣고 ‘설정내용 추가’ 버튼을 누른다.
    • 내용이 잘 들어가 있는지 확인한 다음 ‘적용하기’ 버튼을 누른다.
    • nslookup 명령어를 통해 확인한다. 

      C:\Users\aro>nslookup -type=mx communicationcloud.co.kr
      서버: ns.xxxx.co.kr
      Address: 154.xxx.xxx.xxx

      권한 없는 응답:
      communicationcloud.co.kr MX preference = 9, mail exchanger = mail.communicationcloud.co.kr

  4. Domain을 산 ISP에 spf를 등록한다.
    • 마찬가지로 ‘네임서버(서브도메인) 설정 관리’ 페이지에서 ‘서브도메인’ 항목은 비워두고
    • ‘레코드타입’은 ‘텍스트(TXT)’를 선택하고
    • ‘IP주소/레코드 값’ 항목에는 ‘v=spf1 ip4:111.222.333.444 -all’를 넣고
    • ‘우선순위’ 항목에 적당한 값 (작을 수록 우선순위가 높다)을 넣고 ‘설정내용 추가’ 버튼을 누른다.
    • 내용이 잘 들어가 있는지 확인한 다음 ‘적용하기’ 버튼을 누른다.
    • ‘IP주소/레코드 값’ 항목에 넣을 값은 아래 ‘SPF 작성 도우미’를 눌러 나에게 필요한 SPF 값을 생성한 후 넣는다. 입력시 앞뒤로 “”는 필요 없다.
    • nslookup 명령어를 통해 확인한다. 

      C:\Users\aro>nslookup -type=txt communicationcloud.co.kr
      서버: ns.hansol.co.kr
      Address: 154.10.6.11

      권한 없는 응답:
      communicationcloud.co.kr text =

      “v=spf1 ip4:211.251.236.49 -all”

  5. White List에 Domain을 등록한다.
    • 한국인터넷진흥원(http://www.kisarbl.or.kr)에 접속하면 화이트 도메인의 소개 및 등록과정을 상세히 알려주고 있다. 안내절차에 따라 개인 혹은 사업자가 직접 등록 신청을 해야하며 화이트 도메인을 등록하기 위해서는 위에 언급한 SPF 레코드가 DNS에 반드시 등록되어 있어야 한다.
  6. 서버를 올린 호스팅 업체 또는 상위 업체(IP를 부여한 업체)에게 PTR Record를 등록한다.
    • ucloud의 경우 직접 PTR 레코드를 등록요청 할 수는 없고 IP를 부여한게 kornet이기 때문에 https://dms.kornet.net/ 에 들어 가서 PTR 레코드 등록 요청을 해야 한다. (이거 땜에 내가 회원가입까지 했다…)
  7. email 서버를 구축한다.
    • 원래는 Linux에서 구축할 수 있는 이메일 서버를 찾았는데 적당한 걸 못찾았다. 그래서 hMail과 Mail Enable 둘 중에 고민을 했는데, 멀티 도메인에서 쓰기에는 Mail Enable이 좋을 것 같고, web mail까지 지원을 해서 Mail Enable의 Standard 버전 (Free~!)을 사용하였다. http://www.mailenable.com
  8. pop3, smtp, iMAP 설정 및 테스트를 한다.
    • 매뉴얼을 참조해서 적당히 설정 완료~!

생각보다 꽤 많은 손이 갔고, 오랜 시간이 걸렸다.

다음에 혹시 또 구축할 일이 있으면 위 순서를 참조하기 위해 정리~!

Advertisements

Redmine (Bitnami)에서 thin 서버가 사용하는 port 바꾸기 (windows)

금번에 외부 솔루션 하나를 테스트하기 위해 Redmine 서버에 같이 설치해서 사용하다가

port 충돌이 일어난다는 것을 알았다.

충돌이 일어나는 port는 3002번, thin_redmine2 서비스 였다.

외부 솔루션의 포트를 바꾸려고 알아봤지만 바꿀 수 없다는 대답을 듣고,

Redmine의 thin_redmine 서비스들의 포트를 바꾸는 법을 찾아 여기에 정리해 본다.

(의외로 오래 걸렸다능…)

 

모두 3개의 설정(configure) 파일의 내용을 바꿔주면 설정 완료~!

기존 thin_redmine:3001, thin_redmine2:3002 포트들을 thin_redmine:3009, thin_redmine2:3010으로 바꾸도록 하겠다.

 

  1. Redmine 설정 파일이 있는 폴더로 이동한다.
        Redmine이 설치되어 있는 폴더에서 Redmine의 설정 폴더로 이동한다.
          ex) C:\Bitnami\redmine-3.1.0-0\apps\redmine\conf
  2. httpd-vhosts.conf 파일 내용을 수정한다.
  3. httpd-prefix.conf 파일 내용을 수정한다.
  4. Redmine scripts 폴더로 이동한다
        Redmine이 설치되어 있는 폴더에서 Redmine의 scripts 폴더로 이동한다.
          ex) C:\Bitnami\redmine-3.1.0-0\apps\redmine\scripts
  5. thin_redmine 서비스들의 등록을 해제한다.
        serviceinstall.bat 배치파일을 실행시켜 thine_redmine 서비스들의 등록을 해지한다.
          ex) C:\Bitnami\redmine-3.1.0-0\apps\redmine\scripts\serviceinstall.bat REMOVE
  6. serviceinstall.bat 파일 내용을 수정한다.
        serviceinstall.bat 배치 파일의 ‘install’ 항목에서 this_redmine 서비스 시작시 포트 번호를 바꾸고자 하는 포트 번호로 수정한다.
      수정전)

        if not “”%1″” == “”INSTALL”” goto remove
        “C:\Bitnami\redmine-3.1.0-0/apps/redmine\scripts\winserv.exe” install “redmineThin1” -start auto “C:\Bitnami\redmine-3.1.0-0\ruby\bin\ruby.exe” “C:\Bitnami\redmine-3.1.0-0/apps/redmine\htdocs\bin\thin” start -p 3001 -e production -c “C:\Bitnami\redmine-3.1.0-0/apps/redmine/htdocs” -a 127.0.0.1 –prefix /redmine
        net start redmineThin1 >NUL
        “C:\Bitnami\redmine-3.1.0-0/apps/redmine\scripts\winserv.exe” install “redmineThin2” -start auto “C:\Bitnami\redmine-3.1.0-0\ruby\bin\ruby.exe” “C:\Bitnami\redmine-3.1.0-0/apps/redmine\htdocs\bin\thin” start -p 3002 -e production -c “C:\Bitnami\redmine-3.1.0-0/apps/redmine/htdocs” -a 127.0.0.1 –prefix /redmine
        net start redmineThin2 >NUL
      수정후)

        if not “”%1″” == “”INSTALL”” goto remove
        “C:\Bitnami\redmine-3.1.0-0/apps/redmine\scripts\winserv.exe” install “redmineThin1” -start auto “C:\Bitnami\redmine-3.1.0-0\ruby\bin\ruby.exe” “C:\Bitnami\redmine-3.1.0-0/apps/redmine\htdocs\bin\thin” start -p 3009 -e production -c “C:\Bitnami\redmine-3.1.0-0/apps/redmine/htdocs” -a 127.0.0.1 –prefix /redmine
        net start redmineThin1 >NUL
        “C:\Bitnami\redmine-3.1.0-0/apps/redmine\scripts\winserv.exe” install “redmineThin2” -start auto “C:\Bitnami\redmine-3.1.0-0\ruby\bin\ruby.exe” “C:\Bitnami\redmine-3.1.0-0/apps/redmine\htdocs\bin\thin” start -p 3010 -e production -c “C:\Bitnami\redmine-3.1.0-0/apps/redmine/htdocs” -a 127.0.0.1 –prefix /redmine
        net start redmineThin2 >NUL
  7. thin_redmine 서비스들을 등록한다.
        serviceinstall.bat 배치파일을 실행시켜 thine_redmine 서비스들을 등록한다.
          ex) C:\Bitnami\redmine-3.1.0-0\apps\redmine\scripts\serviceinstall.bat INSTALL
          <주의> INSTALL 철자를 꼭! 대문자로 한다. 아니면 해지가 된다…

 

이상이다~!

‘협업의 기술 (Team Geek A Software Developer’s Guide to Working Well with Others)’

지은이: 브라이언 피츠패트릭 (Brian W. Fitzpatrick), 벤 콜린스-서스먼 (Ben Collins-Sussman)

옮긴이: 장현희

출판사: 제이펍 (jpub)

이 책은 소프트웨어 개발자들간의 협업에 대한 이야기를 다룬다. 내용을 보면 개발 팀 관리에서 사용자 관리(?)까지 이 책에서 다루고 있다. 두 지은이가 꽤 오랜시간동안 경험해 온 이야기들을 잘 정리하여 여러 컨퍼런스 및 실전에서 써먹기까지 한 이야기들이라 현실적이라 말하고 있고, 내 생각에도 꽤 적용할 만한 내용들이 많다.

아쉽다면 번역이 잘된 편이기는 하지만 군데군데 내용 전개가 자연스럽지 못한 곳이 좀 있고, 그러다보니 내용이 잘 이해가 안되는 곳이 있다. 두 번 정도 읽으니 그런 곳도 이해가 되기는 한다. 그리고 외국 사례이고, 그것도 주로 구글과 SVN 개발 관련 사례다보니 우리의 현실과는 좀 다른 것도 있다. 그런 내용은 각자가 알아서 각자의 현실에 맞게 적당히 적용하는 것으로…


그룹프로젝트

차례

  1. 천재 프로그래머의 전설
    • 내 코드를 숨길 수 있게 도와주세요
    • 천재의 전설

      아직 마무리하지 못한 일을 다른 사람이 본다는 건 아주 불안한 일이죠. 다른 사람들이 진지하게 나를 판단하고 나를 바보라고 생각하는 것만큼이요.

    • 숨긴다는 것은 해로운 것이다
    • 결국은 팀이다

      소프트웨어 개발은 팀 스포츠이다.

    • 세 개의 기둥
      • 겸손(Humility)
          당신은 우주의 중심이 아니다. 또한, 전지전능하지도 않으며 항상 성공하는 것도 아니다. 자기 개선에 대해 항상 열려 있어야 한다.
      • 존중(Respect)
          당신은 함께 일하는 사람을 진심으로 존중할 수이썽야 한다. 그들을 인간으로 대하고, 그들의 능력과 업적에 감사해야 한다.
      • 신뢰(Trust)
          함께 일하는 사람들은 숙련된 인력이며, 항상 옳은 일을 할 것이라 믿고 적절하게 그들을 운영할 수 있어야 한다.

      모든 사회적 충돌은 대부분 겸손과 존중, 신뢰의 부족으로 인해 발생한다

    • HRT 실습
      • 자존심 버리기

        ‘겸손해진다는 것’은 누군가에게 당하기만 하는 것과는 다르다. 자신감을 갖는 것은 잘못된 것은 아니다. 단지 아는 체하는 행동을 삼가라는 뜻이다. 당신 자신이 현명한지 아닌지에 대해 걱정하는 것보다는 팀의 목표를 설정하고 조직의 자부심을 높일 수 있도록 ‘집단적’ 자부심에 대해 고려하는 것이 훨씬 낫다.

      • 베푸는 방법과 비판을 받아 들이는 방법 모두 배우기

        무엇보다 가장 중요한 것은 존중이 묻어나야 한다. 건설적인 비판을 하는 사람들은 진정 다른 사람을 위하며, 그 대상이나 대상이 하는 일이 향상되기를 원한다. 당신의 동료를 존중하고 건설적인 비판을 하되, 예의를 갖추는 법을 배워야 한다. 누군가를 진정으로 배려하는 마음이 있다면 요령껏 유용한 표현을 선택하게 될 것이다. 하지만 이 기술은 많은 연습을 거쳐야 얻을 수 있다.

        “이봐, 나는 이 부분의 흐름 제어가 약간 혼란스러운 것 같아. 여기에 xyzzy 코드 패턴을 적용하면 좀 더 명확하고 유지보수가 쉬워지지 않을까?”

      • 빨리 실패하라, 그것에서 배워라, 그리고 반복하라
      • 학습을 위한 시간을 아끼지 마라
      • 인내하라
      • 주변으로부터 영향을 받아들여라
    • 다음장에서는
  2. 환상적인 팀 문화는 어떻게 만들까
    • 문화란 무엇인가?

      당신의 팀 문화는 좋은 사워도우 덩어리와 같다. 당신이 배양한 씨균(당신의 종자)이 당신의 도우(즉, 새로운 구성원)에게 주입되어 이스트균과 박테리아(당신의 팀 구성원)와 함께 성장함에 따라, 마침내 훌륭한 빵 덩어리(당신의 팀)가 탄생하게 되는 것이다.

    • 왜 당신이 관심을 가져야 하는가?

      팀 문화에 있어 흥미로운 점은, 매우 강력하게 정의된 문화를 구축한다면 그 문화가 스스로 선택을 하게 될 것이라는 점이다. 오픈 소스 세계에서 HRT원칙을 근간으로 깔끔하고, 고급스러우며, 유지보수가 쉬운 코드를 작성하는 것을 중시하는 프로젝트는 그들이 존경하고, 신뢰하며, 깔끔하고, 고급스러우며, 유지보수가 쉬운 코드를 작성하는 사람들과 일하고 싶어 하는 엔지니어들을 매료시킨다.

    • 문화와 사람

      소프트웨어의 세계에서는 제품을 구현하는 엔지니어에게는 뛰어난 창의성을 요구하며, 훌륭한 엔지니어를 원한다면(그리고 그들이 계속해서 업무를 수행하게 하려면), 그들을 위한 문화를 만들고 그들이 안전하게 아이디어를 공유하고 의사 결정에 참여할 수 있도록 해야 한다. 만일 팀 단위 업무를 잘 수행하는 뛰어난 엔지니어를 원한다면, 훌륭한 엔지니어들을 고용하는 것부터 시작해야 한다. 우리가 알고 있는 많은 훌륭한 엔지니어들은 거대한 산업 분야에서 자신들이 뭔가를 더 배울 수 있는 팀에 매력을 느낀다.

    • 성공적인 문화의 의사소통 패턴
    • 높은 수준의 동기화
      • 사명
      • 능률적인 회의
      • ‘지리적으로 협업이 어려운’ 팀에서 일하기
      • 디자인 문서
    • 일상적인 논의
      • 메일링 리스트
      • 온라인 채팅
      • 이슈 추적기 사용하기
    • 엔지니어링의 일부로서의 의사소통
      • 코드 주석
      • 소스 코드에 자신의 이름 넣기(‘작성자 태그’ 이슈)
      • 모든 커밋에 대해 코드 리뷰 요구하기
      • 실제 테스트와 릴리즈 프로세스 수립하기
    • 결국은 코드에 대한 것이다
  3. 모든 배에는 선장이 필요하다
    • 공백에 대한 본질적인 혐오감
    • @비난받는 관리자
      • 리더‘는 새로운 ‘관리자‘이다

        전통적인 관리자들은 일을 어떻게 할 것인지를 고민하는 반면, 리더는 무엇을 할 것이지를 고민한다. 그리고 그 일을 해낼 방법을 찾기 위해 그들의 팀을 신뢰한다.

      • 유일하게 무서운 것은… 글쎄, 모든것
    • 헌신적인 리더

      관리자의 가장 중요한 역할이 가정의 건강과 행복을 추가하는 집사처럼 팀에 봉사하는 것이며, 우리가 ‘헌신적인 리더십‘이라고 부르는 덕목을 적극 수용하는 것이다. 헌신적인 리더로서 당신은 겸손과 존중, 그리고 신뢰가 공존하는 분위기 형성에 주력해야 한다. 이는 엔지니어 스스로는 버릴 수 없는 관료주의적 장애물을 제거하고, 팀이 합의를 이끌어 내는 데 도움을 주거나, 심지어는 늦은 시간까지 일하는 팀을 위해 저녁을 사는 것을의미할 수도 있다. 헌신적인 리더는 팀의 균열을 방지할 뿐 아니라 필요한 때 조언을 하기도 하지만, 자신의 손을 더럽히는 것을 두려워하지도 않는다. 헌신적인 리더가 수행하는 유일한 관리한 팀의 기술적, 사회적 건전함을 관리하는 것이다.

    • 안티패턴
      • 안티패턴: 무능력한 구성원의 고용
      • 안티패턴: 저성과자들에 대한 무시
      • 안티패턴: 사람사이의 이슈에 대한 무시
      • 안티패턴: 모든 이들의 친구되기
      • 안티패턴: 고용 기준과 타협하기
      • 안티패턴: 팀을 아이 취급하기
    • 리더십 패턴
      • 자존심을 버려라
      • 선사가 되어라

        당신에게 조언을 구하는 엔지니어는 당신이 그의 문제를 해결해 주는 것을 원하는 게 아니라 그가 문제를 해결할 수 있도록 도와주기를 원하는 것이며, 그가 원하는 도움을 주는 가장 쉬운 방법은 그에게 질문을 하는 것이다.

      • 촉매가 되어라
      • 스승이자 멘토가 되어라
      • 명확한 목표를 설정하라
      • 정직하라
      • 행복을 관찰하라
      • 그 외의 팁과 요령

        최고의 엔지니어들을 (그들의 바람과는 반대로) 관리자 역할로 밀어 넣는 회사들을 볼 때마다 우리 필자들은 항상 놀라곤 한다. 대부분은 그 결과로, 팀은 유능한 엔지니어를 잃는 대신에 수준 이하의 관리자를 얻게 된다.

        새로운 물결을 일으킬 때를 알아야 한다.

        기다린다는 것은 프로세스에 필연적으로 발생할 엄청난 피해를 잠시 연기시키는 것 빡에 되지 않는다. 따라서 행동해야 하며, 그것도 빨리 행동해야 한다.

    • 사람은 식물과 같다

      서로 다른 엔지니어를 키우기 위해서는 서로 다른 것들이 필요하다.

      • 내적 동기부여와 외적 동기부여
    • 최종 의견
  4. 유해한 사람들과 협업하기
    • ‘유해함’의 정의
    • 팀 강화하기
    • 위협 감지하기
      • 다른 사람의 시간을 존중하지 않기
      • 자존심
      • 과도한 특권의식
      • 어수룩한 또는 혼란스러운 커뮤니케이션
      • 피해망상
      • 완벽주의
    • 유해함 무찌르기
      • 완벽주의자의 에너지를 다른 곳으로 돌리기
      • 에너지를 좀먹는 녀석들한테는 먹이를 주면 안된다
      • 너무 감성적이 되지 말 것
      • 분노 속에 담긴 진실을 주목하라
      • 친절함으로 괴물들을 물리쳐라
      • 포기할 때를 알아야 한다
      • 멀리 내다보라
    • 최종 의견

      어리석음으로 충분히 설명될 수 있는 일을 악의의 탓으로 돌리지 마라 – Robert J. Hanlon

  5. 조직 관리 기술
    • 장점과 단점, 그리고 전략
    • 이상: 팀이 회사 내에서 어떤 기능을 해야 하는가?
      • 이상적인 관리자와 함께하는 삶

        만일 당신의 관리자가 HRT 원칙을 이해하는 헌신적인 리더이며 당신의 성공을 돕는 것에 관심이 있는 사람이라면 몇 가지 간단한 일을 통해 당신의 관리자가 자신의 역할을 쉽게 수행할 수 있도록 도울 수 있으며, 그 덕분에 당신 자신이 더욱 생산적이고 가치있는 팀 구성원이 될 수 있다. 일을 처리할 때 더 많은 책임감을 갖자. 위험을 감수하고 실패를 두려워하지 말자. 성인으로서 행동하자. 당신이 확신하지 못하는 일에 대해서는 질문을 하자.

    • 현실: 당신의 주변 상황이 당신의 성공에 방해가 될 때

      행복한 가정은 대부분 비슷하다. 모든 불행한 가정은 각자 나름대로 불행하다. – Leo Tolstoy, Anna Karenina

      • 좋지 않은 관리자와 함께하는 삶
      • 조직 내에서 정치를 일삼는 사람들
      • 좋지 않은 조직
    • 조직 관리하기
      • 권한보다는 용서를 구하는 것이 쉽다
      • 길을 얻을 수 없다면 길을 만들자
      • 관리 역량 향상을 위해 학습하자
      • 행운과 호의의 경제학
      • 안전한 위치까지 승진하기
      • 힘 있는 친구를 찾을 것
      • 바쁜 임원에게 부탁할 때는 메일을 사용하자
    • 두 번째 계획: 퇴사하기
      • 옳은 일을 하고 해고될 때를 기다리자
    • 전혀 희망이 없는 것은 아니다
  6. 사용자도 사람이다
    • 대중적 인지도 관리하기
      • 첫 인상에 주목하라
      • 적게 약속하고 더 많이 주자
      • 업계의 분석가들을 존중하며 일하자
      • 당신의 소프트웨어의 사용성은 어느 정도인가?
      • 대상을 선택하라
      • 진입 장벽에 대해 고민하자
      • 사용자가 아니라 사용성을 측정하자
      • 속도의 문제
      • 모든 것을 제공하려고 하지 말자
      • 게을러지지 말자
      • 복잡함을 숨기자
    • 사용자와의 관계 관리하기

      사용자들은 무엇보다도 자신들의 말을 들어주기를 원한다

      • 잘난 체하지 말자
      • 인내심을 갖자
      • 신뢰와 즐거움을 만들자
      • 사용자를 기억하자

        마케팅: 사람들이 당신의 소프트웨어를 어떻게 인식하고 있는지 알고 있으며, 사람들이 인지할 수 있도록 개입 여부를 결정한다.

        사용성: 소프트웨어는 사용하기 쉽고, 빠르고, 친숙하며, 접근이 쉬워야 한다. 그렇지못하면 사용자들은 떠나게 될 것이다.

        고객 서비스: 장기 고객들과의 적극적인 교류는 소프트웨어의 혁신과 사용자 확보에 영향을 끼친다.

Google Breakpad를 이용하여 Crash Dump 떨어뜨리기

한 사이트에서 개발한 프로그램이 가끔 이유없이 죽고 있었다.

다른 사이트는 그런 일이 없는데 그 사이트에서만 발생하고 있는 일이었다.

보통은 로그를 이용하여 원인을 파악하는데,

그 사이트는 로그가 너무 많이 쌓여서 로그 유지 기간이 짧았고,

반면 프로그램이 다운되는 일은 어쩌다 (한, 두 달에 한 번정도) 발생되는 일이라서 골치가 아팠는데

이 기회에 Breakpad를 적용해서 해결해 보려고 마음 먹었다.

1. Breakpad 소개

Google breakpad home page : https://code.google.com/p/google-breakpad/

Google Chrome처럼, 여러 플랫폼을 지원하는 프로그램을 위한 크래시 덤프를 다루기 위한 툴이다.

Win32 개발자들이 접하는 minidump나, *nix 개발자들이 접하는 coredump를 breakpad 포맷(이라기보단 함수 맵)으로 변경하고, 이를 이용해서 플랫폼이 바뀌어도 같은 형태의 스택 트레이스(stack trace)를 볼 수 있게 해주는 툴이다.

좀 더 세부적으로 보면 다음과 같은 부분으로 되어 있다.

(개별 사용자 용) 크래시가 발생했을 때, 이를 breakpad 에서 사용하는 포맷으로 덤프를 남겨주는 부분: in-process 덤프만 있는 게 아니라, 다른 프로세스에서 dump를 남기는 방식(out-of-process dump)도 지원한다
(Build-System 용) 디버그 정보를 읽어서 breakpad 내부 형식으로 바꾸는 부분 : Win32 pdb 나 –g 옵션을 넣고 빌드한 *nix 바이너리에서 심볼 데이터를 뽑아낸다
(Crash Collector 용) 1에서 나온 정보를 가지고 2를 이용하여 스택 트레이스를 뽑아내는 부분

사실 2, 3 부분은 Windows 환경에서만 프로그래밍 한다면 그다지 중요하지 않다. 어차피 breakpad 도 덤프 자체는 minidump를 쓰고 있고, breakpad 소개의 Build / User / CrashCollector system 다이어그램에 나온 과정도, 디버그 정보가 애초에 분리되어 빌드 되는 환경(/Z7 같은 걸 쓰면 모르겠지만)에선 그다지 더 편해질 건 없다.

그렇지만 1에서 Windows named-pipe를 써서, 크래시가 발생한 프로세스가 아니라, 안전하게 동작 중인 프로세스에서 덤프를 남길 수 있다는 점(Out-of-process 덤프), 그리고 이 덤프 남기는 부분의 코드에서 제공하는 callback 지점들이 적당해서, 이걸 이용해서 간단하게(!) 실제 배치된 시스템의 덤프를 중앙의 서버로 모으는 작업을 간편하게 작성할 수 있었다.

일단 out-of-process로 덤프를 남길 수 있기에, 크래시가 발생한 바이너리에서 할 수 없는 일들 – 메모리 신규 할당, heap 메모리 참조, 기타 등등 – 을 맘대로 해도 되기 때문에 웹 서버나 다른 서버로 덤프를 보내는 일이 쉬워진다.

– rein’s world

out-of-process

breakpad 의 가장 큰 특징은 out-of-process 를 지원하는 것이다. 크래시를 처리하는 함수에서 앞에서 말한 다양한 기능을 추가한다면 제대로 동작하지 않을 수도 있다. 간단한 예로, 사용자에게 의견을 받는 윈도우를 띄운다고 할 때 메인 스레드의 메시지 루프가 깨지면 윈도우 자체를 볼 수 없게 된다.

크래시가 발생한 프로세스 밖(out-of-process)에서 처리하면 이와 같은 문제를 줄일 수 있다. 그래서 크래시 발생을 처리하기 위해 보다 많은 것을 제공할 수 있다. 물론 in-process 도 지원하기 때문에 필요에 맞게 골라 쓰면 된다.

크로스 플랫폼

멀티플랫폼 지원을 고려한다면 breakpad 는 좋은 선택이 될 수 있다. breakpad 를 사용한다면 크로스 플랫폼에 대한 고민을 줄여줄 수 있다.

– 야드버즈의 개발 로그

breakpad를 현재 사용하고 있는 대표적인 프로그램은 Chrome Browser, Firefox Browser, Picasa, Google Earth 등이다.

2. Breakpad 받기

Breakpad는 SVN을 이용하여 내려 받을 수 있다.

SVN은 서버까지 필요 없으므로 Windows용 tortoiseSVN을 설치하면 된다.

tortoiseSVN을 설치했으면 다음과 같이 내려 받는다.

1) Command 창을 열어 먼저 설치하고 싶은 폴더로 이동한뒤, 다음과 같이 실행한다.

svn checkout http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad-read-only

그러면 google-breakpad-read-only 폴더가 생기면서 그 폴더로 checkout을 하고, 소스를 내려 받는다.

2) 탐색기에서 설치하고 싶은 폴더를 만든 뒤, 마우스 오른쪽 버튼을 눌러 로 ‘SVN Checkout’을 선택한다.

URL of Repository 항목에 ‘http://google-breakpad.googlecode.com/svn/trunk’ 를 넣고  OK를 누른다.

그러면 그 폴더로 checkout을 하고, 소스를 내려 받는다.

3. Breakpad build 하기

  1. 1. python 2.x버전 설치: breakpad는 gyp를 이용하여 빌드 시스템을 생성한다. gyp를 사용하기 위해서는 python 2.x버전이 필요하다. gyp가 아직 python 3.x버전과는 호환성 문제가 있는 것 같다. (gyp 자체 문제 + gyp 설정 파일문제가 복합적인듯 하다.)
  2. gyp 소스 가져오기: breakpad 소스 내에 gyp가 내장되어 있지만, 내장 gyp는 버전관리가 안되어 있는듯 하다. gyp 최신 버전이 적용이 안되어 있다. 현재 작성 시간 기준 gyp 최신 소스에는 Visual studio 2012까지 빌드 시스템을 생성할 수 있도록 되어있다. gyp 최신버전을 사용하기 위해서 gyp를 google 저장소에서 checkout하면 된다.
  3. gyp로 빌드 시스템 생성: src\client\windows 폴더에서 ..\..\tools\gyp\gyp.bat breakpad_client.gyp 를 실행하면 솔루션 파일과 프로젝트 파일이 생성되는 것을 볼 수 있다.
  4. Visual Studio로 빌드: 만들어진 솔루션 파일을 열어 그 안에 있는 build_all 프로젝트를 빌드하면 된다.

4. Breakpad test

테스트용 프로그램(crash_generation_app 프로젝트)이 솔루션에 포함돼 있으므로 따로 만들 필요는 없다. 이 테스트 프로그램을 이용하면 in-process 뿐만 아니라 out-of-process 미니덤프도 만들어 볼 수 있다. 여기에서는 out-of-process 미니덤프를 만드는 방법을 소개하겠다.

프로그램을 실행하기에 앞서 C:\Dumps 폴더를 만들어야 한다. 이 폴더를 만들지 않으면 미니덤프를 저장하다가 실패한다.

준비가 다 됐다면 프로그램을 실행해 보자. 제대로 된 out-of-process 를 테스트하기 위해서는 프로세스를 두 개 띄워야 한다. 두 번째 프로세스를 띄울 때 서버를 실행할 수 없다는 에러 메시지가 뜨지만 무시해도 좋다. 그런 다음 서버가 실행되지 않는 프로세스에서 Client -> Deref Zero 메뉴를 선택해 강제로 크래시를 발생시키면 C:\Dumps 폴더에 미니덤프 파일이 생성되는 것을 볼 수 있다.

– 야드버즈의 개발 로그

참고자료

Breakpad 로 CrashReporter 만들기 – rein’s world

원도우즈 환경에서 breakpad 사용하기 – 야드버즈의 개발 로그

[정보] 소프트웨어, 잉여와 공포 – 박상민

웹 서핑중 좋은 글을 발견하여 소개한다.

소프트웨어, 잉여와 공포         by 박상민

글 중에 인상적인 구절을 옮기면,

잉여와 해커 정신이 실리콘밸리의 근본이라면, 한국의 근본 정서는 무엇일까 생각해 본다. 나는 “공포(fear)” 라고 생각한다. 공부를 못하면 루저가 된다는 공포, 숙제를 안해가면 맞을거라는 공포, 소프트웨어때문에 삼성이 무너진다는 공포, 6/25 시절로 다시 돌아갈지도 모른다는 공포.

우리는 개인, 집단 모두 공포에서 벗어나려 치열하게 살고있다. 뛰어난 해킹 잠재력을 가진 얼마나 많은 사람들이 공무원과 교사 시험을 준비하고 있을까? 이건희 회장이 주기적으로 이야기하는 “삼성 최대의 위기”는 정말 언제로 오는 걸까? (SW는 정말로 위기라고 생각한다). 한국형 안드로이드라는 “성스로운 똥” 아이디어를 낸 공무원들은 한국 SW의 미래가 얼마나 두려웠을까?

결론적으로 공포가 지배하는 문화에서 잉여와 해커의 정신은 살아 날 수가 없다. 최근 얼마나 많은 수의 한국 해커들이 국제 오픈소스 프로젝트 (예: Apache) 에 참여하고 있는가 세어본적이 있다. 정말 몇안되는 사람들 뿐이었다.

생각해보면 나도 그런 것 같다, 공포라는 것에 사로잡힌…

과연 우리 사회에서 ‘잉여’라는 게 얼마나 존재할 수 있는지 궁금하다.


아래는 댓글중 발췌하였다.

리누스 토발즈가 한 이야긴데, survivalsocial orderentertainment 자기는 이렇게 세 단계에 사람이 머물러 있다고 생각하고, 오픈소스 운동은 entertainment 에 속하는 사람들이 한다더라고요…

우리나란 social order 상태에 머물러 있는것 같은데, 보수언론은 공포를 자극해서 자꾸 survival쪽으로 끌어내리려 하는것 같습니다. 대기업들은 social order에 머물러 있게 하고요. 사실, 경제적 여건은 entertainment 쪽으로 이동을 해도 될만큼 잘 사는것 같거든요..

말씀하신대로 미국도 예전에 survival을 너무 강조하다보니 오히려 그 반작용(히피 문화라던가요) 에 의해 entertainment 으로 이동한것 아닌가 싶기도 하고요. 암튼 이런것도 공부해 보면 재밌을것 같습니다.

아래는 같이 읽으면 좋은 글들…

빠른 base64 encoding/decoding 구현 by C++

이번에 필요에 의해 base64 encoding/decoding을 구현해야 할 일이 있었다.

사용하던 라이브러리 (ACE/POCO)에 base64 기능이 있었지만, 라이브러리 전환도 고려해야해서 직접 구현하기로 했다.

이런저런 구현 소스들을 찾아 테스트해본 결과는 다음 코드가 가장 속도가 빨랐다.

static const char MimeBase64[] = {
‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’,
‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’,
‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’,
‘Y’, ‘Z’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’,
‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’,
‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’,
‘w’, ‘x’, ‘y’, ‘z’, ‘0’, ‘1’, ‘2’, ‘3’,
‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘+’, ‘/’
};

static int DecodeMimeBase64[256] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
};

typedef union {
struct {
#ifdef LITTLE_ENDIAN
unsigned char c1, c2, c3;
#else
unsigned char c3, c2, c1;
#endif
};
struct {
#ifdef LITTLE_ENDIAN
unsigned int e1:6, e2:6, e3:6, e4:6;
#else
unsigned int e4:6, e3:6, e2:6, e1:6;
#endif
};
} BF;

int HUMRedisObject::_base64enc(char *src, int src_size, char **result)
{
int i, j = 0;
BF temp;

int size = (4 * (src_size / 3)) + (src_size % 3 ? 4 : 0) + 1;
(*result) = new char[size];

for (i = 0 ; i < src_size ; i = i+3, j = j+4)
{
temp.c3 = src[i];
if ((i+1) > src_size) temp.c2 = 0;
else temp.c2 = src[i+1];
if ((i+2) > src_size) temp.c1 = 0;
else temp.c1 = src[i+2];

(*result)[j] = MimeBase64[temp.e4];
(*result)[j+1] = MimeBase64[temp.e3];
(*result)[j+2] = MimeBase64[temp.e2];
(*result)[j+3] = MimeBase64[temp.e1];

if ((i+2) > src_size) (*result)[j+2] = ‘=’;
if ((i+3) > src_size) (*result)[j+3] = ‘=’;
}
(*result)[size-1] = ”;
return size;
}

void HUMRedisObject::_base64dec(char *src, char *result, int *length)
{
int i, j = 0, src_length, blank = 0;
BF temp;

src_length = strlen(src);

for(i = 0 ; i < src_length ; i = i+4, j = j+3){
temp.e4 = DecodeMimeBase64[src[i]];
temp.e3 = DecodeMimeBase64[src[i+1]];
if(src[i+2] == ‘=’){
temp.e2 = 0;
blank++;
} else temp.e2 = DecodeMimeBase64[src[i+2]];
if(src[i+3] == ‘=’){
temp.e1 = 0;
blank++;
} else temp.e1 = DecodeMimeBase64[src[i+3]];

result[j] = temp.c3;
result[j+1] = temp.c2;
result[j+2] = temp.c1;
}
*length = j-blank;
}

원본은 다음과 같다.

빠른 base64 인코딩/디코딩 소스 – by ironiris (https://kldp.org/node/109436)

base64 인코딩/디코딩의 원리 – by I’m MK! (http://www.iamcorean.net/130)

원본과는 다르게 메모리 할당을 함수내에서 구현하고 그 결과를 돌려 주는 형태로 바꾸었다.

원래 할당을 한 구역내에서 해제하는 것을 원칙으로 하고 있으나,

이 경우는 편의성을 생각해서 위와 같이 구현하였다.

VC++에서 Precompiled header 정리

간간히 겪던 문제였었는데 이번 기회에 정리를 할 겸 포스트~!

1. Precompiled header 란?

compiling

Precompiled header에 대해 잘 정리된 글이 있어 잠시 가져와 본다.

C/C++ 언어에서 헤더 파일은 C 전처리기(preprocessor) 에 의해 자동적으로 소스 코드를 포함하게 된다. 그런데 일부 헤더 파일의 경우 방대한 크기의 소스 코드를 포함할 수 있고 (예를 들면 window.h), 이런 코드들을 매번 컴파일하면 컴파일 시간이 매우 길어지게 된다. 그래서 자주 바뀌지 않는 기본적인 라이브러리들의 경우에 컴파일 시간을 줄이고자 컴파일러가 사전에 헤더 파일들을 미리 컴파일 해 놓고 쓸 수 있게 하고 있다. 이렇게 컴파일 시간을 줄이기 위해 사전에 컴파일한 결과물이 VC의 경우 pch(precompiled header)라는 확장자 명으로 저장된다. 비주얼 스튜디어의 솔루션 폴더에 생기는 프로젝트명.pch 가 바로 그것이다. precompiled header 를 사용할 경우 precompiled header 로 지정한 헤더 파일 및 소스 코드는 컴파일시에 컴파일 되지 않고 pch의 결과물을 가져다 사용하게 되는 것이다. – soyoja님 블로그 (http://soyoja.com/372)

그렇다. 매번 컴파일이 오래 걸리는 것을 방지해주기 위하여 사용하는 것이다~!

물론 쓰면 편리한 기능인 것이고…

2. ‘c1083 cannot open precompiled header file’

Visual Studio 에서 가끔, 특히 Clean하고 난 이후에, 다음의 에러 메시지를 내고 컴파일이 안 되는 경우가 있다.
‘c1083 미리 컴파일된 헤더 파일을 열 수 없습니다.(c1083 cannot open precompiled header file)’
이 에러에 대해 msdn문서를 찾아보면, ‘결국 pch파일이 생성되지 않았다./pch파일이 존재하지 않는다.’에 결론이 도달하게 되고,
프로젝트 설정을 이것저것 건드리는 경우가 있다.
그러다보면 어떨 때는 간단히 해결이 되고,
어떨 때는 됐다, 안됐다 하고 아주 속이 터지는 경우가 있을 수 있는데,
이것 역시 잘 정리된 글이 있어 잠~시 가져와 본다.

종종 프로젝트 설정을 잘 못 만지면 pre compiled header 에 대한 오류를 볼 수 있습니다. (나만 그런가?)
그냥 pre compiled header 를 사용안함으로 해버리면 해결 됩니다.

그러나 이건 근본적인 해결책은 되지 못하겠지요. 또한 pre compiled header 를 사용하는 이점을 모두 버려야 하구요 🙂

pre compiled header 옵션이 몇가지가 있는데 모두 어떻게 동작하는지 정확히는 알지 못하겠습니다.
아무튼 난 기본 설정(미리 컴파일된 헤더 파일 사용)을 쓰고 싶단 말입니다 !!
자 ~ 원래 기본 설정(/Yu) 로 바꿔두고요..빌드를 해봅시다.
당연히 미리 컴파일된 헤더를 찾을수 없다고 떠들어 대는 컴파일러 메세지를 볼 수 있을것입니다.

이는 “미리 컴파일된 헤더” 로 지정된 stdafx.h 때문에 그렇습니다.
stdafx.cpp통해서 pch 파일을 생성하고, 나머지는 모두 만들어진 pch 를 통해서 컴파일이 됩니다.
어디선가 pch 파일을 무턱대고 복사해놓고, 빌드를 하면 일치하지 않는다는 등의 또 다른 컴파일러의 불만을 보게 되겠지요. 

stdafx.cpp 의 속성을 위와 같이 미리 컴파일된 헤더 생성(/Yc) 로 두면 문제는 해결됩니다.

– somma 님 블로그 (http://somma.egloos.com/2723641)

그렇다! Project 전체의 precompiled header 설정은 /Yu로, stdafx.cpp 파일의 precompiled header 설정은 /Yc로 하는 것이었다~!!

3. 쓸까? 말까?

내가 개발하고 있는 솔루션은 windwos, linux 모두 지원하도록 개발하고 있어서, visual studio에서는 그냥 켜고 사용하고 (그동안 별 문제가 없어서…), GCC에서는 ‘precompiled header’ 설정은 그냥 끄는 게 편하다고 생각했었다. 하지만 내용을 정리해놓고 보니 그래도 사용하는게 이래저래 장점이 많은 기능이다.

그.렇.다.면~!!!

precompiled header는 사용하는게 좋다~!

전화, 교환기, 컨택센터에 대한 소개글

얼마전 사내 발표에서 우리 사업부에 대한 소개를 할 기회가 생겼다.
그래서 발표준비하느라 정리했던 문서가 있는데
나름 정리가 잘된 것 같아 블로그에 올리기로 했다.
자료를 여기저기서 찾아 정리하느라 Reference를 모두 정리하지 못해 미안한 마음이…
(자료 발췌를 허락해 주신 xguru님께 다시 한번 감사를…)

전화,교환기,컨택센터0

전화,교환기,컨택센터1

전화,교환기,컨택센터2

전화,교환기,컨택센터3

전화,교환기,컨택센터4

전화,교환기,컨택센터5

전화,교환기,컨택센터6

전화,교환기,컨택센터7

전화,교환기,컨택센터8

전화,교환기,컨택센터9

전화,교환기,컨택센터10

Reference

개발 프로세스 관리를 위한 Redmine 설치 및 사용

이번에 우리팀에서 이슈트래커가 필요하게 되어 겸사겸사 Redmine을 설치하게 되었다.

처음에는 trac을 알아보고 설치라려 했으나 Redmine이 사용이 더 편리해보여 Redmine을 설치하였다.

설치는 Redmine에 필요한 Apache, mySQL, Redmine, 등을 각각 설치하는 것 보다는 Bitnami의 Stack을 이용하는 것이 편리해보여 Bitnami의 Redmne Stack을 설치하였다.

그런데 이미 SVN을 사용하고 있기 때문에 Bitnami Redmine Stack을 설치했다가 기존의 SVN과의 연동이 되지 않을까 걱정을 하였지만, 다행히 쉽게 연동이 되었다.

이제 그 설치 순서를 정리해본다.

먼저 설치 환경은 Windows Server 2008 R2를 사용하고 있고, 이미 VisualSVN이 설치되어 사용중에 있다.

1. Bitnami Redmine Stack 설치

먼저 다음 url에서 Bitnami Redmine Stack을 내려 받는다.

http://bitnami.com/stack/redmine

페이지에 보면 설치본도 있지만 vmware와 같은 가상머신에 설치할 수 있는 이미지도 있다. vmware나 virtual box와 같은 가상화 솔루션을 사용하고 있다면 편리하게 설치를 완료할 수 있다. 나는 설치본을 내려 받았다.

다운을 받다 보면 로그인하고 받으면 나중에 더 편리하다고 하지만, 사이트에 계정을 만들기 귀찮은 사람은 ‘No thanks, just take me to the download’을 선택해 그냥 다운 받을 수 있다.

(2014년8월1일 현재 bitnami-redmine-2.5.1-2-windows-installer.exe 버전을 받을 수 있다)

Bitnami Redmine Stack 설치는 말 그대로 ‘다음’, ‘다음’만 누르면 설치가 끝난다. 모두 Apache Web Server, MySQL, SVN, Redmine, 등을 설치하게 된다.

모두 설치하는데에는 약간 시간이 걸린다.

2. Redmine 설정

설치가 모두 끝난 후, ‘모든 프로그램>Bitnami Redmine Stack>redmine manager tool’을 실행시키면 다음과 같은 화면이 나타난다.

이미 MySQL Database, Apache Web Server, Subversion Server, Thin_redmine, Thin_redmine2가 실행이 되어 있을 것이다.

설치시 모든 옵션을 기본으로 설정하였다면 ‘http://localhost/redmine’으로 접속한다.

초기화면이 뜨고 설치시 설정했던 관리자 계정의 아이디와 패스워드로 접속해서 다음과 같은 화면이 뜨면 성공적으로 설치가 된 것이다.

3. 기존의 VisualSVN과 연동

기본 형상관리로 기존에 사용하던 VisualSVN을 연동하는 방법도 있을 것 같다. 하지만 나는 그냥 새로 생성되는 프로젝트나 이슈를 기존의 VisualSVN으로 연동하는 방법을 썼다.

새로 생성한 프로젝트를 선택한뒤, ‘설정’에서 ‘Repositories’를 선택한다.

왼쪽 아래의 ‘New repository’를 누르면 다음과 같은 화면이 나온다.

‘SCM’ 항목은 ‘Subversion’을 선택하고,

‘Identifier’ 항목에는 형상을 나타낼 수 있는 이름을 적는다.

‘URL’ 항목에 기존에 사용하던 VisualSVN의 연결하고 싶은 url을 기입한다. (예: http://192.168.0.10/svn/IS-Package/HUM/trunk)

‘Login’ 항목에는 VisualSVN에서 사용하는 아이디를,

‘Password’ 항목에는 VisualSVN에서 사용하는 암호를 넣고 ‘Create’ 버튼을 누르면 완료~!

프로젝트의 ‘Repositories’ 항목을 선택하면 다음과 비슷한 화면이 나오게 될 것이다.

4. SVN의 Comment와 Redmine의 이슈 상태 연동

이렇게만 설정하고 사용하게되면 개발자들이 이슈를 처리할 때, 개발한 소스를 SVN에 이런저런 Comment와 같이 올리고나서, 다시 Redmine에 접속해서 이슈의 상태를 변동해야 할 것이다. 이런 번거로움이 개발자들이 Redmine을 기피하게하는 요인이 된다고 한다.

다행히도 Redmine에는 SVN의 Comment의 내용과 연동해서, Comment의 미리 정해진 키워드를 인식해서 상태를 변동시키는 기능이 있다.

‘Administration’ 메뉴에서 ‘Settings’를 선택하고, ‘Repositories’ 탭을 선택하면 다음과 같은 화면이 나온다.

이 화면의 ‘Referencing and fixing issues in commit messages’ 항목들이 연동을 가능하게 해주는 설정이다.

화면 아래의 테이블 항목에서 ‘Tracker’ 항목에는 원하는 이슈 타입을 선택하고, ‘Fixing keywords’ 항목에 사용하고 싶은 키워드들을 입력한다. 여러 개의 키워드들을 입력할 때는 쉼표’,’를 넣고 이어 써주면 된다. ‘Applied status’ 항목에 해당하는 상태 값을 선택하고, ‘% Done’ 항목에서 해당하는 진행 퍼센티지 값을 선택하면 된다. 나는 키워드로 ‘fixed,closed,end’를 입력하였고, 세 키워드들에 대해 상태는 ‘Closed’, 퍼센티지는 ‘100%’를 선택하였다.

‘Save’ 버튼을 눌러 저장한 후, 실제 소스를 약간 수정하여 Commit를 해보았다. Comment에 기존에 쓰던 형식 아래에 다음과 같이 입력하였다. #다음에는 해당 이슈의 번호를 적는다.

CONDUCTOR:

    redmine integration test

    end #2

Commit를 하고 Redmine에서 살펴보니 바로 적용되지는 않았다. 하지만 프로젝트의 ‘Repositories’ 탭을 선택하고 다시 살펴보니 적용이 되어 이슈가 ‘Closed’ 상태로 변경이 되어 있었다. 키워드의 위치는 comment의 처음, 중간, 마지막 어디에 적어도 상관이 없었다.

실제 설치하고 나서 살짝 사용해 보니 설치보다 어떻게 사용하는가가 더 중요할 것 같다. 예로 프로젝트는 어떤 식으로 생성해 관리를 하고, 각 프로젝트에 이슈(일감)는 어떤식으로 생성해 할당, 관리를 할 것인가…그리고 사용하는 팀원들이 적절하게 사용할 수 있도록 쓰는 사람들에게 알맞게 적용하는 것이 큰 관건이 될 것 같다.

 

팁1: Redmine 스킨 바꾸는 법

Redmine에는 기본적으로 스킨이 3개정도 들어가 있는데 너무 밋밋하다 싶으면 다음과 같이 스킨을 바꿀 수 있다.

1.다음 URL로 들어가 스킨을 고른다.

redmine theme list 에 들어가 맘에 드는 스킨을 고른다. 화면캡처가 있는 것도 있으니까 확인해 볼 수도 있다. 보통 최신 리스트의 것들이 아무래도 최근 유행하는 것들이다. 스킨을 선택해 스킨을 내려 받는다.

2. 스킨을 설치한다.

설치라고 별거 없다. 받은 파일들을 redmine 설치된 곳 아래에 있는 ‘public/themes’ 폴더에 폴더째로 복사해 넣는다.

3. redmine을 재시작 한다

redmine을 재시작하지 않으면 새로 설치한 스킨을 인식하지 못한다. 가볍게 redmine을 재시작 시킨다.

4. 새로 설치한 스킨을 선택한다

Administration 메뉴의 Settings 메뉴에서 ‘Display’ 항목을 고르면 스킨을 선택할 수 있다. 리스트박스를 선택하면 새로 설치한 스킨이 보일 것이다. 선택하고 ‘Save’ 버튼을 누르면 끝~!

 

설치시 도움이 된 문서들:

http://bitnami.com/stack/redmine – Bitnami Redmine Stack 페이지

http://opentutorials.org/course/438/2397 – 생활코딩 사이트의 redmine 소개 및 사용방법

http://blog.naver.com/PostView.nhn?blogId=jadin1&logNo=70120494742 – redmine과 svn의 연동

http://blog.jidolstar.com/552 – MS윈도우에 Subversion 서버 설치하기 – Http환경으로 만들기

 

REST에 대한 기사 정리

REST에 대해 공부하며 내 생각에 괜찮은 내용을 가진 기사들을 모아 봤다.

다 읽고 내 나름대로 내용을 간단히 정리해 볼 생각이다

 

[REST ①] RESTful 웹서비스에 대해 알아보자!

http://iamcorean.tistory.com/22

[REST ③] Security and REST Web Services by Richard Mooney

http://iamcorean.tistory.com/63

 

[REST] The Resource-Oriented Architecture-1

http://greatkim91.tistory.com/13

 

REST 아키텍처를 훌륭하게 적용하기 위한 몇 가지 디자인 팁
http://spoqa.github.io/2012/02/27/rest-introduction.html

RESTful API를 설계하기 위한 디자인 팁
http://spoqa.github.io/2013/06/11/more-restful-interface.html

 

REST 아키텍쳐에 대한 연재를 시작합니다.
http://bcho.tistory.com/322

REST 연재-1회 REST 아키텍쳐의 기본
http://bcho.tistory.com/321

REST 연재-2회 Advanced REST
http://bcho.tistory.com/344

REST Overview (Draft)
http://www.slideshare.net/Byungwook/rest-ovewview

REST API 디자인 가이드
http://bcho.tistory.com/914

RestFul이란 무엇인가?
http://blog.remotty.com/blog/2014/01/28/lets-study-rest/

 

당신의 API가 RESTFUL 하지 않은 5가지 증거
http://beyondj2ee.wordpress.com/2013/03/21/%EB%8B%B9%EC%8B%A0%EC%9D%98-api%EA%B0%80-restful-%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-5%EA%B0%80%EC%A7%80-%EC%A6%9D%EA%B1%B0/

 

RESTful API Design: what about errors? | Apigee Blog
http://lab.ash84.net/post/86954494579/restful-api-design-what-about-errors-apigee-blog

 

일관성 있는 웹 서비스 인터페이스 설계를 위한 REST API 디자인 규칙

http://blog.outsider.ne.kr/925