1. jenkins 배포 중 No space left on device 발생

2.  /var/lib/docker/overlay2 용량 문제 확인

원인

/var/lib/docker/overlay2 가 용량이 큰 경우 diff/tmp 에 컨테이너 내부 파일구조 변경 사항들이 과도하게 쌓였기 때문.

 

  1. Docker 컨테이너는 여러 레이어로 구성된 이미지를 기반으로 실행됩니다. 각 레이어는 독립적인 파일 시스템을 가지며, Docker는 이를 효율적으로 관리하기 위해 스토리지 드라이버를 사용합니다.
  2. 이번 문제의 원인인 overlay2 드라이버는 Linux의 OverlayFS를 활용해 여러 디렉토리를 하나로 겹쳐 사용하는 유니온 파일 시스템입니다. 컨테이너 실행 중 기존 레이어에 변경 사항이 생기면, 해당 변경 사항만 새로운 레이어에 저장하는 Copy-on-Write(CoW) 전략을 사용하여 필요한 부분만 저장합니다. overlay2의 diff/tmp에 변경 사항이 과도하게 쌓이면 /var/lib/docker/overlay2 경로의 용량이 커질 수 있습니다.

해결

  1. 미사용 이미지, 컨테이너, 볼륨 정리: docker system prune -a --volumes 명령어를 사용하면 중지된 컨테이너와 사용하지 않는 이미지, 네트워크, 볼륨을 안전하게 삭제할 수 있습니다.
  2. 특정 이미지 또는 컨테이너 삭제: 더 이상 필요하지 않은 이미지나 컨테이너만 개별적으로 삭제할 수 있습니다 (docker rmi와 docker rm 명령어 사용).

이처럼 안전하게 정리할 수 있는 명령어로 overlay2의 공간을 확보하는 것이 좋습니다.

사전 체크리스트

  • 포트 설정 확인
    • 6379 기본 redis 포트 확인 → 다음 단계로 진행
  • 방화벽 설정 확인
    • EC2 보안그룹, iptables 확인 6379 port open 확인 → 다음 단계로 진행
  • redis 설치 확인
    • EC2 ubuntu계정 redis-server 명령어 실행

 

체크 리스트 확인 후 docker 내 redis 설치

  • docker 컨테이너 redis 설치
docker exec -it realjeans bash      # realjeans 자리에 컨테이너 name 입력으로 컨테이너 접속
apt-get update -y
apt install redis-server -y
redis-server --daemonize yes

 

프로세스 (Process)

정의

운영체제에서 실행 중인 프로그램 인스턴스를 의미. 각 프로세스는 독립된 메모리 공간과 자원을 할당받아 실행된다. 각각의 프로세스는 독립된 실행 흐름을 가지며, 다른 프로세스와는 메모리등의 자원을 공유하지 않는다.

 

자원 할당

각 프로세스는 독립된 메모리 공간을 할당받아 실행되며, 프로세스 간에 메모리나 파일과 같은 자원을 공유하기 위해 별도의 메커니즘이 필요하다. 프로세스는 운영체제로부터 자원을 할당받는 독립적인 개체로 존재한다.

 

동시성과 병렬성(Process) 

각 프로세스는 독립된 실행 흐름을 가지며, 여러 프로세스는 동시에 실행될 수있다. 여러 프로세스가 동시에 실행되는 것을 병렬 실행이라고 한다.

 

스레드 (Thread)

정의

프로세스 내에서 실행되는 작은 실행 단위. 스레드는 프로세스의 자원을 공유하며 실행된다. 한 프로세스 내에서 여러 개의 스레드가 동시에 실행될 수 있다.

 

자원 할당

스레드는 프로세스 내의 자원을 공유하면서 실행되므로, 스레드는 프로세스의 메모리, 파일, I/O등의 자원에 접근할 수 있다. 따라서 스레드 간의 통신과 자원 공유는 상대적으로 간단하게 이루어진다.

 

동시성(Thread)과 병렬성

