找回密码
 注册

微信登录

微信扫一扫,快速登录

萍聚头条

查看: 224|回复: 0

[欧美剧] 图解 Netflix 网飞架构|技术栈、DGS、Java

[复制链接]
发表于 2025-6-9 09:50 | 显示全部楼层 |阅读模式
作者:微信文章
写在前面

前段时间在网上刷到一个视频 《How Netflix Uses Java - 2025 Edition》


How Netflix Uses Java
看完觉得还挺有意思的,于是想写一篇文档share一下,一起交流学习。当然由于本人的英语能力有限,Java理解缺乏,有错的地方欢迎大家指出来。 也推荐大家看看网飞的技术博客网址,里面很详细的介绍网飞的各个中间件的使用,链接都放文章的最后。
整体架构


Netflix ArchitectureC 端流媒体

网飞作为全球最大的流媒体平台之一,QPS极高,用户数以百万计。服务部署在多个 AWS 区域(四个不同的亚马逊区域)以降低网络IO延迟。

整体架构采用常见的微服务架构,拆分成各个子模块进行单独维护。流媒体部分通常对失败通常可以进行重试,即使部分数据丢失,应用整体仍可工作。而为了更快的速度,会使用基于的内存分布式数据存储。下面我们一个个模块拆分讲解:
Client 模块


这个模块涉及多端开发:
    IOS端:SwiftAndroid端:KotlinWeb端:React

和大多数公司的技术选型一样,猜测也可能会有RN这种跨端的存在。
API Gateway 模块


这是所有来自客户端请求的单入口,主要处理 GraphQL 请求。
    网关接收到 GraphQL 请求根据 federated schema 将请求分解:将一个大的schema请求查询,拆分成多个小查询,以便下一步请求后端服务向多个后端的 DGS 微服务发起请求:并发请求后端多个微服务服务

GraphQL:Facebook 开源的一款API查询语言

客户端可以‌精确指定需要的数据结构和字段‌,避免 REST API 中常见的数据过度获取(Over-fetching)或数据不足(Under-fetching)问题。 这也是Netflix放弃了REST 的原因之一。

举个例子:假设我们有一个图书管理系统,需要查询书籍及其作者信息。
    REST API :多次请求、数据冗余或不足。
      获取书籍列表:GET /books(返回所有书籍字段,但客户端可能只需要书名)获取某本书的作者详情:GET /books/{:id}/author(额外请求,N+1 问题)
    GraphQL:只需发送一次请求‌,精确指定需要的数据

客户端发送:
query {
  book(id: "1") {
    title
    releaseYear
    author {
      name
      country
    }
  }
}

服务端返回:
{
  "data": {
    "book": {
      "title": "xxxx",
      "releaseYear": 2000,
      "author": {
        "name": "xxxxx",
        "country": "xxx"
      }
    }
  }
}
Fanout 扇出


一种并发编程模式,指的是从一个入口点同时向多个目标发送请求或数据的过程。就像扇子展开一样,一个请求"扇出"到多个服务或资源。

    核心特征:
      并发执行 :多个请求同时发出,而不是串行执行聚合结果 :等待所有请求完成后,将结果合并返回性能优化 :总响应时间接近最慢的单个请求,而不是所有请求时间的总和



fanout 扇出DGS 模块 Domain Graph Service


Domain Graph Service 是 Netflix 开发的 GraphQL 框架,基于 Spring Boot 构建。每个 DGS 本质上是一个独立的 Java 微服务,但具备 GraphQL 能力。

从上面我们知道网关接收到 GraphQL 请求后,会根据 Federated GraphQL 规范进行扇出(fanout)操作。这意味着网关会调用多个后端服务来获取完成 GraphQL 查询所需的数据。这些后端服务被称为 DGS (Domain Graph Service)。 各个微服务之间使用gRPC进行通信。
    核心特点
      独立微服务 :每个 DGS 都是完整的微服务,包括部署、扩展和生命周期GraphQL Endpoint 端点:提供 GraphQL API 接口        Schema 定义:定义自己负责的 GraphQL 类型和字段类型扩展 :可以扩展其他服务定义的类型


举个例子:假设网飞有个用户服务DGS,观看历史服务DGS
    用户服务(User Service DGS):定义用户基础Schema
# User Service Schema
type User @key(fields: "id") {
  id: ID!
  email: String!
  name: String!
  createdAt: DateTime!
}

type Query {
  user(id: ID!): User
  users: [User!]!
}
    观看历史服务(History Service DGS):扩展 User 类型,添加观看相关字段
# Viewing History Service Schema
extend type User @key(fields: "id") {
  id: ID! @external
  watchHistory: [WatchRecord!]!
  currentlyWatching: [Content!]!
  watchTime: Int! # 总观看时长(分钟)
  favoriteGenres: [Genre!]!
}

type WatchRecord {
  contentId: ID!
  watchedAt: DateTime!
  progress: Float! # 观看进度 0-1
  rating: Int # 用户评分 1-5
}

