자바 멀티스레드 모델, 그리고 쿠버네티스 위에서의 비용
·
TIL
앞 글에서 Node가 스레드 하나로 어떻게 수천 요청을 받는지 봤다. 이번에는 반대편인 자바의 전통적인 멀티스레드 모델이 같은 문제를 어떻게 푸는지 보고, 두 모델을 쿠버네티스 위에 올렸을 때 비용이 어떻게 달라지는지 정리한다.요청 하나에 스레드 하나자바 서버의 전통적인 모델은 thread-per-request다. 요청이 들어오면 스레드 하나가 그 요청을 잡고, 응답을 보낼 때까지 그 요청 전용으로 붙어 있다. DB를 기다리든 코드를 돌리든 끝날 때까지 다른 요청은 받지 않는다.앞 글의 식당 비유로는 손님 한 명당 웨이터 한 명이 붙어서, 주문을 주방에 넣고 요리가 나올 때까지 테이블 옆에 서서 기다리는 방식이다.스레드를 만드는 건 비싼 일이라 요청마다 새로 만들지 않고, 서버가 켜질 때 정해진 수만큼 ..
Node 서버는 스레드 하나로 어떻게 수천 요청을 받나
·
TIL
Node는 스레드 하나로 돌아가는데 어떻게 수천 개의 요청을 동시에 받을까. 이벤트 루프, 논블로킹 I/O라는 단어는 익숙하지만 실제로 무슨 일이 벌어지는지 코드로 확인하면서 알아보자. 자바 멀티스레드 모델과의 비교는 다음 글에서 이어간다.await는 서버를 기다리게 하지 않는다await는 보통 "이 작업이 끝날 때까지 기다린다"라고 설명하는데, 누가 기다리는지를 구분해야 한다. 기다리는 건 그 함수 하나다. 서버(스레드)는 멈추지 않고 다른 요청을 처리하러 간다.직접 돌려보는 게 빠르다.async function handleRequest(name) { console.log(name, "DB 조회 시작"); await new Promise(r => setTimeout(r, 1000)); // DB 1..
CDN TTL을 1년으로 늘렸는데 아무 일도 안 일어났다
·
TIL
이미지 트래픽이 큰 서비스를 운영하고 있다. CDN은 콘솔 접근 권한이 없는 재판매 상품이고 캐시 히트율은 45% 정도로 낮았다.제일 먼저 의심한 건 TTL이었다. CDN 쪽 TTL이 24시간으로 잡혀 있었는데 우리가 객체에 붙이던 Cache-Control은 1년짜리였다. 어차피 한번 올라간 이미지는 바뀌지 않으니 그 값에 맞춰달라고 요청했다.결과는 +2.96%p. 아무 일도 일어나지 않았다.한참 뒤에 사업자 회신으로 이유를 찾았다. 24시간 동안 요청이 한 번도 없는 콘텐츠는 디스크 관리를 위해 캐시에서 정리한다는 것이었다.캐시에 남으려면 정리 기준도 통과해야 한다TTL과 캐시 정리는 별개라서 둘 다 통과해야 캐시에 남는다.TTL = 이 사본을 얼마나 오래 신선하다고 볼 것인가정리(eviction) =..
도커 파일 작성하기 / 도커 볼륨(volume)
·
책책책을 읽자/따라하며 배우는 도커와 CI 환경
FROM node:10WORKDIR /usr/src/appCOPY package.json ./RUN npm installCOPY ./ ./CMD ["node","server.js"] FROM alpine 베이스 이미지가 아닌 node 이미지를 사용하는 이유베이스 이미지를 alpine 으로 변경한 다음 'docker build .' 명령어 이용해 빌드해 보면, 도커 이미지를 생성하는 중에 npm not found 라는 에러가 뜬다. 이는 alpine 이미지에 가장 최소한의 경량화된 파일만 들어가 있기 때문에 npm 을 사용하기 위한 파일이 들어있지 않기 때무니다.따라서 npm을 사용하지 못하는 alpine 베이스 이미지 대신 npm을 사용할 수 있는 node 이미지를 사용한다. COPY를 두번으로 나눈 이..
도커 파일 작성하기
·
책책책을 읽자/따라하며 배우는 도커와 CI 환경
# 베이스 이미지를 명시합니다.FROM baseImage# 추가로 필요한 파일들을 내려받습니다.RUN command# 컨테이너 시작 시 실행할 명령어를 명시합니다.CMD [ "executable" ] FROM이미지 생성 시 기반이 되는 이미지 레이어 명시: 형식으로 작성태그를 붙이지 않으면 자동으로 가장 최신 버전으로 내려받음ex) ubuntu:14.04RUN도커 이미지가 생성되기 전 수행할 셸 명령어CMD컨테이너가 시작됐을 때 실행할 파일 또는 셸 스크립트도커 파일 내에서 한번만 쓸 수 있음
기본적인 도커 클라이언트 명령어
·
책책책을 읽자/따라하며 배우는 도커와 CI 환경
도커 이미지의 내부 파일 구조 보기docker run ls 컨테이너 나열하기docker ps 컨테이너 이름 변경하기docker rename  모든 컨테이너 나열docker ps -a 도커 컨테이너 생성하고 실행하기docker run => docker create , docker start 명령어를 합친 명령어 도커 컨테이너 중지docker stop => 진행 중인 프로세스를 정리하는 시간을 가진 후 컨테이너 중단 도커 컨테이너 즉시 중지docker kill  도커 컨테이너 삭제docker rm => 실행 중인 컨테이너를 삭제하려고 하면 오류가 발생한다. 중지된 모든 컨테이너 삭제하기docker rm `docker ps -a -q` 도커 이미지 삭제하기docker rmi  사용하지 않는 데이터 삭제하..
도커 이미지가 포함하고 있는것
·
책책책을 읽자/따라하며 배우는 도커와 CI 환경
도커 이미지는 응용프로그램을 실행하는데 필요한 모든것을 포함하고 있습니다. 따라서 도커 이미지를 이용해 도커 컨테이너를 생성하고 애플리케이션을 생성할 수 있습니다. 이때 이미지가 포함하고 있는 필요한 모든 것은 무엇일까요? 응용 프로그램을 실행하는데 필요한 모든 것컨테이너가 시작될 때 실행할 명령어 도커 이미지를 이용해 도커 컨테이너를 만들면 컨테이너 안에서 애플리케이션을 실행합니다. 만약 run kakaotalk 이란 명령어를 입력해 카카오톡 애플리케이션을 실행할 수 있다면, 이 명령어를 이미지가 가지고 있어야 합니다. 실행하고자 하는 프로그램을 구성하는 파일 스냅숏명령어만 있다면 카카오톡을 실행할 수 없습니다. 명령어와 함께 카카오톡을 실행할 때 필요한 파일들도 이미지가 가지고 있어야 합니다.파일 스..
터미널에 docker run hello-world 명령어를 입력하면 어떻게 될까?
·
책책책을 읽자/따라하며 배우는 도커와 CI 환경
PS C:\Users> docker run hello-worldUnable to find image 'hello-world:latest' locallylatest: Pulling from library/hello-worlde6590344b1a5: Pull completeDigest: sha256:e0b569a5163a5e6be84e210a2587e7d447e08f87a0e90798363fa44a0464a1e8Status: Downloaded newer image for hello-world:latestHello from Docker!This message shows that your installation appears to be working correctly.To generate this messag..
글로벌 서비스를 위한 timezone 이해하기
·
카테고리 없음
Timezone 이란?동일한 로컬 시간을 따르는 지역을 의미하며, 주로 해당 국가에 의해 법적으로 지정된다.=> 즉, 정치나 경제적인 이유로 변경이 될 수도 있다. 실제로 우리나라도 변경된 사례가 있다고 한다.보통 국가별로 각자의 고유한 타임존을 가지고 있으며, 면적이 큰 나라들은 지역별로 각지 다른 타임존을 사용할 수도 있다.GMT, UTC, Offset이란?GMT (GreenWich Mean Time) 옛날에는 시간의 개념이 희박했다. 생활권이 그리 넓지 않았기에 각지 지역마다 시간을 다르게 표시했고, 한마디로 '표준'이라는게 없었다. 하지만 기차가 발명되고 사람들의 생활권이 넓어지며 시간 표준이 필요해졌다!그렇게 생겨난게 영국 그리니치 천문대를 기준으로 하는 태양시간이다.UTC (Coordinate..
운영체제
·
기술면접
프로세스와 스레드의 차이프로세스는 실행중인 프로그램을 뜻합니다. 스택, 힙, 데이터, 코드로 이루어져있고 각 프로세스들은 이 자원을 공유하지 않는다. 최소 1개의 스레드(메인 스레드)를 가지고 있습니다.그리고 스레드는 프로세스의 실행의 단위입니다. 프로세스 내에서 스택만 할당받고, 그 이외의 메모리 영역을 다른 스레드와 공유하기 때문에 다른 스레드의 실행 결과를 즉시 확인할 수 있습니다. 멀티 프로세스와 멀티 스레드의 특징멀티 프로세스는 프로세스들 간의 자원을 공유하지 않습니다. 그렇기 때문에 차지하는 메모리가 멀티 스레드에 비해 크지만, 한 프로세스에서 문제가 발생해도 다른 프로세스에 영향을 미치지 않는다는 특징이 있습니다.멀티 스레드는 스택 외에 다른 자원들을 다른 스레드와 공유합니다. 그렇기 때문에..
[JS] n개의 최소공배수
·
코테
문제 설명두 수의 최소공배수(Least Common Multiple)란 입력된 두 수의 배수 중 공통이 되는 가장 작은 숫자를 의미합니다. 예를 들어 2와 7의 최소공배수는 14가 됩니다. 정의를 확장해서, n개의 수의 최소공배수는 n 개의 수들의 배수 중 공통이 되는 가장 작은 숫자가 됩니다. n개의 숫자를 담은 배열 arr이 입력되었을 때 이 수들의 최소공배수를 반환하는 함수, solution을 완성해 주세요.  문제 풀이const gcd = (a,b) => { if(b === 0){ return a; }else if(a%b === 0){ return b; }else{ return gcd(b, a%b); };}const lcm = (a,b) =..
[JS] 점프와 순간 이동
·
코테
문제OO 연구소는 한 번에 K 칸을 앞으로 점프하거나, (현재까지 온 거리) x 2 에 해당하는 위치로 순간이동을 할 수 있는 특수한 기능을 가진 아이언 슈트를 개발하여 판매하고 있습니다. 이 아이언 슈트는 건전지로 작동되는데, 순간이동을 하면 건전지 사용량이 줄지 않지만, 앞으로 K 칸을 점프하면 K 만큼의 건전지 사용량이 듭니다. 그러므로 아이언 슈트를 착용하고 이동할 때는 순간 이동을 하는 것이 더 효율적입니다. 아이언 슈트 구매자는 아이언 슈트를 착용하고 거리가 N 만큼 떨어져 있는 장소로 가려고 합니다. 단, 건전지 사용량을 줄이기 위해 점프로 이동하는 것은 최소로 하려고 합니다. 아이언 슈트 구매자가 이동하려는 거리 N이 주어졌을 때, 사용해야 하는 건전지 사용량의 최솟값을 return하는 s..
피보나치 수 런타임 에러
·
코테
문제피보나치 수는 F(0) = 0, F(1) = 1일 때, 1 이상의 n에 대하여 F(n) = F(n-1) + F(n-2) 가 적용되는 수 입니다.예를들어F(2) = F(0) + F(1) = 0 + 1 = 1F(3) = F(1) + F(2) = 1 + 1 = 2F(4) = F(2) + F(3) = 1 + 2 = 3F(5) = F(3) + F(4) = 2 + 3 = 5와 같이 이어집니다.2 이상의 n이 입력되었을 때, n번째 피보나치 수를 1234567으로 나눈 나머지를 리턴하는 함수, solution을 완성해 주세요. 문제풀이function solution(n) { let newArr = [0, 1, 1] let fib = (n) => { if(newArr[n] !== un..
[JS]JadenCase 문자열 만들기
·
카테고리 없음
문제 JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.sreturn "3people unFollowed me" "3people Unfollowed Me" "for the last week" "For The Last Week"  문제풀이function solution(s) { var answer = ''; let aa = s.split(" ") for(let i = 0; i 기존 문제 풀이는 이랬는데 자꾸 런..
[JS] 퀵정렬, 병합정렬과의 비교
·
카테고리 없음
1. 소개퀵정렬이란 pivot(중심축)을 정하고, 중심축 보다 작은 값들은 왼쪽으로, 큰 값들은 오른쪽으로 보내는것이다.pivot을 정해 왼쪽 오른쪽으로 나누고 다시금 왼쪽 오른쪽에 대해 재귀적으로 pivot을 정해 왼쪽 오른쪽을 나누고.. 이 과정을 반복하다보면 결국 정렬이 완성 된다. 2. 작동개념분할: 입력 배열을 피벗을 기준으로 비균등하게 2개의 부분배열로 분할한다.정복: 부분배열을 정렬한다. 부분 배열의 크기가 충분히 작지 않으면 순환 호출을 이용해 다시 분할 정복 방법을 적용한다.결합: 정렬된 부분 배열들을 하나의 배열에 합병한다.순환 호출이 한번 진행될 때마다 최소한 하나의 원소(피벗)는 최종적으로 위치가 정해지므로, 이 알고리즘은 반드시 끝난다는것을 보장할 수 있다. 3. 시간복잡도평균적으..