신혼여행중 여행 마지막날 생일이었다.

그래서 와이프가 가지고 싶은 물건을 물어봤고 나는 당당히 에어팟2를 이야기했다.

무리해서 환전을 많이해서 40만원정도 남은 상태여서 와이프가 승낙해줬다.

마침 취리히 여행중이었고 근처에 애플스토어가 있어서 방문했다.


주소는 Apple Bahnhofstrasse 이고 취리히 중앙역 걸어서 5분거리에 위치해 있다.

제품을 고르고 있으면 친절하게 직원이 언어를 물어본다. 영어라고 이야기하면 영어로 설명을 해주고 제품을 고른뒤에 찾아가면 결재해준다.


에어팟 2와 정품 실리콘 케이스와 가죽케이스를 구매했다.

다해서 한국돈으로 34만원정도 들었다.

마지막날 프랑을 다 소진했다.




에어팟2의 외관은 크게 달라지지 않았다. 단지 무선충전 지원과 빠른 연결 그리고 아래 사진처럼 충전 led가 뚜껑 내부가 아닌 바깥에 위치했다



에어팟1을 와이프에게 주고 이어폰을 쓰고 있었기때문에 몹시 좋았다.

무선충전까지 되니 너무 좋다.
서울 가면 바로 써봐야겠다.

결혼식 진행할때 특별하게 비디오를 찰영하지 않기로했다.

잘 보지 않을것 같고 가격도 30만원이 넘어서 안하기로 했는데 아쉬운 마음이 들었다.

 

그래서 고프로 같은 액션캠을 구매하여 웨딩촬영으로 사용하고 스위스 신혼여행 가서도 사용하기로 했다.

고프로를 사려고 스타필드를 방문했다.  스타필드에서 카메라 담당자분에게 설명을 들었는데 최근에 나온 고프로 히어로7도 sony fdr-x3000보다 손떨림이 더 나아지지는 않았다고 하였다.

그리고 고프로에 경우에 이쁘지 않다는 여자친구 피셜로 인해 구매가 보류되었다.

 

그래서 결정하게된 소니 액션캠 FDR-X3000

가격은 리모트, 방수 케이스, 정품 셀카봉, 여분 배터리까지해서 쿠팡에서 56만원에 주고 구매했다.

내 돈주고 카메라를 이렇게 비싸게 사다니 후회는 조금 들지만 이왕사는거 좋은거 사기는 잘한 것 같다.

생각보다 오밀조밀한게 앙증맞게 생겼다.

앙증맞은 카메라

 

추가로 같이 구매한 보조 배터리도 1240mAh인데 크기가 작다.

 

리모트는 손목에 달고 다니는 손목밴드와 같이 주는데 이건 좀 불편할거 같고 셀카봉에 낄 수 있어서 좋다.

근데 소니의 가장 큰 단점으로는 역시 리모트가 있어야만 화면을 볼 수있다는거다.

 

카메라와 리모트까지 장착한 화면!

녹화 화면은 생각보다 작다. ㅋㅋㅋㅋ 캠코더가 아닌 작은 액션캠이니 이해하도록 하자.

 

이제 실 사용은 결혼식날 해보겠지만 나쁘지 않을 것 같다.

연속 촬영시간이 겨우 1시간인거는 아쉽지만 그래도 유튜브도 찍어보고 별거 다해봐야겠다.

Ngnix 설명

nginx는 기존 웹서버에서 많은 트래픽을 감당하기 위해서 확정성을 가지고 설계된 비동기 이벤트 드라이븐 방식의 웹서버를 칭한다.


Nginx 설치

nginx를 맥이 있으면 brew를 통해서 간단하게 설치가 가능하다.

1
brew install nginx
cs


Nginx 프로세스

nginx는 하나의 마스터 프로세스와 여러 worker 프로세스를 가진다. 마스터 프로세스의 주요 목적은 read 권한 그리고 성능 측정과 worker 프로세스 관리이다. worker 프로세스는 요청을 처리한다. nginx는 event-based 모델을 사용하고 worker 프로세스 사이에 요청을 효율적으로 분배하기 위해서 os에 의존하는 매커니즘을 사용한다. worker 프로세스에 개수는 설정 파일에서 정의되며 정의된 프로세스 개수와 사용가능한 cpu 코어 숫자에 맞게 자동으로 조정된다.


