매일 15분 전공인증 3기 서울 정모

오랫만에 포스팅인데, 정모 후기 포스팅이다.
‘매일 15분 전공공부를 위한 모임’[각주1]이 벌써 3기째다. 늘 쳐지지만 자극을 많이 받는 모임.
이하 15분 공부방

2019년 1월에 갑자기 진행된 서울 정모의 회의록을 공유한다.


2019 seoul 1월 정모

  • 20:00:00 모임 완료
    • 코리안 타임 없이 다들 정확하게 20:00 정각에 모였다.
      • 부지런, 근면성실한 사람들의 모임이라는것을 만나자마자 느꼈다.

모임시작

  • 윤빠님이 에어닷 이야기를 원철님에게 물어봄
  • 대세 이어폰 이야기 시작
    • qcy 가 가성비가 좋다.
    • qcy2 가 나왔다.
    • 가성비가 킹왕짱이다.

자기소개

  • 아윤빠, 안드로이드 개발
  • 허원철, 게임 회사 서버개발
  • 어리양, blockchain fe, flash, action script 개발자였음
  • 권양, 79년생, AI 공부한지 몇개월, 최근 인공지능 쳇봇이나 콜봇에 관심이 생김
    • 새롭고 신기하고 재밋게 하고 있음
    • EXO 수호봇을 만들겠다.
      • 셀카, 음성 등등을 보내주는 봇이될 예정
  • 박찬호(??? 아직 가입 안되있음, 친구따라 모임에 나옴.), 센터 운영팀(콜센터 운영하는 삼성카드나, 요기요나) 서버 사이트 운영
  • Lone(갓수), 군대를 가려다가 나온 근무지가 맘에 안들어서 병특 알아보는 중. 외주 1년쯤 하고있다 요즘 놀고 있음.
    • 외주는 잡부마냥..
    • 프론트는 일반 타이피컬한 웹을 만들어봤다., node.js
    • 관심사가 매우 다양함
  • 후오오, 서버개발하는 잡부
    • 잡부

모인 이유

  • ‘어리양’님이 모이자고 한걸 후오오가 덥썩 물어서 일정을 추진했다.
    • 그냥 갑자기 보고 싶어서 ㅋㅋ
      • (서기 사족) 사실 전공공부 오픈채팅방에 근면성실한 사람들이 참 많다.
        • 다들 뭐하시는 분들인지 궁금함이 마구 생긴다.
  • 토이프로젝트 하고 있는것들 공유
  • ‘마기’님은 소중함. 밥 잘 사주시는 형이다.[각주2]

