no image
🖌️ GC(Garbage Collection) - 쓰레기통 파해치기
GC(Garbage Collection)는 Java에서 자동으로 메모리를 관리해 주는 메커니즘이다. 프로그래머가 메모리를 관리하지 않아도 사용되지 않는 객체(Garbage)를 JVM이 알아서 제거하기 때문에 메모리 누수를 사전에 방지할 수 있고 애플리케이션이 안정적으로 동작하도록 해준다.📍 GC의 동작 방식Java에서 객체가 생성되면, Heap Memory Area에 할당된다. 하지만 객체가 생성된 뒤로 메모리 관리를 해주지 않게 되면 애플리케이션에 문제가 발생 할 수 있다. 그리고 만약 이 작업을 개발자가 하게 된다면 매우 번거로운 작업이 된다.  하지만 GC(Garbage Collection)는 이 작업을 대신 해준다. GC(Garbage Collection)는 참조되지 않는 객체들을 자동으로 탐지..
2024.09.19
no image
Hexagonal Architecture (헥사고날 아키텍쳐)
Hexagonal Architecture (헥사고날 아키텍쳐)헥사고날 아키텍쳐는 인터페이스 기반 요소에 영향을 받지 않는 핵심 코드를 만들 이를 견고하게 관리하는것이 목표인 아키텍쳐이다.애플리케이션 내부로직과 외부요소를 분리하여 보다 유연하고 확장 가능하며 테스트가 가능한 애플리케이션을 만드는게 목표인 아키텍쳐이다.그리고 헥사고날 아키텍쳐는 "포트 어댑터 아키텍쳐" 하고 불리기도 한다.헥사고날 아키텍쳐의 핵심은 내부로직과 외부요소의 경계를 명확히 구분해서 외부 시스템이 내부 로직에 미치는 영향을 최소화 하는것이다.구조적 특징헥사고날 아키텍처는 일반적으로 6면체의 다이어그램으로 표현되며, 각 면은 포트에 대응된다. 중심에는 애플리케이션의 비즈니스 로직이 있으며, 그 외곽에 포트와 어댑터가 둘러싸고 있다. ..
2024.09.14
Dev
no image
FOMC도 모르면서 재테크를 하시겠다? Good Afternoon이다 이놈들아!
자 첫번째 글이다. 오늘은 폼씨(FOMC)에 대해서 한번 알아보자! 일단 FOMC는 전세계에서 말한마디로 국가를 날려버릴수도 있는 힘을 가진 엄청난 조직이다FOMC는 Federal Open Market Committee(연방공개시장위원회)의 약자이다. FOMC는 미국 연방준비제도(Federal Reserve, 흔히 “Fed”로 알려짐) 내에서 가장 중요한 위원회로, 미국의 통화정책을 결정하는 역할을 한다. 주요 역할:FOMC의 주요 임무는 미국 경제의 안정적인 성장을 유지하기 위해 다음과 같은 통화정책 결정을 내리는 것이다:  1. 금리 조정: FOMC는 미국의 기준 금리인 연방기금금리(Federal Funds Rate)를 조정한다. 이 금리는 은행들이 서로 빌려주는 초단기 자금의 이자율이며, 경제 성장..
2024.09.12
no image
AWS Route 53
Route 53에 들어가기 앞서 베이스 개념이 되는 DNS 개념을 먼저 봐야 한다.우선 DNS 개념을 살짝 보자면DNS(Domain Name System)는 인터넷에서 도메인 이름과 IP 주소를 변환해 주는 시스템이다.사람들이 웹사이트에 접속할 때 사용하는 도메인 이름(예: www.example.com)을 컴퓨터가 이해할 수 있는 IP 주소(예: 192.0.2.1 또는 2001:0db8:85a3:0000:0000:8a2e:0370:7334)로 변환하는 역할을 한다.이제 Route 53을 보자AWS Route 53는 아마존 웹 서비스(AWS)에서 제공하는 DNS(Domain Name System) 웹 서비스이다.Route 53은 인터넷 도메인 이름을 IP 주소로 변환하는 DNS 서버의 기능을 수행하며, ..
2024.09.12
no image
Docker
DockerDocker는 컨테이너 기반의 오픈 소스 플랫폼으로, 애플리케이션을 효율적으로 개발, 배포, 실행할 수 있게 해준다. 컨테이너는 가상화 기술의 일종으로, 운영체제 수준에서 격리된 환경을 제공하여 애플리케이션이 독립적으로 실행될 수 있도록 한다. Docker는 이러한 컨테이너를 쉽게 관리하고 실행할 수 있도록 지원하는 도구이다.Docker는 개발자가 컨테이너를 빌드, 배포 및 실행하도록 지원하는 상용 컨테이너화 플랫폼 및 런타임이다. 단일 API를 통한 간단한 명령과 자동화를 갖춘 클라이언트-서버 아키텍처를 사용한다.또한 Docker는 Dockerfile을 작성한 다음 Docker 서버를 사용하여 이미지를 구축하는 적절한 명령을 실행하여 변경할 수 없는 컨테이너 이미지로 애플리케이션을 패키징하는..
2024.09.10
no image
[InteliJ] 인텔리제이 미사용 import 자동 삭제
mac 기준으로 preference -> Editer -> General -> auto import -> Optimize imports on the fly 체크한다. (이게 제일 편하긴하죠) ++ option + enter 로도 제거가 가능하다.
2022.05.28
Dev
no image
[디자인 패턴]GoF 디자인 패턴
💡 1995년 GoF(Gang of Four)라고 불리는 Erich Gamma, Richard Helm, Ralph Johnson, John Vissides가 처음으로 디자인 패턴을 구체화하였다.GoF의 디자인 패턴은 소프트웨어 공학에서 가장 많이 사용되는 디자인 패턴이다.목적에 따라 분류할 시 생성 패턴 5개, 구조패턴 7개, 행위 패턴 11개 총 23개의 패턴으로 구성된다. 🤷‍♂️GoF 디자인 패턴 GoF디자인 패턴을 분류하는 기준은 두 가지이다. 목적에 따라 분류하면 생성 ,구조, 행동 3가지로 나눌 수 있다. 각각의 패턴이 어떤 일을 하기 위한 것인지에 관한 것이다. 생성 패턴은 객체의 생성 과정에 관여, 구조 패턴은 객체의 합성에 관여, 행동 패턴은 객체가 상호 작용하는 방법이나 관심사를 분리..
2022.03.15
no image
[MYSQL] 프로시저(스토어드 프로그램)
💻프로시저(스토어드 프로그램) 프로시저는 일련의 쿼리를 하나의 함수처럼 실행하기 위한 쿼리의 집합이다. 매개 변수를 받을 수 있고, 반복적으로 사용할 수 있는 BLOCK이다. 일반적으로 연속 실행 또는 구현이 복잡한 트랜잭션을 수행하는 PL/SQL BLOCK을 데이터베이스에 저장하기 위해 생성한다. 💻프로시저(스토어드 프로그램)를 사용하는 이유 🔑데이터베이스의 보안의 향상 MYSQL의 스토어드 프로그램은 자체적인 보안 설정 기능을 가지고 있기 때문에 스토어드 프로그램 단위로 실행 권한을 부여할 수 있다. 이러한 보안 기능을 조합해서 특정 테이블의 읽기와 쓰기 또는 특정 칼럼에 대해서만 권한을 설정하는 등 세밀한 권한 제어가 가능하다. 주요 기능을 스토어드 프로그램으로 작성한다면 SQL 인젝션과 같은 기본..
2022.03.09
728x90

GC(Garbage Collection)는 Java에서 자동으로 메모리를 관리해 주는 메커니즘이다. 프로그래머가 메모리를 관리하지 않아도 사용되지 않는 객체(Garbage)를 JVM이 알아서 제거하기 때문에 메모리 누수를 사전에 방지할 수 있고 애플리케이션이 안정적으로 동작하도록 해준다.

📍 GC의 동작 방식

Java에서 객체가 생성되면, Heap Memory Area에 할당된다. 하지만 객체가 생성된 뒤로 메모리 관리를 해주지 않게 되면 애플리케이션에 문제가 발생 할 수 있다. 그리고 만약 이 작업을 개발자가 하게 된다면 매우 번거로운 작업이 된다. 

 

하지만 GC(Garbage Collection)는 이 작업을 대신 해준다. GC(Garbage Collection)는 참조되지 않는 객체들을 자동으로 탐지하여 제거해준다.

 

자바 개발자라면 크게 신경 쓰지 않았을 것이다. GC(Garbage Collector)가 뒤에서 열심히 객체 메모리 관리 작업을 해주고 있다는 것만 알아두자( 가끔 모니터를 보고 GC야 고마워라고 작게 말하는 것도 좋을 것 같다.)

 

 GC(Garbage Collection)의 단계

📍 Mark

Mark 단계는 GC가 Heap Memory에서 어떤 객체가 여전히 사용 중인지 확인하는 단계

📍 Sweep

마크되지 않은(미사용 객체) 객체들을 실제로 메모리에서 제거하는 과정이다. 미사용 객체를 제거해서 메모리 공간을 확보한다.