Nginx 동작 -S

nginx를 동작시키기 위해서는 다음 옵션을 붙여서 진행한다.

1
nginx -s signal
cs


signal의 종류는 다음과 같다.

 종류

설명 

 stop

 빠른 중지

 quip

 graceful stop

##graceful stop은 요청이 중단되었을 때 로드밸런스에게 해당 노드에 요청을 추가적으로 못하게 하고 현재 노드에 작업을 중지시키고 정상적으로 끝내는 것을 말한다.

 reload

 설정 파일 재 로드

 reopen

 로그 파일  재 오픈


quip를 진행하면 현재 요청을 워커 프로세스에게 끝내라고 보낸다. 그럼 해당 워커 프로세스에 새로운 요청을 보내지 않고 워커 프로세스가 진행중이던 작업이 마무리되면 정상적으로 애플리케이션이 꺼진다. 이를 graceful stop이라고 한다.

reload를 진행하면 syntax 체크를 진행하고 성공하게 되면 older worker 프로세스를 중지 시키고 새로운 worker 프로세스를 만들어서 동작 시킨다. 만약 설정이 이상하면 마스터 프로세스는 작업을 롤백하고 예전 설정으로 동작한다. 중지 요청을 받은 workder 프로세스들은 새로운 요청을 받는 것을 멈추고 자신이 하고 있는 동작을 마무리 한다. 이 동작이 완료되면 그때 older worker 프로세스는 죽는다.

Nginx 설정파일

nginx 정책과 그 모듈들에 동작은 /usr/local/nginx/conf, /etc/nginx, /usr/local/etc/nginx 위치중에 존재하는 nginx.conf 파일 내에서 설정한대로 동작한다. (brew로 설치하는 경우 /usr/local/etc/nginx에 위치)

설정 파일 구조.

설정 파일에 입력하는 값들은 두 가지 형태로 입력이 가능하다. simple 디렉티브와 block 디렉티브 두 가지이다. simple은 이름과 파라미터로 구성되어있고 마지막에 ;이 붙는다. block 디렉티브은 simple과 구조가 같지만 끝에 ; 대신 ({ })이 붙는다. block 명령은 내부에 다른 명령들을 포함할 수있다.

events, http 명령은 main context에 위치하고 server, location은 http에 위치한다.


static content
웹 서버에서 중요한 역할중 하나는 image, html pages와 같은 정적 페이지를 전달하는 것이다. 이를 위해서 http 블록 내부에 있는 server와 location 블록을 수정해보자.

일반적으로 설정 파일은 server_name과 listen port로 구분되는 여러 server 블록을 가지고 있다.

1
2
3
4
http {
  server {
  }
}
cs

기본형태는 이렇다.


그럼 이걸 이용해서 static content에 접근할 수 있게 해보자.

아래와 같이 설정하면 /dd로 오는 요청은 무조건 저쪽 static 페이지를 통하게 된다. 

1
2
3
4
location /dd {
    root /Users/we/Documents
    index index.html
  }
cs

만약 호출 uri가 중첩되는 경우가 아래와 같이 발생하면 가장 긴 uri의 매칭을 따르게 된다.

1
2
3
4
5
6
7
8
9
server {
    location / {
        root /data/www;
    }
 
    location /images/ {
        root /data;
    }
}
cs


만약 설정이 정상적으로 동작하지 않을 때는 로그를 확인해봐야 한다. 로그에는 access.log, error.log가 존재한다. 맥 기준으로 log 폴더는 /usr/local/var/log/nginx에 존재한다.


proxy 설정

정적 페이지 연결과 더불어서 proxy로서 역할을 진행할 수 있다. 여러 서버들 사이에서 요청을 분배하는 것을 reverse proxy라고 한다.

proxy설정은 정적 페이지와 동일하게 http 블록 내에 server 블록으로 설정한다.

1
2
3
4
5
6
7
8
9
10
11
12
server {
  listen 80;
  
  location / {
    proxy_pass http://127.0.0.1:8081;
  }
 
  location /dd {
    root /Users/we/Documents/static;
    index index.html;
  }
}
cs

