[GDC] Weekly Newsletter September 1st

·

28 min read

Table of contents

Go 언어에서의 모델 검증

요약

Go 언어에서 모델 검증은 소프트웨어 개발에서 필수적인 부분입니다. 적절한 검증을 통해 데이터 유효성을 보장하고 이후 작업을 간소화할 수 있습니다. 이 글은 Go 언어에서 모델 검증을 수행하는 다양한 방법과 validator v10 라이브러리에 대해 설명합니다.

소개

Go 언어는 강력한 타입 시스템을 제공하지만, 모델 검증을 위한 내장 기능은 부족합니다. 따라서 개발자는 직접 검증 로직을 작성하거나 외부 라이브러리를 활용해야 합니다. validator v10 라이브러리는 Go 언어에서 모델 검증을 위한 사실상 표준 라이브러리로 자리 잡았습니다. 이 라이브러리는 필드 태그를 사용하거나 사용자 정의 검증 함수를 작성하여 모델 검증을 수행할 수 있습니다.

참고

Read more

유지보수 가능한 Go 코드 작성 방법

요약

이 글은 Go 코드의 유지보수성을 향상시키는 다양한 전략을 소개합니다. main 함수 최소화, 의미 있는 이름 사용, 주석 작성, 코드 중복 방지, 깊은 중첩 방지, 조기 반환 활용, switch 문 활용 등 구체적인 방법들을 제시합니다.

소개

Go는 간결하고 효율적인 코드를 작성하기 위한 강력한 도구이지만, 코드가 복잡해지면 유지보수가 어려워질 수 있습니다. 새로운 팀원이 코드를 이해하고 변경하기 어려워지고, 개발자가 떠날 경우 다른 개발자가 코드를 이어받아 작업하는 데 어려움을 겪을 수 있습니다. 유지보수 가능한 코드는 코드 이해 및 변경을 용이하게 하여 개발 속도를 높이고 유지 관리 비용을 절감하는 데 도움을 줍니다.