📍 Compact

GC가 수행하는 최적화 작업 중 하나, 메모리 단편화 방지를 위해 살아있는 객체들은 Heap Memory 한쪽으로 이동시켜 연속된 메모리 공간을 확보한다. 파편화된 메모리를 한 곳에 모아 최적화된 메모리를 제공할 수 있다.

📍 Evacaution

Evacuation 단계는 Generational GC에서 주로 사용되며, Young Generation에서 Old Generation으로 객체를 이동시키는 과정이다. 

젊은 객체들은 Young Generation에서 빠르게 수거되지만, 오랫동안 살아남은 객체들은 Old Generation으로 이동되어 장기적으로 관리된다. 

이 작업으로 인해 Old Generation이 Young Generation 자리를 불필요하게 점유하는 것을 방지할 수 있다.

📍 Concurrent

Concurrent 단계ZGC, Shenandoah, CMS와 같은 GC에서 사용되며, 대부분의 작업을 애플리케이션과 동시에 수행하는 단계이다.

해당 단계는 애플리케이션 실행과 GC 작업을 병렬로 진행하여 Stop-the-World 시간을 최소화

 

실제로 GC가 어떻게 동작하는지 한번 예제를 보자 

import java.util.ArrayList;
import java.util.List;

public class EX_GC {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        
        for (int i = 0; i < 1000000; i++) {
            list.add(new Object()); // 객체를 계속 생성하여 메모리를 채움
            if (i % 10000 == 0) {
                list.clear(); // 일정 주기마다 리스트를 비워서 GC 대상 객체로 만듦
            }
        }
       
    }
}

우선 EX_GC라는 파일을 생성했다. 위 코드를 보면 객체가 무분별하게 생성된다. GC를 실행시키기 위한 임의의 코드이다.

javac EX_GC.java

우선 텍스트 파일을 컴파일한다.

java -Xms16M -Xmx16M '-Xlog:gc*:file=gc.log:time' EX_GC

 

이제 힙 메모리 공간을 설정하고 GC 로그를 활성화한 다음 Java를 실행시키면 GC가 동작하는 걸 볼 수 있다.

 

 

GC가 동작하면 위 그림처럼 로그가 발생한다. 만약에 메모리가 부족해서 java 실행이 실패하면 로그에

이런 식으로 로그가 남을 것이다. 이제 로그를 몇 개만 까보자 

Heap region size: 1M

 힙 메모리는 1MB 크기의 여러 영역(region)으로 나뉘어 관리되고 있다.

Using G1

JVM이 G1 GC를 사용하고 있음을 나타낸다.

Heap address, size: 16MB

힙 메모리의 주소와 크기 정보이다.

GC(0) Pause Young (Normal) (G1 Evacuation Pause)

이 로그는 첫 번째 GC 이벤트를 의미한다.

GC(0) Pause Young (Normal) (G1 Evacuation Pause) 7M->0M(16M) 0.520ms

첫 번째 GC 후, 힙 메모리 사용량이 7MB에서 0MB로 줄어들었고, 전체 힙 크기는 16MB이다. GC 이벤트는 0.520ms의 짧은 시간 동안 발생했다.

Heap

GC 후 힙 메모리 상태를 보여줍니다. 총 16MB의 힙에서 현재 1.772MB가 사용 중이며, GC 후 Eden 영역에서 살아남은 객체가 3개의 Young 영역에 위치해 있습니다.

(로그는 하나하나 설명하면 루즈해질 것 같아서 몇 개 빼곤 생략했다. 모르는 게 있으면 얼마든지 댓글로 남겨주시면 감사하겠습니다.)

 


이제 GC의 기본적인 동작은 모두 봤으니 GC의 종류를 한번 보자 (이번글의 핵심이기도 하다)

 

📍 GC의 종류

Java에서는 다양한 GC 알고리즘이 제공되며, 각 알고리즘은 서로 다른 성능 특성과 목적을 가지고 있다.

 

1. Serial GC

Java 1.2에 도입되었고 단일 스레드로 GC를 처리한다.

작은 애플리케이션에서 적합하며, Stop-the-World 시간이 길 수 있다.

-XX:+UseSerialGC 옵션으로 사용.

 

2. Parallel GC

Java 1.4에 도입되었고  여러 스레드로 동시에 GC를 처리하여 병렬로 수행된다.

대규모 애플리케이션에서 힙 메모리 관리에 효과적이다.

-XX:+UseParallelGC 옵션으로 사용.

 

3. CMS (Concurrent Mark-Sweep) GC

Java 1.5에 도입되었고응답 시간이 중요한 애플리케이션에서 사용됩니다.

마킹과 스윕 단계를 애플리케이션과 병렬로 수행하여 Stop-the-World 시간을 줄입니다.

-XX:+UseConcMarkSweepGC 옵션으로 사용.

 

4. G1 GC (Garbage First)

Java 1.7부터 시범운영을 하고 Java 9부터 기본 GC로 사용되며, 대규모 애플리케이션에서 성능을 최적화하기 위해 설계되었습니다.

힙 메모리를 여러 개의 작은 영역으로 나누고, 우선적으로 가비지가 많은 영역을 먼저 정리합니다.

-XX:+UseG1 GC 옵션으로 사용.

 

5. ZGC (Z Garbage Collector)

Java 11에 도입된 최신 GC로, 대용량 힙에서도 매우 짧은 Stop-the-World 시간을 보장한다(10ms 이하).

초대형 메모리 시스템을 위해 설계되었으며, 거의 실시간에 가까운 GC 처리가 가능하다.

하지만 ZGC는 기본 GC가 아니고 시범운영만 했지만 java 15부터는 기본 기능으로 사용이 가능하다.

작업 병렬화: 대부분의 GC 작업을 애플리케이션과 병렬로 수행한다. Stop-the-World 시간이 매우 짧고, 큰 힙 메모리에서도 10ms 이하의 지연 시간을 유지할 수 있다.

컬러드 포인터(Colored Pointers): ZGC는 “컬러드 포인터”라는 기술을 사용해 객체 참조를 추적하고, 객체가 이동할 때도 애플리케이션이 중단되지 않도록 한다. 이로 인해 매우 빠른 GC 작업이 가능하다.

대용량 힙에 적합: 수백 GB에서 몇 TB의 힙 메모리에서도 효율적으로 작동하며, 메모리 사용량이 매우 큰 애플리케이션에 적합하다.

-XX:+UseZGC 옵션으로 사용.

 

6. Shenandoah GC

CMS와 비슷하지만 더욱 짧은 Stop-the-World 시간을 제공하며, 대규모 멀티스레드 환경에 적합하다.

병렬 및 동시성: Shenandoah는 거의 모든 GC 작업을 애플리케이션과 동시에 수행한다. 힙 메모리가 매우 크더라도 지연 시간을 최소화하며, 대규모 멀티코어 환경에서 효율적으로 동작한다.

동시 압축(concurrent compaction): Shenandoah는 힙 메모리의 조각화를 방지하기 위해, 객체 이동 및 압축 작업도 애플리케이션과 동시에 수행할 수 있다.

동시 마킹과 스윕: 객체의 생존 여부를 확인하는 마킹 단계와 메모리 해제 작업을 동시에 처리하여 성능을 향상한다.

-XX:+UseShenandoahGC 옵션으로 사용.

 

자 이런 변천사를 봤는데 공통적인 포인트가 있다. Stop-the-World (멈춰! 그 세계)가 공통적으로 들어있다. 점점 루즈해지니 빨리 설명하겠다.

 

Stop-the-World란?

Stop-the-World는 GC가 실행되는 동안 JVM이 모든 애플리케이션 스레드를 일시 중지하고, GC 작업에 필요한 메모리 정리를 완료할 때까지 기다리는 시간을 의미한다. GC는 힙 메모리에서 객체를 수집할 때, 애플리케이션이 메모리를 사용할 수 없도록 하기 위해 이런 일시 중단을 발생시킨다.

 

Stop-the-World가 발생하는 이유

메모리 관리 작업은 매우 중요한 작업으로, 메모리의 일관성을 유지하기 위해 GC는 애플리케이션의 스레드가 메모리 객체를 동시에 변경하지 않도록 모든 스레드를 멈추게 한다. 이것이 Stop-the-World 이벤트이다.

 

  • Serial GC는 단일 스레드라 Heap Memory가 커질수록 Stop-the-World가 길어진다.
  • Parallel GC는 병렬 스레드긴 하지만 Stop-the-World 시간이 상대적으로 길고, 애플리케이션 성능에 영향을 미칠 수 있다.
  • CMS, G1 GC는 Stop-the-World 시간을 줄이려는 목표를 가지고 있으며, 애플리케이션과 병렬로 GC 작업을 수행한다.
  • ZGC와 Shenandoah는 가장 짧은 Stop-the-World 시간을 목표로 하며, 대부분의 GC 작업을 애플리케이션과 동시에 처리하여, 매우 짧은 지연 시간(10ms 이하)을 유지한다.

