나무모에 미러 (일반/밝은 화면)
최근 수정 시각 : 2025-12-05 18:15:05

Cloudflare Workers

Cloudflare Worker에서 넘어옴

파일:Cloudflare Workers.svg
1. 개요2. 특징
2.1. V8 isolate
3. workerd4. Wrangler5. 지원 언어6. 장점
6.1. 다양한 서비스 연동
7. 단점8. 외부 링크9. 관련 문서

1. 개요

소개 페이지

Cloudflare의 엣지 네트워크에서 실행되는 서버리스 컴퓨팅 환경 및 플랫폼.

클라우드플레어의 기존 망 인프라를 사용하여 전세계 330개 이상 도시에 분산된 서버에 소스 코드를 캐시해 실행할 수 있으며, 전 세계 95% 사용자에게 50ms 이하의 지연 시간을 보장한다.

경쟁 재품으로는 AWS Lambda Edge, Vercel, Netfify 서비스 등이 있다.

2. 특징

2.1. V8 isolate

파일:cf-workers-isolate.webp

How Workers works - Isolates
Cloud Computing without Containers

대형 클라우드 플랫폼도 해결 못한 콜드 스타트를 Cloudflare가 해결 가능했던 이유는 생성될 때 오버헤드가 비교적 큰 가상머신이나 컨테이너를 생성하는 대신 V8 엔진을 기반으로 isolate를 생성하도록 설계되었기 때문이다.[1] 커널 차원의 프로스세스 containerization 및 자원 관리를 택하는 대신 V8 인스턴스 하나만 띄우고 그 안에 isolate 컨텍스트를 필요에 따라 생성 및 관리하기 때문에 로드타임이 5ms 밖에 걸리지 않는 것. 엄밀히는 V8위의 경량 런타임인 workerd를 사용한다.

Workers는 HTTPS 요청으로 호출되는데 TLS negotiation 단계에서부터 런타임을 준비한다. 사용자와 Workers 사이의 평균 대기 시간이 5ms 보다는 오래 걸리는데 TLS handshake가 끝나고 통신하는 과정에서는 즉시 실행 가능한 상태니까 콜드 스타트가 아예 존재하지 않는 것. #

대신 동일한 엔진을 사용하는 웹 브라우저의 단점 또한 그대로 계승한다. 사용 가능한 프로그래밍 언어가 JavaScript 또는 JavaScript로 컴파일 가능한 언어 및 WebAssembly만 지원하기에 언어 차원에서의 범용성이 떨어진다는 점이 가장 대표적이다.

또한 업계에서 사실상 표준으로 인정되는 런타임인 Node.js가 아닌 V8만을 사용하므로 Node.js에서 쓰일 것을 상정하고 만들어진 코드와 호환성 이슈가 있을 수 있는데, 쉽게 말하면 기존 Node.js에서 작동하던 수많은 라이브러리들과 그 라이브러리의 indirect한 종속성들을 Workers에서는 사용하지 못할 수 있다는 뜻이다. 대표적으로 패키징 문제가 있겠으나 이는 wrangler가 esbuild로 번들링을 수행하며 해결되었다.

다만 여전히 node:os, node:fs 등 Node.js 표준 라이브러리나 native code(node-gyp 등)등과의 호환성 이슈가 있을 수 있는데, Cloudflare도 이 문제점을 인지하고 있는지 node-compat 호환성 플래그를 이용해 Workers에서 일부 Node.js 기본 모듈을 이용할 수 있다. # 결국 node-compat을 사용하거나 cfworker 등 CF Workers 런타임 API와 호환되는 대체 라이브러리를 새로 개발하거나 사용하는 수밖에 없는데, 후자의 경우는 필연적으로 마이그레이션 비용과 vendor-lockin을 유발시킨다. 이를 표준화하기 위해 WinterTC가 논의되고 있지만 갈길은 멀다.

또한 다른 컨테이너 기반 서비스와 다르게 컴퓨팅 메모리가 128 MB로 굉장히 작은 양으로 제한되어 있어 사실상 MSA 설계가 강제되며, (람다 특징이기도 하지만) CPU 실행 시간이 트리거당 최대 30초로 제한된다는 점 때문에 설계 자유도가 높지 않다.[2]

3. workerd