15분 공부방에서 활동 한게 된 후 느낀거

  • 후오오
    • 15분 공부방 짱짱맨, 간증을 시작합니다.
    • 나는 몹시 게으른데, 열심히 하시는 분들을 보고 감명 받아서 따라 하게됨.
    • 몇일 빠지더라도, 100일을 채워야 겠다 라는 마음가짐(만)이 생김
    • 공부 인증 외에도 개발 꿀팁들이 마구 올라와서 좋음
    • 사실 15분 공부방에 어떻게 들어오게되었는지 기억은 나지 않음
  • 아윤빠
    • 안드로이드방에서 수지아부[각주3]님 약에 팔려서 들어오게 되었다.
      • 갓원철님이 영혼의 라이벌이었다.
        • 매일매일 원철님이랑 같이 영혼의 공부 맞다이
        • 누가누가 열심히 하나 배틀이 시작되어 서로 성장해버렸다.
      • 4.5년차에 맞는 나의 실력을 키우기 위해서 열심히 하다가…
      • 슬럼프가 좀 있다가…
      • 끌려다닐만한 사람을 찾아라
        • 배울 사람들을 찾아다니면서 실력이 늘어난 것 같다
      • 곧 성공각
      • 어리양님이 아윤빠님을 칭찬해주었다.
  • 원철님
    • 1기때 열심히 했다.
      • 아윤빠님과 인증배틀
    • 주변에 그렇게 하는 사람들이 있으니까, 불타오르게 화하아아아 하게되었다.
    • (사족) 영문 블로그 링크를 자주 전달해준다.
    • 너무 열심히 하면 디스크 터지니 쉬엄쉬엄 하자
  • 어리양
    • 액션스크립트에서 프론트로 이직을 했음.
    • 어떻게하는지는 알겠는데 환경이 달라서
    • 머리로는 아는데 손이 안따라줌
    • reactive 방(오픈채팅)에 계신 수지아부님의 링크를 보고 공부를 해야겠다 라고 다짐을 하고 채팅방에 들어옴
    • 함수형방도 1년쯤 됨
      • 함수형프로그래밍 방 아껴주세요 (하트)
    • 어떻게든 15분씩 했다.
      • (사족 진짜 대단)
    • 머리아파도 틈틈히 공부했다.
      • (사족 진짜 대단.2)
    • 요콩님과 인증 배틀
      • (사족) 역시 라이벌이 있으면 크게 성장하는 것 같다.
    • 코틀린 공부가 당장 필요하지는 않지만,
      • 같이 공부하는게 참 좋다.
      • 공부도 공부지만, 어떤 사람들과 공부를 하느냐도 중요하다
    • 엉뚱한 프로젝트를 하고 있는데, 도전하고, 러닝메이트들이 있어서 할 수 있을 것 같은 느낌이 든다.
    • 안드로이드 앱 만들고 있다
    • Q. 인강 듣는거?
      • 인강 따로 듣는건 없고 Vue.js 토이프로젝트
      • 하스켈 스터디중
        • 가장쉬운 하스켈 <- 책 추천받음
  • 권양
    • 비트코인 방 가면 블록체인 기술을 가르쳐 줄 것으로 알고 방에 감
    • 인공지능 코인들을 보다가
    • 메인 잡과 인공지능이 시너지가 가능할 것 같다는 생각이 스침
    • 개발자들 공부하는거에 자극 받음 -> 나도 해야겠다
    • 비트코인방에서 수지아부님의 링크를 보고 유입
  • Lone
    • 어떻게 들어왔는지 기억이 안남
    • 뭐 하나만 파는게 아니라, 여러개의 뽐뿌를 막 생기는 모임이다
    • 관심사의 변경 히스토리
      • unity
      • node.jsk
      • c++, 옥찬우님 책을 사서… 방-치
      • 최근
        • python, flask, django
  • 박찬호
    • 개발자들 모여있다. 라고 해서 옴
    • Lone 의 소개로 옴
      • 친구랑 처음만나서 했던거 : unity
    • 백엔드 쪽 공부중

Q. 요즘 보고 있는 책이나 최근 주문한 책?

(이어서…)책안보는 개발자

  • 인터넷의 도큐멘트가 잘 되있음
    • 사실 공식 도큐멘트가 짱임
  • vs 이동시간에 뭔가 할게 없어서 책을 본다

Q. 업무툴로 추천할만한 것들 뭐 없나?

  • 와카타임
    • 코드 타임 트래킹…
    • 내가 업무시간에 어떤걸 얼만큼 하는지 트래킹해줌
    • 각종 IDE에 플러그인으로 장착가능
  • 노션
    • 역시 요즘 핫한 노션. 역시 쓰는사람이 있다.
  • 에버노트
    • 유료로..
  • bear + trello
  • 원노트
  • github issue
  • bitbucket

마무리

  • 다들 학구열이 높당.
  • 수지아부님은 짱인것 같다.
    • 아닌게 아니라 다들 수지아부님의 영향을 많이 받고 있음.
  • 개발자 생태계는 수도권이 아무래도 잘 되있다.
  • k는 무엇인가
    • 2017 드로이드 나이츠에서 나눠준 스티커의 정체불명 ‘K’ 심볼. 무슨뜻인지 끝내 알지 못했다.

각주

  1. ‘매일 15분 전공공부를 위한 모임’
    • 카카오톡 오픈채팅방. 매일매일 15분씩 전공공부를 하고 인증하자. 취지로 개설되어 현재 3기.
    • 지금(2019-02-12)은 3기지만, 2기 모집글
  2. ‘마기님’
  3. ‘수지아빠’
    • 못하는 것도, 모르는 것도 없는 수지아빠님
    • 자세한 설명은 블로그로 대신한다.

진짜 마무리

혼자 공부하는 것도 좋지만, 뛰어난 러닝메이트들과 함께 할 수 있다면 시너지가 배가된다.

