2020년 6월 16일 화요일

ZeroMQ 기본 개념

• ZeroMQ 등장의 배경

요즘 많은 애플리케이션은 LAN 또는 인터넷과 같은 일종의 네트워크를 통해 확장되는 구조를 갖는다. 이는 응용 프로그램 개발자로 하여금 일종의 메시징을 수행하게끔 한다.  일부 개발자는 메세지-큐 제품을 사용하지만 아직도 대부분은 TCP를 사용해 메시징을 수행한다. 이 프로토콜은 사용하기 어렵진 않지만 여러 케이스에 대응해 안정적인 방식으로 동작시키긴 어렵다. (메시지의 전달을 보장한다던가, 서로 다른 아키텍처 간의 메시지 전달이라던가 하는.) 게다가 재사용 가능한 메시징 시스템을 구축하는 것은 매우 어려운 일이다. 만들어진 제품을 사용하더라도 상대적으로 복잡하고 비싸며 제대로 쓰기까지 몇 주에서 몇 달이 걸릴 수도 있다.

최근의 대부분의 메시징 프로젝트는 중심에 broker를 두는 방식으로 설계되어 있다. Broker는 어드레싱, 라우팅, 큐잉등의 역할을 수행하게 되는데 이러한 구조를 따르면 네트워크의 복잡성을 꽤나 줄여주기 때문에 혜택이 크다. 하지만 broker 자체가 병목이 되거나 broker가 제대로 동작하지 않을 때 전체 네트워크에 위협이 되는 등의 문제가 생긴다. 이러한 구조를 따르는 프로젝트에선 두번째 세번째 네번째 broker를 추가로 띄우는 방식으로 이를 보완하지만 이는 다시 구성을 복잡하게 만들어 버린다.

ZeroMQ는 위 요구사항과 문제점을 해결하기 위해 만들어졌다. ZeroMQ는 쉽고 가벼운, 모든 프로그래밍 언어와 모든 OS에서 동작하는 메시징 기술이다. ZeroMQ는 다양한 기술적 이슈와 장애를 대응하면서 마치 작은 서버처럼 동작한다.


• ZeroMQ가 제공하는 패턴

ZeroMQ에선 어느 쪽이 연결되고 어느 쪽이 바인딩되는지는 중요하지 않다. 그리고 ZeroMQ는 전달하고 받는 데이터의 길이만을 알고 있다. 보내고 받는 데이터가 종단에서 어떻게 해석되는가에 대해선 관여하지 않는다. 그러한 부분의 책임은 사용자에게 있다. 복잡한 데이터 형식을 주고 받는다면 프로토콜 버퍼 같은 라이브러리를 사용할 수도 있을 것이고, 단순하게 문자열 데이터를 주고받을 수 있을 것이다. (C로 작업하는 경우 수신한 문자열에 null 바이트 처리를 해주어야 한다.)

ZeroMQ는 요청과 응답이 있는 REP-REQ 패턴, 발행-구독의 PUB-SUB 패턴 등을 제공한다. PUB-SUB 패턴의 경우 비동기로 동작하는데 SUB 소켓은 PUB 소켓보다 먼저 실행되더라도 첫 n개의 메시지를 놓칠 가능성이 있다. SUB 소켓과 PUB 소켓이 서로 연결되는데 걸리는 시간이 짧지 않기 때문이다. 이런 경우에 대해 SUB 소켓의 연결을 확인한 뒤 메시지를 발행할 수 있는 기법이 마련되어 있다. (단순히 sleep 한 뒤 동작하게 하는 방법도 있지만 권장되진 않는다.)

마지막으로 PUSH-PULL 방식을 제공한다. 단방향으로 흐르는 데이터 스트림을 다루는데 효과적이다. 단지 초기 데이터 또는 task를 내보내는 연결점에 데이터를 끌어오는 worker를 붙이거나 떼는 방식으로 네트워크를 확장하거나 축소할 수 있다. 하나의 연결점에 연결된 다수의 소켓은 고르게 처리된다. 이걸 fair-queuing이라고 부른다. fair-queuing 이지만 문제점이 없진 않은데 여러 개의 노드를 같이 동작시켜도 초기 연결 과정에서 가장 먼저 연결된 worker에 일시적으로 작업이 쏠리는 경우가 발생할 수 있다.