성능영향? 멈춘다? 개발자들은 알레르기 반응이 슬슬 올라올 거다. 하지만 자바 8 이상이라면 두 눈 뜨고 실제로 보긴 힘들 거다.(그 이하버전을 쓰신다면 유감입니다.) 

GC가 메모리 정리를 효율적으로 마칠 때까지 모든 애플리케이션 스레드는 멈추게 된다. 그러나 Stop-the-World 시간이 너무 길어지면 애플리케이션 성능에 큰 영향을 미칠 수 있다. 이를 최소화하는 것이 GC의 주요 목표 중 하나이다.  

 

개념적인 내용은 끝이 났다. GC를 이렇게 글로 다룬 이유는 갑자기 개발을 하다가 GC를 파보고 싶어서 파 봤는데 내가 그냥 GC? 그거 메모리 비워주고 관리해 주는 거 아니야?라고 생각했던 나 자신 반성하도록,,,,,,개인적으로 재밌었다. 다음 성능개선점을 찾을 때 이게 도움이 될지는 모르지만 뭔가 언젠간 분명 이게 차별점이 될 거라 믿는다.


아 그리고 ZGC는 따로 한번 더 다뤄볼 예정이다.

 


📍 참고자료

https://coderstea.in/post/java/get-ready-to-deep-dive-java-memory-management-garbage-collector/

https://www.geeksforgeeks.org/garbage-collection-java/

https://d2.naver.com/helloworld/1329

728x90

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

[디자인 패턴]GoF 디자인 패턴  (0) 2022.03.15
[JAVA]반복문 안에서 List 요소 삭제  (0) 2022.03.04
[Code] Refactoring , 리펙토링  (0) 2022.02.28
[Design Pattern] 빌더 패턴(Builder Pattern)  (0) 2021.12.02
[JAVA]Optional이란?  (0) 2021.06.17
728x90

Hexagonal Architecture (헥사고날 아키텍쳐)

헥사고날 아키텍쳐는 인터페이스 기반 요소에 영향을 받지 않는 핵심 코드를 만들 이를 견고하게 관리하는것이 목표인 아키텍쳐이다.
애플리케이션 내부로직과 외부요소를 분리하여 보다 유연하고 확장 가능하며 테스트가 가능한 애플리케이션을 만드는게 목표인 아키텍쳐이다.
그리고 헥사고날 아키텍쳐는 "포트 어댑터 아키텍쳐" 하고 불리기도 한다.

헥사고날 아키텍쳐의 핵심은 내부로직과 외부요소의 경계를 명확히 구분해서 외부 시스템이 내부 로직에 미치는 영향을 최소화 하는것이다.

스크린샷 2024-09-14 오후 3 35 42

구조적 특징

헥사고날 아키텍처는 일반적으로 6면체의 다이어그램으로 표현되며, 각 면은 포트에 대응된다. 중심에는 애플리케이션의 비즈니스 로직이 있으며, 그 외곽에 포트와 어댑터가 둘러싸고 있다. 외부 시스템(사용자 인터페이스, 데이터베이스, 외부 API 등)은 어댑터를 통해 포트에 연결된다.

1. 포트 (Ports)

포트는 헥사고날 아키텍처에서 가장 중요한 추상화 레이어로, 애플리케이션 코어(핵심 비즈니스 로직)와 외부 시스템(데이터베이스, API, UI 등) 간의 통신 경계 역할을 한다.

  • 입력 포트(Input Ports): 외부에서 들어오는 요청을 처리하기 위한 인터페이스로, 애플리케이션의 비즈니스 로직을 외부에서 접근할 수 있게 만드는 역할을 한다. 예를 들어, 사용자가 웹 브라우저를 통해 요청을 보내면, 이 요청이 애플리케이션의 비즈니스 로직으로 전달되기 위한 경로다.
  • 출력 포트(Output Ports): 애플리케이션이 외부 시스템과 상호작용할 때 사용하는 인터페이스다. 데이터베이스나 외부 API와 통신할 때, 출력 포트는 이러한 외부 시스템과의 상호작용을 추상화하여 애플리케이션 로직이 직접적으로 외부 시스템에 의존하지 않게 한다.

포트의 핵심 역할은 외부와의 의존성을 최소화하고, 비즈니스 로직이 외부 기술에 종속되지 않도록 인터페이스로 분리하는 역할을 한다.

 

2. 어댑터 (Adapters)

어댑터는 포트와 외부 시스템을 구체적으로 구현하여 연결하는 부분이다. 어댑터는 포트를 통해 비즈니스 로직과 외부 시스템 간의 통신을 가능하게 하며, 외부 시스템의 구체적인 구현 세부 사항을 처리한다.

  • 입력 어댑터(Input Adapters): 외부로부터 들어오는 요청을 받아 입력 포트를 호출하는 역할을 한다. 예를 들어, 웹 요청을 처리하는 컨트롤러(Controller)나 메시지 큐 소비자가 입력 어댑터의 예다. 사용자의 입력을 받아 내부 비즈니스 로직으로 전달하는 역할을 한다.
  • 출력 어댑터(Output Adapters): 애플리케이션이 외부 시스템(데이터베이스, 외부 API 등)과 상호작용할 때 출력 포트를 통해 데이터를 주고받는 역할을 한다. 예를 들어, 데이터베이스 접근 레이어, 외부 API 호출 클라이언트 등이 출력 어댑터로 동작한다.

어댑터의 핵심 역할은 외부 시스템과의 상호작용을 처리하여, 애플리케이션 내부의 비즈니스 로직이 외부 시스템의 세부 구현에 영향을 받지 않도록 한다.

 

3. 유즈케이스 (Use Case)

유즈케이스는 헥사고날 아키텍처에서 비즈니스 로직을 구현하는 부분이다. 유즈케이스는 애플리케이션이 제공하는 기능적 요구 사항을 처리하며, 사용자의 요청에 따라 비즈니스 로직을 실행하고, 필요한 데이터 또는 결과를 반환한다.

  • 유즈케이스는 도메인 계층의 엔티티를 사용하여 비즈니스 로직을 처리하고, 출력 포트를 통해 외부 시스템과 상호작용한다.
  • 유즈케이스는 애플리케이션의 특정 작업을 수행하는 방법을 정의한다. 예를 들어, “사용자 생성”, “주문 처리”와 같은 애플리케이션의 주요 기능이 유즈케이스로 정의된다.

유즈케이스는 애플리케이션이 “무엇을” 해야 하는지 정의하고, 이 비즈니스 로직이 외부 시스템과 상호작용할 때 포트를 사용하여 통신하는 역할을 한다.

4. 엔티티 (Entities)

엔티티는 애플리케이션의 비즈니스 도메인을 표현하는 객체로, 애플리케이션에서 핵심적인 데이터와 그와 관련된 비즈니스 규칙을 캡슐화한다. 엔티티는 도메인 모델의 중심으로, 비즈니스의 중요한 개념(예: User, Order, Product)을 나타낸다.

  • 엔티티는 고유한 식별자를 가지고 있으며, 비즈니스 로직에서 중요한 역할을 한다. 예를 들어, User 엔티티는 사용자 정보를 담고 있으며, 그 사용자가 애플리케이션 내에서 수행할 수 있는 행동이나 비즈니스 규칙을 관리한다.
  • 엔티티는 애플리케이션의 도메인 계층에서 사용되며, 유즈케이스에서 비즈니스 로직을 처리할 때 중요한 역할을 한다.

엔티티는 애플리케이션의 비즈니스 규칙과 도메인 상태를 정의하고 유지하는 중요한 객체다.

핵사고날 아키텍쳐에서 Java/Spring을 사용 할 때 권장하는 패키지 구조를 한번 보자 (말 그대로 권장 사항이다. 본인 프로젝트에 맞게 커스텀은 얼마든지 가능하다.)

com.example.project
│
├── application
│   ├── service
│   ├── dto
│   └── port
│       ├── input
│       └── output
│
├── domain
│   ├── model
│   └── repository
│
├── infrastructure
│   ├── adapter
│       ├── input
│       └── output
│   └── configuration
│
└── web
    ├── controller
    ├── dto
    └── exception

우선 패키지별로 하는 역할에 대해서 알아보자

 

⚒️ application

application layer은 비즈니스 로직을 담당하는 핵심 계층이다. 헥사고날아키텍쳐에서 application layer는 외부의 영향을 받지 않는다.

각 패키지의 역할들을 보자

  • service : 애플리케이션의 주요 비즈니스 로직을 처리하는 서비스 클래스가 위치한다.
  • dto : Data Transfer Object로, 데이터 교환을 위한 객체를 정의한다. 애플리케이션에서 외부 시스템과 데이터를 주고받을 때 사용된다.
  • port :
    • input : 외부에서 애플리케이션으로 들어오는 요청을 처리하는 입력 포트. 서비스 계층에서 사용하는 인터페이스들이 이곳에 위치한다.
//입력포트로서 값을 받아 처리한다.
public interface UserService {
    UserDto getUserById(Long id);
    void createUser(UserDto userDto);
}
  • output : 애플리케이션이 외부 시스템(데이터베이스, 외부 API 등)과 상호작용할 때 사용하는 출력 포트. 외부 의존성과 상호작용하는 부분이 추상화되어 여기에 정의된다.