스레드는 하나의 프로세스 내에서 동시에 실행될 수 있다. 다중 스레드를 사용하면 여러 스레드가 동시에 작업을 처리할 수 있다. 하지만 실제로 동시에 실행되는 것은 여러 스레드의 작업이 CPU의 코어를 번갈아가면서 실행되는 것이고, 스레드는 동시성을 구현하는 데 사용되며, 여러 스레드 간에 작업을 조율하고 자원을 공유하기 위해 동기화 메커니즘을 사용한다.

 

 

 

'Dev > JavaScript' 카테고리의 다른 글

동기 (Synchronous)와 비동기 (Asynchronous)  (0) 2023.05.31
콜백 함수 (Callback Function)  (0) 2023.05.30
이벤트 루프 (Event Loop)  (0) 2023.05.30
데이터 타입의 종류와 메모리 할당  (0) 2023.02.22
JavaScript 설명  (0) 2023.02.13

동기 실행 (Synchronous)

 동기 실행은 코드가 순차적으로 실행되는 방식이다. 한 작업이 끝나기를 기다렸다가 다음 작업을 실행하는 방식. 코드의 실행은 호출된 순서대로 진행되며, 하나의 작업이 완료되기 전까지는 다음 작업이 시작되지 않는다. 동기 실행은 직관적이고 순서가 중요한 작업에 적합하다. 하지만 한 작업이 끝날 때까지 다른 작업을 기다려야 하므로 시간이 오래 걸리는 작업이 있다면 전체 프로그램의 실행이 느려질 수 있다는 단점이 있다.

console.log("첫 번째 작업");
console.log("두 번째 작업");
console.log("세 번째 작업");

위 코드 실행 시 "첫 번째 작업" 부터 차례대로 로그를 출력한다.

 

 

비동기 실행  (Asynchronous)

비동기 실행은 코드의 실행이 순차적이지 않고, 작업이 완료되기를 기다리지 않고 다음 작업을 실행하는 방식이다. 비동기 작업은 별도의 실행 흐름을 생성하여 작업을 백그라운드에서 수행하고, 해당 작업이 완료될 때 결과를 반환하거나 알림을 받는다. 이를 통해 다른 작업을 동시에 수행할 수 있으므로 전체적인 실행 시간을 단축시킬 수 있다. 비동기 실행은 I/O 작업이나 네트워크 요청과 같이 시간이 오래 걸리는 작업에 유용하다.

console.log("첫 번째 작업");

setTimeout(function() {
  console.log("두 번째 작업");
}, 2000);

console.log("세 번째 작업");

위 코드 실행 시 "첫 번째 작업"을 출력한 후, setTimeout 함수는 2초 후에 콜백 함수를 실행한다. 그러나 콜백 함수의 실행을 기다리지 않고, 바로 다음코드 라인으로 넘거간다. 따라서 "세 번째 작업"을 출력 후 2초가 지난 뒤에 "두 번째 작업"을 출력한다.

 

 

파일 읽기 작업 수행 동기와 비동기 차이점

1. 동기적으로 파일을 읽는 작업을 수행한다면, 파일을 읽을 때까지 다음 코드 라인으로 진행되지 않는다.

2. 비동기적으로 파일을 읽는 작업을 수행한다면, 파일 읽기 작업이 백그라운드에서 수행되는 동안 다음 코드 라인을 실행할 수 있다. 파일 읽기 작업이 완료되면 콜백 함수나 promise를 통해 결과를 처리할 수 있다.

'Dev > JavaScript' 카테고리의 다른 글

프로세스 (Process)와 스레드 (Thread)의 차이  (0) 2023.05.31
콜백 함수 (Callback Function)  (0) 2023.05.30
이벤트 루프 (Event Loop)  (0) 2023.05.30
데이터 타입의 종류와 메모리 할당  (0) 2023.02.22
JavaScript 설명  (0) 2023.02.13

 

AWS 홈페이지 elasticCache 검색

 

 