ZeroMQ 애플리케이션은 context를 만드는 것으로 작업이 시작된다. 하나의 프로세스는 반드시 하나의 context만을 만들어 사용해야 한다. context는 프로세스에서 사용하는 모든 소켓을 담는 컨테이너로 동작한다. 여러 개의 context를 만들어 사용할 수도 있지만 ZeroMQ는 이를 서로 다른 인스턴스(프로세스)로 인식하게 되므로 일반적인 사용 방식은 아니다. (리눅스의 fork()를 쓴다면 context를 생성하는 zmq_ctx_new()는 fork() 이후에 호출하는 것이 바람직하다.)

ZeroMQ에서 소켓은 여러 연결을 자동으로 관리하는 작은 백그라운드 통신 엔진의 출입구로 작동한다. 사용자는 내부의 연결을 확인하거나 제어할 수 없게끔 되어 있는데 이는 의도적인 설계이며 오히려 이러함 감춤이 ZeroMQ 확장성의 키 요소가 된다.

2020년 5월 28일 목요일

[Java] 러시아 시간 출력 오류

특정 국가, 환경에서 Java에서 가져온 시간과 윈도우에 적용된 시간 값이 다른 경우가 발생할 수 있다.

이는 대부분 오래된 JDK나 JRE를 사용해서 생긴 문제라고 보면 된다.

우리에겐 낯설은 써머타임(Daylight saving time, DST)에 대한 것인데,
써머타임 적용, 폐지에 대한 신규 정보가 JVM 시스템에 반영되어있지 않아서 발생하는 문제라고 한다.

해결은 JDK나 JRE를 최신 버전으로 올려주면 되는데 문제는 쉽게 업데이트를 결정할 수 없는 경우다. (안정성 또는 호환성 고려, 폐쇄망 환경 등으로 인한 업데이트의 어려움)

이 경우엔 아래의 두가지 대안이 있다.


1. 실행 옵션에 -XX:+UseGetTimeOfDay를 적용.

시간 관련 동작 수행 시 매번 gettimeofday() 시스템 콜을 이용해 시스템 시간을 가져온다. 성능 저하가 있다.



2. 타임존 정보를 갱신해주는 프로그램을 이용해 패치 (Time Zone Updater)

오라클에서 제공하고 있다. 

tzupdater.jar를 내려받은 후 아래 명령어를 실행해주면 시간이 정상적으로 보정된다.
java -jar tzupdater.jar -v -f -l http://data.iana.org/time-zones/releases/tzdata2017c.tar.gz


2020년 5월 24일 일요일

[Java] 빈도수를 간단하게, map의 merge()

Map을 이용해 빈도수를 계산할 때 어떤 언어에서는 간단히 myMap[key]++과 같이 해주면 되는데 Java에서는 그렇게 동작하지 않는다.

그래서 대개 AtomicInteger와 같이 레퍼런스 타입으로 처리하거나 ContainsKey 또는 get()의 null값 체크 후 빈도수를 기록하는 지저분한 코드가 작성되곤 한다.

Java 8에선 이러한 문제(?)가 다소 해결되었는데 아래와 같이 Map의 merge 함수를 이용하면 한 줄의 코드로 단순 카운팅 기능을 구현할 수 있다. 한 줄의 코드이지만 Atomic operation은 아님에 주의할 필요는 있다.

myMap.merge(key, 1, Integer::sum);

함수 이름이 좀 헷갈리게 지어진 것은 아쉽지만 한번 기억해두면 쓰기 편하다.

public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

• key: 키

• value: 값. 초기 값으로 쓰이거나 이전 갑과 병합됨.