[[JavaScript|
파일:JavaScript 로고.svg
JavaScript
관련 문서
]]
{{{#!wiki style="margin: 0 -10px -5px; min-height: calc(1.5em + 5px)"
{{{#!folding [ 펼치기 · 접기 ]
{{{#!wiki style="margin: -5px -1px -11px"
<colbgcolor=#f7df1e,#f7df1e><colcolor=#000,#000> 관련 문서 표준(TC39 · 브라우저 전쟁) · Vanilla JS · AJAX · JSFuck · 상태관리 라이브러리 · JSON
문법 표준 내장 객체, this · undefined
구현체 <bgcolor=#f7df1e,#f7df1e> 엔진 V8 · SpiderMonkey · JavaScriptCore · 헤르메스 · Boa
<bgcolor=#f7df1e,#f7df1e> 런타임 Node.js · Deno · Bun · workerd
패키지 관리자 npm · Bun
파생 언어 TypeScript · CoffeeScript · ActionScript · AssemblyScript · elm · ReasonML · ReScript
관련 인물 브랜든 아이크
기타 JavaScript npm 마비 사태 }}}}}}}}}


GitHub

클라우드플레어에서 Workers 배포 환경 용도로 개발한 JavaScript 런타임. 상술한 대로 엔진으로는 V8을 임베드해서 사용하며, 그 외 Node.js처럼 CF worker 실행 환경(execution context)으로 들어오는 API를 구현한다. 실제 Cloudflare Workers 배포 환경에서는 workerd 런타임 위에 클라우드플레어 자체적으로 추가적인 레이어를 올려 사용한다.#

Cloudflare Workers 출시 이후 5년이 지난 2022년 9월 27일, 아파치 라이선스 2.0 오픈 소스로 공개되었다.# 유닉스의 데몬 프로세스의 관습적 표기인 -d 와 같은 작명법의 이름으로, 이 때문에 전부 소문자로 쓰는 것이 원칙이다.[3]

기존 Node.js를 런타임으로 사용하던 miniflare가 해당 출시 이후 workerd를 내부 런타임으로 사용하도록 바뀌었다.[4]#

4. Wrangler

공식 문서 github

Cloudflare Workers 프로젝트를 관리하기 위한 CLI. 주로 로컬에서 miniflare를 돌리거나 CI 환경에서 Worker로 배포하기 위한 프로세스를 구성하는 데 사용된다.

바인딩 등을 정의하기 위한 설정 파일wrangler.jsoncwrangler.toml을 사용할 수 있다. v3.91.0버전 이후로는 JSONC 파일이 더 권장된다.[5]

내부적으로 workerd를 동적 링킹하여 실행하는데, 이때문에 Nix 환경에서는 EPIPE 에러를 보게 된다. 이 경우 pkgs.wranglerwrangler flake 를 사용할 수 있다.

5. 지원 언어

후술할 WebAssembly 지원으로 인해 사실상 대부분의 언어를 사용할 수 있으므로[6][7] 클라우드플레어에서 공식적으로 first-class 지원하는 언어만 나열한다.

2024년 4월 2일부터 공식 Python 지원이 오픈 베타로 출시되었다.#

파이썬의 경우 V8 isolate에 Pyodide를 WASM으로 올린 후 그 위에 CF Worker 런타임 바인딩을 Pyodide FFI를 통해 연결한다. Pyodide의 경우 각 cpython 버전별 인터프리터와 표준 라이브러리가 별도 WASM module로 컴파일되어 런타임에 동적 링킹되는데, 이 때문에 단일 호스트에서 각 버전별로 동일한 모듈을 공유하게 되면서 메모리 크기를 줄일 수 있다.[8] 패키지를 사용할 시 cold start를 줄이기 위해 deploy 시점에 미리 패키지가 로딩된 isolate의 메모리 스냅샷을 백업한 후 실행 시점에서 다시 로딩해 사용한다.#

Pyodide가 현재 특정 Python 버전을 고정하지 못한다는 문제가 있다.#[9] V8 모드에서도 똑같이 나타나는 문제이긴 한데, 구버전 호환성이 거의 완벽하게 유지되는 JavaScript와 다르게 Python은 그렇지 않아 문제가 된다.[10]

6. 장점

