Go와 Rust에 대한 사랑 열변!

발행: (2025년 12월 14일 오전 02:38 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to
Warning: rant!

Introduction

난 이 개소리에 지쳤다. 몇 주마다 어떤 러스트 개발자가 “두려움 없는 동시성이라도 시도해봤나요?” 라는 얄팍한 멘트와 함께 여기 슬쩍 들어와서, 러스트가 세상의 모든 문제를 해결하는 프로그래밍 언어의 재림이라고 떠들어대는 것이다. 뉴스 플래시: 그렇지 않다. 그것은 과도하게 설계된 부풀린 쓰레기이며, 그 동시성 이야기는 현대 프로그래밍 언어 담론에서 가장 과장된 거짓 중 하나다.

Go’s Concurrency Model

Go(그리고, 네, 그 이전의 Erlang/BEAM)는 실제로 동시성을 제대로 구현했다.

  • Goroutine은 비용이 거의 들지 않는다.
  • 채널은 내장되어 있고 관용적이다.
  • 스케줄러는 전투 테스트를 거쳤다.

수천, 심지어 수백만 개의 동시 작업을 뇌가 녹거나 컴파일러가 난리를 치지 않고도 생성할 수 있다. 간단하고 예측 가능하며, 박사 학위 없이도 실제 프로덕션 시스템에 확장할 수 있다.

Rust’s Concurrency Model

Rust? 오우. 그들은 “두려움 없는 동시성”을 자랑한다. 빌림 검사기가 컴파일 타임에 데이터 레이스를 잡아주기 때문이다. 멋진 이야기, 형. 하지만 알겠는가? 그건 전쟁의 절반에 불과하고, 아주 작은 절반이다.

진짜 동시성 버그는 단순히 공유된 가변 상태가 아니라, 교착 상태, 활동 교착, 기아, 우선순위 역전, 그리고 최악은 실행기를 블로킹하는 것이다.

Rust의 주류 async 생태계(Tokio, async‑std, 그 주간 유행하는 어떤 것이든)에서는 모든 것이 스레드 풀 위에서 협력적 멀티태스킹이다. 한 바보가 블로킹 함수를 호출한다—.await가 비밀리에 std::thread::sleep을 하거나, 파일을 동기식으로 읽거나, 내부에서 블로킹되는 크레이트를 호출하고—, 전체 런타임이 기아 상태에 빠진다. “엄청나게 동시적인” 앱이 한 스레드에서 멈추고 나머지는 빈둥거린다.

이것은 파이썬의 GIL이나 자바의 스레드 블로킹과 정확히 같은 함정이다. Rust는 이를 막지 않는다; 대신 직접 찾아서 spawn_blocking으로 감싸거나, 의존성이 완전히 async‑all‑the‑way‑down인지 기도하게 만든다(스포일러: 아니다).

그리고 “하지만 Send/Sync 트레잇!”이라는 변명을 하지 말라. 트레잇은 서드파티 라이브러리를 자동으로 논블로킹하게 만들지 않는다. 한두 개의 게으른 개발자(또는 오래된 크레이트)만 있으면 당신의 두려움 없는 동시성은 어느 GC 언어만큼이나 취약해진다.

Comparison

AspectGoRust
Concurrency primitivesGoroutine, 채널(내장)Future, async 런타임(Tokio, async‑std)
Blocking pitfalls시스템 전체를 실수로 블로킹하기 어려움단 하나의 동기 호출만으로 실행기를 쉽게 블로킹할 수 있음
Compile‑time safety가비지 컬렉터를 통한 메모리 안전빌림 검사기가 메모리 안전을 보장
Developer experience빠른 컴파일, 단일 바이너리, 가독성 좋은 코드가파른 학습 곡선, 어디에나 있는 라이프타임, 장황한 async 보일러플레이트
Typical use‑case서버, 백엔드, 네트워크 서비스제로‑코스트 추상화와 GC 일시정지가 필요 없는 저수준 시스템

Rust의 빌림 검사기는 메모리 안전에 뛰어나지만(축하합니다, GC 없이 GC를 재발명했군요), 그 대가로 컴파일러와 끝없이 싸워야 하고, 모든 시그니처에 라이프타임이 들어가며, “색칠된” async 코드가 전염되어 코드베이스 전체가 핀‑프로젝션 악몽이 된다.

Conclusion

Go는 일을 해낸다. 빠른 컴파일, 단일 바이너리 배포, 며칠 안에 새로운 개발자를 온보딩할 수 있는 지루할 정도로 읽기 쉬운 코드, 그리고 실제로 즐거운 동시성. Rust? 가파른 학습 절벽, 인생 선택을 의심하게 만드는 빌림 오류, 그리고 장황함 = 덕목이라고 믿는 전도사 커뮤니티.

Rust는 제 역할을 한다: 제로‑코스트 추상화와 GC 일시정지가 필요 없는 저수준 시스템. 하지만 서버, 백엔드, 네트워크 서비스—우리가 r/golang에서 하는 일—에 대해서는 과대 포장된 과잉이다. 여기서 당신의 컬트 언어를 떠들지 마라. 우리는 Goroutine이 있다. 우리는 채널이 있다. 우리는 확장 가능한 단순함이 있다.

Go는 왕이다. Rust는 뒤에서 “내 소유권 모델이야!”라고 외치는 시끄러운 아이일 뿐이다

내려투표해라, Rustbucks. 나는 여기서 코드를 배포하고 있을 테니, 너희는 아직 컴파일러와 씨름하고 있겠지.

Back to Blog

관련 글

더 보기 »

Go 서버에서 고성능 SQLite 읽기

워크로드 가정 이 권장 사항은 다음을 전제로 합니다: - 읽기가 쓰기보다 우세하고 쓰기는 드물거나 오프라인 - 단일 서버 프로세스가 데이터베이스를 소유함 - 다중 goroutine…