• remappingFunction: 새로운 값을 지정하는데 쓰이는 함수, 이전 값이 있는 경우 호출됨. BiFunction은 함수 인수가 2개이면서 결과 값이 있는 함수를 뜻한다.

2020년 5월 19일 화요일

[NSIS] StrCpy 사용법

IndexOf와 RIndexOf랑 StrCpy를 쓰면 결과물이 지저분해질 순 있어도 NSIS 내부에서 원하는 문자열 조작을 어떤식으로든 할 수 있다.

문법
StrCpy 저장변수 문자열 [최대길이] [시작_오프셋]
: 최대 길이와 시작 오프셋이 생략되거나 음수 값이 올 수 있는게 특징이다.

예시
StrCpy $0 "a string"
→ "a string" - 기본 복사

StrCpy $0 "a string" 3
→ "a s" - 최대 길이를 3으로 지정했으므로 처음의 3글자인 "a s"만 선택됨.

StrCpy $0 "a string" -1
→ "a strin" - 최대 길이를 음수로 하면 문자열의 뒤에서 부터 잘라내는 동작을 함.

StrCpy $0 "a string" "" 2
→ "string" - 복사 시작 위치를 2로 지정했으므로 "a "가 스킵됨.

StrCpy $0 "a string" "" -3
→ "ing" - 복사 시작 위치를 음수로 하면 뒤에서 지정된 길이만큼 문자열을 가져옴.

StrCpy $0 "a string" 3 -4
→ "rin" - 뒤에서 부터 4글자인 "ring"을 가져온 다음 앞의 3글자인 "rin"만 선택됨.

https://nsis.sourceforge.io/Reference/StrCpy

2020년 5월 18일 월요일