경쟁 제품 대비 가성비가 좋은 편이다. Workers는 전 세계에서 유일하게 I/O 대기 시간에 요금이 청구되지 않고 CPU 연산 시간에만 요금이 청구되어, I/O 위주의 작업일 경우 타의 추종을 불허할 수준의 압도적인 가성비를 보여준다. 반면에 CPU 집약적인 작업은 성능과 비용 측면에서 적합하지 않다.

클플 네트워크 인프라를 그대로 사용하는 만큼 낮은 가격에 비해 세계 전역에서 평균적으로 낮은 지연시간을 기본적으로 제공한다는 점이 꽤 크다. 다른 클라우드 IaaS/PaaS 서비스의 경우 리전 구성부터 시작해 이 모든 걸 일일히 해야 하는 경우가 많기 때문. CF workers의 추상화 위에서는 코드 레이어에서 리전의 개념이 사실상 존재하지 않는다.

서버리스의 고질적인 단점으로 평가받던 콜드 스타트를 근본적으로 없애버렸다는 점이 높게 꼽힌다. V8 isolation 환경 관련 호환성 문제에만 걸리지 않는다면 매력적인 제품인건 분명하기 때문에 앞으로의 잠재력은 높게 평가할 수 있다.

6.1. 다양한 서비스 연동

범용성, 호환성이 성공에 큰 영향을 주는걸 알고있는지, 꾸준하게 범용성을 개선하기 위한 기능들을 출시하고 있다. 예로, Durable Objects 기능은 전역 네트워크에 고유한 단 하나의 객체를 유지시키고 이를 대상으로 RPC 요청을 가능하게 만들어 stateful한 기능들을 (Websocket 등) 설계 가능하며, TCP/IP로 통신하는 SQL를 사용 가능하도록 SQL Proxy를 지원한다.

또한, Queue가 출시된 뒤로 코레오그래피 패턴의 MSA 설계가 용이해졌고, Workflow가 출시된 뒤로 오케스트레이션 패턴의 MSA를 설계도 용이해졌다. 그러나 OS에 접근이 필요한 라이브러리는 사용이 불가하는 등의 기존 Node.js에서 작동하던 라이브러리를 상당수 사용할 수 없기 때문에[11] 타사 컴퓨팅 제품과 같이 사용해야 하는 상황이 많다. 따라서 백엔드 전체를 Workers로만 구축하려면 구현이 가능한지부터 잘 따져봐야 한다.

이외에도 바인딩으로 CF의 다른 서버리스 서비스, 가령 Workers KVR2, D1 등과 연계해서 사용하기가 좋다.

7. 단점

region pin이 어떤 형태로든 불가능하다. smart placement를 사용하면 간접적으로 배치가 가능하긴 하지만, 구체적으로 특정 장소에 고정하는 것은 불가능하다. 때문에 worker가 직접 최초 요청을 발생시키는 상황(cron 등)에서는 레이턴시 문제가 발생할 수 있다.

8. 외부 링크

9. 관련 문서



[1] V8 엔진은 크롬 브라우저에서 JavaScript 코드를 실행하는 엔진이다.[2] 사실 설계 자유도는 단점이라고만 보기는 어렵긴 하다. 백엔드 아키텍처 설계 방식이 강제되면, 일관성이라는게 생기기 때문에 장기적으로는 오히려 유지보수가 편해지는 장점이 있다.[3] The name is not capitalized because it is a program name, which are traditionally lower-case in Unix-like environments. #[4] With the release of workerd, Miniflare and the Wrangler CLI tool will now be able to provide a more accurate simulation by leveraging the same runtime code we use in production. #[5] As of Wrangler v3.91.0 Wrangler supports both JSON (wrangler.json or wrangler.jsonc) and TOML (wrangler.toml) for its configuration file. Prior to that version, only wrangler.toml was supported. Cloudflare recommends using wrangler.jsonc for new projects. #[6] Until now, Workers has only supported JavaScript. With the addition of WebAssembly, you can now use a wide range of languages #[7] Workers also supports WebAssembly (abbreviated as "Wasm") — a binary format that many languages can be compiled to. This allows you to write Workers using programming language beyond the languages listed above, including C, C++, Kotlin, Go and more. #[8] It is designed to allow the core interpreter and each native Python module to be built as separate WebAssembly modules, dynamically linked at runtime. This allows the code footprint for these modules to be shared among all Workers running on the same machine, rather than requiring each Worker to bring its own copy. This is essential to making WebAssembly work well in the Workers environment, where we often run thousands of Workers per machine — we need Workers using the same programming language to share their runtime code footprint. #[9] Being tied to use only one version of Python/Pyodide (the one that Workerd embeds) #[10] There is a challenge with Python though — both Pyodide and CPython are versioned. Updated versions are published regularly and can contain breaking changes. And Pyodide provides a set of built-in packages, each with a pinned version number. #[11] V8 엔진이 기반인 만큼 근본적으로 해결하기는 앞으로도 어렵다. 그래서 Cloudflare는 SQL Proxy 처럼 인기 있는 제품들을 우선으로 범용성을 계속해서 개선해 나가겠다고 한다.


