엔티티와 테이블을 정확히 매핑하기 위해 JPA는 다양한 어노테이션을 지원합니다. 이번 포스팅에서는 다음 매핑에 대해 다룹니다.

  • 객체와 테이블 매핑
    • @Entity, @Table
  • 기본 키 매핑
    • @Id
  • 필드와 컬럼 매핑
    • @Column

@Entity

JPA를 사용해서 테이블을 매핑할 클래스는 @Entity 를 필수로 붙여야합니다. @Entity 적용시 기본 생성자는 필수입니다.

@Table

엔티티와 매핑할 테이블을 지정합니다.

데이터베이스 스키마 자동 생성

JPA는 클래스의 매핑 정보와 데이터베이스 방언을 사용해서 데이터베이스 스키마를 생성합니다. 다음과 같이 설정하면 기존 테이블을 삭제하고 새로 생성합니다 (DROP+CREATE). create-drop / update / validate / none 옵션이 있습니다.

1
spring.jpa.hibernate.ddl-auto=create

기본 키 (Primary Key) 매핑

JPA가 제공하는 데이터베이스 기본 키 생성 전략은 다음과 같습니다.

  • 직접 할당
    • 애플리케이션에서 직접 할당합니다.
  • 자동 생성
    • IDENTITY
      • 기본 키 생성을 데이터베이스에 위임합니다.
    • SEQUENCE
      • 데이터베이스 시퀀스를 사용해 기본 키를 할당합니다.
    • TABLE
      • 키 생성 테이블을 사용합니다.

@Column

객체 필드를 테이블 칼럼에 매핑합니다. 속성 중에 name, nullable 이 주로 사용됩니다.

Reference

자바 ORM 표준 프로그래밍 <김영한>

Comment and share

JPA Simple Test

in JPA

이번 포스팅에서는 JPA를 이용해 객체를 Database 에 저장하는 Test를 하고자 합니다. Database는 Docker 를 통해 Postgres를 사용합니다.

Docker

Docker는 공식 홈페이지에서 쉽게 설치할 수 있습니다 : https://docs.docker.com/docker-for-mac/install/

Docker 를 설치하고 다음 명령어를 통해 Postgres Container를 띄웁니다.

1
docker run -p 5432:5432 -e POSTGRES_PASSWORD=1234 -e POSTGRES_USER=jko -e POSTGRES_DB=springdata --name postgres_boot -d postgres

Postgres Bash에 붙습니다.

1
docker exec -i -t postgres_boot bash

postgres 계정으로 springdata 데이터베이스에 접근합니다.

1
2
su - postgres
psql springdata

Account 테이블을 생성합니다.

1
CREATE TABLE ACCOUNT (id int, username varchar(255), password varchar(255));

의존성 추가

JPA를 사용하기 위한 의존성과 Postgresql 을 사용하기 위한 의존성을 추가합니다.

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>

설정

Database 연결을 위한 정보를 입력하고, Database Schema를 실행시마다 새로 생성되게 (ddl-auto=create) 설정합니다. 그리고, non_contextual_create=true 를 설정해야 어플리케이션 실행시 발생하는 postgres 에러를 해결할 수 있습니다.

1
2
3
4
5
6
spring.datasource.url=jdbc:postgresql://localhost:5432/springdata
spring.datasource.username=jko
spring.datasource.password=1234

spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

Account