[C#] Task, Task

Task와 Task의 Generic인 Task<TResult>는 쓰레드풀에서 쓰레드를 가져와 비동기 작업을 실행해 준다. Generic은 값을 반환하는 작업인 경우에 쓰인다. Task를 실행한 다음엔 IsCanceled, IsCompleted, IsFaulted 등 속성을 이용해 Task의 상태를 확인할 수 있다.

Task를 실행하는 방법엔 여러가지가 있다. Task 인스턴스를 만든 다음 Start() 메서드를 호출하거나 TaskFactory.StartNew(Action<Object>, Object) 메서드를 호출해 한번에 처리하는 방식이 있다. 더 간단하게는 Task.Run()을 이용할 수도 있다. 다만 이 메서드는 .Net 4.5 이상에서 제공된다.

Task는 비동기적으로 실행되기 때문에 Task의 모든 작업이 끝나기 전에 애플리케이션이 종료되는 경우가 생길 수 있다. 이러한 경우엔 Wait() 메서드를 이용해 Task의 작업이 끝날때까지 호출 쓰레드가 기다리게 할 수 있다. 무한정 기다리기 싫은 경우엔 Wait() 메서드에 timeout을 지정해주면 된다.

Task는 대기하지 않고 백그라운드에서 돌리고 싶은 작업이 있을 때 유용하다. 실행 문맥과 독립적인 작업을 Task로 처리하면 사용자가 대기하지 않아도 되기 때문에 사용성 측면에서도 이점이 있다. 여기에 코드까지 깔끔해지는 것은 덤이다.


// Task의 생성과 실행을 따로.
var t1 = new Task(() => {
    // work
});

t1.Start();
// other work
t1.Wait();

// Task의 실행과 생성을 한 번에.
var t2 = Task.Factory.StartNew(() => {
    // work
});
// other work
t2.Wait();


2020년 5월 14일 목요일

GTA 5 (Grand Theft Auto V) PC 무료



















무려 GTA 5를 21일까지 에픽게임즈에서 무료로 다운로드 받을 수 있다.

출시된지 오래된 게임이라 높은 사양을 요구하지 않아서 대부분의 PC에서 부담없이 즐길 수 있으리라 생각된다.

최소 사양
권장 사양
OS
Windows 10 64비트, Windows 8.1 64비트, Windows 8 64비트, Windows 7 64비트 서비스 팩 1, Windows Vista 64비트 서비스 팩 2* (*Vista OS에서는 NVIDIA 비디오 카드를 권장합니다)
OS
Windows 10 64비트, Windows 8.1 64비트, Windows 8 64비트, Windows 7 64비트 서비스 팩 1
프로세서
인텔 코어 2 쿼드 CPU Q6600 @ 2.40GHz(4 CPU) / AMD Phenom 9850 쿼드코어 프로세서(4 CPU) @ 2.5GHz
프로세서
인텔 코어 i5 3470 @ 3.2GHZ(4 CPU) / AMD X8 FX-8350 @ 4GHZ(8 CPU)
메모리
4GB RAM
메모리
8GB RAM
비디오 카드
NVIDIA 9800 GT 1GB / AMD HD 4870 1GB (DX 10, 10.1, 11)
비디오 카드
NVIDIA GTX 660 2GB / AMD HD7870 2GB
사운드 카드
DirectX 10 100% 호환
사운드 카드
DirectX 10 100% 호환
HDD 공간
90 GB available space
HDD 공간
90 GB available space

누구에겐 부담을 가질만한 잔인한 샌드박스 게임이지만 공짜라는데 뭐 받지 않을 이유가 있나.
내려받기는 에픽 게임즈 런처 설치한 뒤 런처 통해서 내려받는 방법이 가장 수월하다.


2020년 4월 20일 월요일

어떻게 일하며 성장할 것인가 - 전영민 지음.

이 책은 2014년 선임 진급할 때 연구소장님께서 주셨던 책으로 지금도 가끔씩 들여다 보는 책이다. 지금 생각해보면 진부하면서도 인상적인 진급 선물이었다. 그 당시 잘나가는 인문학 서적도 아니고 자칫 반감을 살 수도 있는 자기개발서를 굳이 골라 후배들에게 선물해준 것이다. 몇마디 조언이나 커피 한잔 사주며 퉁(?)치셔도 될 일이었는데 말이다. 굳이.. 뭐, 덕분에 지금도 회사 생활 나름 잘 하고 있다. 2015년 이전의 회사 생활이 그립긴 하지만. 그 때가 힘들긴 했어도 회사 다니는 맛(?) 같은게 있었던 것 같다. 밤새고 샤워하는 와중에 해답이 보인다던가, 꿈속에서도 일한다던가..;;

이 책은 롯데 그룹에서 꽤 오래 재직하신 분께서 들려주는 회사 생활 가이드? 노하우? 뭐 그런 책이다. 꽤나 단정적이고 솔직하게 책을 쓰셨기 때문에 일정부분 반감이 생기긴 해도 도움이 되는 충고들이 많이 담겨있다. 아예 책이 마음에 안든다고 해도 건질 것은 있다. 적어도 윗 분들(?)이 요즘 아래 사람들을 어떻게 생각하고 있는지에 대해서 조금이나마 살펴볼 수 있는 그런 부분에서. 나쁘게 얘기하면 꼰대 마인드? 뭐 그런거.. 근데 나도 년차가 어느정도 쌓이다 보니 걍 수긍이 되버리는 대목들이 이젠 더 많다..

몇 대목 옮겨 적어보고 이 책은 놓아주기로.

'인사'에 대해.
인사는 확률게임인 것 같다. 도무지 속을 알 수 없는 사람을 다루는 일인데 완벽한 인사란 게 세상에 존재할 수 없다. .. 승진심사를 할 때 정해진 승진 티오에 따라 작업을 하다 보면 승진 서열부에 줄을 긋게 된다. 이름이 그 줄 위에 있으면 승진이고 그 밑은 탈락이다. 그러면 그 줄 바로 위에 있는 사람과 바로 밑에 있는 사람이 차이가 크게 나서 그렇게 운명이 갈린 걸까? 사실 두 사람이 뒤바뀌어도 누구 하나 느끼지 못할 정도의 차이일 뿐이다. 고등학교 때 반 석차 15등과 16등이 정말 차이가 있어서 그렇게 된 걸까? 그런 것과 유사한 것이다. ...
→ 여기서 저자의 팁은? 조직 내의 누가 보더라도 저 친구는 1등이다라는 느낌이 들 수 있도록 노력하라 이다. ㄷㄷ
명함에 집착하지 마라. 중요한 것은 명함에 적힌 것이 아니라 당신 자신의 역량이다.

'아이디어'에 대해.
창의성이라는 것은 타고나는 것이 아니다 더구나 만사를 삐딱하게 보는 시각에서 나오는 것도 아니다. ... 창의성이라는 것은 살아오면서 축적해온 지식과 경험이 집중적인 문제 해결의지와 맞부디쳐서 터지는 스파크일 뿐이다. ... 직장생활은 지겨운 밥벌이가 아니다. 일이 지겨운 이유는 당신이 맡은 일을 개선하거나 바꾸려 하지 않고 지난 달에 했던 그 방식으로 계속하니까 그런 것이다. 규정된 원칙에 따라 시키는 대로만 하니까 그게 지겨운 것이다 당신이 조금 더 고민해서 그 원칙을 바꾸려고 해보라 매일이 새로워질 것이다.
일반적인 사람들은 '경로 의존성'이라는 것에 지배를 당한다 자신들이 과거에 성공했던 방법이나 칭창받았던 행동을 강화하고 반복하려는 성향이 있다는 말이다.

'변화'에 대해.
변화는 작심만으로는 부족하다. 그런 나태와 게으름을 이겨내고 변화를 지속시키는 방법은 일상에서 변화의 플랫폼을 만드는 수밖에 없는 것 같다. 변화의 플랫폼은 행동의 방아쇠와 같은 것이다. 특정한 상황적인 계기에 도달하면 특정한 행동을 하겠다는 사전 계획이라는 뜻이다.
→ 예를 들면 이런 것. 3호선을 타다가 고속터미널 역이라는 안내가 나오면 무조건 내려서 9호선으로 갈아타게 되는 것. 월요일 아침에는 하늘이 무너져도 반드시 무엇을 하겠다는 결심이 목표를 지키는데 큰 힘이 되는 것이다.

'열정'에 대해.
열정을 불러올 수 있는 목표는 몇 가지 갖추어야 할 요건이 있다.
1. 정해진 시간
2. 목표의 구체성 - 시간이 되었을 때 목표의 달성 정도를 측정할 수 있어야 한다.
3. 목표의 난이도 - 최선을 다했을 때 달성이 가능할 정도로
4. 목표의 가슴 떨림
5. 목표에 도달하는 것에 대한 중간 목표 설정
보통의 인간이라면 작은 성공에 자신을 계속 노출시키는 것이 도움이 된다. 어디선가 읽은 내용에선 목표를 주변 사람에게 말로 알리는 것도 효과가 있다고 한다.

디플레이션 시대의 생존법(?)
2020년부터는 한국에서도 베이비붐 세대의 은퇴가 본격화된다 그들은 은퇴하면서 가지고 있는 부동산이나 투자자산을 처분해서 빚부터 갚으려 할 것이다. 그러면 그때부터 한국도 대규모 부채의 구조조정기에 들어갈 것으로 예상한다 그렇게 되면 추가로 부동산이나 주식 가격은 내려갈 수 있다.
해리 덴트는 우리가 앞으로 봉착하게 되는 디레버리징과 디플레이션 시대에 살아남을 수 잇는 방법을 두 가지 추천했다. 첫 번째는 절대 빚지지 말라는 것이다. 대부분의 자산 가치가 떨어지는 마당에 빚을 얻어서 무엇을 산다는 것은 바로 죽음으로 가는 길이다. ...
두 번째 생존방법은 지금 다니는 직장을 지키라는 것이다 이런 때일수록 가장 확실한 생존방법은 지금 자리를 지키는 것이다. ... 가능하면 절대 다른 곳을 쳐다보지 말고 지금 있는 곳에서 최선을 다해서 살아남아라.