728x90
반응형

계기

컨테이너를 구동하였을 때,
해당 컨테이너가 정상적으로 올라간 것으로 보였지만 로그를 확인하거나 exec 명령어로 컨테이너 내부에 접근하고자 했을 때 문제가 발생하고 있는 것을 확인한 적이 여러번 있었다.

때문에 컨테이너의 정상 여부(Health) 를 주기적으로 체크하며 모니터링 할 필요가 있다.

healthcheck 옵션

  • docker compose 설정
    • healthcheck 라는 설정을 함으로써 가능하다.
      • test: 헬스체크 시도 시에 실행할 동작을 정의한다. 단순 curl/wget 으로 요청을 날려볼 수 있고, CLI를 넣을 수도 있으며, 함수를 실행시킬 수도 있다.
      • interval: 말 그대로 체크 실행 주기를 의미한다.
      • timeout: 실행된 헬스체크 동작에 대한 리턴을 기다리는 시간(timeout)을 의미한다.
      • retries: 타임아웃이 걸려 체크 실패 시 재시도 횟수를 의미한다. 재시도까지 전부 실패하면 unhealthy 상태가 된다.
      • start_period: 컨테이너 구동을 기준으로, 헬스체크를 시작할 때까지의 시간을 의미한다. 처음 구동 시, 초기 세팅에 시간이 많이 걸리는 경우가 있기 때문
    • 상태값
      • 0 : healthy. 즉 건강한 상태이다.
      • 1 혹은 다른 숫자: unhealthy. 비정상적인 문제가 발생하고 있다.
services:
    app:
        expose:
            - ${APP_PORT}
        healthcheck:  
            // 헬스체크를 위해 실행할 함수
            test: curl --fail http://localhost:5000/ || exit 1  

            // REDIS 체크의 경우
            test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]

            // 체크 실행 주기
            interval: 40s 
            // 타임아웃 
            timeout: 30s  
            retries: 3  
            // 컨테이너 구동 후 체크 시작할 시점
            start_period: 60s
  • DockerFile 설정

    • 도커 파일 설정은 Dockerfile의 이미지 빌드 과정에 입력된다.
    • 이외 헬스 체크 주기 등의 옵션은 컨테이너 구동 시 입력한다.
    FROM asdcasdcas
    # ... 빌드 내용
    
    # 컨테이너에서 구동하는 어플리케이션의 /health 엔드포인트에 요청을 날리는 것이 헬스체크 방식이다.
    HEALTHCHECK CMD curl --fail http://localhost/health
    docker container run -d -p 8080:80 --health-interval 5s app_image/stable/latest

    결과

    • 헬스체크가 완료되면 아래처럼 보이게 된다.

주기 설정에 관하여

  • healthcheck 는 어찌 되었건 cpu 등 서버 리소스를 사용하기 때문에 적당한 주기(interval)로 실행시켜야 한다.
  • 또한 실제로 헬스체크 동작을 실행시켰을 때 받아올 수 있는 정도의 주기로 실행해야 한다.
    • 만약 헬스체크 대상 어플리케이션의 특정 함수 동작 주기가 1분인데, 10초마다 헬스체크를 한다면, 이는 자원 낭비일 것이다.
728x90
반응형
728x90
반응형

Golang은 뛰어난 동시성 지원이 장점이라고들 한다.

일반적으로 쓰레드를 활용하여 동시성 프로그래밍을 하지만, Golang은 고루틴 goroutine으로 가능하다.

 

고루틴 Goroutine

공시적인 설명으로는 경량 쓰레드이다. 실제 OS의 쓰레드를 사용하는 것이 아닌, golang의 런타임에서 관리되는 논리적 / 가상적 쓰레드이다.

 

사용법

go func() {

    // 대충 코드

  }()

이게 끝이다.

 

thread VS goroutine