만약 listen을 기재하지 않으면 80으로 기본으로 매핑된다. 만약 아래와 같이 server 바로 밑에 root를 적게되면 server에 기재한 root에서 정적페이지 index.html을 찾고 각 location에 root를 입력해도 무시된다.

1
2
3
4
5
6
7
server {
    listen 8080;
    root /data/up1;
 
    location / {
    }
}
cs


또한 경로 매핑을 정규식으로도 진행할 수 있다. 아래와 같이 설정하면 .gif, .jpg, .png 형태로 들어오는 경우에 매핑 된다.

1
2
3
location ~ \.(gif|jpg|png)$ {
    root /data/images;
}
cs


설정 파일 폴더 구조

  • sites-available : 가상 서버 환경들에 대한 설정 파일들이 위치하는 부분. 가상 서버를 사용하거나 사용하지 않던간에 그에 대한 설정 파일들이 위치하는 곳
  • sites-enabled : sites-available에 있는 가상 서버 파일들중에서 실행시키고 싶은 파일을 symlink로 연결한 폴더. 실제로 이 폴더에 위치한 가상서버 환경 파일들을 읽어서 서버를 세팅한다.
  • nginx.conf : Nginx에 관한 설정파일로 Nginx 설정에 관한 블록들이 작성되어 있으며 이 파일에서 sites-enabled 폴더에 있는 파일들을 가져온다. (include 명령어를 사용).


gzip

gzip은 전달해오는 요청을 압축해서 진행하기 위해서 사용하는 옵션이다. types를 통해서 수용하는 타입도 정의할 수 있다.


apache와 많은 부분이 다르다. 정확하게 어떤 웹 서버가 좋다고 할 수는 없지만 많은 트래픽을 받는 경우에는 nginx를 사용하면 좋을 것 같다.

'IT 지식 > nginx' 카테고리의 다른 글

nginx 정리와 설치 및 기본 설정방법  (0) 2019.02.15

전통적으로 메시지 모델은 Shared Message Queue, Publish-subscribe로 구분된다. 두 가지 모델 모두 그들만에 pros and cons를 보유하고 있다. 하지만 이 두개의 모두 최초 디자인 제한 때문에 큰 데이터를 다루기에는 부족했다. Apache Kafka는 두 모델 중 publish-subscribe 메시징 모델을 구현한 모델로 부족했던 부분을 수정하고 실시간 분석을 위한 스트리밍 데이터를 처리할 수 있도록 가능해졌다. kafka는 LinkedIn에서 2010년에 방대한 데이터 처리를 위해서 개발되었다. Apache Kafka는 전통적인 메시징 모델이 달성하지 못한 격차를 해소했다. Kafka는 두 모델의 개념을 구현하여 단점을 극복하고 동시에 두 가지 방법론을 모두 통합 할 수있는 유연성을 제공한다.


Shared Message Queues
Shared Message Queues 메시지 큐는 producer에서 single consumer에게 스트리밍 데이터를 전송할 수 있다. 큐에 저장된 메시지는 한번만 읽기가 가능하고 하나의 consumer만 읽을 수 있다. subscribers는 메시지를 큐의 끝에서 메시지를 읽어서 가지고 온다. Queueing 시스템은 성공적으로 읽혀진 메시지를 큐에서 제거한다.

약점
한번 읽고 지워지는 SharedMessage Queue는 같은 도메인에 속해 있고 event-driving programming을 하는 명령어와 같은 메시지에서 적합하다. 만약 많은 consumer들이 shared queue에 접근을 하게 된다면 해당 컨슈머들은 logical domain이 같아야 하고 같은 기능을 수행해야 한다. 그렇기 때무에 shared queue는 single domain 소비로 제한된다.

Publish-Subscribe System
publish-subscribe모델은 여러 publisher가 발행이 가능하고 여러 subscriber가 구독이 가능하게 설계되어 있다. 그래서 모든 메시지는 토픽을 구독하는 모든 subscriber들에게 전송이 가능하도록 되어있다.

약점
subscriber로부터 publisher의 logical 결합이 loosely-coupled 되어 있지만 scale은 한정적이다. 각각의 subscriber는 모든 파티션으로 부터 메시지를 접근하기 위해서는 모든 파티션을 접근해야한다. 그러므로 전통적인 pub-sub 모델은 작은 네트워크에서 동작하도록 되어있다.