type Content {
  id: ID!
  title: String!
}

这时客户端发送一个统一的查询,就可以获取来自多个服务的数据:
query GetUserProfile($userId: ID!) {
  user(id: $userId) {
    # 来自 User Service
    name
    email
    subscription
   
    # 来自 Viewing History Service
    watchTime
    favoriteGenres
    currentlyWatching {
      title
      type
    }
  }
}

这些 DGS 彼此无需了解,只需向 Federated Gateway 发布它们的 Schema。而 Gateway 是知道如何与 DGS 通信,因为它们都有 GraphQL 端点。

⚠️ 注意:这里是 Endpoint 端点,不是端口 Port
DataStore 模块


data store 数据存储
存储模块其实还有很多,我这里大概讲讲几个重要的:
    关系型数据库PostgreSQL、MySQL:主要存储Netflix 平台的各种数据,包括用户数据、节目信息、订阅信息以及账单交易等。非关系型数据Cassandra:存储用户观看历史数据。这是一种 NoSQL 数据库,具备强大的时序数据处理能力、可扩展性、高可用性和快速读写性能,非常适合时序数据的存储。EV Cache:网飞自研的一个基于Memcached的内存存储的开源、快速的分布式缓存。用于缓存例如电影、电视剧的标题、描述、用户的在线状态等等。BigSearch:基于ES的一个图关系搜索,为了实现 GraphQL 架构中跨服务的复杂查询(虽然不叫bigsearch,我这里就随便命名了一个)Kafka+FlinkCDC:数据库变更后,通过CDC连接器触发Kafka事件流更新ES中的索引信息。AWS S3:亚马逊云服务提供的对象存储服务,用来存储电影、剧集等各种资源以及进行全球分发。ML Model:机器学习的各种模型,用于推荐等等场景。Power BI:用于建立各种报表进行分析。
infrastructure 基础架构模块


通用基础架构
网飞作为流媒体领域的互联网巨头,技术水平非常高,开源很多自研的框架。我们结合上面的一些技术栈来讲讲:
    AWS:这个云服务我就不赘述了CDN:将内容分发到更靠近用户的服务器节点,提高视频流的观看体验,包括降低延迟、增加稳定性、提高用户体验、以及节约带宽成本Atlas:一种用于管理维度时间序列数据的后端系统,可以处理来自各种来源的大量指标数据,例如服务的性能指标、用户行为数据等。网飞开源Eureka‌:服务注册与发现组件,实现微服务动态调度。网飞开源Jenkins:CI 工具(非网飞开源)Spinnaker:一个开源的持续交付平台,CD工具(非网飞开源)K8S / Titus:容器集群管理工具Chaos Monkey:混沌工程,随机终止生产环境中运行的虚拟机实例和容器 ,用来测试系统的弹性和容错能力。网飞开源Zuul‌:动态路由与服务网关,处理负载均衡和请求过滤。网飞开源

此外网飞还有很多的开源项目,感兴趣可以到网飞的github中查看:


B 端企业应用

同样的,网飞也是全球最大的电影制片厂之一,因此有很多支持电影制作的内部企业应用。这类应用通常是更传统的企业应用,QPS低,并发用户少,只需要单区域部署。 与流媒体应用不同,数据准确性非常关键,不能容忍失败(例如,保存数据必须成功)。这类应用的数据通常更适合存储在关系型数据库中(如 PostgreSQL、MySQL)。

很多公司的B端应用其实是单体式的,毕竟单体维护起来比微服务容易很多。但网飞的B端服务采用了和流媒体C端相同的基于 GraphQL 的架构。


ToB Application Architecture
同样通过 GraphQL 请求到达 Federated Gateway,Gateway 再将请求路由到对应的 DGS(Java/Spring Boot 微服务)。这些 DGS 可能连接到 PostgreSQL 等关系型数据库,各个DGS微服务之间通信同样使用 gRPC。

⚠️ 注意这里的一个细节,JDK版本是17/21+,我们知道很多公司的JDK版本还是停留在JDK8,网飞之前也是JDK8,在这几年才升级到高版本的JDK。这带来繁重的兼容工作外,还带来了巨大的性能提升,而篇幅受限,网飞架构的演进,Java的升级就放在下一篇文章中
参考

[1] https://www.youtube.com/watch?v=XpunFFS-n8I&ab_channel=Java

[2] https://blog.bytebytego.com/p/evolution-of-java-usage-at-netflix

[3] https://netflixtechblog.com

[4] https://netflixtechblog.com/how-netflix-content-engineering-makes-a-federated-graph-searchable-part-2-49348511c06c

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册 微信登录

×
Die von den Nutzern eingestellten Information und Meinungen sind nicht eigene Informationen und Meinungen der DOLC GmbH.
您需要登录后才可以回帖 登录 | 注册 微信登录

本版积分规则

Archiver|手机版|AGB|Impressum|Datenschutzerklärung|萍聚社区-德国热线-德国实用信息网

GMT+2, 2025-6-29 19:50 , Processed in 0.082648 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表