Account Class를 다음과 같이 정의합니다. @Entity 에 이름을 따로 정하지 않으면 Class의 이름이 Table의 이름으로 매칭됩니다. 그리고, 각 필드 (id, username, password) 에는 @Column 이 생략되어 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package jko.jpatest;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Account {

@Id
@GeneratedValue
private Long id;

private String username;

private String password;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

JpaRunner

Database 에 Insert Query 를 날리기 위해 JPA api 를 사용할 수도 있고, Hibernate api 를 사용할 수 도 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package jko.jpatest;

import org.hibernate.Session;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;


@Component
@Transactional
public class JpaRunner implements ApplicationRunner {

@PersistenceContext
EntityManager entityManager;

@Override
public void run(ApplicationArguments args) throws Exception {

Account account = new Account();
account.setUsername("jko");
account.setPassword("123");

// 1. jpa api
// entityManager.persist(account);

// 2. hibernate api
Session session = entityManager.unwrap(Session.class);
session.save(account);
}
}

Reference

https://www.inflearn.com/course/스프링-데이터-jpa

Comment and share

객체 모델과 관계형 데이터베이스 모델은 지향하는 페러다임이 서로 다릅니다. 페러다임의 불일치 문제를 해결하기 위한 결과물이 ‘JPA’ 입니다. 이번 포스트에서는 객체 모델과 관계형 데이터베이스 모델의 페러다임 차이를 비교합니다.

Granularity (밀도)

  • 객체
    • 다양한 크기의 객체
    • 커스텀한 타입
  • 릴레이션
    • 테이블
    • 기본 데이터 타입 (UDT는 비추)

Subtype

  • 객체
    • 상속 구조
    • 다형성
  • 릴레이션
    • 테이블 상속 無 (상속 기능을 구현했다 하더라도 표준 기술이 아닙니다.)
    • 다형적인 관계 無

Identity

  • 객체
    • 레퍼런스 동일성 (==)
    • 인스턴스 동일성 (equals() 메소드)
  • 릴레이션
    • 주키 (primary key)

Association

  • 객체
    • 객체 레퍼런스로 관계 표현
    • 방향이 존재
    • 다대다 관계 가능
  • 릴레이션
    • Foreign Key 로 관계 표현
    • 방향이라는 의미가 無
    • 다대다 관계 불가능. (조인 테이블 또는 링크 테이블을 사용해서 두개의 1대다 관계로 풀어야 합니다)

Data Navigation

  • 객체
    • 레퍼런스를 이용해 다른 객체로 이동 가능
    • 콜렉션 순회 가능
  • 릴레이션
    • SQL을 직접 다루면 처음 실행하는 SQL에 따라 객체 그래프를 어디까지 탐색할 수 있는지 정해집니다. 이것은 큰 제약입니다. 왜냐하면, 비즈니스 로직에 따라 사용하는 객체 그래프가 다른므로 언제 끊어질지 모를 개체 그래프를 함부로 탐색할 수 없기 때문입니다.
    • 데이터베이스에 요청을 적게 할 수록 성능이 좋습니다. 따라서 Join을 씁니다.
    • 너무 많이 한 번에 가져오려고 해도 문제입니다.

Reference

Comment and share

ORM

in JPA

JPA (Java Persistence API)

자바 진영의 ORM 기술 표준입니다. Application 과 JDBC 사이에서 동작합니다.
JPA는 쉽게 이야기해서, 인터페이스를 모아둔 것입니다. 따라서 JPA를 사용하기 위해서는, JPA를 구현한 ORM Framework를 선택해야합니다.

ORM Framework

  • Hibernate
  • EclipseLink
  • DataNucleus

ORM (Object-Relational Mapping)

ORM은 애플리케이션의 클래스와 SQL 데이터베이스의 테이블 사이의 맵핑 정보를 기술한 메타데이터를 사용하여 자바 애플리케이션의 객체를 SQL데이터베이스의 테이블에 자동으로 영속화 해주는 기술입니다.

궁극적으로 코딩하려는 방법

Hibernate나 JPA 같은 ORM을 사용해서 궁극적으로 코딩을 하려는 방법은 Domain Model을 사용하는 방식 (Object) 으로 프로그래밍을 하려고 합니다.
Hibernate가 자동생성하는 SQL뿐만 아니라 임의로 JDBC를 사용하는 Query를 직접 사용할 수도 있습니다.

JDBC 를 직접 사용 하는 방식

1
2
3
4
5
6
7
8
try(Connection connection = DriverManager.getConnection(url, username, password)){
System.out.println("Connection created: "+ connection);
String sql = "CREATE TABLE ACCOUNT (id int, username varchar(255), password varchar(255));";
sql = "INSERT INTO ACCOUNT VALUES(1, 'freelife', 'pass');";
try(PreparedStatement statement = connection.prepareStatement(sql)){
statement.execute();
}
}

Domain Model 을 사용하는 방식

1
2
Account account = new Account(“freelife”, “pass”);
accountRepository.save(account);

왜 Domain Model 을 사용할까

  • 객체 지향 프로그래밍의 장점을 활용
  • 각종 디자인 패턴을 적용
  • 코드 재사용성이 증가
  • 비즈니스 로직 구현 및 테스트 용이

ORM의 장점

  • 생산성
    • SQL을 작성하고 JDBC API를 사용하는 반복적인 작업을 개발자가 직접 하지 않아도 됩니다.
  • 유지보수성
    • 코드가 굉장히 간결해지고 코드양이 줄어 유지보수성 증가합니다.
  • 성능
    • 논쟁의 여지가 있음 SQL단건만 보면 ORM이 더 느릴수있습니다.
    • Hibernate는 객체와 테이블에 데이터 사이에 캐시가 존재하므로 불필요한 쿼리를 사용하지 않습니다.
    • 하나의 트랜잭션 내에서 여러 요청이 일어나도 정말로 데이터베이스에 반영해야되는 시점에만 반영을 합니다.
    • 데이터가 같거나 반영할 필요가 없다면 반영하지 않아서 성능에 장점이 있습니다.
    • 성능 최적화를 위한 여러가지 기능들을 제공함
  • 벤더 독립성
    • 데이터베이스를 변경하면 JPA 에게 다른 데이터베이스를 사용한다고 알려주기만 하면 됩니다.
    • 데이터베이스가 바뀌어도 코드가 변경되지 않습니다.
    • Hibernate가 데이터베이스 sync를 할때 객체를 영속화 할때 발생하는 SQL만 자동으로 바뀝니다.

Reference

Comment and share

Git 정리

in Git

add

add를 통해, 선택적으로 파일을 커밋할 수 있습니다. add를 하면 커밋 대기 상태(stage)로 들어가기 때문입니다.

파일을 저장할때, 파일의 이름이 달라도 내용이 같으면 같은 object file을 가리킵니다.

working space 에서 add 를 하면 내용들이 index 파일 (커밋 대기상태, staging area) 에 등록됩니다.

그리고 commit 을 하면 index 파일에 등록된 내용들이 repository에 object 로 등록됩니다.

만약, 파일에 a라고 적혀있으면, a와 여러 부가적인 정보를 추가해서 압축합니다. 그리고 이걸 sha1 이라는 방법으로 hash 를 통과시킵니다. hash 로 얻은 값으로 objects 라는 디렉토리 안에, 디렉토리와 파일을 만들어서 a 라는 내용을 저장합니다. 그리고 index 파일에 f1.txt 는 이것이다 라고 적습니다.

objects 라는 디렉토리에 들어가는 파일은 크게 세 가지입니다.

  1. blob : 파일을 내용을 담음

  2. tree : blob에 대한 정보를 담고 있음

  3. commit

log & diff

변경 사항 확인할 수 있습니다.

  1. git log –branches –decorate –graph

    브렌치들 사이의 커밋 차이를 보여줍니다.

    –oneline 을 뒤에 붙이면 더 간결하게 볼 수 있습니다.

  2. git log exp..master

    exp branch 에는 없고, master 에는 있는 것을 보여줍니다.

  3. git log -p exp..master

    소스코드 까지 보여줌

merge

master 브렌치로 체크아웃하고, git merge exp 하면 exp branch 내용을 master 로 가져옵니다.

merge 방법에는 두 가지가 있습니다.

  1. fast-forward (빨리 감기)

    commit을 생성하지 않습니다.

  2. recursive strategy

    merge-commit을 생성합니다.

stash

감추다, 숨겨두다라는 뜻입니다. 브렌치로 작업하다가 안 끝났는데, 다른 브렌치로 체크아웃해서 다른일을 해야하는 경우, commit을 해야 체크아웃할수 있습니다. 근데, 커밋하기 애매한 경우가 있습니다. 그래서 stash 이용해서, 작업하던 것을 숨겨둘수 있습니다.

stash list 는 명시적으로 삭제하지 않으면, 항상 살아있습니다. apply를 하면 list에서 삭제 되지 않습니다. drop을 쓰면 가장 최신 stash가 삭제됩니다.

stash 는 버전 관리가 되고 있는 파일에만 적용됩니다. 즉, add를 한 파일만 stash 가 적용됩니다.

  1. git stash apply; git stash drop

  2. git stash pop

git은 HEAD 란 파일을 가지고 있습니다. 이 파일은 ref/heads/master 라는 파일을 가리키고 있고, 이 파일은 가장 최근에 커밋한 커밋의 오브젝트 아이디를 가지고 있습니다. exp 라는 bracn로 체크아웃하면 HEAD 파일은 ref/heads/exp 를 가집니다.

reset

체크아웃하고 있는 (현재 사용하고 있는 브렌치) 브렌치가 가리키는 최신 커밋을 바꾸는 행위입니다.

조금전에 한 reset 취소는 다음과 같이 할 수 있습니다. ORIG_HEAD가 지웠던 커밋을 저장하고 있기 때문입니다.

1
git reset --hard ORIG_HEAD

특정 커밋으로 이동하고 싶으면 다음과 같이 할 수 있습니다.

1
git checkout <특정 커밋의 아이디>

soft, mixed, hard 옵션을 줄 수 있습니다. 보통 hard를 많이 씁니다.

ssh

id_rsa key를 가지고 있는 사람은, id_rsa.pub key 를 가지고 있는 사람의 컴퓨터에 접속할 수 있습니다.

  1. https

    push or clone 할때마다 아이디와 pwd 입력해야합니다.

  2. ssh

    자동 로그인이 가능합니다. ssh-keygen 으로, id_rsa을 만들어서 깃에 등록하면 됩니다.

git pull / git fetch

local 의 master : a b c

remote 의 master : a b c d

이 상태에서 git fetch를 수행하면 HEAD는 여전히 a b c 파일의 커밋을 가리키고 있습니다. 즉, 지역 저장소의 마스터 브렌치에는 어떠한 영향도 끼치지지 않습니다. 지역 저장소로 가져오기만 하기 때문에, 원격자장소의 내용과 지역 저장소의 내용을 diff 명령어로 비교 할수 있습니다.

정리하자면, fetch는 원격 저장소로부터 필요한 파일들만 받기만 합니다. pull은 원격 저장소로부터 필요한 파일들만 받고 병합까지 해줌.

tag
1
git push --tags

위 명령은, remote 인 github의 release에 tag가 추가됩니다. 그냥 git push 하면 tag는 push 안됩니다.

tag는 두 종류가 있습니다.

  1. annotated tag

    tag 에 상세 메세지를 기록할 수 있습니다.

    1
    git tag -a 태그이름 -m '메시지'
  2. light weight tag

    태그 메시지를 안 적는 일반 tag 입니다.

rebase

일종의 merge 입니다. merge 보다 어렵습니다.

reference

생활코딩-지옥에서 온 Git

Comment and share

React.js

in etc
React.js가 무엇인가요?

컴포넌트라는 개념에 집중이 되어있는 라이브러리입니다.

어떤 특징이 있나요?
  1. UI 컴포넌트만 지원합니다.

  2. Virtual DOM을 가지고 있습니다.

    다시 그릴 때는 구조체의 전후 상태를 비교하여 변경이 필요한 최소한의 요소만 실제 DOM에 반영합니다.

    따라서 무작위로 다시 그려도 변경에 필요한 최소한의 DOM만 갱신되기 때문에 빠르게 처리할 수 있습니다.

  3. 단방향 데이터 흐름을 지향합니다.

    데이터를 관리하는 모델 컴포넌트가 있고, 데이터를 UI 컴포넌트에 전달하는 단순한 데이터 흐름입니다.

  4. JSX 문법을 가지고 있습니다.

    UI를 구성할 때 사용하는 구문입니다. Javascript 의 extension입니다.

컴포넌트가 뭔가요?

props를 input으로 하고 UI가 어떻게 보여야 하는지 정의하는 React Element를 output으로 하는 함수입니다

DOM이 무엇인가요?

DOM Document Object Model로, 웹 페이지의 객체 지향 표현입니다. 웹 브라우저를 통해 해석되어 화면에 나타납니다.

Virtual DOM(Document Object Model) 이 무엇인가요?

가상의 DOM 입니다. 변화가 일어나면, 실제로 브라우저의 DOM 에 새로운걸 넣는것이 아니라, 자바스크립트로 이뤄진 가상 DOM 에 한번 렌더링을 하고, 기존의 DOM 과 비교를 한 다음에 정말 변화가 필요한 곳에만 업데이트를 합니다. 이로써, 브라우저 내에서 발생하는 연산의 양을 줄이면서 성능이 개선됩니다.

컴포넌트는 어떻게 만드나요?

클래스를 통해서 만드는 방법과, 함수로 만드는 방법이 있습니다. 클래스형태로 만들어진 컴포넌트에는 꼭, render 함수가 있어야 합니다. render함수 내부에서는 JSX 를 return 해주어야 합니다.

props와 state가 뭔가요?

리액트 컴포넌트에서 다루는 데이터는 props 와 state 입니다. props 는 부모 컴포넌트가 자식 컴포넌트에게 주는 값입니다. 자식 컴포넌트에서는 props 를 받아오기만하고, 받아온 props 를 직접 수정 할 수 는 없습니다. state 는 컴포넌트 내부에서 선언하며 내부에서 값을 변경 할 수 있습니다.

브라우저는 어떻게 동작하나요?

  1. DOM tree를 생성합니다.

    브라우저가 HTML 을 전달받으면, 브라우저의 렌더 엔진이 이를 파싱하고 DOM 노드(Node) 로 이뤄진 트리를 만듦니다. 각 노드는 각 HTML 엘리먼트들과 연관되어있습니다.

  2. Render Tree를 생성합니다.

    그리고, 외부 CSS 파일과 각 엘리먼트의 inline 스타일을 파싱합니다. 스타일 정보를 사용하여 DOM 트리에 따라 새로운 트리, 렌더트리를 만듦니다.

  3. Layout

    렌더 트리가 다 만들어지고 나면, 레이아웃 과정을 거칩니다. 각 노드들은 스크린의 좌표가 주어지고, 정확히 어디에 나타나야 할 지 위치가 주어집니다.

  4. painting

    렌더링 된 요소들에 색을 입히는 과정입니다. 트리의 각 노드들을 거쳐가면서 paint() 메소드를 호출합니다. 그러고나면, 스크린에 원하는 정보가 나타납니다.

reference

https://velopert.com/3612

Comment and share

RabbitMQ

in etc
RabbitMQ가 뭔가요?

producers 로부터 메시지를 받아 consumers 에게 전달해주는 서비스입니다.

producing이 뭔가요?

메시지를 전송한다는 의미입니다. 메시지들을 전송하는 프로그램을 producer 라 부릅니다.

consuming이 뭔가요?

Consuming은 메시지를 수신한다는 의미입니다. 메시지 수신을 기다리는 프로그램을 consumer라고 합니다.

메세지 큐가 왜 필요한가요?
  1. Queue에 넣기 때문에 나중에 처리 할 수 있습니다. (비동기)
  2. 애플리케이션과 분리 할 수 있습니다.
  3. 다수의 프로세스들이 큐에 메시지를 보낼 수 있습니다.
다른 메세징 시스템은 뭐가 있나요?

activeMQ, kafka 등이 있습니다.

rabbitMQ와 kafka의 차이는 뭔가요?

kafaka는 scale out과 high availability 를 위해, 브로커들이 클러스터로 구성되어 동작하도록 설계되었습니다.

rabbitMQ는 AMQP 프로토콜을 사용하고, kafaka는 단순한 메시지 헤더를 지닌 TCP기반의 프로토콜을 사용합니다.

rabbitMQ는 Producer가 broker에게 다수의 메시지를 전송할 때 각 메시지를 개별적으로 전송하고, kafka는 다수의 메시지를 batch형태로 broker에게 한 번에 전달할 수 있어 TCP/IP 라운드트립 횟수를 줄일 수 있다.

rabbitMQ는 메시지를 기본적으로 메모리에 저장하고, kafka는 메시지를 파일 시스템에 저장합니다.

rabbitMQ는 Consumer에 의해 처리된 메시지(acknowledged message)를 곧바로 삭제하고, kafka는 처리된 메시지를 삭제하지 않고 파일 시스템에 그대로 두었다가 설정된 수명이 지나면 삭제합니다.

rabbitMQ는 broker가 consumer에게 메시지를 push해 주는 방식인데 반해, Kafka는 consumer가 broker로부터 직접 메시지를 가지고 가는 pull 방식으로 동작합니다.

reference

http://epicdevs.com/17

Comment and share

Joi

in Node.js
Joi 가 뭡니까 ?

Hapi.js에서 사용하는 parameter 검증 모듈입니다.

Joi 를 사용하지 않으면 ?

routing 의 handler 에서 parameter 를 검증하는 로직과 서버 자원을 조회하는 로직이 섞여있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var users = ['Chris', 'Mod', 'Daniel', 'JT', 'Justin'];

server.route({
method: 'GET',
path:'/users/{id}',
handler: function (req, reply) {

// 파라메터 검증
if (req.params.id &lt; users.length) {

// 검증을 통과하면 로직 수행
reply({user: users[req.params.id]});
} else {

// 검증 미통과시 404 에러코드 반환
reply('No user').code(404);
}
}
});
Joi 를 사용하면 ?

config 속성을 통해 parameter 를 검증할 수 있습니다. config.validate 속성에 자바스크립트 객체를 설정했습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var Joi = require('joi');

server.route({
method: 'GET',
path:'/users/{id}',
handler: function (req, reply) {
reply({user: users[req.params.id]});
},

// config.validate 속성에 검증 로직을 추가한다. 일종의 스키마 형태
config: {
validate: {
params: {
id: Joi.number().integer().min(0).max(users.length)
}
}
}
});

Comment and share

Docker

in etc
도커가 뭔가요?

컨테이너 기반의 가상화 플랫폼입니다.

컨테이너가 뭔가요?

격리된 공간에서 프로세스가 동작하는 기술입니다. 추가되거나 변하는 값은 변하는 값은 컨테이너에 저장됩니다.

이미지가 뭔가요?

컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것 입니다. 상태값을 가지지 않고 변하지 않습니다(Immutable).

이미지와 컨테이너의 관계는?

컨테이너는 이미지가 실행된 상태입니다. 같은 이미지에서 여러개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있습니다.

예를 들면?

ubuntu이미지는 ubuntu를 실행하기 위한 모든 파일을 가지고 있습니다. MySQL이미지는 debian을 기반으로 MySQL을 실행하는데 필요한 파일과 실행 명령어, 포트 정보등을 가지고 있습니다.

이미지는 어떻게 관리하나요?

도커 이미지는 Docker hub 에 등록하거나 Docker Registry 저장소를 직접 만들어 관리할 수 있습니다

기존의 가상화 기술이랑 차이점은?

VMware나 VirtualBox같은 가상머신은 호스트 OS위에 게스트 OS 전체를 가상화하여 사용하는 방식입니다. 이 방식은 여러가지 OS를 가상화(리눅스에서 윈도우를 돌린다던가) 할 수 있고 비교적 사용법이 간단하지만 무겁고 느려서 운영환경에선 사용할 수 없었습니다.

이러한 상황을 개선하기 위해, CPU의 가상화 기술을 이용한 반 가상화 기술이 등장했습니다. 게스트 OS가 필요하긴 하지만 전체OS를 가상화하는 방식이 아니였기 때문에 호스트형 가상화 방식에 비해 성능이 향상되었습니다.

전가상화든 반가상화든 추가적인 OS를 설치하여 가상화하는 방법은 어쨋든 성능문제가 있었고 이를 개선하기 위해 프로세스를 격리 하는 방식이 등장합니다.

도커의 장점은?

더 이상 의존성 파일을 컴파일하고 이것저것 설치할 필요가 없습니다. 말그대로 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문입니다. 이제 새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운받고 컨테이너를 생성만 하면 됩니다. 한 서버에 여러개의 컨테이너를 실행할 수 있고, 수십, 수백, 수천대의 서버도 문제없습니다.

reference

https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

Comment and share

REPL

in Node.js
REPL (Read Eval Print Loop)은?

node.js 코드를 입력할 수 있는 대화형 인터프리터입니다. 터미널에서 node 명령어를 실행하면 실행됩니다.

(cf) event loop thread 란 ?

node.js는 io 작업시 기다리지 않습니다. 즉, block 되지 않습니다. 따라서 하나의 thread가 다른 요청을 받아서 작업을 처리할수 있습니다. 이 요청을 받아서 처리하는 Thread를 ELP(Event Loop Thread) 라고 합니다.

Comment and share

Author's picture

junhee.ko

Always Learning


Engineer


Incheon