//출력 포트로서 DB와 통신한다.
public interface UserRepository {
    User save(User user);
    Optional<User> findById(Long id);
}

위 그림에서 보이는 계층 중에서 application 계층은 UseCase에 속한다.

 

⚒️ domain

//주된 객체가 되는 도메인 모델이다.
public class User {
    private Long id;
    private String name;
    private String email;
    // Constructors, getters, setters
}

도메인 계층은 비즈니스 규칙과 엔티티를 담고 있는 부분이다. 이는 애플리케이션의 중심부로, 모든 비즈니스 로직의 핵심을 이루며 외부 시스템과는 독립적이다.

  • model: 애플리케이션의 핵심 비즈니스 모델(도메인 엔티티)을 정의한다. 예를 들어, User, Order 등의 엔티티가 이곳에 포함된다.
  • repository: 도메인에서 사용하는 저장소 인터페이스. 데이터베이스와의 상호작용을 위한 인터페이스가 여기에 정의된다.

⚒️ infrastructure

인프라스트럭처 계층은 외부 시스템과의 연결을 담당하는 계층이다. 데이터베이스, 외부 API, 메시징 시스템 등과의 통신을 여기서 처리하며, 헥사고날 아키텍처에서 말하는 어댑터가 위치하는 곳이다.

  • adapter
    • input: 외부에서 들어오는 요청을 처리하는 입력 어댑터. 예를 들어, REST 컨트롤러, 메시지 큐 소비자, 스케줄러 등이 해당된다.
package com.example.web.controller;

import com.example.application.port.input.UserService;
import com.example.application.dto.UserDto;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    // 사용자 생성 (입력 요청)
    @PostMapping
    public ResponseEntity<Void> createUser(@RequestBody UserDto userDto) {
        userService.createUser(userDto);  // 입력 포트(UserService)를 호출
        return ResponseEntity.ok().build();
    }

    // 모든 사용자 조회 (입력 요청)
    @GetMapping
    public ResponseEntity<List<UserDto>> getAllUsers() {
        List<UserDto> users = userService.getAllUsers();  // 입력 포트(UserService)를 호출
        return ResponseEntity.ok(users);
    }

    // 특정 사용자 조회 (입력 요청)
    @GetMapping("/{id}")
    public ResponseEntity<UserDto> getUserById(@PathVariable Long id) {
        UserDto user = userService.getUserById(id);  // 입력 포트(UserService)를 호출
        return ResponseEntity.ok(user);
    }

    // 사용자 업데이트 (입력 요청)
    @PutMapping("/{id}")
    public ResponseEntity<Void> updateUser(@PathVariable Long id, @RequestBody UserDto userDto) {
        userService.updateUser(id, userDto);  // 입력 포트(UserService)를 호출
        return ResponseEntity.ok().build();
    }

    // 사용자 삭제 (입력 요청)
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);  // 입력 포트(UserService)를 호출
        return ResponseEntity.ok().build();
    }
}
  • output: 애플리케이션이 외부로 데이터를 보낼 때 사용하는 출력 어댑터. 예를 들어, 데이터베이스에 데이터를 저장하는 JPA 리포지토리, 외부 API 호출 클라이언트 등이 여기에 포함된다.
  JPA 리포지토리를 사용해 데이터베이스와 상호작용하는 로직을 구현한다.
  @Repository
public class UserRepositoryImpl implements UserRepository {
    private final JpaUserRepository jpaUserRepository;

    public UserRepositoryImpl(JpaUserRepository jpaUserRepository) {
        this.jpaUserRepository = jpaUserRepository;
    }

    @Override
    public User save(User user) {
        return jpaUserRepository.save(user);
    }

    @Override
    public Optional<User> findById(Long id) {
        return jpaUserRepository.findById(id);
    }
}
  • configuration: Spring의 @Configuration 클래스나 외부 서비스와 관련된 설정 파일들이 이곳에 위치한다. 예를 들어, Bean 등록, 외부 시스템과의 연결 설정 등을 처리한다.

🌐 web (프레젠테이션 레이어)

웹 계층은 사용자와의 상호작용을 처리하는 부분으로, 주로 REST API 요청을 받아 비즈니스 로직을 호출하는 역할을 한다. 이 계층은 헥사고날 아키텍처의 입력 어댑터로 동작한다.

  • controller: Spring MVC 컨트롤러가 위치하는 곳이다. 사용자의 요청을 받아서 애플리케이션의 비즈니스 로직에 전달하는 역할을 한다.
@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    // 사용자 생성
    @PostMapping
    public ResponseEntity<Void> createUser(@RequestBody UserDto userDto) {
        userService.createUser(userDto); // 비즈니스 로직 실행 (입력 포트 호출)
        return ResponseEntity.ok().build(); // 응답 처리
    }
}
  • dto: 웹 계층에서 사용되는 요청과 응답 데이터를 정의한다.
@Getter
@Setter
@NoArgsConstructure
@AllArgsConstructure
public class UserDto {

    private Long id;
    private String name;
    private String email;
}
  • exception: 웹 계층에서 발생하는 예외 처리를 관리한다. 주로 전역 예외 핸들러가 이곳에 위치한다.
@ControllerAdvice
public class GlobalExceptionHandler {

    // 사용자 정의 예외 처리
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND); // 404 에러 반환
    }

}

마무리

헥사고날 아키텍쳐의 구조를 전체적으로 뜯어보았다. 다른 방식의 헥사고날도 있겠지만 권장되는 방식을 위주로 해서 조금 아쉬운 부분은 있지만 본인이 개선 해가면서 더 나은 아키텍쳐를 개발하길 바란다 !^ 아키텍쳐에 노력을 들일수록 모든 상황이 좋아지는 것은 아니라 생각을 한다. 하지만, 아키텍쳐 패턴을 통해 규칙을 정하고 규칙에 따라 개발을하게 된다면 그리고 유지보수가 좋아지고, 예상 가능한 위치에 패키지나 클래스가 그리고 함수가 있다면 노력할 만한 가치가 있다 생각을 한다.

헥사고날 아키텍쳐가 정답은 아니지만, “상황에 따라 다르다”라는 말이 있듯이 상황에 맞게 사용을 할 수 있을 것 같습니다.

728x90
728x90

자 첫번째 글이다. 오늘은 폼씨(FOMC)에 대해서 한번 알아보자! 일단 FOMC는 전세계에서 말한마디로 국가를 날려버릴수도 있는 힘을 가진 엄청난 조직이다

FOMC는 Federal Open Market Committee(연방공개시장위원회)의 약자이다. FOMC는 미국 연방준비제도(Federal Reserve, 흔히 “Fed”로 알려짐) 내에서 가장 중요한 위원회로, 미국의 통화정책을 결정하는 역할을 한다.

출처 :https://namu.wiki/w/%EC%97%B0%EB%B0%A9%EC%A4%80%EB%B9%84%EC%A0%9C%EB%8F%84

 

주요 역할:

FOMC의 주요 임무는 미국 경제의 안정적인 성장을 유지하기 위해 다음과 같은 통화정책 결정을 내리는 것이다:

 

1. 금리 조정: FOMC는 미국의 기준 금리인 연방기금금리(Federal Funds Rate)를 조정한다. 이 금리는 은행들이 서로 빌려주는 초단기 자금의 이자율이며, 경제 성장과 물가 안정을 위한 중요한 수단이다.

2. 자산 매입 및 매도: 경기 조절을 위해 미국 국채 및 다른 금융 자산을 매입하거나 매도하는 방식으로 통화 공급량을 조절한다. 양적 완화(Quantitative Easing)도 이런 정책의 일환이기도 하다.

3. 물가 안정과 고용 극대화: FOMC는 물가 안정과 고용 극대화를 목표로 경제 상황에 맞춰 금리를 조정하거나 다른 통화정책을 시행한다.

 

FOMC 회의

https://www.tossbank.com/articles/fomc

FOMC는 정기적으로 연 8회 회의를 열고, 이때 경제 지표, 인플레이션, 고용 동향 등을 분석하여 금리 인상, 인하, 동결 여부를 결정합니다. FOMC의 결정은 세계 경제와 금융 시장에 큰 영향을 미치기 때문에 전 세계에서 주목받는다.

 

FOMC 회의에서 발표하는 결과에 따라 주식시장이 요동치기도 한다. 그리고 미국 기준 금리에 따라 한국 주식시장과 한국 기준 금리도 영향이 있으니 투자에 관심이 있는 분이라면 챙겨 보시길 바란다. 

 

금리가 주식시장과 대출 이런 부분에서 와닿는 곳도 있지만 고용시장이나 이런 체감이 딱히 되지 않는 부분에도 영향이 있다. 다음글은 경제 지표에 대해서 한번 다뤄보겠다.

 

 