또한 subscriber와 publisher에 디커플링이 메시지의 신뢰도를 낮추는 영향을 준다. 모든 메시지가 모든 subscriber들에게 전송되기 때문에 메시지가 다른 subscirber에게 전송되는 경우 subscriber들 사이에 sync를 맞추는게 실질적으로 어렵다.


그럼 어떻게 Kafka는 두 모델을 결합했을까?
kafka는 shared message queue 시스템과 pub-sub 모델의 장점을 가지고 만들어졌다. 그 성공은 두개의 컨셉을 기준으로 만들어졌다.
  • consumer group 사용
  • broker들로 부터 메시지 리텐션

consumer가 그룹에 소속되고 topic을 구독할 때 오직 하나의 consumer만 그룹내에서 토픽의 메시지를 읽는다. 그리고 메시지는 broker 내부 토픽에서 사라지지 않고 보유되는데 이는 shared message queue 시스템과 다른점이다.

여러 consumer group은 같은 토픽에서 값을 읽을 수 있으며, 또한 서로 다른 logical application domain에서 다른 시간데에서도 읽을 수 있다. 그러므로 kafka는 같은 consumer group에 속한 consumer들의 높은 확정성을 제공하고 동시에 독립적인 애플리케이션들이 동작할 수 있는 이점이 있다.

Consumer Group
consumer group은 kafka가 message queue와 pub-sub 모델들의 이점을을 가질 수 있도록하는 유연성을 제공한다. 같은 그룹에 속한 consumer들은 group id를 공유한다. 이 consumer들은 토픽의 파티션을 공장하게 나눈다. 이 각각의 파티션들은 오직 그룹내에 하나의 consumer에서만 소비된다.

kafka Consumer Groups
만약 같은 그룹에 모든 consumer가 들어있으면 kafka 모델은 전통적인 message queue처럼 동작한다. 왜냐면 각각의 메시지가 하나의 consumer에게만 발행되는 부분이 같기 때문이다. 각각의 파티션은 거의 그룹내에 하나의 consumer와 연결된다.

여러 consumer group가 존재할 때 데이터 소비 모델은 전형적인 pub-sub 모델을 따른다. 메시지는 모든 consumer group에게 전송된다.

만약 하나의 consumer만 들어있는 그룹이 있으면 그 consumer가 모든 파티션을 담당한다.

이상적으로 topic의 파티션 수와 consumer group에 consumer 수가 맞으면 최적으로 효율을 가진다. 만약 consumer가 파티션보다 많으면 consumer들이 idle상태에 빠지게 되므로 자원 낭비가 발생된다. 만약 partition이 consumer보다 많은 경우 consumer들은 여러 파티션에서 값을 있는데 이는 각 파티션에서 읽는 값이 서로 순서가 맞지 않게 읽게 되기 때문에 문제의 소지가 있다. kafka는 파티션 사이에서 메시지의 순서를 보장하지 않는다. 그러므로 kafka는 오직 하나의 consumer가 하나의 파티션의 내용을 구독할 때만 순서가 보장된다. 메시지는 또한 processing중에 그룹화된 키를 통해서 정렬될 수 있다.

kafka는 offset commit과 form을 사용하여 브로커에서 구독 그룹으로 메시지가 전송되었느지 보증한다. 파티션은 consumer그룹내에 오직 하나 또는 하나 이상의 관계를 consumer와 맺을 수 있기 때문에 메시지 중복을 피하기 위해서 한번에 그룹내에서 한번에 하나의 그룹에게만 메시지를 전송한다.

Reblancing
consumer그룹이 scales up & down을 하기 때문에 동작중인 consumer들은 파티선을 그 들 사이에서 쪼갠다. Reblancing은 consumer와 broker의 충돌 또는 topic이나 partition 추가로 인해 파티션과 consumer의 소유권이 변경되면서 진행된다. 이 매커니즘을 이용하여 안전하게 시스템으로 부터 consumer의 추가와 제거가 가능하다.
-> 요약하면 consumer에 문제가 발생하면 다른 consumer가 파티션의 메시지를 받는다 이런 것 같다.