리소스 > Redis 클러스터

Redis 클러스터 생성 클릭

 

 

새 클러스터 구성 및 생성 > 클러스터 모드 (Shading 기능 사용 시 활성화)

 

 

클러스터 모드 off
클러스터 모드 on

클러스터 모드 on 시 위와 같이 샤드 수를 설정할 수 있다.

샤드 수 외 다른 설정은 필요 시 변경 ( 여기선 디폴트로 설정 )

 

 

AZ Failover 기능 사용 시 Master 캐시 노드의 문제가 생길 경우 Read Replica가 Master로 승격하여 사용된다.

 

 

서브넷 설정 및 보안 그룹 설정은 redis가 사용될 ec2에 맞게 설정한다.

콜백함수란?

다른 함수에게 인자로 전달되어 나중에 호출되는 함수

콜백 함수는 비동기적 작업, 이벤트 처리, 데이터 요청 및 처리 등 다양한 상황에서 사용된다.

코드의 유연성과 효율성을 높일 수 있다.

 

콜백 함수의 패턴

비동기 작업의 콜백 함수

  • 다른 함수에게 콜백 함수를 인자로 전달한다. 이때 함수는 비동기적인 작업을 수행으로 콜백 함수를 호출할 수 있다.
  • 작업이 완료되거나 이벤트가 발생했을 때 적절한 동작을 수행할 수 있다.
function asyncOperation(callback) {
  setTimeout(function() {
    console.log('비동기 작업 완료');
    callback();
  }, 2000);
}

function handleCallback() {
  console.log('콜백 함수 호출됨');
}

asyncOperation(handleCallback);
// 2초 후에 '비동기 작업 완료' 출력 후 '콜백 함수 호출됨' 출력

 

이벤트 핸들러의 콜백 함수

  • 이벤트가 발생했을 때 실행될 함수로 콜백 함수를 등록한다.
  • 이벤트가 발생하면 등록된 콜백 함수가 호출되어 특정 동작을 수행한다.
document.getElementById('myButton').addEventListener('click', function() {
  console.log('버튼이 클릭되었습니다.');
});

id가 'myButton'인 버튼을 클릭했을 때 콜백 함수가 실행되며, '버튼이 클릭되었습니다.'를 출력

 

 

배열의 forEach 메소드에 콜백 함수 전달

const numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(number) {
  console.log(number * 2);
});
// 배열의 각 요소에 대해 콜백 함수 실행 후, 2, 4, 6, 8, 10 출력

배열의 각 요소에 대해 콜백 함수를 실행하고, 각 요소에 2를 곱한 결과를 출력

이벤트 루프 설명

JavaScript는 단일 스레드 환경, 동기적으로 이벤트를 처리하는 메커니즘을 갖는다.

이벤트 루프란 이벤트 처리를 위한 주요한 컴포넌트로서, 이벤트 발생과 이벤트 핸들러 실행 사이의 상호작용을 관리한다.

 

일반적으로 JavaScript 코드는 순차적으로 실행되지만, 이벤트 루프를 통해 비동기적인 작업은 바로 반환되지 않고 나중에 완료될 때까지 기다리지 않고도 계속해서 다음 코드를 실행 할 수 있다.

 

이벤트 루프의 역할

1. 비동기 작업을 관리하고 완료되면 이벤트 큐에 해당 이벤트를 넣는다. 이벤트는 이벤트 큐에 순서대로 쌓이게 된다.

2. 현재 실행 중인 코드의 완료 여부를 확인하고, 실행할 다음 이벤트를 이벤트 큐에서 가져와 처리한다.

  •  이벤트 큐(Event Queue) JavaScript에서는 이벤트 루프와 동일어로도 쓰인다.
  •  비동기 이벤트 처리를 위해 사용되는 자료구조. 이벤트를 기록하고, 순차적으로 처리하는 방식으로 동작한다. 일반적으로 이벤트 큐는 이벤트가 발생하는 순서대로 큐에 저장되고, 발생한 순서대로 처리한다.