+ 번외

  1. 여담으로 파월 의장이 Good Afternoon으로 인사하면 좋은 쪽으로든 안 좋은 쪽으로든 큰일이 난다. hello everyone로 시작한다면 동결이거나 큰 변화가 없을 가능성이 크다.(여담이지만 대부분 맞았다.)
  2. 파월 의장은 목소리가 성우급으로 좋다. 근데 사람들은 그 목소리를 싫어한다(?)

 

 

728x90

AWS Route 53

ryudjae
|2024. 9. 12. 10:53
728x90

Route 53에 들어가기 앞서 베이스 개념이 되는 DNS 개념을 먼저 봐야 한다.

DNS 동작 flow

우선 DNS 개념을 살짝 보자면DNS(Domain Name System)는 인터넷에서 도메인 이름과 IP 주소를 변환해 주는 시스템이다.

사람들이 웹사이트에 접속할 때 사용하는 도메인 이름(예: www.example.com)을 컴퓨터가 이해할 수 있는 IP 주소(예: 192.0.2.1 또는 2001:0db8:85a3:0000:0000:8a2e:0370:7334)로 변환하는 역할을 한다.

이제 Route 53을 보자

AWS Route 53는 아마존 웹 서비스(AWS)에서 제공하는 DNS(Domain Name System) 웹 서비스이다.

  • Route 53은 인터넷 도메인 이름을 IP 주소로 변환하는 DNS 서버의 기능을 수행하며, 이를 통해 사용자들이 도메인 이름을 통해 서버, 애플리케이션, 또는 서비스에 접근할 수 있도록 해준다.
  • Route 53에 53은 왜? 53일까? 53은 전통적인 DNS 포트 번호여서 53을 사용한다.
  • Route 53은 유료이다. 월 0.5$의 비용이 발생한다. (추가 비용 발생 가능)

그리고 추가적으로 Route 53을 사용하다 보면 TTL이라는 개념이 계속 나올 것이다.

TTL(Time to Live)

클라이언트가 웹 서버에 접속했을 때 도메인으로 DNS 요청을 보내면 DNS로부터 회신을 받는데 TTL은 이 회신에 대한 응답을 캐싱하는 시간을 설정하는 것이다.

TTL이 100 정도 된다고 하면 클라이언트 요청에 대한 DNS 요청은 100초 동안 DNS 시스템에 쿼리를 날리지 않고 캐싱된 정보를 사용한다.

AWS Route 53 동작방식

  1. Web Browser (웹 브라우저)
    1. 사용자가 웹 브라우저에 example.com 같은 도메인 이름을 입력하면, 브라우저는 그 도메인에 해당하는 IP 주소를 찾기 위해 Local DNS Server에 요청을 보낸다. 이때 캐시(CACHE)와 TTL(Time to Live)을 사용해 로컬에서 이미 해당 도메인에 대한 정보를 가지고 있는지 확인한다.
    2. 만약 캐시된 IP 주소가 있다면, 캐시에서 IP 주소를 가져와 웹 서버로 연결한다.
  2. Local DNS Server (로컬 DNS 서버)
    1. 로컬 DNS 서버는 사용자의 ISP(인터넷 서비스 제공자) 또는 회사 네트워크에 의해 할당되고 관리된다.
    2. 로컬 DNS 서버는 example.com에 대한 IP 주소를 캐시에서 찾는다. 만약 캐시에 없다면, 루트 DNS 서버에 질의한다.
  3. Root DNS Server (루트 DNS 서버)
    1. 루트 DNS 서버는 도메인 이름의 최상위 수준에서 이름을 관리하며, 여기서는 도메인의 최상위 관리기관인 ICANN에 의해 관리된다.
    2. 루트 DNS 서버는. com 같은 Top-Level Domain (TLD) 서버의 네임서버(NS)를 반환한다.
  4. TLD DNS Server (. com)
    1. TLD DNS 서버는. com과 같은 최상위 도메인에 대한 정보를 관리한다. IANA(Internet Assigned Numbers Authority)가 관리하는 이 서버는 example.com 도메인의 Second-Level Domain (SLD)에 대한 정보를 알고 있다.
    2. TLD DNS 서버는 example.com에 대한 네임서버(NS) 정보를 반환한다.
  5. SLD DNS Server (example.com)
    1. SLD DNS 서버는 실제 도메인인 example.com에 대한 정보를 제공한다. 이 서버는 도메인 등록기관(예: Amazon Registrar, Inc.)에 의해 관리된다.
    2. SLD DNS 서버는 example.com의 IP 주소(예: 9.10.11.12)를 로컬 DNS 서버에 반환한다.
  6. 웹 서버에 연결
    1. 로컬 DNS 서버는 받은 IP 주소를 웹 브라우저에 전달한다.
    2. 웹 브라우저는 해당 IP 주소로 연결하여 example.com 웹 서버에 접속하고, 웹사이트의 콘텐츠를 로드한다.

AWS Route 53 기능

  1. DNS 관리(Domain Name System)
    1. Route 53은 도메인 이름을 IP 주소로 매핑해 주는 DNS 서비스이다. 예를 들어, www.example.com이라는 도메인 이름을 해당 웹 서버의 IP 주소로 변환하는 작업을 담당한다.
    2. 이 DNS 서비스는 AWS에서 호스팅 된 애플리케이션뿐만 아니라, 다른 위치에 있는 리소스(예: 외부 웹 서버)에 대한 DNS 설정도 지원한다.
  2. 도메인 등록(Domain Registration)
    1. Route 53을 사용하면 도메인 이름을 직접 구입하고 등록할 수 있습니다. Route 53은 여러 최상위 도메인(TLD)을 지원하며, 이를 통해 .com, .net, .org 등의 도메인을 쉽게 등록할 수 있다.
  3. 트래픽 관리(Traffic Flow)
    1. Route 53은 다양한 트래픽 관리 정책을 제공한다. 이를 통해 사용자 요청을 다양한 AWS 리소스나 외부 서버로 라우팅 할 수 있다.
  4. 트래픽 라우팅 정책 옵션

    1. 단순 라우팅(Simple Routing): 특정 IP 주소 또는 도메인으로 트래픽을 간단히 전달한다.
    2. 지연 시간 기반 라우팅(Latency-based Routing) : 사용자의 위치에서 가장 적은 지연 시간이 예상되는 리전으로 트래픽을 라우팅합니다. 이를 통해 사용자에게 더 빠른 응답을 제공할 수 있다.
    3. 가중치 기반 라우팅(Weighted Routing) : 여러 서버나 리소스에 트래픽을 분배할 때, 가중치를 설정하여 특정 리소스에 트래픽을 더 많이 보내거나 덜 보내는 방식으로 제어할 수 있습니다. 이를 통해 여러 서버 간에 부하 분산을 유도할 수 있다.
    4. 지리적 위치 기반 라우팅(Geolocation Routing) : 사용자 위치에 따라 트래픽을 특정 서버로 라우팅 할 수 있습니다. 이를 통해 사용자에게 가까운 서버나 특정 지역에 맞는 리소스로 트래픽을 보낼 수 있다.
    5. 장애 조치 라우팅(Failover Routing) : 특정 리소스가 장애가 발생했을 때 백업 리소스로 자동 전환하여 트래픽을 전송한다. 이를 통해 높은 가용성을 유지할 수 있음.
      1. CloudWatch를 사용해 모니터링이 가능하다.
    6. 다중 값 응답 라우팅(Multi-Value Answer Routing) : 여러 서버에 트래픽을 분산할 수 있으며, 건강 검사를 통과한 서버들에만 트래픽을 보내고 이는 부하 분산과 함께, 건강하지 않은 리소스에는 트래픽을 보내지 않는 기능을 제공.
    7. IP기반 라우팅 : IP 주소 범위를 기반으로 하는 라우팅
  5. 헬스 체크(Health Checks)
    1. Route 53은 헬스 체크(Health Check) 기능을 통해 리소스가 정상적으로 작동하는지 주기적으로 확인합니다. 이를 통해 트래픽을 정상적으로 작동하는 서버나 리소스에만 전달하도록 할 수 있다.
    2. 예를 들어, 웹 서버가 응답하지 않으면 자동으로 다른 가용 리소스나 백업 서버로 트래픽을 전환하는 기능을 제공한다.
  6. 통합된 AWS 서비스
    1. Route 53은 AWS의 다양한 서비스와 쉽게 통합된다. 예를 들어, S3 버킷, EC2 인스턴스, Elastic Load Balancing(ELB)와 같은 서비스와 손쉽게 연동할 수 있다.
    2. 이를 통해 사용자 트래픽을 AWS 리소스에 안정적이고 신속하게 라우팅할 수 있다.
  7. 안정성과 확장성
    1. Route 53은 매우 높은 가용성과 확장성을 제공하는 글로벌 DNS 서비스입니다. 분산된 AWS의 인프라 덕분에 전 세계적으로 안정적인 DNS 쿼리 응답을 제공하며, 대규모 트래픽 처리에 유리하다.
  8. 도메인 이름 기반 리소스 관리
    1. Route 53을 사용하면 도메인 이름 기반으로 AWS에서 실행 중인 서비스와 애플리케이션을 쉽게 관리할 수 있습니다. 도메인 이름과 AWS의 특정 리소스 간의 매핑을 간단히 설정하고 변경할 수 있다.
  9. 다양한 레코드 타입 지원

    1. Route 53은 여러 가지 DNS 레코드 타입을 지원한다.
      1. A 레코드: 도메인 이름을 IPv4 주소로 매핑
      2. AAAA 레코드: 도메인 이름을 IPv6 주소로 매핑
      3. CNAME 레코드: 도메인 이름을 다른 도메인 이름으로 매핑
        1. Route 53에서 DNS nameSpace 또는 Zone Apex의 상위 노드에 대한 CNAMES를 생성할 수 없다.
      4. NS 레코드 : 호스팅 존의 Name server이다.
        1. 서버의 DNS Name 또는 Ip 주소로 호스팅 존에 대한 DNS 쿼리에 응답할 수 있다.
        2. Route 53 Hosted Zones : 레코드의 컨테이너이고 도메인과 서브도메인으로 가는 트래픽의 라우팅 방식을 제어한다.
          1. Public hosted Zones
            1. example.com 이 public domain이라면 Public hosted Zones 을 만들 수 있다.
            2. 퍼블릭존은 application.example.com의 ip주소를 알 수 있다.
          2.  Private hosted Zones
            1. 공개되지 않는 도메인 이름을 지원한다.
            2. 가상 프라이빗 클라우드(VPC)만이 URL을 rosolve 할 수 있다.
            3. 사내 네트워크가 Private hosted Zones에 해당한다. (회사 네트워크 내에서만 접속 가능)
        3. 트래픽이 도메인으로 라우팅 되는 방식을 제어한다.

 