kafka가 시작되면서 브로커는 consumer의 RegisterConsumer 요청을 수신한 consumer group의 하위 집합에 대한 코디네이터로 표시되고 소유해야할 파티션 목록이 포함된 RegisterConsumer Response를 반환한다. 또한 코디네이터는 컨슈머가 살아있거나 죽었는지 체크하고 결함을 찾기위해 동작을 시작한다. 또한 세션이 끊어지기 전에 consumer가 코디네이터 브로커에게 heartbeat 신호 전송에 실패하면 코디네이터는 해당 consumer를 dead로 표시하고 rebalance를 실행한다. 세션 타임아웃 시간은 session.timeout.ms 속성에서 설정할 수 있다. 예를들어 그룹 A의 C2가 실패 했으면 C1그리고 C3가 짧게 자기들의 파티션에서의 메시지 소비를 정지하고 파티션들은 C1과 C2에 대해서 reassian된다. C2 consumer는 잃게 되지만 rebalancing 프로세스가 실행되고 파티션이 그룹내에 다른 consumer들에게 재 할당된다. GroupB는 Group A의 이런 현상이 전혀 영향을 주지 않는다.

결론
shared message queue는 메시지 프로세스내에서 scale을 허용한다 하지만 싱글 도메인에서만 사용이 가능하다. pub-sub 모델은 consumer들에게 브로드캐스팅을 지원하지만 scale이 제한된다. kafka는 shared message queue에서 scale을 가져왔고 pub-sub 아키텍쳐를 consumer gorup를 구현함으로써 단점을 보안하여 재 구현하여 가져왔다. consumer group를 구현함으로써 scale과 멀티 도메인을 사용할 수 있게 되었다. 그리고 kafka에 rebalacing을 통해서 그룹내에서 문제 발생시 문제를 해결할 수 있다.

원문
https://blog.cloudera.com/blog/2018/05/scalability-of-kafka-messaging-using-consumer-groups/




여러 쓰레드를 실행해야할 때,  큐에 넣고 작업을 진행하거나 할 수 있으면 더욱 효율적으로 관리 할 수있다.


그래서 자바 1.5부터 자바 플랫폼에는 java.util.concurrent가 추가되었다. 이 패키지에는 Executor Framework가 들어 있는데 이는 인터페이스 기반 task 실행 프레임워크이다.


해당 Executor를 실행하기 위해서는 다음과 같이 입력하면 된다.

1
2
3
4
5
6
7
ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.    
    @Override
    public void run() {
        System.out.println("dbsafer");
    }
});
cs


그리고 만약 executor안에 요소가 모두 실행이 끝난뒤에는 실행자가 꺼지지는 않는다.

이를 명시적으로 꺼주어야 하는데 그때 shutdown() 메소드를 이용하면 된다.


이른 기능을 제외하고도 임의에 task의 작업을 기다릴 수도 있고 task가 끝날때마다 정보를 가져오도록 할수도 있다. 


여러 작업을 관리해야하는 경우에는 ThreadPool을 만들어서 작업할 수 있다. 이런 작업을 제공하는 ThreadPool은 newCachedThreadPool과 newFixedThreadPool이 있다.


먼저 newCachedThreadPool은 부하가 크지않고 작은 프로그램에서 사용하기에 적합하다. 설정도 필요없고 보통 많은일을 알아서 처리한다. 하지만 작업량이 많은곳에서는 적합하지 않다. 

왜냐하면 해당 쓰레드풀은 작업이 큐에 들어가는 것이 아니라 실행을 담당하는 스레드에 바로 넘겨진다. 그렇기 때문에 task가 많이 지정될 경우에는 상당히 많은 양의 쓰레드가 생성이 되어 CPU의 사용량이 증가된다.


그렇기 때문에 이를 보안하는 ThreadPool이 있는데 newFixedThreadPool이다.


newFixedThreadPool은 스레드 개수가 고정된 풀을 만들어서 제어가 손쉽다.


이런 실행자들을 이용하여 쓰레드를 관리하면 별도의 개별쓰레드를 만들어서 관리하는 것보다 훨씬 편하고 안정적이다.


  출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙68



+ Recent posts