이벤트 루프의 동작 과정

1. Call Stack에 코드를 추가하여 실행한다.

2. Call Stack이 비어 있으면 이벤트 큐에서 다음 이벤트를 가져와 Call Stack에 추가한다.

3. Call Stack에 추가된 이벤트의 코드가 실행되고 Call Stack이 다시 비워질 때까지 이과정을 반복한다.

 

while(queue.waitForMessage()){
  queue.processNextMessage();
}

queue.waitForMessage() 함수는 현재 처리할 수 있는 메시지가 존재하지 않으면 새로운 메시지가 도착할 때까지 동기적으로 대기한다.

 

런타임 상황의 메모리 동작

런타임 환경에서 메모리 관리

Stack

  • 스택은 메모리의 한 영역으로, 함수 호출과 관련된 정보를 저장하는데 사용된다.
  • 함수가 호출될 때마다 Stack Frame이라는 메모리 블록이 생성되어 스택에 쌓인다.
  • 현재 실행 중인 함수의 정보, 매개변수, 로컬 변수 및 복귀 주소 등이 스택 프레임에 저장된다.
  • 함수가 실행을 완료하면 해당 함수의 Frame이 제거되고 스택의 맨 위에 있는 다음 스택 프레임이 실행된다. 이를 함수 호출 스택 (CallStack)이라고 한다.
function foo(b) {
  let a = 10
  return a + b + 11
}

function bar(x) {
  let y = 3
  return foo(x * y)
}

const baz = bar(7) // 42를 baz에 할당
  1. bar를 호출할 때, bar의 인수와 지역 변수를 포함하는 첫 번째 프레임이 생성됩니다.
  2. bar가 foo를 호출할 때, foo의 인수와 지역 변수를 포함하는 두 번째 프레임이 생성되어 첫 번째 프레임의 위로 푸시됩니다.
  3. foo가 반환하면, 맨 위의 프레임 요소를 스택 밖으로 꺼냅니다. (bar 호출 프레임만 남음)
  4. bar가 반환하면, 스택이 빕니다.

Heap

  • 힙은 동적으로 할당되는 객체 데이터를 저장하는데 사용된다. 객체와 배열 같은 자료구조들은 힙에 저장되며, 이들을 참조를 통해 접근한다.
  • 힙은 가비지 컬렉션에 의해 관리되며, 사용하지 않는 개체들은 자동으로 해제된다.

 

Queue

  • 큐는 비동기 작업의 처리를 위해 사용되는 자료구조
  • 비동기적으로 발생하는 이벤트나 작업은 이벤트 루프를 통해 큐에 추가된다.
  • 큐는 FIFO 원칙에 따라 동작하며, 새로운 이벤트는 큐의 뒤에 추가 되고 실행 할 이벤트는 큐의 앞에서 제거된다.
  • 이벤트 루프는 큐에 있는 이벤트를 순차적으로 처리하고, 해당 이벤트에 할당된 콜백 함수를 실행한다.

 

이러한 메모리 구조와 큐는 자바스크립트의 비동기적인 특성을 관리하고, 함수 호출과 객체 데이터를 저장하며, 이벤트 처리를 순서대로 처리함으로써 프로그램의 실행을 관리한다.

 

참조

 

  • 시나리오
  1.  VScode 환경에서 테스트 시 문제 없이 진행
  2.  배포서버 (EC2 Ubuntu express 환경)에서 테스트 시 fetch is not defined 에러 발생

 

const fetch = require("node-fetch");
const Joi = require("joi");
const UserRepository = require("../repositories/users.repository");
const jwt = require("jsonwebtoken");

fetch 메소드를 사용하는 js파일에 패치 선언

 

npm install node-fetch@2

 

EC2 Ubuntu 서버 배포 파일에 위 명령어 실행 후 서버 재실행

 

조치 후 fetch 동작 확인

+ Recent posts