All
14 posts
AWS ECS Fargate에 nGrinder 구축하기

nGrinder? ECS 클러스터 생성하기 Controller 구축 태스크 정의 생성 보안 그룹 생성 로드 밸런서 생성 서비스 생성 Agent 구축 태스크 정의 생성 서비스 생성 확인 Agent 스케일링 정리 nGrinder? nGrinder는 Naver에서 제공하는 성능 테스트 툴입니다. 직관적인 UI/UX로 많은 회사에서 사용하고 있는 성능 테스트 툴이지만 직접 구축해서 사용해야 합니다. nGrinder는 웹 기반의 GUI를 제공해 성능 테스트를 시작하고, 결과를 확인할 수 있는 Controller와 성능 테스트를 진행할 때 Controller의 요청에 따라 실제 서버에 부하를 발생시키는 Agent로 구성되어있습니다. 위 그림에서 알 수 있듯이 Controller는 하나의 서버에만 구축해도 되지만 Agent는 큰 부하를 발생시키기 위해서 여러 개의 서버에 구축해야 합니다. 이 글에서는 다루지 않지만 성능 테스트의 대상이 되는 서버에 설치하는 Monitor도 있습니다. Mon…

January 08, 2022
AWS
산업기능요원 2021년 11월 논산 훈련소 후기 (2021.11.11 ~ 2021.12.02)