Literal 변수와 Bind 변수

Literal 변수

SQL문장 작성시, WHERE절의 비교되는 값에 문자/숫자 상수값을 하드코딩해서 작성한 것이다.

변수값이 빈번히 변하는 쿼리를 Literal SQL로 작성하게 되면 DB의 Library Cache 내에서 매번 다른 쿼리로 인식되어 Hard parsing을 수행한다.

운영상의 특이사항은 없지만, 시스템 성능을 저하시킬 수 있다.

자주 사용하는 Literal SQL을 확인하여, 바인드 변수를 사용하는 것을 권장한다.

  • 예시
    SELECT * FROM EMP WHERE EMP_NO=’123’;

Bind 변수

SQL문장 작성시, WHERE절의 특정값을 표시하는 자리에 바인드 변수 형태(:B)로 작성하는 것이다.

Bind 변수를 사용하게 되면 최초 1번만 Hard parsing을 수행하고, 이후 동일 형태의 쿼리가 들어오면 이전에 수립한 실행계획(Library Cache)을 재사용한다. 불필요한 Hard parsing을 하지 않는다.

시스템 성능상에 더 효율적이다.

  • 예시
    SELECT * FROM EMP WHERE EMP_NO=:emp_no;

Hello, Service Discovery

다른 수많은 소프트웨어 기술과 같이 Service Discovery도 이전부터 존재하던 개념이다. 그러나 최근 클라우드 및 마이크로서비스 아키텍처의 부흥과 함께 종종 언급되며 우리들의 눈에 띄는 것처럼 보인다. 한번 이번 기회에 Service Discovery에 대해 간단히 알아보자.

Service Discovery

위키피디아에서는 Service Discovery에 대한 문서가 빈약한 편이지만 간단하게 Service Discovery는 네트워크 상에서 제공되는 서비스 또는 장치의 자동 탐지라고 정의하고 있다. MSA의 입장에서 살펴보면 네트워크로 연결되어있는 여러 서비스들을 자동으로 탐지하여 그 정보들을 관리하는 것이다. 네트워크 상에 A 서비스와 B 서비스가 존재하며 각 서비스는 HTTP RESTful API를 제공한다. A가 B의 API를 사용하기 위해서는 B의 IP와 포트 같은 주소가 필요하다. 같은 물리 서버에 동작한다고해도 최소한 자신과 같은 서버에서 동작한다는 사실과 포트는 알고 있어야할 것이다. 이렇게 A가 B의 주소 정보를 구체적으로 알고 있어야 한다는 사실은 A와 B의 구조에 몇가지 제한을 만들게 된다.

첫 번째로 B를 scale-out 하는 경우를 예로 들 수 있다. B가 보단 많은 트레픽을 처리하기 위해서 scale-out을 한다고 해보자. A는 추가된 B 서비스의 서버 주소 정보를 추가적으로 알아야한다. 개발자는 직접 A에 B와 관련된 설정이 해주어야할 것이다. 만약, A 뿐만이 아니라 C, D 서비스도 B를 이용하는 있었다면 모두 일일이 새롭게 설정을 해주어야할 것이다. 설정이 별로 어렵지 않고 그정도는 직접 해줘도 괜찮다고 할 수도 있다. 그렇다면 auto scale-out은 어떻게 해야할까? 들어오는 트레픽에 비례해서 자동으로 B의 인스턴스가 추가된다고하면 A, C, D는 어떻게 할 것인가? B 서비스가 별도의 로드밸런서에 연동되어 자동으로 부하분산을 해주고 있다고해도 역시 개발자가 직접 로드밸런서에 새롭게 추가된 추가적인 B 인스턴스에 대해서 설정을 해주어야하는 번거로운 작업이 존재한다.

두 번째로 클라우드 환경에서는 IP 같은 주소 정보가 매우 동적이라는 것이다. 어찌보면 위에서 잠깐 언급한 auto scale-out와 이어지는 이야기일 수도 있다. 클라우드 환경에서는 서버 인스턴스가 얼마든지 실시간으로 간단하게 추가 및 제거될 수 있다. 이 과정에서 부여받는 주소 정보는 예측이 불가능하다.