1. 메모리 사용량

  • goroutine: 생성시 약 2KB의 스택 메모리 혹은 힙 메모리 공간만을 사용한다.
  • thread: 약 1MB 의 메모리 공간을 사용한다.
  • P.S. Guard Page: 쓰레드가 사용할 메모리 공간과 각 메모리 간의 경계 역할
  • 따라서 스레드 기반의 동시성 처리는 결국 메모리 부족 현상(OutOfMemory) 문제 발생할 수 있으므로, 스레드를 미리 생성해 재활용하는 형태가 될 수 있음.

 

2. 비용

  • goroutine: 런타임에서 논리적으로(하드웨어와 상관 없이) 생성되고 소거되기 때문에 가볍다.
  • thread: OS 에 스레드 생성을 요청해 사용하고 작업 완료 시 다시 OS에 반환해야 한다.
  • 따라서 쓰레드 생성시마다 OS에 요청해 생성하고 다시 반환하는 방식이 더 리소스 사용량이 많다.

 

3. Context Switching 비용

  • 하나의 스레드가 특정 작업 처리를 위해 사용(Blocking)된다면, 다른 쓰레드가 대신하여 처리하도록 스케쥴링 됨
  • goroutine: 3개의 레지스터(PC(Program Counter)), SP(Stack Pointer), DX)만 save/restore 작업을 함
  • thread: 스레드가 스케쥴링고 교체되는 동안 스케쥴러에서는 모든 레지스터들을 save/restore 해야함
  • 일반적으로 16개의 범용 레지스터, PC, SP, Segment 레지스터, 16개의 XMM레지스터, FP coprocessor state, 16개의 AVX 레지스터, 모든 MSR들 등 save/restore 작업을 진해해야함
  • 따라서 Context Switching 할 때 save/restore 해야하는 레지스터의 개수부터가 큰 차이가 남

 

결론

golang이 메모리 사용량과 쓰레드 생성과 작업처리에 있어서의 비용 측면에서 효율적이다.

 

마지막

goroutine의 동작 방식과 쓰레드 종류에 대해선 다음에 서술하고자 한다.

 

REFERENCE

- https://velog.io/@khsb2012/go-goroutine

 

 

728x90
반응형

'백엔드 Backend > Golang' 카테고리의 다른 글

[Neo4J] 데이터 핸들링하기  (1) 2024.12.09
[Neo4j] Golang 으로 쿼리 핸들링  (0) 2024.12.06
[Neo4j] Golang으로 Neo4j 연동  (0) 2024.12.05
[GO] Ubuntu 서버에 설치  (1) 2024.10.30
728x90
반응형

_Event Loop_

이벤트 루프란 무엇일까?

 

Event Loop

이벤트 루프는 node.js의 기본적인 동작 방식이다.

Call Stack과 Callback Queue의 상태를 체크하여, Call Stack이 빈 상태가 되면 Callback Queue의 첫번째 콜백을 Call Stack으로 밀어넣는다. 이를 틱(Tick)이라 한다.

  • Call Stack: 코드가 실행될 때 쌓이는 곳. Stack 형태로 쌓임. 함수를 실행하고 값을 **return 하면 call Stack에서 제거**된다.
  • Callback Queue: 비동기적으로 실행된 콜백함수가 보관된 영역. eg. setTimeout에서 타이머 완료 후 실행되는 함수 등...

 

이벤트 루프는 총 6개의 단계를 가진다.

 

이벤트 단계

  • Timer 단계
    • 이벤트 루프의 시작 단계이다.
  • Pending(I/O) 콜백 단계
  • Idel, Prepare 단계
  • Poll 단계
  • Check 단계
  • Close 단계

 

microTaskQueue

이벤트 루프는 우선적으로 Microtask Queue를 먼저 확인한다.

MicroStack Queue에 콜백이 있다면 이를 먼저 Call Stack에 담는다.

 

 

이벤트 루프는 계속 공부를 더 해야겠다..

 

참고 링크

 

728x90
반응형

'백엔드 Backend > Nodejs' 카테고리의 다른 글

[NODEJS] Async/Await 란?  (0) 2024.10.23
[NODEJS] Promise란?  (0) 2024.10.22
Nodejs 란?  (1) 2024.09.30

+ Recent posts