--- id: wiki-2026-0508-netflix-마이크로서비스-전환 title: Netflix 마이크로서비스 전환 category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Netflix Microservices, Netflix Cloud Migration, Netflix Architecture] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [microservices, netflix, case-study, cloud-migration, resilience] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: java framework: spring-boot-spinnaker --- # Netflix 마이크로서비스 전환 ## 매 한 줄 > **"매 monolith → 매 1000+ microservice, 매 7년 의 journey"**. 2008 DB 손상 outage → 2009 AWS migration 시작 → 2016 완전 전환. 매 Chaos Engineering, Spinnaker, Hystrix, Eureka 의 birthplace. 매 modern microservice playbook 의 reference. ## 매 핵심 ### 매 timeline - **2008.08**: DVD shipping DB corruption — 3-day outage. Monolith fragility 의 trigger. - **2009-2012**: Cassandra adoption, Edge service split, AWS migration 시작. - **2013-2015**: Hystrix, Eureka, Ribbon, Zuul OSS 공개. - **2016.01**: 마지막 datacenter 종료. 100% AWS. - **2020+**: Service mesh (Envoy), gRPC migration, GraphQL federation. ### 매 driver - **Scale**: 매 30M (2008) → 200M+ (2020) subscribers. - **Velocity**: 매 daily deploy 의 thousands. - **Resilience**: 매 region failure 의 graceful degrade. - **Polyglot**: 매 service 의 own stack 의 freedom. ### 매 응용 1. Stream startup: 매 Netflix OSS 의 reuse (Eureka, Spinnaker). 2. Enterprise migration: strangler pattern + edge first. 3. Resilience: Chaos Monkey 의 culture adoption. ## 💻 패턴 ### Strangler Fig migration ```java // API Gateway routes — gradual cutover @Component public class FeatureRouter { @Value("${migration.user-service.percent}") int migrationPercent; public Route route(Request req) { if (req.path().startsWith("/users") && ThreadLocalRandom.current().nextInt(100) < migrationPercent) { return Route.NEW_MICROSERVICE; } return Route.LEGACY_MONOLITH; } } ``` ### Circuit breaker (Resilience4j, Hystrix successor) ```java import io.github.resilience4j.circuitbreaker.*; CircuitBreakerConfig cfg = CircuitBreakerConfig.custom() .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofSeconds(30)) .slidingWindowSize(20) .build(); CircuitBreaker cb = CircuitBreaker.of("recommendations", cfg); Supplier call = CircuitBreaker.decorateSupplier( cb, () -> recoClient.fetch(userId)); Recommendations result = Try.ofSupplier(call) .recover(t -> Recommendations.fallback()) // degraded UX .get(); ``` ### Eureka service discovery (client) ```java @SpringBootApplication @EnableDiscoveryClient public class RecommendationServiceApp { } // caller @Autowired DiscoveryClient discovery; List instances = discovery.getInstances("user-service"); ``` ### Chaos Monkey schedule ```yaml # spinnaker chaos-monkey config chaos: enabled: true schedule: "MON-FRI 09:00-15:00 PT" meanTimeBetweenKillsInWorkDays: 2 exceptions: - { account: prod, region: us-east-1, stack: critical-payment } ``` ### Spinnaker pipeline (deploy) ```json { "stages": [ { "type": "bake", "package": "user-service", "baseOs": "bionic" }, { "type": "deploy", "clusters": [{ "account": "prod", "region": "us-east-1", "strategy": "redblack", "capacity": { "min": 6, "max": 60 } }] }, { "type": "wait", "waitTime": 600 }, { "type": "checkPreconditions", "preconditions": [{ "type": "expression", "context": "kayentaPass" }] } ] } ``` ### Bulkhead isolation ```java ThreadPoolBulkheadConfig bulkhead = ThreadPoolBulkheadConfig.custom() .maxThreadPoolSize(10) .coreThreadPoolSize(5) .queueCapacity(20) .build(); ``` ### Backpressure with reactive ```java // Spring WebFlux public Flux stream(String userId) { return userClient.getProfile(userId) .timeout(Duration.ofMillis(200)) .flatMapMany(p -> recoClient.recommend(p)) .onBackpressureBuffer(1000, BufferOverflowStrategy.DROP_OLDEST); } ``` ### Canary analysis (Kayenta) ```yaml canaryConfig: metrics: - name: error-rate query: "avg(error_count) / avg(request_count)" criticality: critical direction: increase - name: latency-p99 criticality: high ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Startup pre-PMF | Monolith. Don't copy Netflix yet. | | Growing (50+ eng) | Extract edge services first | | Scale (Netflix-class) | Full microservices + service mesh | | Resilience-critical | Chaos engineering + canary mandatory | **기본값**: Modular monolith → strangler extraction when team/load demands. ## 🔗 Graph - 부모: [[Microservices]] - 변형: [[Service-Oriented-Architecture]] · [[Service Mesh]] - 응용: [[Chaos-Engineering]] · [[Spinnaker]] - Adjacent: [[Strangler-Pattern]] · [[Circuit-Breaker]] ## 🤖 LLM 활용 **언제**: 매 case study 의 summarize, OSS Netflix tool 의 explain, migration sequence 의 propose. **언제 X**: 매 own org 의 readiness 판단 — team maturity, ops capacity 의 honest assessment. ## ❌ 안티패턴 - **Cargo cult**: 매 5-person startup 의 microservices = 매 distributed monolith hell. - **No observability first**: 매 100 services + no tracing = debug 의 impossible. - **Big bang migration**: 매 monolith 의 1 day 의 split = outage. - **Skip chaos**: 매 production failure mode 의 unknown until customer hits it. ## 🧪 검증 / 중복 - Verified (Netflix Tech Blog 2009-2024, "Building Microservices" by Newman, AWS re:Invent Netflix talks). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — Netflix microservices migration case study + patterns |