Service Discovery는 클라이언트가 주소를 명시적으로 알고 있어야한다는 제한점으로부터 우리를 해방시켜준다. Service Discovery는 서비스들의 주소를 자동으로 탐지하고 관리를 해주기 때문이다. Service Discovery에 의해 주소 정보가 관리되기에 클라이언트는 더 이상 서버의 주소 및 포트에 대해서 알 필요가 없으며 어떤 서비스가 존재한다는 것만 알면 된다. 다른 서비스와의 통신에 좀 더 추상화된 레이어를 제공한다고 볼 수 있다. 또한, 서버 측도 서비스 주소를 자동으로 탐지하여 관리하기에 보다 물리적인 인프라에 제약을 받지않고 다이나믹하게 서비스를 운영할 수 있다.

Service Registry

Service Discovery에서 네트워크 내의 각종 서비스에 대한 주소 정보를 저장하고 관리하는 중앙 서버를 Service Registry라고 부른다. 다른 서비스들의 주소 정보를 제공하므로 고가용성이 요구되지만 최신 Service Discovery 플랫폼들은 만에 하나 Service Registry가 죽어버리더라도 문제없이 서비스들 간에 통신이 가능하도록 방법을 제공하기 때문에 부담은 덜하다.

Pattern

Service Discovery는 크게 두가지 패턴을 가지고 있다. 하나는 Client-Side Discovery Pattern이며 나머지 하나는 Server-Side Discovery이다.

Client-side Discovery

Client-side Discovery

클라이언트가 직접 Service Registry로부터 특정 서비스의 주소 정보를 받아와서 통신을 하는 패턴. 클라이언트가 직접 주소를 가져와서 서비스와 직접 통신을 하기 때문에 불필요한 네트워크 부하를 줄일 수 있다. 또한, 클라이언트가 특정 서비스의 모든 인스턴스 주소를 알 수 있기 때문에 자신인 원하는대로 로드밸런싱을 할 수도 있다. 단 이점은 단점이 되기도 하는데, 자신이 서비스 주소를 가져오고 원하는대로 로드밸런싱을 할 수 있다는 말은 클라이언트가 Service Discovery를 위한 추가적인 기능을 개발해야된다는 말이기 때문이다.

Server-side Discovery

Server-side Discovery

이 패턴은 클라이언트가 Service Registry에 대해서는 전혀 몰라도 되는 패턴이다. 서버와 클라이언트 사이에는 요청 유형에 따라(예를 들어, URL 경로 등) 적절한 서비스 인스턴스로 전달을 해주는 라우팅 서버가 존재한다. 이 라우팅 서버는 Service Registry를 참고하여 서비스에 대한 주소 정보를 얻고 이를 바탕으로하여 클라이언트로부터의 요청을 서비스 인스턴스에 전달한다. 클라이언트는 로드밸런서와만 통신을 하기 때문에 따로 Service Discovery와 관련된 특별한 작업을 신경 쓸 필요가 없다. 하지만 로드밸런서는 SPOF(Single Point Of Failure)가 될 수 있기 때문에 매우 중요한 요소로서 높은 고가용성이 요구될 것이다.

Next - Service Discovery 구현체

다음 포스트에서는 Service Discovery 구현체를 몇가지 알아볼 것이다. 첫 번째로 Java로 개발된 Netflix의 Eureka에 대해서 알아보고, 두 번째로 Go로 개발된 HashiCorp의 Consul 이렇게 두 가지를 알아볼 것이다.

pm2와 config를 활용한 node.js app 실행 환경 관리

process managing

node.js 앱을 배포하다 보면, 모니터링, 프로세스 관리, std 로그 관리 등이 필요할 때가 있다. 요런 니즈로 사용하는 것들은 크게 forever, nodemon, pm2등이 있다.

forever,nodemon,pm2 npmtrends 생각보다 nodemon을 많이쓴다!?


그중에서도 pm2는 모니터링 및 프로세스의 현재 상태를 시각적으로도 잘 보여주고, 여러 프로세스를 관리할 때 용이하게 되어있어서 애용하는 도구다. 무엇보다 세련되게 생겼다.

http://pm2.keymetrics.io/