5. MX 레코드: 메일 서버에 대한 정보를 제공
6. TXT 레코드: 도메인과 관련된 다양한 텍스트 정보를 제공 (예: 인증, 보안 설정)

 


reference

https://www.udemy.com/course/best-aws-certified-developer-associate/?kw=AWS&src=sac&couponCode=ST17MT91224A

https://docs.aws.amazon.com/ko_kr/route53/

 

https://docs.aws.amazon.com/ko_kr/route53/

 

docs.aws.amazon.com

 

728x90

'Dev > 인프라' 카테고리의 다른 글

Docker  (1) 2024.09.10
[Server] CI/CD  (0) 2021.11.08
[Server] 로드 밸런싱(Load balancing)  (0) 2021.11.05
[AWS] EC2 인스턴스 구축하기  (0) 2021.10.24
[Server]운영 서버에 대한 정리  (0) 2021.10.21

Docker

ryudjae
|2024. 9. 10. 14:31
728x90

Docker

Docker는 컨테이너 기반의 오픈 소스 플랫폼으로, 애플리케이션을 효율적으로 개발, 배포, 실행할 수 있게 해준다. 컨테이너는 가상화 기술의 일종으로, 운영체제 수준에서 격리된 환경을 제공하여 애플리케이션이 독립적으로 실행될 수 있도록 한다. Docker는 이러한 컨테이너를 쉽게 관리하고 실행할 수 있도록 지원하는 도구이다.

Docker는 개발자가 컨테이너를 빌드, 배포 및 실행하도록 지원하는 상용 컨테이너화 플랫폼 및 런타임이다. 단일 API를 통한 간단한 명령과 자동화를 갖춘 클라이언트-서버 아키텍처를 사용한다.

또한 Docker는 Dockerfile을 작성한 다음 Docker 서버를 사용하여 이미지를 구축하는 적절한 명령을 실행하여 변경할 수 없는 컨테이너 이미지로 애플리케이션을 패키징하는 데 일반적으로 사용하는 도구 키트를 제공한다. 개발자는 Docker 없이도 컨테이너를 만들 수 있지만 Docker 플랫폼을 사용하면 보다 쉽게 만들 수 있다. 그런 다음 이러한 컨테이너 이미지를 Kubernetes, Docker Swarm, Mesos 또는 HashiCorp Nomad와 같은 컨테이너를 지원하는 모든 플랫폼에서 배포하고 실행할 수 있다.

Docker의 주요 개념

 1. 이미지 (Image)

  • Docker 이미지는 애플리케이션과 그 애플리케이션이 실행되기 위해 필요한 모든 종속성을 포함한 불변의 템플릿이다. 이미지에는 파일 시스템, 코드, 런타임, 시스템 도구 및 라이브러리 등이 포함되어 있다.
  • Docker 이미지는 Dockerfile이라는 텍스트 파일로 정의할 수 있으며, 이를 통해 이미지를 빌드할 수 있다.

2. 컨테이너 (Container)

  • Docker 컨테이너는 이미지를 실행한 상태로, 애플리케이션을 실행하는 독립적인 환경이다. 각 컨테이너는 격리된 환경에서 실행되며, 호스트 시스템의 리소스를 공유한다.
  • 컨테이너는 가볍고, 빠르게 시작할 수 있으며, 여러 컨테이너가 같은 호스트에서 동시에 실행될 수 있다.

3. Dockerfile

  • Dockerfile은 이미지를 빌드하기 위한 명령어들이 담긴 텍스트 파일이다. 이 파일을 바탕으로 Docker 이미지를 생성한다.
  • Dockerfile에서는 어떤 베이스 이미지(예: Ubuntu, Python 등)를 사용할지, 추가로 설치할 패키지나 파일 등을 정의할 수 있다.

 

베이스 이미지 선택  
FROM ubuntu:20.04

필요한 패키지 설치  
RUN apt-get update && apt-get install -y python3

# 애플리케이션 복사  
COPY ./app /app

# 애플리케이션 실행  
CMD ["python3", "/app/main.py"]

4. Docker Hub

  • Docker Hub는 Docker 이미지를 공유하고 배포하는 중앙 저장소이다. 사용자는 Docker Hub에서 공개된 이미지를 다운로드할 수 있으며, 자신이 빌드한 이미지를 업로드하여 다른 사람과 공유할 수 있다.

5. 레지스트리 (Registry)

  • Docker 이미지가 저장되는 장소를 레지스트리라고 한다. Docker Hub는 공개 레지스트리이며, 기업들은 자체적으로 사설 레지스트리를 운영할 수 있다.

6. 볼륨 (Volume)

  • Docker 볼륨은 컨테이너와 호스트 간에 데이터를 공유할 수 있는 방식이다. 컨테이너가 삭제되더라도 데이터는 유지되며, 볼륨을 통해 여러 컨테이너 간에 데이터를 공유할 수도 있다.

7. 네트워크 (Network)

  • Docker는 컨테이너 간 통신을 위해 네트워크를 설정할 수 있다. 각 컨테이너는 격리된 네트워크에서 동작하며, 필요에 따라 다른 컨테이너와 네트워크를 통해 통신할 수 있다.

Docker의 주요 특징

1. 경량성

  • Docker 컨테이너는 기존의 가상 머신(VM)과 비교해 매우 가볍다. VM은 별도의 운영체제(OS)를 필요로 하지만, Docker 컨테이너는 호스트 OS의 커널을 공유하므로 시작 속도가 빠르고 리소스 소모가 적다.

2. 이식성

  • Docker 이미지를 사용하면 애플리케이션을 "한 번 빌드하여 어디서든 실행"할 수 있다. 컨테이너는 운영체제나 인프라에 상관없이 일관된 실행 환경을 제공한다. 이를 통해 개발 환경과 실제 운영 환경 간의 차이를 최소화할 수 있다.

3. 격리성

  • 각 Docker 컨테이너는 독립된 환경에서 실행되므로, 다른 컨테이너와 격리된 상태로 동작한다. 이를 통해 충돌이나 의존성 문제를 방지할 수 있다.

4. 확장성

  • Docker는 여러 컨테이너를 쉽게 배포하고 관리할 수 있으며, 컨테이너를 클러스터링하거나 오케스트레이션 도구(Kubernetes, Docker Swarm 등)를 사용하여 쉽게 확장할 수 있다.

5. 버전 관리 및 재사용성

  • Docker 이미지는 버전 관리가 가능하며, 여러 이미지 레이어를 사용하여 재사용성을 높인다. 즉, 한 이미지의 일부만 변경해도 전체를 다시 빌드할 필요 없이 변경된 부분만 갱신할 수 있다.

Docker의 사용 사례

1. 개발 환경 통합

  • Docker를 사용하면 개발자들이 동일한 개발 환경에서 작업할 수 있다. 운영체제나 라이브러리 버전에 상관없이, 모든 개발자가 동일한 컨테이너에서 애플리케이션을 실행하고 개발할 수 있다.

2. CI/CD 파이프라인

  • Docker는 CI/CD(Continuous Integration/Continuous Deployment) 파이프라인에서 중요한 역할을 한다. 빌드, 테스트, 배포 환경을 모두 Docker 컨테이너로 관리하면, 각 단계가 일관된 환경에서 실행되므로 오류 발생 가능성이 줄어든다.

3. 마이크로서비스 아키텍처

  • Docker는 마이크로서비스 아키텍처에서 널리 사용된다. 각 마이크로서비스는 독립적인 컨테이너로 실행되며, 서로 격리되어 배포와 확장이 용이하다.

