Go + TypeScript 모놀리스: TormentNexus가 AI 커널을 위해 두 가지 언어를 사용하는 이유
요약
TormentNexus가 고성능 Go 커널과 유연한 TypeScript 비즈니스 로직을 결합한 폴리글랏 모놀리스 아키텍처를 채택한 이유를 설명합니다. Go의 고루틴을 활용해 대규모 동시성을 처리하고, TypeScript로 AI 추론 및 오케스트레이션을 관리하는 전략을 다룹니다.
핵심 포인트
- Go를 사용하여 446개의 HTTP 핸들러와 고루틴 기반의 고성능 커널 구축
- TypeScript를 통해 AI 모델 추론 및 비즈니스 로직 오케스트레이션 수행
- 마이크로서비스의 운영 오버헤드를 피하기 위한 폴리글랏 모놀리스 전략
- 단일 바이너리 배포를 통한 시스템 단순성 및 모듈식 설계 유지
Go + TypeScript 모놀리스: TormentNexus가 AI 커널을 위해 두 가지 언어를 사용하는 이유
TormentNexus가 Go와 TypeScript 모놀리스(Monolith)를 선택한 배경에 있는 아키텍처 결정을 살펴보세요. 왜 Go가 446개의 HTTP 핸들러(Handlers)와 고루틴(Goroutines)으로 핵심 커널을 구동하고, TypeScript가 비즈니스 로직 계층을 관리하는지 알아보세요.
관습을 벗어난 선택: 폴리글랏 모놀리스 (Polyglot Monolith)
마이크로서비스(Microservices)가 대화의 중심인 시대에, TormentNexus는 정교하게 구조화된 모놀리스의 힘에 승부수를 던졌습니다. 우리의 아키텍처는 의도적인 혼합입니다. 성능에 집착하는 Go 코어와 유연한 TypeScript 비즈니스 로직 계층의 결합입니다. 이는 무작위적인 조합이 아닙니다. 확장 가능하고 유지보수가 용이한 AI 백엔드를 구축하기 위한 타겟팅된 전략입니다. 단일 배포 단위 내에서 폴리글랏 아키텍처(Polyglot architecture)를 수용함으로써, 우리는 각 언어가 가장 중요한 지점에서 고유한 강점을 활용하며, 분산 시스템의 운영 오버헤드를 피하는 동시에 아키텍처의 명확성을 유지합니다.
그 핵심에서 TormentNexus는 단일 바이너리(Single binary)이며, 배포 시에는 모놀리스이지만 설계상으로는 모듈식(Modular)입니다. Go 부분은 고성능 커널로서 작동하며, 로우 I/O (Raw I/O), 커넥션 풀링 (Connection pooling), 그리고 동시성 (Concurrency)을 관리합니다. 모듈로 컴파일되는 TypeScript 계층은 AI 모델 추론 (Inference), 요청 검증 (Request validation), 그리고 응답 형성 (Response shaping)의 미묘한 오케스트레이션 (Orchestration)을 처리합니다. 이러한 분리를 통해 우리 팀은 통합된 코드베이스의 단순성을 희생하지 않으면서도, 각 작업에 가장 적합한 언어로 작업할 수 있습니다.
왜 Go가 완벽한 커널인가: 446개의 핸들러로 동시성을 길들이기
TormentNexus의 커널은 Go로 작성되었으며, 여기에는 타당한 이유가 있습니다. 우리 시스템은 대량의 동시적이고 I/O 바운드(I/O-bound)인 요청을 처리해야 합니다. 즉, 요청을 라우팅하고, 토큰을 인증하며, AI 모델을 위한 작업을 큐잉(Queuing)해야 합니다. Go의 고루틴(Goroutines)은 이를 위한 완벽한 도구입니다. 우리는 단순히 고루틴을 사용하는 것에 그치지 않고, 전체 요청 라이프사이클(Request lifecycle)을 고루틴을 중심으로 구축했습니다.
현재 릴리스 버전은 정확히 **446개의 HTTP 핸들러 (HTTP handlers)**를 등록합니다. 각 핸들러는 우리의 Go 기반 HTTP 라우터 (HTTP router)에 등록된 경량 함수입니다. 요청이 도착하면 즉시 새로운 고루틴 (goroutine)으로 래핑됩니다. 이 고루틴은 초기 HTTP 헤더 (HTTP headers) 파싱부터 최종 응답 스트리밍 (streaming)에 이르기까지 요청의 라이프사이클 (lifecycle)을 소유합니다. 이 모델은 스레드 경합 (thread contention)을 제거하며, 우리의 단일 프로세스가 수천 개의 진행 중인 요청 (in-flight requests)을 효율적으로 처리할 수 있게 합니다.
// 우리 커널의 핸들러 등록에 대한 단순화된 모습
func main() {
kernel := http.NewServeMux()
...
이 Go 커널은 다운스트림 서비스 (downstream services)로의 커넥션 풀 (connection pools)을 관리하고, 저수준 프로토콜 협상 (low-level protocol negotiation)을 수행하며, Prometheus 카운터 (counters)를 사용하여 446개 엔드포인트 (endpoints) 각각에 대한 상세한 메트릭 (metrics)을 노출합니다. 이 커널의 역할은 순수한 성능과 신뢰할 수 있는 동시성 (concurrency)을 보장하는 것이며, 이는 우리의 더 복잡한 AI 로직이 안전하게 실행될 수 있는 토대가 됩니다.
모놀리스 내의 TypeScript: AI 비즈니스 로직 구조화
Go가 신경계라면, TypeScript는 두뇌입니다. 모델 선택 (model selection), 프롬프트 템플릿 (prompt templating), 토큰 계산 (token counting), 응답 검증 (response validation), 그리고 과금 로직 (billing logic)을 포함하는 우리의 핵심 AI 오케스트레이션 (orchestration) 로직은 TypeScript로 작성되었습니다. 이 계층은 우리의 모놀리스 (monolith) 설계 덕분에 프로세스 내 함수 호출 (in-process function calls)을 통해 Go 커널과 직접 인터페이스합니다.
TypeScript는 복잡하고 데이터 집약적인 작업에 필요한 구조적 엄격함을 제공합니다. TypeScript의 정적 타입 시스템 (static type system)은 AI 백엔드 (backends)에 내재된 다양한 페이로드 (payloads) 및 모델 설정 (model configurations)을 다룰 때 매우 가치 있습니다. 우리는 모델 응답, 프롬프트 템플릿, 사용자 권한에 대해 엄격한 인터페이스 (interfaces)를 정의함으로써, 동적 타입 언어 (dynamically typed language)였다면 런타임 오류 (runtime failures)로 나타났을 수 있는 일련의 오류들을 컴파일 타임 (compile time)에 잡아냅니다.
// TypeScript는 우리 AI 작업에 대한 계약 (contracts)을 정의합니다
interface InferenceRequest {
modelId: string;
...
이러한 모듈성 덕분에 우리는 동시성 (concurrency)을 처리하는 핵심적인 Go 커널을 건드리지 않고도, 새로운 모델 제품군에 대한 지원을 추가하거나 과금 계산 방식을 변경하는 것과 같은 AI 워크플로우 (workflows)를 업데이트할 수 있습니다. 이는 민첩성을 유지하는 **Go TypeScript 모놀리스 (monolith)**를 유지하는 핵심입니다.
프로세스 내 통신 (In-Process Communication): 제로 레이턴시 브릿지
이 아키텍처의 마법은 Go 커널과 TypeScript 레이어가 별개의 프로세스가 아니라 동일한 바이너리의 일부라는 점입니다. 이는 마이크로서비스 (microservices) 접근 방식에서 발생할 수 있는 모든 네트워크 직렬화 (serialization) 오버헤드를 제거합니다. 우리의 TypeScript 코드는 WASM 모듈로 컴파일되거나 Go WASM 인터프리터를 통해 실행되어, Go 핸들러 (handlers)에서 직접 함수 호출을 할 수 있게 해줍니다.
/v1/chat/completions 엔드포인트로 요청이 들어오면, Go 핸들러는 HTTP 요청을 파싱하고 로컬 캐시를 사용하여 API 키를 검증한 다음, 우리의 TypeScript executeInference 함수를 직접 호출합니다. gRPC 호출도, 다른 서비스로의 HTTP 요청도 없습니다. 그저 인메모리 (in-memory) 함수 호출일 뿐입니다. 이 아키텍처는 I/O 및 동시성 (concurrency)을 위해 컴파일 언어의 성능 이점을 제공하는 동시에, 비즈니스 로직을 위해 TypeScript의 개발자 경험 (developer experience)과 타입 안전성 (type safety)을 결합합니다.
모듈형 모놀리스의 배포 및 관측성 (Observability)
다중 언어 모놀리스 (polyglot monolith)를 배포하는 것은 마이크로서비스 메쉬 (mesh of microservices)를 오케스트레이션하는 것보다 간단합니다. 우리는 Go 바이너리, 컴파일된 TypeScript 모듈, 그리고 모델 설정 파일을 포함하는 단일 자급자족형 컨테이너 이미지를 빌드합니다. 우리의 CI/CD 파이프라인은 멀티 스테이지 Docker 빌드 (multi-stage Docker build)를 사용하여 두 언어를 모두 컴파일하고 가볍고 안전한 최종 이미지를 생성합니다. 단 한 번의 배포 명령으로 전체 AI 백엔드를 함께 확장할 수 있습니다.
관측성 (Observability)은 중앙 집중화되어 있습니다. Go 커널의 모든 메트릭 (요청 레이턴시, goroutine 수, 커넥션 풀 통계)과 TypeScript 레이어의 메트릭 (추론 시간, 토큰 사용량, 캐시 히트율)은 단일 Prometheus 엔드포인트 세트로 집계됩니다. 이를 통해 여러 서비스에 걸쳐 로그를 상관 분석할 필요 없이 시스템 상태에 대한 총체적인 뷰 (holistic view)를 확보할 수 있습니다.
# 우리의 최종 Docker 이미지는 단일화되고 최적화된 아티팩트 (artifact)입니다
FROM golang:1.21 as builder
WORKDIR /app
...
이러한 접근 방식은 배포 복잡성을 획기적으로 줄여주며, 수십 개의 서비스에 걸쳐 서로 다른 런타임 (runtime)을 관리해야 하는 "다중 언어 확산 (polyglot sprawl)" 문제를 제거합니다. 이는 진정한 **모듈형 모놀리스 (modular monolith)**입니다.
결론: 성능이 뛰어나고 유지보수가 용이한 AI 백엔드
Go + TypeScript 모놀리스를 선택한 것은 TormentNexus를 위한 의도적인 아키텍처 (architectural) 결정이었습니다. 이를 통해 Go로 고동시성 (high-concurrency), 고성능 커널 (kernel)을 작성하는 동시에, 복잡한 AI 오케스트레이션 (orchestration)을 위해 TypeScript의 표현력이 풍부한 타입 시스템 (type system)을 활용할 수 있습니다. 우리는 446개 이상의 엔드포인트 (endpoints)를 처리하기 위한 고루틴 (goroutines)의 가공되지 않은 속도와, 핵심 비즈니스 로직을 위한 TypeScript의 안정성을 모두 확보했으며, 이 모든 것이 단일하고 배포하기 쉬운 단위 내에서 이루어집니다.
이 **다중 언어 아키텍처 (polyglot architecture)**는 모놀리스가 퇴보가 아님을 증명합니다. 명확한 경계를 가지고 설계된다면 모놀리스는 강력하고 현대적인 접근 방식이 될 수 있습니다. 집약적인 AI 백엔드 (AI backend) 시스템을 구축하는 팀에게 이 모델은 성능, 개발자 편의성 (developer ergonomics), 그리고 운영의 단순함이 매력적으로 결합된 형태를 제공합니다.
우리의 모듈형 모놀리스 아키텍처가 실제로 작동하는 모습을 확인하거나 우리의 기술적 선택에 대해 더 자세히 알고 싶다면, TormentNexus를 방문하여 API 문서를 살펴보시기 바랍니다.
원문 게시 위치: tormentnexus.site
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기