#!if version2 == null
{{{#!wiki style="border:1px solid gray;border-top:5px solid gray;padding:7px;margin-bottom:0px"
[[크리에이티브 커먼즈 라이선스|[[파일:CC-white.svg|width=22.5px]]]] 이 문서의 내용 중 전체 또는 일부는 {{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/Cloudflare|Cloudflare]]}}}{{{#!if external != "o"
[[Cloudflare]]}}}}}} 문서의 {{{#!if uuid == null
'''uuid not found'''}}}{{{#!if uuid != null
[[https://namu.wiki/w/Cloudflare?uuid=ec1c302b-cd37-49bf-8a7e-8857dc3f20bb|r1015]]}}} 판{{{#!if paragraph != null
, [[https://namu.wiki/w/Cloudflare?uuid=ec1c302b-cd37-49bf-8a7e-8857dc3f20bb#s-4.2.2|4.2.2번 문단]]}}}에서 가져왔습니다. [[https://namu.wiki/history/Cloudflare?from=1015|이전 역사 보러 가기]]}}}
#!if version2 != null
{{{#!wiki style="display: block;"
{{{#!wiki style="border:1px solid gray;border-top:5px solid gray;padding:7px;margin-bottom:0px"
[[크리에이티브 커먼즈 라이선스|[[파일:CC-white.svg|width=22.5px]]]] 이 문서의 내용 중 전체 또는 일부는 다른 문서에서 가져왔습니다.
{{{#!wiki style="text-align: center"
{{{#!folding [ 펼치기 · 접기 ]
{{{#!wiki style="text-align: left; padding: 0px 10px"
{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/Cloudflare|Cloudflare]]}}}{{{#!if external != "o"
[[Cloudflare]]}}}}}} 문서의 {{{#!if uuid == null
'''uuid not found'''}}}{{{#!if uuid != null
[[https://namu.wiki/w/Cloudflare?uuid=ec1c302b-cd37-49bf-8a7e-8857dc3f20bb|r1015]]}}} 판{{{#!if paragraph != null
, [[https://namu.wiki/w/Cloudflare?uuid=ec1c302b-cd37-49bf-8a7e-8857dc3f20bb#s-4.2.2|4.2.2번 문단]]}}} ([[https://namu.wiki/history/Cloudflare?from=1015|이전 역사]])
{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid2 == null
'''uuid2 not found'''}}}{{{#!if uuid2 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph2 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]]){{{#!if version3 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid3 == null
'''uuid3 not found'''}}}{{{#!if uuid3 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph3 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version4 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid4 == null
'''uuid4 not found'''}}}{{{#!if uuid4 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph4 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version5 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid5 == null
'''uuid5 not found'''}}}{{{#!if uuid5 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph5 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version6 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid6 == null
'''uuid6 not found'''}}}{{{#!if uuid6 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph6 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version7 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid7 == null
'''uuid7 not found'''}}}{{{#!if uuid7 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph7 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version8 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid8 == null
'''uuid8 not found'''}}}{{{#!if uuid8 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph8 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version9 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid9 == null
'''uuid9 not found'''}}}{{{#!if uuid9 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph9 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version10 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid10 == null
'''uuid10 not found'''}}}{{{#!if uuid10 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph10 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version11 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid11 == null
'''uuid11 not found'''}}}{{{#!if uuid11 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph11 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version12 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid12 == null
'''uuid12 not found'''}}}{{{#!if uuid12 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph12 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version13 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid13 == null
'''uuid13 not found'''}}}{{{#!if uuid13 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph13 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version14 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid14 == null
'''uuid14 not found'''}}}{{{#!if uuid14 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph14 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version15 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid15 == null
'''uuid15 not found'''}}}{{{#!if uuid15 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph15 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version16 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid16 == null
'''uuid16 not found'''}}}{{{#!if uuid16 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph16 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version17 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid17 == null
'''uuid17 not found'''}}}{{{#!if uuid17 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph17 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version18 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid18 == null
'''uuid18 not found'''}}}{{{#!if uuid18 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph18 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version19 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid19 == null
'''uuid19 not found'''}}}{{{#!if uuid19 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph19 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version20 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid20 == null
'''uuid20 not found'''}}}{{{#!if uuid20 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph20 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version21 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid21 == null
'''uuid21 not found'''}}}{{{#!if uuid21 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph21 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version22 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid22 == null
'''uuid22 not found'''}}}{{{#!if uuid22 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph22 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version23 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid23 == null
'''uuid23 not found'''}}}{{{#!if uuid23 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph23 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version24 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid24 == null
'''uuid24 not found'''}}}{{{#!if uuid24 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph24 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version25 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid25 == null
'''uuid25 not found'''}}}{{{#!if uuid25 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph25 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version26 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid26 == null
'''uuid26 not found'''}}}{{{#!if uuid26 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph26 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version27 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid27 == null
'''uuid27 not found'''}}}{{{#!if uuid27 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph27 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version28 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid28 == null
'''uuid28 not found'''}}}{{{#!if uuid28 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph28 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version29 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid29 == null
'''uuid29 not found'''}}}{{{#!if uuid29 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph29 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version30 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid30 == null
'''uuid30 not found'''}}}{{{#!if uuid30 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph30 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version31 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid31 == null
'''uuid31 not found'''}}}{{{#!if uuid31 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph31 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version32 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid32 == null
'''uuid32 not found'''}}}{{{#!if uuid32 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph32 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version33 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid33 == null
'''uuid33 not found'''}}}{{{#!if uuid33 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph33 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version34 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid34 == null
'''uuid34 not found'''}}}{{{#!if uuid34 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph34 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version35 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid35 == null
'''uuid35 not found'''}}}{{{#!if uuid35 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph35 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version36 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid36 == null
'''uuid36 not found'''}}}{{{#!if uuid36 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph36 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version37 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid37 == null
'''uuid37 not found'''}}}{{{#!if uuid37 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph37 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version38 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid38 == null
'''uuid38 not found'''}}}{{{#!if uuid38 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph38 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version39 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid39 == null
'''uuid39 not found'''}}}{{{#!if uuid39 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph39 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version40 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid40 == null
'''uuid40 not found'''}}}{{{#!if uuid40 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph40 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version41 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid41 == null
'''uuid41 not found'''}}}{{{#!if uuid41 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph41 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version42 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid42 == null
'''uuid42 not found'''}}}{{{#!if uuid42 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph42 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version43 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid43 == null
'''uuid43 not found'''}}}{{{#!if uuid43 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph43 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version44 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid44 == null
'''uuid44 not found'''}}}{{{#!if uuid44 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph44 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version45 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid45 == null
'''uuid45 not found'''}}}{{{#!if uuid45 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph45 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version46 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid46 == null
'''uuid46 not found'''}}}{{{#!if uuid46 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph46 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version47 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid47 == null
'''uuid47 not found'''}}}{{{#!if uuid47 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph47 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version48 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid48 == null
'''uuid48 not found'''}}}{{{#!if uuid48 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph48 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version49 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid49 == null
'''uuid49 not found'''}}}{{{#!if uuid49 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph49 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}{{{#!if version50 != null
{{{#!wiki style="display: block;"

{{{#!wiki style="display: inline-block"
{{{#!if external == "o"
[[https://namu.wiki/w/|]]}}}{{{#!if external != "o"
[[]]}}}}}} 문서의 {{{#!if uuid50 == null
'''uuid50 not found'''}}}{{{#!if uuid50 != null
[[https://namu.wiki/w/?uuid=|r]]}}} 판{{{#!if paragraph50 != null
, [[https://namu.wiki/w/?uuid=#s-|번 문단]]}}} ([[https://namu.wiki/history/?from=|이전 역사]])}}}}}}}}}}}}}}}}}}}}}