이 글에서는 Go 코드의 유지보수성을 높이기 위한 다양한 전략을 소개합니다.

  • main 함수 최소화: main 함수는 Go 프로그램의 진입점이므로 가능한 한 간단하게 유지하는 것이 좋습니다. main 함수는 주로 다른 패키지의 함수를 호출하여 애플리케이션을 시작하고 실행합니다.
  • 의미 있는 이름 사용: 변수, 함수, 구조체, 인터페이스 등에 의미 있는 이름을 사용하면 코드 가독성을 높일 수 있습니다. 이름은 코드가 무엇을 하는지 명확하게 나타내야 합니다.
  • 주석 작성: 중요한 코드 부분에 자세한 주석을 추가하면 코드를 이해하는 데 도움을 줍니다. 주석은 코드가 어떻게 작동하는지, 어떤 목적으로 작성되었는지 설명해야 합니다.
  • 코드 중복 방지: 동일한 코드를 여러 번 반복하는 것은 유지보수에 큰 어려움을 야기할 수 있습니다. DRY (Don't Repeat Yourself) 원칙을 따르고 코드를 재사용 가능한 함수로 분리하여 코드 중복을 최소화해야 합니다.
  • 깊은 중첩 방지: 깊은 중첩은 코드 가독성을 떨어뜨리고 오류 발생 가능성을 높입니다. 중첩된 if 문을 최소화하고 조기 반환을 활용하여 코드를 간단하게 유지하는 것이 중요합니다.
  • 조기 반환 활용: 함수가 특정 조건을 만족하면 즉시 반환하여 불필요한 처리를 줄일 수 있습니다.
  • switch 문 활용: if 문 대신 switch 문을 사용하면 코드 가독성과 유지보수성을 향상시킬 수 있습니다. switch 문은 여러 조건을 간결하게 비교하고 해당 조건에 맞는 코드를 실행하는 데 유용합니다.

참고

Read more

gRPC와 REST HTTP API 간의 간극을 메우는 방법: gRPC 서비스를 REST 세계에 공개하기

요약

이 글은 gRPC 서비스와 RESTful HTTP API 간의 간극을 해소하고 Apigee 엔터프라이즈 API 관리 플랫폼으로 향상된 솔루션을 소개합니다. gRPC 서비스를 RESTful HTTP API로 노출하여 더 넓은 개발자와 애플리케이션에 접근할 수 있도록 하는 방법을 보여줍니다.

소개

현대 마이크로서비스 아키텍처를 설계할 때 성능은 매우 중요합니다. 고주파 트레이딩 및 실시간 시스템 뿐 아니라, 서비스 간 통신에서 발생하는 몇 밀리초의 지연도 전체 사용자 경험에 큰 영향을 미칩니다. 이러한 환경에서 gRPC는 고성능 통신 프로토콜로 자리 잡았으며, 낮은 지연 시간, 효율적인 직렬화 및 강력한 형식의 메시지로 인해 널리 채택되고 있습니다.

그러나 대부분의 시스템 경계를 넘나드는 서비스 간 통신은 여전히 HTTP API에 크게 의존합니다. 이는 API가 API 생산자와 소비자의 형태로 분리된 엔터티 간의 계약 역할을 하기 때문이며, gRPC로 전환하면 많은 마찰이 발생합니다. 또한 모든 개발자가 gRPC 서비스를 소비할 준비가 되어 있거나 경험이 있는 것은 아닙니다. 따라서 API 제공자는 gRPC 서비스만 노출함으로써 잠재적인 사용자를 놓칠 위험이 있습니다.

이 블로그에서는 고성능 gRPC 서비스와 널리 채택된 RESTful HTTP API 생태계 간의 간극을 쉽게 해소하는 방법을 보여줍니다. 기존 gRPC 서비스와 함께 배포할 수 있는 자동 생성된 gRPC 게이트웨이를 활용하여 HTTP 인터페이스를 제공하는 프로토콜 변환을 처리하는 솔루션을 제안합니다. 마지막으로, Apigee를 엔터프라이즈 API 관리 플랫폼으로 도입하여 안전하고 셀프 서비스 방식으로 깔끔한 RESTful API фасаду를 제공합니다.

참고

Read more

Go에서 defer 키워드: 기본부터 함정까지

Summary

Go의 defer 키워드는 함수 종료 직전에 실행될 코드를 지정하는 데 사용됩니다. defer는 코드의 가독성을 높이고 리소스 해제, 에러 처리 등에 유용하지만, 몇 가지 함정이 존재합니다. 본 글에서는 defer의 기본적인 사용법부터 고급 기능, 그리고 잠재적인 문제점까지 자세히 살펴봅니다.

Introduction

Go 언어에서 defer 키워드는 함수가 종료되기 직전에 코드 블록을 실행하도록 지정하는 특별한 기능입니다. defer로 선언된 코드는 함수가 정상적으로 종료되든, 에러가 발생하든, panic()으로 인해 중단되든 상관없이 항상 실행됩니다.

defer는 일반적으로 함수 내에서 사용한 리소스를 해제하는 데 사용됩니다. 예를 들어, 파일을 열어 작업한 후에는 파일을 닫아야 합니다. 이 때 defer를 사용하면 함수가 종료될 때 파일을 자동으로 닫을 수 있습니다.

file, err := os.Open("myFile.txt")
if err != nil {
  // 에러 처리
}
defer file.Close() // 파일 닫기 defer
// 파일 작업 수행

defer는 함수가 끝날 때까지 실행을 미루므로 여러 개의 defer를 사용할 수 있습니다. 이 경우 defer가 선언된 순서와 반대로 실행됩니다.

defer fmt.Println("Third")
defer fmt.Println("Second")
defer fmt.Println("First")

위 코드를 실행하면 "First", "Second", "Third" 순으로 출력됩니다.

defer는 리소스 해제뿐만 아니라 에러 처리, 로그 기록, 함수 실행 전후 작업 등 다양한 용도로 사용될 수 있습니다. Go 프로그래밍에서 defer는 코드를 깔끔하게 유지하고 안정성을 높이는 데 도움이 되는 중요한 기능입니다.

Reference

Read more

우아한 종료: 프로그램을 깔끔하게 종료하는 방법 (Go와 Kubernetes)

요약

이 글은 Go 언어로 작성된 프로그램이 Kubernetes 환경에서 우아하게 종료되는 방법을 소개합니다. 특히, SIGTERM 신호 처리를 통해 진행 중인 작업을 완료하고 데이터 손실 없이 안전하게 종료하는 방법에 초점을 맞춥니다.

소개

프로그램이 정상적으로 종료될 때, 또는 예상치 못한 오류 발생 시에도 데이터 손실 없이 안전하게 종료되는 것은 중요합니다. 이를 "우아한 종료"라고 하며, 특히 Kubernetes와 같은 컨테이너 환경에서 필수적입니다.

이 글에서는 Go 언어를 사용하여 Kubernetes 환경에서 프로그램이 우아하게 종료되는 방식을 실제 코드 예시와 함께 살펴봅니다.

  • Unix 시스템의 신호(SIGTERM, SIGKILL, SIGINT, SIGQUIT) 개념과 우아한 종료의 중요성을 설명합니다.
  • Go에서 신호 처리를 위한 signal.NotifyContext 함수를 사용하는 방법을 보여줍니다.
  • 간단한 Go HTTP 서버를 예시로 사용하여 우아한 종료를 구현하는 방법을 단계별로 설명합니다.
  • Kubernetes에서 제공하는 terminationGracePeriodSeconds 설정과 preStop 훅의 역할을 설명합니다.
  • 다양한 웹 프레임워크(Echo, Gin, Fiber)에서 우아한 종료가 처리되는 방식을 간략하게 소개합니다.

추천

  • Go 프로그램 개발 시, signal.NotifyContext를 사용하여 SIGTERM 신호를 처리하는 것을 고려해야 합니다.
  • Kubernetes 환경에서 실행되는 프로그램의 경우 terminationGracePeriodSeconds 설정을 적절하게 조정해야 합니다.
  • preStop 훅을 사용하여 프로그램 종료 전에 필요한 작업(데이터 저장, 연결 해제 등)을 수행하도록 설정해야 합니다.

참고

Read more

Goakt: Go Actor 프레임워크

Summary

Goakt는 Go 언어를 위한 Actor 프레임워크로, 고루틴과 채널을 사용하여 비동기 작업 처리 및 분산 시스템 개발을 간편하게 지원합니다. 프로토콜 버퍼를 메시지 포맷으로 사용하여 빠르고 효율적인 통신을 제공합니다.

Introduction

Goakt는 Actor 모델을 기반으로 설계된 Go 언어용 프레임워크입니다. 배우 모델은 독립적인 Actor들이 메시지를 통해서만 통신하는 분산 시스템 모델입니다. Goakt는 Go의 고루틴과 채널을 활용하여 Actor 모델을 효과적으로 구현합니다.

Goakt는 다음과 같은 장점을 제공합니다:

  • 간편한 사용: Actor 생성 및 메시지 전달이 간단합니다.
  • 비동기 처리: 고루틴과 채널을 활용하여 비동기적으로 작업을 처리합니다.
  • 병렬 처리: 여러 Actor를 동시에 실행하여 병렬 처리를 수행합니다.
  • 확장성: Actor 시스템을 쉽게 확장할 수 있습니다.
  • 분산 처리: 클러스터 모드를 지원하여 분산 시스템 개발을 용이하게 합니다.
  • 높은 성능: 프로토콜 버퍼를 메시지 포맷으로 사용하여 빠르고 효율적인 통신을 제공합니다.

Recommendation

Goakt는 비동기 작업 처리 및 분산 시스템 개발을 쉽게 구현하고 싶은 Go 개발자에게 유용한 프레임워크입니다. 특히 분산 시스템, 게임 서버, 멀티 스레드 애플리케이션 개발에 적합합니다.

Reference

Read more

Caution

  • Goakt는 클러스터 모드에서 Actor의 고유성을 보장합니다. 즉, 클러스터 내에서 동일한 이름의 Actor는 하나만 존재할 수 있습니다.
  • Goakt는 Actor의 상태를 지속적으로 유지하기 위한 기능을 제공하지 않습니다. Actor의 상태를 지속적으로 유지하려면 별도의 분산 저장소를 사용해야 합니다.
  • Goakt는 프로토콜 버퍼를 메시지 포맷으로 사용합니다. 따라서 프로토콜 버퍼에 대한 기본적인 이해가 필요합니다.

    Go 기반 마이크로서비스 프레임워크, Go-Doudou: 가볍고 강력한 API 개발 솔루션

요약

Go-Doudou는 Go 언어로 구현된 경량 마이크로서비스 프레임워크로, OpenAPI 3.0(REST) 및 Protobuf v3(gRPC) 사양을 기반으로 합니다. 모놀리식 서비스 애플리케이션도 지원하며, 빠른 개발 속도와 효율적인 운영을 목표로 합니다.

소개

Go-Doudou는 Go 언어를 사용하는 개발자들이 마이크로서비스 아키텍처를 쉽고 빠르게 구축할 수 있도록 돕는 프레임워크입니다. 다음과 같은 장점을 제공합니다.

  • 간편한 인터페이스 정의: Go 인터페이스를 기반으로 하므로 별도의 IDL(Interface Definition Language) 학습이 필요하지 않습니다.
  • 강력한 코드 생성 기능: 내장된 CLI를 통해 인터페이스 정의만으로 서비스 코드를 자동 생성하여 개발 시간을 단축시킵니다.
  • 클라우드 네이티브 환경 지원: 클라우드 네이티브 환경에 최적화되어 빠른 프로토타입 제작과 잦은 배포를 지원합니다.
  • 서비스 거버넌스 기능: 원격 구성 관리, 클라이언트 측 부하 분산, 속도 제한, 회로 차단, 벌크헤드, 타임아웃, 재시도 등 다양한 서비스 거버넌스 기능을 제공합니다.
  • 모놀리식 및 마이크로서비스 아키텍처 지원: 모놀리식과 마이크로서비스 아키텍처를 모두 지원하여 개발자가 시스템을 유연하게 설계할 수 있도록 합니다.

Go-Doudou는 RESTful API, gRPC 기반 마이크로서비스, 웹 서비스, 게임 서버 등 다양한 분야에서 활용될 수 있습니다.

참고

Go-Doudou GitHub 저장소

주의

  • Go-Doudou는 아직 개발 중인 프로젝트이며, 안정성이 완벽하게 보장되지 않을 수 있습니다.
  • 사용 전에 Go-Doudou의 문서와 코드를 자세히 검토하고, 필요에 따라 수정 및 개선을 수행해야 합니다.

    Go의 새로운 unique 패키지: 중복 제거를 통한 효율성 향상

요약

Go 1.23 버전부터 unique 패키지가 추가되어 비교 가능한 값들의 중복 제거를 지원합니다. 이 패키지는 값들을 캐싱하여 메모리 사용량을 줄이고, 중복된 값 비교 연산을 간소화하여 프로그램 성능을 향상시킵니다.

소개

unique 패키지는 Go에서 중복 제거(interning)를 위한 새로운 기능을 제공합니다. 중복 제거는 동일한 값을 여러 번 생성하는 대신 단일한 캐시된 값을 사용하여 메모리 사용량을 절감하고 값 비교 연산을 효율적으로 수행하는 기법입니다.

예를 들어, 문자열을 중복 제거하면 동일한 문자열을 여러 번 생성하는 대신 단일한 캐시된 문자열을 사용하여 메모리를 절약할 수 있습니다. 또한, 중복 제거된 문자열의 경우 포인터 비교만으로 동일성을 확인할 수 있어, 문자열 전체를 비교하는 것보다 훨씬 빠릅니다.

unique 패키지는 Make 함수를 제공하여 비교 가능한 모든 유형의 값을 중복 제거할 수 있습니다. Make 함수는 제공된 값을 캐싱하고 Handle[T] 타입의 래퍼 값을 반환합니다. Handle[T]는 값의 캐시된 복사본을 나타내며, 두 개의 Handle[T] 값은 그들이 생성된 값이 동일할 때만 동일하다고 간주됩니다. Handle[T]는 포인터 비교를 통해 효율적으로 비교할 수 있습니다.

unique 패키지는 Handle[T]가 존재하는 동안 캐시된 값을 유지하고, 모든 Handle[T]가 사라지면 캐시된 값을 삭제합니다. 이는 unique 패키지가 메모리 관리에 대한 명확한 정책을 제공하며, 가비지 컬렉터가 캐시된 값을 효율적으로 회수할 수 있도록 돕습니다.

참고

Go 블로그: New unique package

FastDB: Go로 구현된 빠르고 지속적인 메모리 내 키/값 저장소

요약

FastDB는 Go로 구현된 키/값 저장소로, 빠른 속도와 데이터 지속성을 제공합니다. 메모리 내에서 데이터를 저장하고 필요에 따라 디스크에 지속적으로 저장합니다.

소개

FastDB는 Go 언어로 개발된 키/값 저장소입니다. 다른 데이터베이스와 달리 FastDB는 데이터를 디스크에 지속적으로 저장하는 동시에 메모리 내에서도 빠르게 액세스할 수 있도록 설계되었습니다. 이를 통해 빠른 데이터 액세스 속도와 데이터 지속성을 동시에 보장합니다.

FastDB의 주요 특징은 다음과 같습니다.

  • 빠른 속도: 메모리 내 저장을 활용하여 매우 빠른 데이터 액세스 속도를 제공합니다.
  • 지속성: 데이터 지속성을 위해 백업 메커니즘을 제공하여 데이터 손실 위험을 최소화합니다.
  • 버킷: 데이터를 버킷으로 분류하여 효율적인 데이터 관리를 가능하게 합니다.
  • 쉬운 사용: 간단한 API를 통해 쉽게 데이터를 저장, 조회, 업데이트 및 삭제할 수 있습니다.

FastDB는 웹 애플리케이션, 캐싱, 임베디드 시스템 등 다양한 용도로 사용할 수 있습니다. 특히 빠른 데이터 액세스가 중요한 애플리케이션에 적합합니다.

참고

Read more

Sponge: 웹 및 마이크로서비스 프로젝트 개발을 위한 강력한 Go 프레임워크

Summary

Sponge는 웹 및 마이크로서비스 프로젝트 개발을 쉽게 만들어주는 강력한 Go 개발 프레임워크입니다. 자동 코드 생성, Gin 및 GRPC 통합, 풍부한 코드 생성 명령어 세트를 제공하여 개발 효율성을 향상시키고 개발 난이도를 줄여줍니다.

Introduction

Sponge는 Go로 작성된 개발 프레임워크로, 코드 생성, 개발, 테스트, API 문서화, 배포 등 프로젝트 개발의 모든 단계를 지원합니다. 자동 코드 생성 기능을 통해 CRUD API를 포함한 웹 또는 gRPC 서비스를 개발할 때 Go 코드를 직접 작성하지 않고도 컴파일 및 배포할 수 있습니다. MySQL, MongoDB, PostgreSQL, TiDB, SQLite 등 다양한 데이터베이스를 지원합니다.

Sponge는 웹 또는 gRPC 서비스를 개발할 때 데이터베이스 테이블 정의, 프로토 파일을 통한 API 설명 정보 정의, 생성된 템플릿 파일에서 비즈니스 로직 코드 작성 등 3가지 핵심 부분에 집중할 수 있도록 지원하며, 나머지 Go 코드는 자동으로 생성됩니다. 이를 통해 개발 효율성을 크게 향상시키고 개발 난이도를 줄여줍니다.

Recommendation

웹 또는 gRPC 서비스 개발을 빠르고 효율적으로 수행하고자 하는 Go 개발자에게 Sponge를 추천합니다. 특히 CRUD API를 포함한 서비스 개발 시 유용하며, "로우 코드" 방식을 통해 고품질 프로젝트를 개발하는 데 도움을 줄 수 있습니다.

Reference

Read more

GoFast: 빠르고 확장 가능한 웹 애플리케이션을 위한 궁극의 기반

Summary

GoFast는 Go 언어와 SvelteKit/Next.js의 강력한 조합을 활용하여 고성능, 확장 가능한 웹 애플리케이션을 개발하기 위한 최고의 기반을 제공하는 템플릿입니다. 강력한 CLI 도구를 통해 빠르고 쉽게 프로젝트를 설정할 수 있습니다.

Introduction

GoFast는 Go 언어의 뛰어난 성능과 SvelteKit/Next.js 프레임워크의 현대적인 기능을 결합하여 웹 개발의 효율성을 극대화하는 템플릿입니다. GoFast는 REST API, 웹소켓, 데이터베이스 통합, 템플릿 엔진, 미들웨어, 테스트 도구 등 다양한 기능을 제공하여 개발자들이 복잡한 설정 없이 즉시 프로젝트를 시작하고, 빠르게 결과물을 만들 수 있도록 지원합니다.

GoFast는 다음과 같은 장점을 제공합니다.

  • 고성능 백엔드: Go 언어 기반으로 빠르고 효율적인 백엔드를 구축할 수 있습니다.
  • 최신 프론트엔드 기술: TypeScript, SvelteKit/Next.js를 사용하여 현대적인 프론트엔드 애플리케이션을 개발할 수 있습니다.
  • 최적화된 성능 및 확장성: Go 언어와 SvelteKit/Next.js의 장점을 활용하여 최적화된 성능과 뛰어난 확장성을 확보할 수 있습니다.
  • 풍부한 생태계 및 커뮤니티 지원: Go 언어와 SvelteKit/Next.js의 활발한 커뮤니티와 다양한 패키지를 통해 개발을 더욱 효율적으로 진행할 수 있습니다.
  • 강력한 GoFast CLI: GoFast CLI를 통해 필요한 기술을 선택하고 프로젝트를 빠르게 설정할 수 있습니다.
  • 통합된 기능: GoFast는 결제, 이메일, 파일 저장소 등 웹 애플리케이션 개발에 필수적인 기능을 통합하여 개발 시간을 단축시켜줍니다.

Recommendation

GoFast는 빠르고 효율적인 웹 개발을 원하는 개발자들에게 강력히 추천합니다. 특히, 고성능 웹 애플리케이션을 구축해야 하는 경우, Go 언어와 SvelteKit/Next.js의 장점을 활용하고 싶은 개발자들에게 유용합니다.

Reference

GoFast 웹사이트

Caution

GoFast는 베타 버전으로, 아직 완전히 완성되지 않았습니다. 따라서, GoFast를 사용할 때는 최신 정보를 확인하고, 필요에 따라 코드를 수정해야 할 수도 있습니다.

Go 컴포넌트 기반 프로그래밍 라이브러리: gomponents

요약

gomponents는 Go에서 컴포넌트 기반 프로그래밍을 위한 라이브러리입니다. 재사용 가능한 UI 컴포넌트를 만들고 관리하여 웹, 모바일, 데스크톱 애플리케이션 개발을 더욱 효율적으로 수행할 수 있도록 도와줍니다.

소개

gomponents는 복잡한 템플릿 언어를 사용하지 않고도 Go에서 직접 HTML 5 컴포넌트를 작성할 수 있도록 설계된 라이브러리입니다. 컴포넌트 기반 프로그래밍을 통해 코드를 재사용 가능한 독립적인 구성 요소로 분할하여 애플리케이션 개발을 더욱 효율적이고 관리하기 쉽게 만들 수 있습니다.

gomponents는 Go에서 컴포넌트를 정의, 조합, 렌더링하는 기능을 제공하며, 컴포넌트는 HTML, XML, JSON 등 다양한 형식으로 출력될 수 있습니다. 또한 데이터 바인딩과 이벤트 처리를 지원하여 복잡한 UI를 쉽게 구축하고 컴포넌트 간의 상호 작용을 효과적으로 관리할 수 있습니다.

gomponents는 특히 Go를 사용하여 복잡한 UI를 구축하고자 하는 개발자들에게 유용하며, 웹, 모바일, 데스크톱 애플리케이션 개발에 적용 가능합니다.

참고

Read more

Elasticsearch가 다시 오픈 소스로 돌아왔습니다

요약

Elasticsearch는 Elastic NV의 상업 라이선스 도입으로 인해 오픈 소스에서 벗어났지만, 다시 오픈 소스로 돌아왔습니다. 이는 Apache 2.0 라이선스를 추가하여 개발자들이 더 많은 선택지를 가지게 되었습니다.

소개

Elasticsearch는 2023년 1월 Elastic NV가 상업 라이선스를 도입하면서 많은 개발자들의 비난을 받았습니다. 개발자들은 오픈 소스 정신에 반하는 행위라고 비난하며 불만을 표출했고, Elastic은 이에 대한 압도적인 반응을 받아 Elasticsearch를 다시 오픈 소스로 전환하기로 결정했습니다.

Elasticsearch는 이제 Apache 2.0 라이선스와 함께 AGPL 라이선스를 선택할 수 있게 되었으며, 이는 Elasticsearch의 발전과 커뮤니티의 활발한 참여를 이끌어낼 것으로 기대됩니다.

참고

Elasticsearch 오픈 소스 다시 공개

모든 개발자가 알아야 할 디자인 원칙

요약

본 글은 소프트웨어 개발에서 핵심적인 디자인 원칙 9가지를 소개하고, 각 원칙의 장점과 적용 사례를 통해 깔끔하고 유지보수 가능하며 효율적인 코드를 작성하는 방법을 제시합니다.

소개

소프트웨어 개발에서 단순히 기능적인 코드를 작성하는 것만큼 중요한 것은 깔끔하고, 유지보수 가능하며, 효율적인 코드를 작성하는 것입니다. 이를 위해 개발자는 다양한 디자인 원칙을 이해하고 적용해야 합니다. 본 글에서는 개발자가 알아야 할 핵심적인 디자인 원칙 9가지를 소개하고, 각 원칙의 장점과 적용 사례를 통해 그 중요성을 강조합니다.

  • KISS (Keep It Simple, Stupid): 디자인과 구현을 단순하게 유지하여 코드의 가독성을 높이고 오류 가능성을 줄이는 원칙입니다.
  • DRY (Don't Repeat Yourself): 코드 중복을 최소화하여 코드의 유지보수성을 높이고 개발 시간을 단축시키는 원칙입니다.
  • YAGNI (You Ain't Gonna Need It): 불필요한 기능 구현을 피하고 실제로 필요할 때 추가하는 것을 권장하는 원칙입니다.
  • Encapsulate What Varies: 코드에서 변경될 가능성이 높은 부분을 캡슐화하여 시스템의 나머지 부분에 영향을 주지 않고 독립적으로 변경할 수 있도록 하는 원칙입니다.
  • Program to an Interface, Not an Implementation: 구체적인 구현보다는 추상적인 인터페이스에 의존하여 코드의 유연성을 높이는 원칙입니다.
  • Favor Composition Over Inheritance: 클래스 관계를 설계할 때 상속보다는 합성을 우선시하여 더 유연한 디자인을 만드는 원칙입니다.
  • Strive for Loosely Coupled Designs: 시스템의 각 구성 요소가 서로 독립적으로 작동하도록 설계하여 유지보수와 확장성을 높이는 원칙입니다.
  • Law of Demeter (LoD): 객체는 자신, 인자로 전달된 객체, 자신이 생성한 객체, 자신이 직접 포함하는 구성 요소의 메서드만 호출해야 한다는 원칙입니다.
  • SOLID 원칙: 객체 지향 프로그래밍에서 사용되는 5가지 원칙으로, 소프트웨어의 유연성, 확장성, 유지보수성을 향상시키는 데 중요한 역할을 합니다.

본 글은 다양한 디자인 원칙들을 소개하고, 각 원칙의 장점과 적용 사례를 통해 소프트웨어 설계의 중요성을 강조합니다.

참고

Read more

C4 모델을 이용한 소프트웨어 아키텍처 다이어그램

요약

C4 모델은 소프트웨어 아키텍처를 시각화하기 위한 간단하고 효과적인 방법으로, 복잡한 시스템을 4가지 레벨(Context, Container, Component, Code)로 나누어 표현하여 이해 관계자 간의 원활한 소통을 돕습니다.

소개

C4 모델은 소프트웨어 아키텍처를 시각화하고, 개발팀과 이해 관계자 간의 소통을 개선하기 위해 고안되었습니다. C4 모델은 시스템의 맥락부터 코드까지 4가지 레벨로 구성됩니다. 각 레벨은 시스템을 점점 더 상세하게 보여주며, 이를 통해 이해 관계자는 자신에게 필요한 수준의 정보를 얻을 수 있습니다.

  • Context 레벨: 시스템의 외부 환경과의 상호 작용을 보여줍니다. 시스템과 주요 이해 관계자, 외부 시스템 간의 관계를 표현합니다.
  • Container 레벨: 시스템을 구성하는 주요 컨테이너(예: 웹 서버, 데이터베이스)와 그들의 관계를 나타냅니다.
  • Component 레벨: 각 컨테이너 내부의 구성 요소(예: 클래스, 인터페이스)를 표시합니다.
  • Code 레벨: 컴포넌트의 세부적인 구조와 클래스 간의 관계를 보여줍니다.

C4 모델은 간결하고 명확한 표현 방식을 사용하며, Structurizr와 같은 도구를 활용하여 코드 기반으로 다이어그램을 생성하고 관리할 수 있어 효율성을 높입니다.

참고

Read more

서버 설정 기초: 초보자를 위한 종합 가이드

요약

본 글은 서버 설정의 기본적인 개념부터 SSH, 사용자 관리, 로그 관리, 백업, 네트워크 보안, Nginx 설정, 유용한 도구, DNS, Docker까지 다룹니다. 초보자들이 서버 설정과 관리에 대한 포괄적인 이해를 얻도록 돕고, 실제 환경에 적용할 수 있는 실질적인 지침을 제공합니다.

소개

웹사이트, 애플리케이션, 데이터베이스 등을 운영하려면 안정적이고 안전한 서버 환경 구축이 필수입니다. 하지만 서버 설정은 복잡한 과정으로, 처음 접하는 사용자에게는 어려움을 느낄 수 있습니다.

본 글은 이러한 어려움을 해소하고, 초보자도 쉽게 서버를 설정하고 관리할 수 있도록 상세한 설명과 실제 예제 코드를 제공합니다. 각 단계별로 필요한 명령어와 설정 파일 수정 방법을 알려주며, 팁과 주의 사항을 함께 제시합니다.

내용

  • SSH 설정: 안전한 원격 접근을 위한 SSH 설정 방법을 설명합니다. SSH 키 생성, 사용자 계정 생성, root 계정 보호, 패스워드 인증 비활성화 등을 상세히 다룹니다.
  • 사용자 관리: "최소 권한의 원칙"을 적용하여 사용자 계정을 생성하고 관리하는 방법을 소개합니다. 애플리케이션별 사용자 계정 생성 및 권한 설정을 통해 시스템 보안을 강화하는 방법을 알려줍니다.
  • 로그 관리: 로그 회전 설정을 통해 로그 파일 크기를 제어하고, 시스템 상태를 모니터링하는 방법을 설명합니다. Nginx 로그 회전 예시를 통해 실제 적용 방법을 보여줍니다.
  • 백업: 서버 데이터를 안전하게 보호하기 위한 백업 방법을 다룹니다. 풀 백업, 디퍼런셜 백업, 인크리멘탈 백업의 차이점을 설명하고, 3-2-1 백업 규칙을 소개합니다. 다양한 백업 도구와 전략을 소개하며, 백업 테스트의 중요성을 강조합니다.
  • 네트워크 보안: UFW와 Fail2Ban을 사용하여 서버의 네트워크 보안을 강화하는 방법을 알려줍니다. 포트 규칙 설정, 액세스 제한, 불필요한 포트 차단 등을 통해 외부 공격으로부터 서버를 보호합니다.
  • NGINX 설정: 웹 서버로 널리 사용되는 Nginx의 기본 설정 및 활용 방법을 소개합니다. 정적 웹사이트, 프록시 패스, 웹 소켓 등 다양한 설정 예시를 제공합니다.
  • 유용한 도구: 서버 관리를 편리하게 돕는 다양한 도구를 소개합니다. Btop, Neoss, GoAccess, MC, NCDU 등을 활용하여 시스템 성능 모니터링, 로그 분석, 파일 관리, 디스크 용량 관리 등을 효율적으로 수행할 수 있습니다.
  • DNS 설정: 인터넷에서 서버를 접근 가능하도록 DNS 설정 방법을 설명합니다. A 레코드 설정, 정적 IP, 동적 DNS 등을 다루며, 홈 네트워크 환경에서도 DNS를 활용하는 방법을 소개합니다.
  • Docker 활용: Docker의 장단점을 비교 분석하고, 컨테이너 기반 애플리케이션 배포 및 관리 방법을 간략하게 소개합니다. Docker 설치 및 기본 사용 방법에 대한 공식 가이드 링크를 제공합니다.

참고

  • Enki의 서버 설정 스크립트: 본 글에서 소개된 설정들을 자동화하는 데 도움이 되는 스크립트를 제공합니다. 링크

주의 사항

  • 보안: 서버 설정 과정에서 보안에 유의해야 합니다. SSH 키와 비밀번호는 안전하게 보관하고, 불필요한 포트는 차단해야 합니다.
  • 백업: 데이터 손실을 방지하기 위해 정기적인 백업을 실시하고, 백업 데이터의 무결성을 확인해야 합니다.
  • 로그 모니터링: 시스템 로그를 주기적으로 확인하여 이상 징후를 파악하고, 문제 발생 시 신속하게 대응해야 합니다.
  • 시스템 업데이트: 최신 보안 패치를 적용하여 시스템 취약점을 해소하고, 안전한 서버 환경을 유지해야 합니다.

    배포 시점에 급상승하는 API Latency 해결하기 — Django + Gunicorn 사례

요약

Django와 Gunicorn으로 구성된 백엔드 서비스에서 배포 시점에 API Latency가 급상승하는 문제를 해결한 경험을 공유합니다. Gunicorn의 Preloading 기능을 활용하고, Django의 WSGI 설정 파일을 분석하여 문제 발생 원인을 찾아냈으며, Django 애플리케이션의 대부분을 미리 로드하여 API 지연 문제를 해결했습니다.

소개

레몬베이스 팀은 Django와 Gunicorn을 사용하여 백엔드 서비스를 운영하고 있습니다. 서비스 배포는 Github Actions를 활용한 CI/CD 파이프라인을 통해 자동으로 이루어지는데, 배포 시점마다 API Latency가 급격하게 증가했다가 감소하는 현상이 발생했습니다. 이로 인해 사용자들이 일시적으로 불편을 겪을 수 있었고, 문제 해결이 시급했습니다.

문제 분석

Datadog를 활용하여 시스템 성능과 상태를 모니터링한 결과, API Latency가 급격하게 상승하는 시점이 배포 시점과 일치한다는 것을 확인했습니다. Datadog APM 기능과 View Related Traces 기능을 통해 문제 발생 지점을 Django Jinja Template 로드 후 Middleware 호출 전으로 좁혀나갔습니다.

발생 원인 추측

문제 분석 결과, Gunicorn의 preload_app = True 옵션이 정상적으로 동작하지 않아 Cold Start가 발생하는 것으로 추측했습니다. Gunicorn의 Preloading 기능을 자세히 살펴본 결과, Worker Process 생성 시 Django 애플리케이션의 일부(View, Model 등)만 로드된 상태였고, 실제 HTTP 요청 처리 시 추가적인 로드 작업이 필요하여 지연이 발생하고 있었습니다. 특히, urls.py 로드 시간이 Middleware 호출 전 Latency의 주요 원인이었습니다.

해결 방식

wsgi.py에서 urls.py와 같은 사전 로드가 필요한 부분들을 로드하여 Gunicorn의 Preloading 흐름에 포함시켰습니다. Django의 get_resolver() 함수를 사용하여 urls.py를 사전 로드하고, 이와 함께 View, Model 등 대부분의 코드들을 미리 로드하도록 수정했습니다.

참고

주의

  • Gunicorn 설정은 애플리케이션의 요구 사항에 따라 달라질 수 있습니다. 본 글에서 소개된 설정은 일반적인 예시이며, 실제 환경에서는 추가적인 조정이 필요할 수 있습니다.
  • Gunicorn 설정을 변경할 때는 시스템 성능에 미치는 영향을 주의 깊게 모니터링해야 합니다.

시스템 디자인에서 메시지 큐 활용하기

요약

메시지 큐는 시스템 디자인에서 비동기식 통신과 작업 처리를 위한 필수적인 요소입니다. 메시지 큐를 사용하면 서로 다른 시스템이나 프로세스 간의 결합을 줄이고 확장성과 안정성을 향상시킬 수 있습니다.

소개

온라인 스토어를 예로 들어보겠습니다. 고객이 주문을 할 때마다 결제 처리, 재고 업데이트, 주문 확인 이메일 발송 등의 작업을 수행해야 합니다. 특히 트래픽이 많은 시간대에는 이러한 작업을 동시에 처리하면 고객 경험이 저하될 수 있습니다. 서버를 확장하여 많은 작업을 처리할 수 있지만, 모든 작업을 동시에 처리하지 않아도 되는 경우 메시지 큐를 사용하여 작업을 나중에 처리하는 것이 더 효율적입니다.

메시지 큐는 생산자와 소비자 간의 비동기식 통신을 지원하는 지속적인 메모리 내 구성 요소입니다. 메시지 큐는 버퍼 역할을 하여 비동기 요청을 분산시킵니다. 생산자(또는 게시자)라고 하는 입력 서비스는 메시지 큐에 메시지를 생성하고 게시합니다. 소비자(또는 구독자)라고 하는 다른 서비스는 큐에 연결하여 메시지에서 정의된 작업을 수행합니다.

참고

Read more

페이스북의 시간 동기화: 수백만 서버에 걸친 정확한 시계

요약

페이스북은 수백만 서버에 걸쳐 정확한 시간을 동기화하기 위해 NTP 프로토콜을 사용했지만, 더욱 정밀한 시간 동기화를 위해 Precision Time Protocol (PTP)로 전환했습니다. PTP는 하드웨어 타임스탬핑과 투명 클럭을 사용하여 네트워크 지연을 최소화하고 나노초 수준의 정확도를 달성합니다.

소개

페이스북과 같은 대규모 서비스는 수백만 개의 서버가 연결되어 있고, 이 서버들은 서로 통신하고 데이터를 공유해야 합니다. 이러한 상황에서 모든 서버가 동일한 시간을 가지고 있는 것은 매우 중요합니다. 시간 동기화가 제대로 이루어지지 않으면 데이터 무결성이 손상되고, 트랜잭션 순서가 혼란스러워지며, 사용자 경험이 저하될 수 있습니다.

초기에는 Network Time Protocol (NTP)를 사용하여 시간을 동기화했습니다. NTP는 계층적인 시스템으로, 가장 정확한 시간 서버가 최상위에 위치하고, 다른 서버들은 이 시간 서버로부터 시간을 동기화합니다. 하지만 페이스북의 규모가 커지고, 더욱 정밀한 시간 동기화가 필요해짐에 따라 NTP의 한계가 드러났습니다.

페이스북은 NTP 대신 Precision Time Protocol (PTP)를 도입했습니다. PTP는 NTP보다 더 정확하고, 네트워크 지연에 덜 민감합니다. PTP는 하드웨어 타임스탬핑과 투명 클럭을 사용하여 나노초 수준의 정확도를 달성합니다. 페이스북은 PTP를 사용하여 서버 간 시간 동기화를 더욱 정밀하게 수행하고, 데이터 일관성을 유지하며, 사용자 경험을 개선했습니다.

권장 사항

페이스북의 시간 동기화 시스템은 대규모 서비스에서 시간 동기화를 구현하는 데 대한 좋은 사례입니다. PTP는 NTP보다 더 정확하고, 확장성이 뛰어나 대규모 서비스에 적합합니다.

참고

Read more

초경량 쿠버네티스 개발 환경 구축: Kardinal 소개

Summary

Kardinal은 공유된 쿠버네티스 클러스터 내에서 초경량 개발 환경을 구축하기 위한 프레임워크입니다. Kardinal을 사용하면 개발자들은 쿠버네티스 기반 애플리케이션의 개발 및 테스트 환경을 최소한의 리소스로 구축하여 개발 속도와 효율성을 극대화할 수 있습니다.

Introduction

새로운 기능을 테스트하려면 일반적으로 별도의 애플리케이션 환경을 구축해야 하며, 이는 비용이 많이 들고 리소스 낭비가 심할 수 있습니다. Kardinal은 개발자들이 필요에 따라 동적으로 관리되는 임시 환경을 생성할 수 있도록 하여 이러한 문제를 해결합니다. 즉, 개발자들은 불필요한 오버헤드 관리 없이 중요한 기능 개발에 집중할 수 있습니다.

Kardinal은 "흐름(flow)"이라는 새로운 개념을 도입하여 쿠버네티스 클러스터에서 흐름을 통해 에피머럴 환경을 구축합니다. 흐름은 특정 기능 개발에 관련된 서비스를 배포하고 테스트하기 위해 필요에 따라 생성됩니다. 기존의 개발 환경에서는 다른 개발자들이 이미 배포한 리소스를 여러 번 다시 배포해야 하는 경우가 많아 비효율적이고 리소스 사용량이 많았습니다.

Kardinal은 개발 중인 기능과 관련된 최소한의 리소스만 배포하고 다른 워크플로우에서 이미 배포된 리소스를 재사용하여 이러한 비효율성을 해결합니다. 이러한 전략은 리소스 사용량을 최적화합니다. 단일 서비스 테스트 또는 격리된 상태의 전체 애플리케이션 흐름이 필요하든 Kardinal의 유연한 아키텍처를 통해 효율적인 테스트와 개발이 가능합니다.

Kardinal의 주요 장점:

  • 에피머럴 환경: 필요할 때만 환경을 생성하고 사용이 끝나면 바로 삭제합니다.
  • 최소 리소스 사용: 활성 상태인 서비스만 배포하고 나머지는 Kardinal에서 처리합니다.
  • 유연한 흐름 유형: 단일 서비스 테스트부터 전체 애플리케이션 흐름까지 다양한 유형의 흐름을 지원합니다.
  • 비용 절감: 불필요한 리소스 중복을 방지하여 비용을 절감할 수 있습니다.
  • 오픈 소스: Kardinal은 오픈 소스이므로 개발자는 자신의 워크플로우에 맞게 자유롭게 사용할 수 있습니다.

Reference

Read more

시스템 디자인 인터뷰에서 Twitter(X) 설계하기

Summary

이 글은 시스템 디자인 인터뷰에서 Twitter를 설계하는 방법을 단계별로 설명합니다. 대규모 사용자 기반, 높은 가용성, 안정성 등 Twitter의 기능적 요구 사항과 비 기능적 요구 사항을 다루며, API 설계, 데이터베이스 설계, 고수준 설계, 요청 흐름, 상세 구성 요소 설계, 트레이드오프, 실패 시나리오, 병목 현상 등을 분석합니다.

Introduction

시스템 디자인 면접은 소프트웨어 개발자들에게 흔한 면접 유형입니다. 이 면접에서는 후보자가 대규모 분산 시스템을 설계하고 구현하는 능력을 평가합니다. Twitter와 같은 복잡한 시스템을 설계하는 것은 쉬운 일이 아니지만, 시스템 디자인 원리를 이해하고 적용하면 성공적인 솔루션을 만들 수 있습니다.

이 글에서는 Twitter를 시스템 디자인 면접에서 설계하는 방법을 자세히 살펴봅니다. Twitter의 핵심 개념인 트윗, 사용자, 팔로워를 소개하고, 시스템 구현에 필요한 데이터베이스, 캐싱, 분산 시스템 등 아키텍처적 고려 사항을 다룹니다.

Twitter는 하루에 수십억 건의 트윗을 처리하는 대규모 분산 시스템입니다. 따라서 효율적인 데이터베이스, 캐싱, 분산 시스템 아키텍처가 필수적입니다. 이 글은 시스템 디자인 면접에서 Twitter를 효과적으로 설계하고, 면접관에게 자신의 기술력을 증명하는 데 도움이 될 것입니다.

Recommendation

  • 다양한 시스템 설계 문제를 풀어보며 시스템 디자인 면접 준비를 하세요.
  • Twitter의 아키텍처와 주요 기능을 깊이 이해하세요.
  • 데이터베이스, 캐싱, 분산 시스템 등 시스템 설계의 기본 원리를 숙지하세요.
  • 시스템 디자인 템플릿을 활용하여 체계적인 설계를 진행하세요.

Reference

Read more

S3 조건부 쓰기를 이용한 리더 선출

요약

이 글은 Amazon S3의 조건부 쓰기 기능을 사용하여 분산 시스템에서 리더를 선출하는 방법에 대해 설명합니다. S3의 새로운 기능을 활용하여 리더를 효율적으로 선출하고, 다른 노드와의 경쟁 상태를 방지하는 방법을 소개합니다.

소개

분산 시스템에서 리더 선출은 여러 노드 중 하나를 리더로 지정하여 특정 작업을 수행하도록 하는 중요한 과정입니다. 이는 여러 노드가 동일한 작업을 수행하여 데이터 중복 및 오류 발생을 방지하기 위해 필요합니다. 일반적으로 ZooKeeper나 Postgres Advisory Locks와 같은 분산 락 시스템을 사용하여 리더를 선출하지만, S3와 같은 오브젝트 스토리지 시스템을 사용하는 경우 별도의 서비스를 구축하는 것은 비용 및 운영적인 측면에서 부담이 될 수 있습니다.

S3는 최근 조건부 쓰기를 지원하게 되어 리더 선출을 위한 새로운 방법을 제공합니다. 조건부 쓰기를 사용하면 특정 조건이 충족될 때만 데이터를 쓰도록 할 수 있으므로, 리더 선출 과정에서 발생할 수 있는 경쟁 상태를 효과적으로 방지할 수 있습니다.

참고

Read more

개인용 LLaMA 3.1 RAG API 배포하기

요약

이 글은 LitServe를 사용하여 확장 가능하고 서버리스한 멀티 GPU 지원으로 검색 기반 생성(RAG) 애플리케이션을 배포하는 방법을 보여주는 Lightning Studio입니다. AI 배포를 간소화하세요.

소개

Lightning AI Studio는 사용자 정의 머신 러닝 모델을 배포하고 관리하는 데 사용할 수 있는 플랫폼입니다. 이 글에서는 Lightning AI Studios를 사용하여 개인용 LLaMA 3.1 RAG API를 배포하는 방법을 설명합니다.

LLaMA 3.1은 Meta에서 개발한 강력한 언어 모델입니다. RAG를 사용하면 모델이 외부 데이터베이스에서 관련 정보를 검색하여 더 나은 응답을 생성할 수 있습니다. 이 글에서는 이러한 기능을 활용하여 자신만의 맞춤형 LLaMA 3.1 RAG API를 구축하고 사용자 지정 데이터 세트를 사용하여 쿼리에 응답하도록 하는 방법을 보여줍니다.

이 가이드에서는 Lightning AI Studios에 대한 기본적인 이해와 LLaMA 3.1 RAG 모델에 대한 기본적인 지식이 있다고 가정합니다.

참고

자세히 알아보기

주의

  • 이 Studio는 개인용 LLaMA 3.1 RAG API를 배포하는 방법을 보여줍니다.
  • LitServe를 사용하여 확장 가능하고 서버리스한 멀티 GPU 지원을 제공합니다.
  • AI 배포를 간소화하는 데 도움이 됩니다.

    Fuite: 웹 애플리케이션 메모리 누수 찾기 도구

요약

Fuite는 웹 애플리케이션의 메모리 누수를 찾기 위한 CLI 도구입니다. Puppeteer를 사용하여 크롬을 실행하고, 웹 페이지를 로드하고, 시나리오를 실행하여 메모리 누수를 감지합니다.

소개

Fuite는 "누수"를 뜻하는 프랑스어로, 웹 애플리케이션에서 발생하는 메모리 누수를 찾는 데 도움이 되는 도구입니다. Fuite는 Puppeteer를 사용하여 크롬을 실행하고, 웹 페이지를 로드하여 여러 번의 시나리오를 반복적으로 실행합니다. 각 시나리오 실행 후 메모리 사용량을 비교하여 누수가 발생하는지 확인합니다.

Fuite는 다음과 같은 누수를 감지할 수 있습니다.

  • 객체 누수 (크롬 힙 스냅샷으로 캡처)
  • 이벤트 리스너 누수
  • DOM 노드 누수 (DOM에 연결된 노드 - 분리된 노드는 "객체"에 표시됨)
  • 배열, 맵, 세트, 일반 객체와 같은 컬렉션 누수

추천

  • 웹 애플리케이션의 메모리 누수를 찾아야 할 때
  • SPA (Single-Page Application)에서 메모리 누수를 찾아야 할 때
  • Puppeteer를 사용하는 웹 애플리케이션에서 메모리 누수를 찾아야 할 때

참고

Read more

주의

  • Fuite는 크롬 브라우저에 의존합니다. 다른 브라우저는 지원하지 않습니다.
  • Fuite는 웹 페이지의 주 프레임에 집중합니다. 크로스-오리진 iframe이나 웹 워커에서 발생하는 메모리 누수는 감지하지 못합니다.
  • Fuite는 웹 페이지의 JavaScript 힙 크기를 측정합니다. 네이티브 브라우저 객체의 크기는 무시합니다.
  • 소스 코드가 축소된 경우 클래스 이름이 축소된 버전으로 표시되어 디버깅이 어려울 수 있습니다.
  • Fuite는 큰 힙 스냅샷 파일을 분석하는 데 많은 메모리를 사용할 수 있습니다. Node.js가 메모리 부족 오류를 발생시키는 경우 NODE_OPTIONS=--max-old-space-size=8000 fuite <url>와 같이 실행해야 합니다.

    팬텀 토큰 접근 방식: API 보안 강화

요약

팬텀 토큰 접근 방식은 마이크로서비스 보안을 위해 불투명 토큰과 구조화된 토큰의 장점을 결합한 프라이버시 보호 토큰 사용 패턴입니다. 이 패턴을 이해하려면 불투명 토큰과 구조화된 토큰의 기본적인 차이점을 이해하는 것이 중요합니다.

소개

OAuth 2.0가 정의될 때, 토큰은 의도적으로 추상적으로 유지되었으며, 포맷은 정의되지 않았습니다. 즉, 권한 부여 서버가 발급하는 토큰의 포맷에 제한은 없습니다. 실제로 두 가지 유형의 토큰을 구분할 수 있습니다.

  • 불투명 토큰 (참조에 의한)
  • 구조화된 토큰 (값에 의한)

불투명 토큰은 리소스 서버에 의미가 없는 임의의 문자열입니다. 즉, 토큰은 불투명합니다. 그러나 토큰에는 유효성 또는 승인된 범위 목록과 같이 리소스 서버(API 또는 마이크로서비스)의 권한 부여 결정에 관련되거나 필수적인 메타데이터가 연결되어 있을 수 있습니다. 불투명 토큰만 사용하는 시스템에서 리소스 서버는 토큰 자체에서 이러한 정보를 검색할 수 없으며, 아래에 설명된 것처럼 인트로스펙션 엔드포인트에서 권한 부여 서버로 요청을 보내야 합니다.

불투명 토큰과 함께 사용되는 흐름

불투명 토큰은 사용자 속성과 토큰 메타데이터에 대한 참조로 간주할 수 있습니다. 따라서 불투명 토큰을 전달하는 것은 참조에 의한 토큰 전달이라고도 할 수 있습니다.

각 토큰을 유효성 검사하기 위해 조회해야 하는 경우, 리소스 및 권한 부여 서버뿐만 아니라 인프라에도 부하가 발생합니다. JSON 웹 토큰(JWT)과 같은 구조화된 토큰 포맷은 이 문제를 해결합니다. JWT 토큰은 HTTP 헤더 및 쿼리 매개변수에 전달되도록 설계된 컴팩트하고 가벼운 토큰입니다. 데이터 무결성을 보호하기 위해 서명되며, 프라이버시를 위해 암호화할 수도 있습니다. 포맷이 잘 정의되어 있기 때문에 리소스 서버는 다른 시스템을 호출하지 않고도 토큰을 디코딩하고 검증할 수 있습니다.

구조화된 토큰은 값에 의한 토큰입니다. 토큰에는 리소스 서버가 권한 부여 결정을 내리는 데 필요한 충분한 데이터가 포함되어 있습니다. 또한 토큰에는 사용자 정보가 포함되어 있는 경우도 많습니다. 특정 경우, 이러한 토큰은 개인 식별 정보(PII) 또는 법률이나 규정으로 보호되는 다른 데이터를 포함할 수 있으며, 토큰과 관련 시스템은 규정 준수 요구 사항의 대상이 됩니다.

팬텀 토큰 접근 방식

팬텀 토큰 접근 방식은 불투명 토큰의 보안과 JWT의 편리성을 결합한 API 및 마이크로서비스 보안을 위한 규범적인 패턴입니다. 핵심 아이디어는 참조에 의한 토큰과 값에 의한 토큰을 쌍으로 사용하는 것입니다. 값에 의한 토큰(JWT)은 참조에 의한 동등한 토큰(불투명 토큰)을 통해 얻을 수 있습니다. 클라이언트는 JWT를 인식하지 못하기 때문에 이 토큰을 팬텀 토큰이라고 합니다.

클라이언트가 토큰을 요청하면 Token Service는 참조에 의한 토큰을 반환합니다. 모든 요청마다 API 및 마이크로서비스가 Token Service를 호출하여 참조에 의한 토큰을 해결하도록 하는 대신, 이 패턴은 일반적으로 클라이언트와 API 사이에 배치되는 API 게이트웨이, 리버스 프록시 또는 다른 미들웨어를 활용합니다. 이를 통해 API 및 마이크로서비스는 클라이언트가 불투명 토큰만 가져오기 때문에 클라이언트에 데이터를 노출하지 않고도 JWT의 이점을 누릴 수 있습니다.

팬텀 토큰 접근 방식

  1. 클라이언트는 OAuth 2.0 흐름을 사용하여 참조에 의한 토큰을 가져옵니다.
  2. 클라이언트는 API에 대한 요청에서 토큰을 전달합니다.
  3. 리버스 프록시는 Token Service의 인트로스펙션 엔드포인트를 호출하여 값에 의한 토큰을 조회합니다.
  4. 리버스 프록시는 마이크로서비스에 대한 실제 요청에서 참조에 의한 토큰을 값에 의한 토큰으로 대체합니다.

불투명 토큰 사용의 이점

불투명 토큰의 주요 이점은 보안입니다. 액세스 토큰은 API인 리소스 서버용으로 의도되었습니다. 그러나 클라이언트는 이 규칙을 위반하고 토큰을 파싱할 수도 있습니다. 불투명 토큰을 사용하면 클라이언트는 액세스 토큰의 내용을 기반으로 로직을 구현하는 것을 방지할 수 있습니다. 또한 클라이언트용 불투명 토큰은 규제된 공간을 제한하고 데이터 유출 및 규정 준수 위반의 위험을 제거합니다. 클라이언트에 데이터가 제공되지 않기 때문에 클라이언트가 데이터에 액세스하거나 유출하는 것이 불가능합니다.

동시에 보안이 강화되면서 성능이 최적화됩니다. 마이크로서비스는 서비스 처리에 필요한 모든 데이터가 포함된 JWT 토큰을 사용합니다. 시간이 오래 걸리는 요청은 필요하지 않습니다. 또한 이 패턴은 리버스 프록시의 캐싱 메커니즘을 활용할 수 있습니다. 값에 의한 토큰은 만료될 때까지 캐싱할 수 있습니다. Curity Identity Server는 이 목적으로 최신 값이 포함된 HTTP 캐시 헤더를 지원합니다. 결과적으로 토큰 교환에 필요한 요청 수가 최소화되고 시스템 성능이 최적화됩니다.

팬텀 토큰 접근 방식은 OAuth 2.0 표준을 준수합니다. 클라이언트 또는 API는 이 패턴에 대한 독점적인 솔루션을 구현할 필요가 없습니다. 이는 패턴을 공급업체 중립적이고 모든 OAuth 2.0 에코시스템에 적용할 수 있도록 합니다.

추가 자료

팬텀 토큰에 대한 튜토리얼과 GitHub의 NGINX용 모듈을 확인해 보세요.

ReactiveSearch API: 선언적 쿼리 및 기본 제공 액세스 제어 기능을 갖춘 Elasticsearch용 API 게이트웨이

Summary

ReactiveSearch API는 Elasticsearch 데이터에 액세스하고 조작하기 위한 선언적이고 강력한 API 게이트웨이입니다. 개발자는 복잡한 Elasticsearch 쿼리를 쉽게 작성하고, 액세스 제어 기능을 통해 보안을 강화할 수 있습니다.

Introduction

ReactiveSearch API는 Appbase.io에서 개발한 오픈 소스 API로, Elasticsearch, OpenSearch, Solr, MongoDB Atlas Search, OpenAI와 같은 검색 엔진 및 데이터베이스와 통합됩니다. 특히 웹 검색, 앱 검색, 전자 상거래 검색 등 다양한 검색 기능을 구현하는 데 적합합니다.

ReactiveSearch API는 다음과 같은 주요 장점을 제공합니다.

  • 선언적 쿼리: 복잡한 Elasticsearch DSL을 사용하는 대신 간단하고 직관적인 선언적 쿼리 방식을 제공합니다.
  • 액세스 제어: Elasticsearch 데이터에 대한 액세스 권한을 제어하여 보안을 강화할 수 있습니다.
  • 플러그인 확장성: 다양한 플러그인을 통해 기능을 확장하고 사용자 정의할 수 있습니다.
  • 다양한 검색 엔진 지원: Elasticsearch, OpenSearch, Solr, MongoDB Atlas Search, OpenAI 등 다양한 검색 엔진 및 데이터베이스를 지원합니다.

Reference

Read more

JavaScript의 안전한 할당 연산자: try...catch 블록과 작별 인사

요약

이 글은 JavaScript의 새로운 안전한 할당 연산자 제안을 소개하며, 이를 통해 try...catch 블록을 사용하지 않고도 잠재적인 오류를 안전하게 처리할 수 있는 방법을 설명합니다.

소개

JavaScript 개발자는 코드에서 오류를 처리하기 위해 try...catch 블록을 자주 사용합니다. 하지만 try...catch 블록은 코드를 복잡하게 만들고 가독성을 떨어뜨릴 수 있습니다. JavaScript의 안전한 할당 연산자는 이러한 문제를 해결하기 위해 제안되었습니다.

이 연산자는 변수에 값을 할당할 때 오류가 발생하면 특정 값을 할당하여 프로그램이 예상치 못한 종료를 방지합니다. 예를 들어, 객체의 속성에 값을 할당할 때 해당 속성이 존재하지 않으면 기존의 코드에서는 오류가 발생하지만 안전한 할당 연산자를 사용하면 오류를 처리하고 기본 값을 할당할 수 있습니다.

안전한 할당 연산자는 JavaScript 개발자에게 보다 간결하고 안전한 코드 작성을 가능하게 합니다. 이는 try...catch 블록의 대안으로 사용될 수 있으며, 특히 비동기 작업이나 데이터베이스 쿼리와 같이 오류가 발생할 가능성이 높은 코드에서 유용합니다.

추천

JavaScript 개발자는 안전한 할당 연산자를 사용하여 코드를 단순화하고 오류 처리를 개선할 수 있습니다. 특히 비동기 작업이나 데이터베이스 쿼리와 같이 오류가 발생할 가능성이 높은 코드에서 유용하게 활용될 수 있습니다.

참고

주의

  • 안전한 할당 연산자는 아직 제안 단계이며, 현재 버전의 JavaScript에서는 사용할 수 없습니다.
  • 안전한 할당 연산자는 try...catch 블록을 완전히 대체할 수 없으며, 특정 상황에서는 try...catch 블록이 더 적합할 수 있습니다.

    UV: 통합된 Python 패키징

요약

UV는 Rust로 작성된 매우 빠른 Python 패키지 관리자로, 기존 pip 워크플로우를 대체합니다. UV는 Python 프로젝트, 명령줄 도구, 단일 파일 스크립트, 심지어 Python 자체까지 관리하는 종합적인 솔루션을 제공합니다.

소개

Astral은 Python 생태계를 위한 고성능 개발 도구를 만드는 회사로, 매우 빠른 Python linter 및 formatter인 Ruff로 유명합니다. 2024년 2월에 출시된 UV는 처음에는 pip를 대체하는 빠른 Python 패키지 설치 및 해결 도구로 시작되었습니다.

이번에 발표된 UV의 기능 확장은 초기 출시 이후 가장 큰 변화입니다:

  • 종합적인 프로젝트 관리: uv run, uv lock, uv sync를 통해 UV는 표준 기반 메타데이터를 사용하여 교차 플랫폼 락파일을 생성하고 설치할 수 있습니다. 이는 Poetry, PDM, Rye와 같은 도구에 대한 고성능, 통합된 대안입니다.
  • 도구 관리: uv tool installuv tool run(別名 uvx)를 통해 UV는 격리된 가상 환경에 명령줄 도구를 설치하고 명시적인 설치 없이 일회성 명령을 실행할 수 있습니다. (uvx ruff check처럼). 이는 pipx와 같은 도구에 대한 고성능, 통합된 대안입니다.
  • Python 설치: uv python install을 통해 UV는 Python을 부트스트랩하고 설치하여 pyenv와 같은 도구에 대한 고성능, 통합된 대안을 제공합니다.
  • 스크립트 실행: UV는 이제 PEP 723 기반의 내장된 종속성 메타데이터를 사용하여 완벽하게 격리된 단일 파일 Python 스크립트를 관리할 수 있습니다. uv run으로 독립 실행형 Python 스크립트를 실행해 보세요.

이 모든 기능은 매우 빠르고 교차 플랫폼인 종속성 해결 도구에 의해 지원됩니다.

참고

Read more

Go수다 규칙: Go 개발자들의 수다방 가이드

Summary

Go수다 규칙은 Go 언어 개발자들의 활발한 커뮤니티인 Go수다 채팅방의 원활한 운영과 긍정적인 분위기를 조성하기 위한 가이드라인입니다.

Introduction

Go수다 채팅방은 Go 언어에 관심있는 개발자들이 모여 정보를 공유하고 서로 돕는 공간입니다. 이 규칙은 채팅방 참여자들이 편안하고 즐겁게 소통하며, 건설적인 대화를 이어갈 수 있도록 돕는 목적으로 만들어졌습니다.

Go수다 규칙은 다음과 같은 내용을 담고 있습니다:

  • 입장 및 퇴장: 공지 확인과 인사를 통해 원활한 참여를 유도합니다. 부적절한 행동은 강제 퇴장으로 이어질 수 있습니다.
  • 대화 매너: 다른 주제나 질문은 대화 중간에 끼어들지 않고 적절한 시기에 하는 것을 권장하며, 비방이나 불쾌한 언행은 삼가야 합니다.
  • 광고: 개발 관련 세미나, 모임, 번개 광고는 허용되지만, 회사 채용, 소개, 스터디 등은 관리자의 승인이 필요합니다.
  • 관리자: 커뮤니티 운영과 관리를 위해 총괄자와 관리자들이 활동하며, 문의사항이나 불편한 점은 언제든지 연락할 수 있습니다.
  • 함께하는 커뮤니티: Go수다 규칙은 Go Developer Community와 연계되어 활동하며, Go 언어 관련 정보 공유 및 개발자 커뮤니티 활성화에 기여합니다.

Recommendation

Go수다 채팅방에 참여하고 싶은 Go 개발자라면, Go수다 규칙을 숙지하고, 다른 참여자들과 긍정적이고 건설적인 소통을 통해 즐거운 커뮤니티 활동을 하시기 바랍니다.

Reference

Go수다 규칙 웹사이트

Caution

Go수다 규칙은 Go수다 채팅방의 원활한 운영을 위한 지침이며, 모든 상황에 적용될 수 있는 절대적인 규칙은 아닙니다.

주의

  • 이 글은 Gemini Flash를 이용하여 생성한 것으로, 사실과 다를 수 있습니다.