4. 애플리케이션 이식성

  • Docker 이미지를 사용하면 다양한 환경(로컬, 클라우드, 온프레미스)에서 동일한 애플리케이션을 실행할 수 있다. 이를 통해 개발 환경과 운영 환경 간의 차이를 최소화할 수 있다.

Docker와 가상 머신(VM) 비교

항목 Docker 컨테이너 가상 머신(VM)
성능 가볍고 빠른 시작 무겁고 부팅 시간이 필요
운영체제 호스트 OS의 커널을 공유 각 VM마다 독립된 OS가 필요
격리 수준 프로세스 수준에서의 격리 완벽한 운영체제 수준의 격리
리소스 사용 매우 적은 리소스 사용 더 많은 리소스 사용
배포 속도 매우 빠름 느림

Docker의 한계

1. 보안 이슈

  • Docker 컨테이너는 동일한 커널을 공유하기 때문에, 완벽한 OS 수준의 격리를 제공하지는 못한다. 민감한 환경에서는 VM을 사용하는 것이 더 안전할 수 있다.

2. 상태 저장 애플리케이션

  • Docker 컨테이너는 기본적으로 상태가 없는(stateless) 애플리케이션을 실행하는 데 최적화되어 있다. 데이터베이스와 같은 상태 저장(stateful) 애플리케이션을 관리하려면 추가적인 설정이 필요할 수 있다.

3. 복잡한 네트워킹

  • Docker 네트워크 설정이 복잡할 수 있으며, 대규모 애플리케이션에서는 네트워크 구성이 중요한 이슈가 될 수 있다.

Docker는 컨테이너화된 애플리케이션을 패키징하고 배포하는 효율적인 방법을 제공하지만, Docker만으로는 대규모로 컨테이너를 실행하고 관리하기 어렵다. 여러 서버/클러스터에서 컨테이너를 조정 및 예약하고, 가동 중지 시간 없이 애플리케이션을 업그레이드 또는 배포하고, 컨테이너의 상태를 모니터링하는 것은 고려해야 할 사항 중 일부에 불과하다.
이와 같은 여러 문제를 해결하기 위해 컨테이너를 오케스트레이션하는 솔루션이 Kubernetes, Docker Swarm, Mesos, HashiCorp Nomad 등의 형태로 등장했다. 이를 통해 조직은 대량의 컨테이너와 사용자를 관리하고 부하를 효율적으로 분산하며 인증 및 보안, 다중 플랫폼 배포 등을 제공할 수 있다.

📍 결론

Docker는 애플리케이션의 개발, 배포, 관리를 쉽게 할 수 있는 도구로, 특히 마이크로서비스 아키텍처와 클라우드 환경에서 널리 사용된다. 경량성, 이식성, 확장성 등 여러 장점이 있지만, 보안 문제나 네트워크 복잡성 등과 같은 한계도 존재한다. 이를 이해하고 적절한 상황에서 Docker를 활용하면 개발과 운영 효율성을 크게 향상시킬 수 있다.


참조 자료

https://aws.amazon.com/ko/docker/
https://aws.amazon.com/ko/blogs/containers/deploy-applications-on-amazon-ecs-using-docker-compose/
https://www.atlassian.com/ko/microservices/microservices-architecture/kubernetes-vs-docker

728x90

'Dev > 인프라' 카테고리의 다른 글

AWS Route 53  (5) 2024.09.12
[Server] CI/CD  (0) 2021.11.08
[Server] 로드 밸런싱(Load balancing)  (0) 2021.11.05
[AWS] EC2 인스턴스 구축하기  (0) 2021.10.24
[Server]운영 서버에 대한 정리  (0) 2021.10.21
728x90

mac 기준으로 preference -> Editer -> General -> auto import -> Optimize imports on the fly 체크한다.

(이게 제일 편하긴하죠)

 

 

++ option + enter 로도 제거가 가능하다.

728x90

'Dev' 카테고리의 다른 글

인증(Authentication)과 인가(Authorization)  (4) 2024.10.06
Hexagonal Architecture (헥사고날 아키텍쳐)  (1) 2024.09.14
빅데이터 처리  (0) 2022.02.11
[기술면접] JAVA  (0) 2022.01.24
[기술면접]알고리즘 + 자료구조  (0) 2022.01.23
728x90
💡 1995년 GoF(Gang of Four)라고 불리는 Erich Gamma, Richard Helm, Ralph Johnson, John Vissides가 처음으로 디자인 패턴을 구체화하였다.GoF의 디자인 패턴은 소프트웨어 공학에서 가장 많이 사용되는 디자인 패턴이다.목적에 따라 분류할 시 생성 패턴 5개, 구조패턴 7개, 행위 패턴 11개 총 23개의 패턴으로 구성된다.

🤷‍♂️GoF 디자인 패턴

GoF디자인 패턴을 분류하는 기준은 두 가지이다.

  1. 목적에 따라 분류하면 생성 ,구조, 행동 3가지로 나눌 수 있다. 각각의 패턴이 어떤 일을 하기 위한 것인지에 관한 것이다. 생성 패턴은 객체의 생성 과정에 관여, 구조 패턴은 객체의 합성에 관여, 행동 패턴은 객체가 상호 작용하는 방법이나 관심사를 분리하는 방법이다.
  2. 범위에 따라 분류도 가능하다. 패턴을 주로 클래스에 적용하는지, 객체에 적용하는 지 구분하는 것이다. 클래스 패턴은 클래스와 서브 클래스 간의 관령성을 다룬다. 주로 상속을 통해 관련되며, 컴파일 타임에 정적으로 결정된다. 객체 패턴은 객체 간의 관련성을 다루고, 런타임에 변경될 수 있는 동적인 성격을 가진다.

 

🔨생성 패턴

생성 패턴은 객체의 생성과 관련된 패턴이다. 객체의 인스턴스 과정을 추상화하는 방법이다. 객체의 생성과 참조 과정을 캡슐화하며 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 받지 않도록 하여 프로그램에 유연성을 더해준다.생성 클래스 패턴은 객체를 생성하는 일부를 서브 클래스가 담당하도록 하며, 생성 객체 패턴은 객체 생성을 다른 객체에게 위임한다.

추상 팩토리(Abstract Factory) 구체적인 클래스를 지정하지 않고 인터페이스를 통해 서로 연관되는 객체들을 그룹으로 표현함
빌더(Builder) 복합 객체의 생성과 표현을 분리하여 동일한 생성 절차에서도 다른 표현 결과를 만들어낼 수 있음
팩토리 메소드(Factory Method) 객체 생성을 서브클래스로 위임하여 캡슐화함
프로토타입(Prototype) 원본 객체를 복사함으로써 객체를 생성함
싱글톤(Singleton) 어떤 클래스의 인스턴스는 하나임을 보장하고 어디서든 참조할 수 있도록 함

 

🔨구조 패턴

구조 패턴은 클래스나 객체들을 조합해 더 큰 구조로 만들 수 있게 해주는 패턴이다. 구조 클래스 패턴은 상속을 통해 클래스나 인터페이스를 합성하고, 구조 객체 패턴은 객체를 합성하는 방법을 정의한다.

어댑터(Adapter) 클래스의 인터페이스를 다른 인터페이스로 변환하여 다른 클래스가 이용할 수 있도록 함
브리지(Bridge) 구현부에서 추상층을 분리하여 각자 독립적으로 확장할 수 있게 함
컴포지트(Composite) 객체들의 관계를 트리 구조로 구성하여 복합 객체와 단일 객체를 구분없이 다룸
데코레이터(Decorator) 주어진 상황 및 용도에 따라 어떤 객체에 다른 객체를 덧붙이는 방식
퍼싸드(Facade) 서브시스템에 있는 인터페이스 집합에 대해 하나의 통합된 인터페이스(Wrapper) 제공
플라이웨이트(Flyweight) 크기가 작은 여러 개의 객체를 매번 생성하지 않고 가능한 한 공유할 수 있도록 하여 메모리를 절약함
프록시(Proxy) 접근이 어려운 객체로의 접근을 제어하기 위해 객체의 Surrogate나 Placeholder를 제공

 

🔨행위 패턴

행위 패턴은 클래스나 객체들이 서로 상호작용하는 방법이나 어떤 태스크, 어떤 알고리즘을 어떤 객체에 할당하는 것이 좋을지를 정의하는 패턴이다. 즉, 객체나 클래스의 교류 방법에 대해 정의하는 것이다. 행위 패턴은 하나의 객체로 수행할 수 없는 작업을 여러 객체로 분배하면서 그들 간의 결합도를 최소화 할 수 있도록 도와준다. 행위 클래스 패턴 은 상속을 통해 알고리즘과 제어 흐름을 기술하고, 행위 객체 해턴 은 하나의 작업을 수행하기 위해 객체 집합이 어떻게 협력하는지를 기술한다.