기존 pm2 1.x.x 버전을 쓰고 있는 서버가 있어서, 이번에 배포 환경 정리하면서 pm2 로 업그레이드하였고, pm2 2.x에서 나온 ecosystem을 활용했다.

ecosystem 외에도 clustering, deployment 등도 제공한다. 나중에 시간 내서 읽어보자. PM2 Documents

config

https://github.com/lorenwest/node-config

config 패키지를 사용하면 application 내에서 손쉽게 configuration에 접근할 수 있다. 물론 환경별로 configuration을 관리할 수 있고, default 값에 변경되는 값만 override 할 수도 있다.

pm2 + config

pm2의 ecosystem을 활용하면 실행 시에 NODE_ENV를 명시해서 넘길 수 있다.

pm2 ecosystem.config.js --env production

// ex) ecosystem.config.js
{
  "apps" : [{
    "name"        : "worker",
    "script"      : "./worker.js",
    "watch"       : true,
    "env": {
      "NODE_ENV": "development"
    },
    "env_production" : {
       "NODE_ENV": "production"
    }
  }]
}

전달받은 NODE_ENV 이름에 맞는 config 파일은 config/ 디렉토리 안에 추가해주면, application 전체에서 config로 쉽게 접근이 가능하다.

[Project Root]
  ├ (...)
  ├ package.json
  ├ config/
  │ ├ default.json // config 의 기본 파일이다.
  │ └ production.json
  │
  └ ecosystem.config.js

상호 순환 참조가 꼭 필요한가?

상호 순환 참조

많은 언어에서 상호 참조는 안티 패턴으로 인식된다. 참조를 한다는 뜻은 클래스(구현체, 모듈, 기타 등등) 하나를 설명하기 위해서는 다른 클래스의 도움을 받아야 한다는 것이다.

  • Class A가 B를 의존하고, Class B가 A를 의존하는 경우.
  • Class A가 B를 의존하고, Class B가 C를 의존하고, Class C가 다시 A를 의존하는 경우.

즉 의존 관계도를 그릴 때, loop 가 이뤄진 경우를 말한다. 프로젝트가 작을 때는 쉽게 파악이 되지만, 이해 관계자들도 떠나고, 프로젝트가 커져 의존관계가 큰 원을 그리는 경우 (A -> B -> C -> D -> E -> A)는 논리적으로 발견하기 힘들어진다.

class A {
    B b;
}
class B {
    A a;
}
//

class A {
    B b;
}
class B {
    C c;
}
class C {
    A a;
}

왜 안 좋은가?

패키지 내부에서의 상호의존은 경우에 따라 허용해야 할 수도 있지만 범용적인 예를 다뤄보자. 상호 의존을 하게 되면 의존을 하는 클래스들끼리 강한 결합을 하게 된다. A가 변했을 때, 죄 없는 B도 같이 변해야 할 필요성이 있다는 것이다. 강한 결합은 의도하지 않은 부수효과를 발생하고 결국 전체적인 질이 하락하게 된다. 정원에 난 잡초 하나를 뽑지 않고 놔두면, 잡초는 무럭무럭 옆으로 자라난다. 개발자는 자신이 관리하는 코드를 깨끗하고 명료하게 관리해야 할 책임이 있다.

어떻게 파훼해야 하는가?

대부분의 문제는 파인만 알고리즘으로 풀 수 있다. feynman_algorithm

  1. 문제를 쓴다.
  2. 매우 깊게 생각한다.
  3. 답을 쓴다.

Class A가 B를 참조해야 하는 이유를 골똘히 생각해보자. 왜 참조하고 있는가? 그리고 Class B가 A를 참조해야 하는 이유를 골돌히 생각해보자. 왜 참조하고 있는가?

의존성의 방향을 한쪽 방향으로 바꿔줄 필요가 있다. 의존성의 방향을 한쪽으로만 통제하면 변경에 영향을 받는 부분을 명확하게 이해할 수 있어진다.

혹은 A와 B를 모두 알고 있는 Class C를 만들어서 A와 B에서 의존적으로 하는 일을 위임받아서 하는 방법도 있다.

간혹 언어의 특성을 이용해서 문제를 잠시 회피하는 방법도 있다. (C++ 에서 포인터를 사용한다거나, 모듈을 하나씩 빌드한다거나.)

더 읽어보면 좋을 것들