머리 세면, 샤워 1차 PCR 전(1일차 ~ 2일차) 1차 PCR 이후, 2차 PCR 전(3일차 ~ 12일차) 2차 PCR 후(13일차 ~ 22일차) 식사 1차 PCR 전(1일차 ~ 2일차) 1차 PCR 이후, 2차 PCR 전(3일차 ~ 12일차) 2차 PCR 후(13일차 ~ 22일차) 부식 마스크 세탁 생활관 PX 불침번 2차 PCR 전(1일차 ~ 12일차) 2차 PCR 이후(13일차 ~ 22일차) 인편, 편지, 전화 중대장 훈련병, 소대장 훈련병, 분대장 훈련병 종교 기타 준비물 들고 가서 유용했던 것들 훈련 군대 예절 교육(5일차) 구급법, 인장법 교육 및 실습(6일차) 정훈평가(8일차) 사격, 수류탄 선행 학습(8일차) 실내 맨손 제식 교육 및 평가, 실외 제식 교육 및 평가(9일차) 화생방 교육 및 평가(12일차) 각개 기초 훈련, 사격 훈련(13일차) 수류탄 훈련, 각개 심화 훈련(14일차) 각개 종합 훈련(15일차) 사격 훈련(16일차) 체력 검정(19일차) 행군(20…

January 02, 2022
Others
Mac 한글 키보드에서 항상 원화(₩)대신 백틱(`) 입력되게 하기

맥북 키보드에는 따로 ` 키가 없다. 그대신 ₩과 ~키가 그려진 자판을 눌러야 백틱(`)을 입력할 수 있다. 처음 맥북을 사용할 때 어쩔 때는 백틱이 입력되고 어쩔 때는 원화 표시가 입력되어 기준이 궁금할 수 있는데 바로 한영 상태에 따라서 입력되는 키가 달라진다. 한글 상태일 때는 ₩가 입력된다. 영어 상태일 때는 `가 입력된다. 한글 상태에서도 option키를 누르면 `를 입력할 수 있다. 다만 문서를 작성할 때나 코드를 작성할 때 매번 한영 상태를 바꿔주거나 option 키를 누르기엔 너무 귀찮다. 이는 아래와 같은 방법들로 해결할 수 있다. Mac의 DefaultKeybindings 설정하기 Mac OS의 Cocoa’s text system은 ~/Library/KeyBindings/에 DefaultKeyBinding.dict 파일을 만들어 커스텀할 수 있다. 이에 대한 자세한 내용은 공식 문서 에 나와 있다. 우선 ~/Library/KeyBindings 폴더에 설정 파일을 …

December 29, 2021
Others
Spring과 Spring Boot

EJB(Enterprise Java Bean) 컴퓨터와 인터넷이 발전하면서 기업에서 요구하는 IT 기술적 수준 또한 높아졌다. 그에 따라 J2EE가 나오고 Servlet과 JSP 등을 사용하게 되었지만 복잡한 엔터프라이즈 서비스를 개발하기에는 여전히 부족한 부분들이 많았다. 엔터프라이즈 서비스를 개발하면서 크게 2가지 어려움이 존재했다. 우선, 서비스가 성장함에 따라 비즈니스 로직 자체가 복잡해지기 시작했다. 그리고 빠르면서도 안정적이고 확장 가능한 서비스를 만들기 위해 필요한 로우 레벨의 기술들이 존재했다. 예를 들면 트랜잭션 처리나 동시성 문제, 리소스 풀링, 보안 등이 있다. Servlet과 JSP를 사용해 이전보다는 비교적 편하게 Presentation 레이어를 구현할 수 있었다. 그러나 그 뒷단에서는 트랜잭션 관리를 하면서 사용자의 요청을 검증하고, 물건의 수량을 체크하면서 멀티 스레드 관리를 하는 코드가 존재할 수 밖에 없었다. 복잡해진 비즈니스 로직과 로우 레벨의 기술…

October 31, 2021
Spring
단일 인스턴스로 구성된 레디스에서의 분산 락 구현

분산락이란 분산 락(Distributed Lock)은 여러 프로세스가 상호 배타적으로 공유되는 자원을 다뤄야 하는 경우 유용하게 사용됩니다. 하나의 프로세스 내에서 여러 스레드에 대해서 락을 걸어야 한다면 언어에서 제공해주는 Synchoronize 기능이나 Lock 등을 활용할 수 있지만 여러 프로세스 또는 물리적으로 분리된 서버에서 Lock을 걸어야 한다면 이런 방법을 사용할 수 없습니다. 대신 여러 서버 간의 세션 정보를 공유하기 위해서 Redis를 사용하는 것처럼 분산 락을 구현하기 위해서 레디스를 사용할 수도 있습니다. 실제로 레디스 공식 문서에서 레디스로 분산 락 매니저(DLM: Distributed Lock Manager)를 구현한 라이브러리들을 소개하고 있습니다. 라이브러리마다 조금씩 다른 점근 방식을 사용하고 있으며 복잡한 구현 방식을 택하는 대신 간단한 접근 방식을 사용함으로써 낮은 보증을 제공하기도 합니다. 이 글은 레디스 공식 문서에서 설명하는 단일 인스턴스에…

October 23, 2021
Infra
Node.js 이벤트 루프(Event Loop) 샅샅이 분석하기

글에 들어가기에 앞서 Node.js의 이벤트 루프의 경우 공식 문서에 설명이 부족하고 이에 따라 여러 사람들이 각자 나름대로 분석한 글이 많아 무엇이 이벤트 루프의 정확한 동작인지 알기 힘듭니다. 혼자 이벤트 루프를 공부해보면서 여러 글들, 공식 문서, 그리고 Node.js의 소스 코드를 참고하면서 내용들을 정리해놓았지만 여전히 이 글에도 틀린 내용이 존재할 수 있습니다. 만약 그런 부분이 보인다면 댓글로 달아주시면 감사하겠습니다. Node.js Event Loop 흔히 Node.js를 싱글 스레드 논 블로킹이라고 한다. Node.js는 하나의 스레드로 동작하지만 I/O 작업이 발생한 경우 이를 비동기적으로 처리할 수 있다. 분명 하나의 스레드는 하나의 실행 흐름만을 가지고 있고 파일 읽기와 같이 기다려야 하는 작업을 실행하면 그 작업이 끝나기 전에는 아무것도 할 수 없어야만 한다. 그러나 Node.js는 하나의 스레드만으로 여러 비동기 작업들을 블로킹 없이 수행할 수 있고 그 …

October 12, 2021
Javascript/Typescript
IntelliJ는 왜 Arrays.asList대신 Collections.singletonList를 추천해줄까?

Intellij를 사용하다 보면 Arrays.asList 함수를 이용해서 리스트를 전달해 줄 때가 많다. 이 때 전달하는 원소의 개수가 1개인 경우 Intellij는 위와 같이 Arrays.asList 대신 Collections.singletonList를 사용하라고 한다. 단순히 원소를 리스트로 바꾸어서 전달하는데 무슨 차이가 있을지 궁금해서 한번 찾아보았다. Arrays.asList 우선 Arrays.asList의 구현은 아래와 같다. Arrays의 내부 클래스인 ArrayList를 생성해서 반환하는 것을 알 수 있다. 또한 이 List는 크기가 고정되어 있어 add나 remove 등을 호출하면 UnsupportedOperationException을 던진다. 실제로 Arrays 클래스는 AbstractList 추상 클래스를 상속받고 있으며 add나 remove 등 List의 크기를 변경하는 메소드를 오버라이드하지 않는다. 또한 이러한 메소드는 AbstractList에 Unsupp…

August 28, 2021
Java
IntelliJ
데이터베이스 정규화 이론 1. 정규화이론이란?

정규화 이론이란? 정규화란 관계형 데이터베이스의 설계에서 중복을 최소화하게 데이터를 구조화하는 프로세스다. 정규화 이론은 RDB 설계 이론의 왕도라고 알려져있다. 따라서 정규화 이론이 RDB의 일부라고 생각할 수 있지만 이는 사실이 아니다. 관계형 모델 자체는 정규화 되어있지 않아도 똑같이 릴레이션 연산을 처리할 수 있다. 하지만 정규화 되어있지 않은 RDB의 릴레이션 연산은 어려워질 수 있다. 그렇다면 데이터베이스를 정규화 했을 때 우리가 얻을 수 있는 장점은 무엇일까? 바로 모순을 방지할 수 있다는 것이다. 모순이란 데이터가 논리적으로 불일치가 일어나는 상태이며, 이런 모순이 일어난 상태를 **변칙(Anomalies)**라고 하기도 한다. 즉, 이 변칙을 방지할 수 있는 설계 이론이 바로 정규화 이론이다. 모순, 이상 그렇다면 실제로 정규화 되어있지 않은 데이터베이스는 어떤 문제가 발생할 수 있을까? 다음과 같은 예를 생각해보자. 이름 학과 등록금 이도환 경영학과 400 노종수…

August 28, 2021
Database
데이터베이스 정규화 이론 2. 1NF

1NF 1NF의 조건은 한마디로 정리하면 “릴레이션 이어야 한다”는 것이다. 관계형 모델이야 당연히 릴레이션으로 구성되겠지만 SQL과 같은 우리가 실제로 사용하는 데이터베이스에 적용되는 조건이다. SQL의 테이블이 1NF이기위한 조건은 다음과 같다. 행이 위에서 아래로 정렬돼 있지 않다. 열이 왼쪽에서 오른쪽으로 정렬돼 있지 않다. 중복하는 행이 존재하지 않는다. 각 행과 열의 교차점(즉 열의 값)은 도메인(데이터형)에 속하는 요소의 값을 딱 한개만 가진다. 모든 열의 값은 정의된 것이어야 하고 각 행은 항상 존재한다. 1번, 2번 조건 실제 SQL 사양에서는 테이블 컬럼에 순서가 존재하기에 이를 만족하지 않는다. 하지만 이는 엄밀히 따졌을 때의 얘기이고 실제론 컬럼이나 행의 위치에 위존하는 쿼리를 작성하지 않으면 된다. 데이터베이스 사양에서 순서가 존재하더라도 그 순서에 의존하지 않는 쿼리를 작성하지 않는다면 1NF 1, 2번 조건을 만족할 수 있다는 것이다. 컬럼의 순서에 의존…

August 28, 2021
Database
데이터베이스 정규화 이론 3. 2NF, 3NF, BCNF

후보키, 슈퍼키 이전 글에서 얘기한 함수 종속성을 알아보기 위해서는 후보키와 슈퍼키라는 개념을 알아야 한다. 후보키란 릴레이션에서 튜플의 값을 고유하게 만드는 속성의 집합이다. 즉, 후보키가 정해지면 해당 row의 값이 모두 정해진다는 것이다. 이 때 후보키는 더는 속성을 줄일 수 없는 상태여야 한다. 잘 와닿지 않으니 다음 테이블들을 살펴보며 이해해보자. id 이름 1 A 2 B 3 C 가장 간단한 예다. id가 정해지면 그에 따라 이름도 정해지는 것을 알 수 있다. SQL에서 우리가 보는 Primary Key가 후보키의 대표적인 예다. id가 정해지면 다른 row의 값이 모두 결정된다. 주민번호 출생지 이름 20200101 서울 A 19870312 경기 B 19990815 서울 C Primary Key만이 후보키가 될 수 있는 건 아니다. 다음과 같은 예를 생각해보자. 이 테이블에는 id 컬럼이 존재하지 않는다. 하지만 주민번호가 결정되면 출생지와 이름 모두 결정된다는 사실을 …

August 28, 2021
Database
Lombok이란?

Lombok이란? Lombok이란 Java의 라이브러리로 반복되는 메소드를 Annotation을 사용해서 자동으로 작성해주는 라이브러리다. 보통 DTO나 Model, Entity의 경우 여러 속성이 존재하고 이들이 가지는 프로퍼티에 대해서 Getter나 Setter, 생성자 등을 매번 작성해줘야 하는 경우가 많은데 이러한 부분을 자동으로 만들어주는 라이브러리라고 할 수 있다. 또한 DTO와 같이 자주 변경되는 클래스의 경우 멤버 변수가 추가되거나 없어질 때마다 Getter, Setter, 생성자 등을 수정해줘야 하는 경우가 발생한다. 이러한 경우에도 Lombok을 이용하면 단순히 프로퍼티를 추가하고 삭제하는 것만으로도 충분하다. Lombok을 이용해서 작성한 코드는 컴파일 과정에서 Annotation을 이용해서 코드를 생성하고 이런 결과물이 .class에 담기게 되는 것이다. 귀찮은 과정을 줄여주고 반복되는 코드 작성을 대신 해준다는 점에서 많은 개발자들이 선호하는 라이브러리이지만…

August 28, 2021
Java
스택 기반 VM과 레지스터 기반 VM

가상 머신(VM) 가상 머신(VM : Virtual Machine)은 물리적인 CPU에 의해 처리되는 동작을 흉내낼 수 있어야 한다. 따라서 일반적으로 VM은 아래의 개념들을 구현(포함)해야 한다. 소스 코드를 VM이 실행할 수 있는 바이트 코드로 변환 명령어와 피연산자를 포함하는 데이터구조 함수를 실행하기 위한 콜스택 다음 실행할 명령어를 가리키는 IP(Instruction Pointer) 가상 CPU Fetch IP가 가리키는 명령어를 가져온다 Decode 가져온 명령어를 디코드(해석)한다. Execution 디코딩된 명령어를 수행한다 일반적으로 위 개념을 구현하는 방법은 크게 2가지가 존재한다. 스택 기반의 VM 레지스터 기반의 VM 두 방법은 피연산자를 저장하고 다시 가져오는 메커니즘이 다르다. JVM이 바로 스택 기반의 VM이다 스택 기반의 VM JVM과 Net CLR이 스택 기반의 VM이다. 예를 들어 13 + 20 + 7 을 계산한다고 하자. CPU의 덧셈 연산은 2…

August 27, 2021
Java
delete 대신 구조 분해 할당을 사용해서 프로퍼티 지우기

프로퍼티 지우기 우리는 보통 delete 키워드를 사용해서 오브젝트의 프로퍼티를 지운다. delete의 문제는 이 동작이 객체를 수정한다는 것이다. 즉, 원본 객체를 바꿔버리며 이는 원하지 않는 사이드 이펙트가 생길 수도 있다. 우리에게 익숙한 delete 대신 구조 분해 할당을 사용하면 같은 효과를 얻으면서도 부작용을 막을 수 있다. 구조 분해 할당 구조 분해 할당은 우리가 변수를 선언할 때 사용할 수 있는 일종의 Syntatic Sugar다. 일반적으로 아래와 같이 사용한다. 자세한 설명은 여기를 참고하자. 이 구조 분해 할당이 rest parameter와 함께 사용되면 아래와 같은 동작이 가능하다. ... 연산자는 우리가 원하는 값을 제외하고 남은 값들을 얻어내는데 사용될 수 있다. 다르게 말하면, 우리가 원하는 값을 제외한 객체를 얻어낼 수 있다. 웹 사이트에 사용자 정보를 보여주기 위해서 user 객체를 반환해야 된다고 생각해보자. 당연히 우리는 password 프로퍼티를…

August 27, 2021
Javascript/Typescript
ERESOLVE unable to resolve dependency tree 해결하기

상황 블로그를 만들기 위해 Gatsby Starter 메뉴얼에 따라서 아래 명령어를 실행했다. 공식 문서에서 제공하는 설치 방법임에도 불구하고 아래와 같은 오류가 발생했다. 자세히 오류를 살펴보면 아래와 같이 해석할 수 있다. @tryghost/helpers-gatsby@1.0.56 모듈을 설치하던 중 react@"^16.9.0" 에 의존하는 것을 발견했다. 그러나 root project에서 발견된 react는 17.0.2 버전이라 react@"^16.9.0" 의존성을 해결하지 못했다. 그 아래에 해결책 또한 제공하고 있다. npm install 할 때 --force 또는 --legacy-peer-deps와 함께 실행하라는 것이다. 즉, npm install --legacy-peer-deps 를 실행하면 위 의존성 문제를 해결할 수 있다. npm의 의존성 관리 조금 더 자세한 설명은 아래와 같다. npm은 아래 5가지 종류의 의존성을 제공하고 있다. dependencies 프로젝트…

August 26, 2021
Javascript/Typescript