책임 연쇄(Chain of Responsibility) 요청을 받는 객체를 연쇄적으로 묶어 요청을 처리하는 객체를 만날 때까지 객체 Chain을 따라 요청을 전달함
커맨드(Command) 요청을 객체의 형태로 캡슐화하여 재사용하거나 취소할 수 있도록 저장함
인터프리터(Interpreter) 특정 언어의 문법 표현을 정의함
반복자(Iterator) 내부를 노출하지 않고 접근이 잦은 어떤 객체의 원소를 순차적으로 접근할 수 있는 동일한 인터페이스 제공
중재자(Mediator) 한 집합에 속해있는 객체들의 상호작용을 캡슐화하여 새로운 객체로 정의
메멘토(Memento) 객체가 특정 상태로 다시 되돌아올 수 있도록 내부 상태를 실체화
옵서버(Observer) 객체 상태가 변할 때 관련 객체들이 그 변화를 통지받고 자동으로 갱신될 수 있게 함
상태(State) 객체의 상태에 따라 동일한 동작을 다르게 처리해야할 때 사용
전략(Strategy) 동일 계열의 알고리즘군을 정의하고 캡슐화하여 상호교환이 가능하도록 함
템플릿 메소드(Template Method) 상위클래스는 알고리즘의 골격만을 작성하고 구체적인 처리는 서브클래스로 위임함
방문자(Visitor) 객체의 원소에 대해 수행할 연산을 분리하여 별도의 클래스로 구성함
728x90
728x90

💻프로시저(스토어드 프로그램)

프로시저는 일련의 쿼리를 하나의  함수처럼 실행하기 위한 쿼리의 집합이다.  매개 변수를 받을 수 있고, 반복적으로 사용할 수 있는  BLOCK이다.
일반적으로 연속 실행 또는 구현이 복잡한 트랜잭션을 수행하는  PL/SQL BLOCK을 데이터베이스에 저장하기 위해 생성한다.

 

💻프로시저(스토어드 프로그램)를 사용하는 이유

🔑데이터베이스의 보안의 향상

MYSQL의 스토어드 프로그램은 자체적인 보안 설정 기능을 가지고 있기 때문에 스토어드 프로그램 단위로 실행 권한을 부여할 수 있다. 이러한 보안 기능을 조합해서 특정 테이블의 읽기와 쓰기 또는 특정 칼럼에 대해서만 권한을 설정하는 등 세밀한 권한 제어가 가능하다.

주요 기능을 스토어드 프로그램으로 작성한다면 SQL 인젝션과 같은 기본적인 보안 사고는 피할 수 있을 것이다.

 

🔑기능의 추상화

일련번호와 같은 복잡한 방식으로 생성되는 경우 생성 방식이 복잡하여 , MYSQL의 Auto_increment를 이용할 수가 없다. 만약 애플리케이션에서 일련번호 생성용 모듈을 개발한다면 개발하는 언어별로 호환되지 않을뿐더러 직접 SQL 클라이언트에서는 사용이 불가능하다. 일련번호 생성용 프로그램을 MYSQL 서버의 스토어드 프로그램으로 구현한다면 애플리케이션이나 SQL 클라이언트에서도 쉽게 사용할 수 있다. 

 

🔑절차적 기능 구현 

DBMS 서버에서 사용하는 SQL쿼리는 절차적인 기능을 제공하지 않는다. 즉, SQL 쿼리에서는 IF나 WHILE과 같은 제어 문장을 사용할 수 없다. 그러나 스토어드 프로그램은 DBMS 서버에서 절차적인 기능을 실행할 수 있는 제어 기능을 제공한다. 가끔 SQL 문장으로 절대 처리할 수 없는 것들이 있다. 일반적으로 이런 상황에서는 데이터를 애플리케이션에서 가공한 후 다시 데이터 베이스에 저장하는 형태로 개발을 진행을 하지만  스토어드 프로그램을 이용해 절차적인 기능을 구현한다면 최소한 네트워크 경유에 걸리는 시간만큼은 줄일 수 있고 불필요한 애플리케이션 코드를 줄일  수 있다.

 

🔑개발 업무의 구분

순수하게 애플리케이션을 개발하는 조직과 DBMS 관련 코드를 개발하는 조직이 별도로 구분되어 있다면 DBMS코드를 개발하는 조직에서는 트랜잭션 단위로 데이터베이스를 처리를 하는 스토어드 프로그램을 만들어 API처럼 만들어 제공하고 애플리케이션 개발자는 스토어드 프로그램을 호출해서 사용하는 형태로 역할을 구분해서 개발을 진행할 수도 있다.

🔑네트워크 소요시간 절감

일반적으로 애플리케이션과 데이터베이스 서버는 같은 네트워크 구간에 존재하므로 SQL의 실행 성능에서 네트워크를 경유하는 데 걸리는 시간은 많은 신경을 쓰지 않는다. 그러나 하나하나 쿼리가 가볍고 빠르게 처리될 수 있다면 네트워크를 경유하는 데 걸리는 시간에서 이슈가 발생할 수 있다. 하나의 프로그램에서 100번, 200번씩 실행해야 하는 쿼리를 스토어드 프로그램으로 구현한다면 스토어드 프로그램을 호출할 때 한 번만 네트워크를 경유하면 되기 때문에 네트워크 소요 시간을 줄이고 성능을 개선할 수 있다.

 

💻프로시저(스토어드 프로그램)의 단점

 

🔨낮은 처리 성능 

스토어드 프로그램은 MYSQL 엔진에서 해석되고 실행된다. 하지만 MYSQL 서버는 스토어드 프로그램과 같은 절차적 코드 처리에 중점을 두고 처리하는 것이 아니라서 다른 프로그램 언어에 비해 성능이 떨어진다.

 

 

🔨애플리케이션 코드의 조각화

애플리케이션의 설치나 배포 작업이 갈수록 복잡해진다. 각 기능을 담당하는 프로그램 코드가 자바와 MYSQL스토어드 프로그램으로 분산된다면 애플리케이션의 설치나 배포가 복잡해 서지고 유지보수 또한 어려워질 수 있다.

 

 

💻프로시저(스토어드 프로그램)의 사용 예제

1. 프로시저 생성

  • DEFINER : 접근 권한
  • PROCEDURE : 프로시저 이름
  • 매개변수 + 타입
  • SET 변수 설정
    • 기호가 없을 때 프로시저 실행이 끝나면 초기화
    • @가 있으면 프로시저가 끝나도 계속 유지
  • CONCAT() : 문자열 합치기
  • PREPARE : 실행 준비
  • EXECUTE : PREPARE 된 것을 실행 

 

프로시저 기본 형태

CREATE DEFINER=`DB권한이 있는 아이디`@`%` PROCEDURE `프로시저이름`
BEGIN
  SELECT * 
  FROM 테이블명
END

DB에 접속하는 ID명을 적어준다. 여기에 적는 ID는 무조건 권한이 있는 ID를 넣어야 한다.

 

프로시저 인자 값 및 파라미터를 받을 때

CREATE DEFINER=`DB권한이 있는 아이디`@`%` PROCEDURE `프로시저이름`(
   IN 변수명 자료형   
   OUT 변수명 자료형 
)
BEGIN
    SELECT *
    FROM 테이블명
    WHERE 컬럼명 = 변수명
END

받을 변수명 자료형 (INT, VARCHAR(40) 등)을 입력해준다. 받을 때는 IN을 사용하고 반환하는 변수의 자료형은 OUT

 

 

프로시저 변수 할당

 

CREATE DEFINER=`DB권한이 있는 아이디`@`%` PROCEDURE `프로시저이름`(
    IN 변수명 자료형
)
BEGIN
    SET @v_code = '123';
    SELECT *
    FROM 테이블명
    WHERE 컬럼 = 변수명 AND
    	  컬럼 = @v_code
EN

변수를 할당할 때 바로 값을 적어도 되지만 서브 쿼리를 사용하여 (@v_code = (select,,,,from...))할당할 수 있다.

프로시저 조건문 사용하기 IF, ELSEIF, OR, AND..

CREATE DEFINER=`DB아이디`@`%` PROCEDURE `프로시저명`(
    IN 변수명 자료형
)
BEGIN
    SET @v_code = '123';
    IF @v_code!='' THEN
      SELECT *
      FROM 테이블명
      WHERE 컬럼 = 변수명 AND
    	    컬럼 = @v_code
    END IF;
END

IF 조건문 OR 조건문 THEN
실행 문구
ELSE IF 조건문 THEN
실행 문구
END IF;
등의 형태로 쓸 수 있으며
NULL 체크는 IS NOT NULL / IS NULL을 쓸 수 있다.

⚒프로시저 생성 예제

CREATE DEFINER='root'@'%' PROCEDURE test_prc(id int(10))
BEGIN
SET @t1 = CONCAT('SELECT * FROM test_', id);
PREPARE s FROM @t1;
EXECUTE s;
END

이런 식의 프로시저는 테이블 이름을 배열 변수에 담아서 LOOPING 돌려 한번에 처리 가능하다. 

 


REFERENCE

https://unlimitedcoding.tistory.com/15

https://velog.io/@ym1085/MySQL-%ED%94%84% EB% A1% 9C% EC% 8B% 9C% EC% A0%80% EB% 9E%80

728x90