35、FlixTube 技术深度解析:视频流、上传与手动部署

FlixTube 技术深度解析:视频流、上传与手动部署

1. 视频流处理

FlixTube 的核心功能之一是视频流处理。视频流从外部云存储开始,经过三个微服务,最终在用户的网页浏览器中显示。以下是视频流的详细路径:
- Azure 存储微服务 :通过 HTTP GET /video 路由从 Azure 存储中检索视频,并将其流式传输到 HTTP 响应。

app.get("/video", (req, res) => { 
    const videoId = req.query.id; 
    const blobService = createBlobService();
    streamVideoFromAzure(blobService, videoId, res) 
      .catch(err => { 
            // ... error reporting omitted ...
            res.sendStatus(500);
        }); 
});
  • 视频流微服务 :该微服务将来自视频存储的流式视频通过 Node.js 流传输到自己的 HTTP 响应。此外,它还会广播“视频已观看”消息,以便其他微服务可以记录用户的观看历史。
app.get("/video", (req, res) => { 
    const videoId = req.query.id;
    const forwardRequest = http.request( 
        {
            host: `video-storage`,
            path: `/video?id=${videoId}`,
            method: 'GET',
            headers: req.headers,
        }, 
        forwardResponse => {
            res.writeHeader(forwardResponse.statusCode, 
            forwardResponse.headers);
            forwardResponse.pipe(res); 
        }
    );

    req.pipe(forwardRequest);
    broadcastViewedMessage(messageChannel, videoId); 
});
  • 网关微服务 :这是视频流到达前端之前的最后一站。网关微服务将来自视频流微服务的流式视频传输到自己的 HTTP 响应,从而将视频传递到前端。
app.get("/api/video", (req, res) => { 
    const forwardRequest = http.request( 
        {
            host: `video-streaming`,
            path: `/video?id=${req.query.id}`,
            method: 'GET',
        }, 
        forwardResponse => {
            res.writeHeader(forwardResponse.statusCode, 
                    forwardResponse.headers);
            forwardResponse.pipe(res);
        }
    );

    req.pipe(forwardRequest); 
});
  • 前端显示 :使用 HTML 视频元素触发 HTTP GET 请求,该请求依次触发对网关、视频流和视频存储的请求,最终将视频显示给用户。
<video controls autoplay muted>
    <source src={{video.url}} type="video/mp4"> 
    Your browser does not support the video tag.
</video>

视频流处理的流程可以用以下 mermaid 流程图表示:

graph LR
    A[外部云存储] --> B[视频存储微服务]
    B --> C[视频流微服务]
    C --> D[网关微服务]
    D --> E[前端网页浏览器]
2. 视频上传

视频上传是 FlixTube 的另一重要功能,它允许用户将视频添加到系统中。视频上传的路径如下:
- 前端上传 :使用浏览器的 fetch 函数通过 HTTP POST 请求将视频上传到后端。由于前端是纯 JavaScript 网页,没有构建过程,因此使用 fetch 函数而不是 Axios 库。

fetch("/api/upload", { 
        body: file, 
        method: "POST", 
        headers: { 
            "File-Name": file.name,
            "Content-Type": file.type,
        }, 
    })
    .then(() => { 
        // ... Update the UI after the upload ... 
    })
    .catch((err) => { 
        // ... Handle the upload error ...
    });
  • 网关微服务 :接收来自前端的 HTTP POST 请求,并将其转发到视频上传微服务。
app.post("/api/upload", (req, res) => { 
    const forwardRequest = http.request(
        {
            host: `video-upload`,
            path: `/upload`,
            method: 'POST',
            headers: req.headers,
        }, 
        forwardResponse => {
            res.writeHeader(forwardResponse.statusCode, 
            forwardResponse.headers);
            forwardResponse.pipe(res); 
        }
    );

    req.pipe(forwardRequest);
});
  • 视频上传微服务 :为视频创建唯一 ID,并将请求转发到视频存储微服务。上传成功后,广播“视频已上传”消息,以便元数据微服务可以记录新视频。
app.post("/upload", (req, res) => { 
    const fileName = req.headers["file-name"]; 
    const videoId = new mongodb.ObjectId(); 
    const newHeaders = Object.assign({}, req.headers, 
    { id: videoId }); 
    streamToHttpPost(req, `video-storage`, 
    `/upload`, newHeaders) 
      .then(() => {
            res.sendStatus(200); 
        })
      .then(() => {
            // Broadcast message to the world.
            broadcastVideoUploadedMessage( 
                /* params omitted */
            );
        })
      .catch(err => {
            console.error(`Failed to capture uploaded file ${fileName}.`);
            console.error(err);
            console.error(err.stack);
        });
});
  • 视频存储微服务 :将上传的视频保存到 Azure 存储中。
app.post("/upload", (req, res) => { 
    const videoId = req.headers.id;                
    const mimeType = req.headers["content-type"];  
    const blobService = createBlobService();
    uploadStreamToAzure(req, mimeType, 
    videoId, blobService) 
      .then(() => {
            res.sendStatus(200); 
        })
      .catch(err => { 
            // ... error reporting omitted ...
            res.sendStatus(500); 
        });    
});

视频上传的流程可以用以下 mermaid 流程图表示:

graph LR
    A[前端网页浏览器] --> B[网关微服务]
    B --> C[视频上传微服务]
    C --> D[视频存储微服务]
    D --> E[外部云存储]
3. 手动部署 FlixTube 到生产环境

在将 FlixTube 部署到生产环境之前,需要手动部署以测试和调试部署脚本。以下是手动部署的详细步骤:

3.1 前提条件
  • Azure CLI 工具 :用于与 Azure 云服务进行交互。可以通过 az --version 检查是否安装,如果未安装,可以参考 安装说明 进行安装。
  • Terraform :用于创建和管理云基础设施。可以通过 terraform --version 检查是否安装,如果未安装,可以从 这里 下载最新版本。
3.2 Azure 认证

在部署基础设施之前,需要使用 Azure CLI 工具进行账户认证。可以使用 az account show 检查当前使用的账户,并复制输出中的 id 字段(Azure 订阅 ID)和 tenantID 字段。此外,还需要创建一个服务主体,以便 Kubernetes 集群可以与 Azure 账户进行交互。

az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/<subscription-id>"

请将 <subscription-id> 替换为实际的订阅 ID,并复制输出中的 appId(在 Terraform 脚本中称为 client_id)和 password(在 Terraform 脚本中称为 client_secret)字段。

3.3 配置存储

需要一个 Azure 存储账户来存储和检索视频。如果已经在第 4 章中创建了存储账户,可以重复使用;否则,按照第 4.4.1 节的说明创建一个新的存储账户。在存储账户中创建一个名为 videos 的容器,并记录存储账户名称和访问密钥。

3.4 部署应用程序
  • 初始化 Terraform :进入脚本目录并初始化 Terraform,安装所需的各种提供者。
cd chapter-9/example-1/scripts
terraform init
  • 部署基础设施 :使用 terraform apply 命令部署基础设施。在开始之前,需要提供以下输入变量:
  • app_version :第一次可以输入 1,后续调用 terraform apply 时应递增该数字。
  • client_id :Azure 服务主体的 ID。
  • client_secret :服务主体的密码。
terraform apply

手动部署的步骤可以总结为以下表格:
| 步骤 | 操作 | 说明 |
| ---- | ---- | ---- |
| 1 | 安装 Azure CLI 和 Terraform | 确保所需工具已安装 |
| 2 | 进行 Azure 认证 | 验证账户并创建服务主体 |
| 3 | 配置存储账户 | 创建存储账户和容器,并记录相关信息 |
| 4 | 初始化 Terraform | 安装所需的提供者 |
| 5 | 部署基础设施 | 提供输入变量并执行部署命令 |

通过以上步骤,我们可以手动将 FlixTube 部署到生产环境,为后续的持续部署奠定基础。

FlixTube 技术深度解析:视频流、上传与手动部署

4. Terraform 脚本结构

Terraform 脚本在 FlixTube 的手动部署中起着关键作用,其结构有助于高效地创建和管理云基础设施。以下是脚本目录的主要组成部分:
- 可复用模块 modules/microservice 目录下的 main.tf 文件是一个可复用的 Terraform 代码模块,可用于部署所有微服务,避免代码重复。
- 各种配置文件 :包含 backend.tf container-registry.tf database.tf 等文件,分别用于配置后端存储、容器注册表、数据库等。
- 状态文件 terraform.tfstate 记录了生产基础设施的状态,首次调用 Terraform 后会生成该文件。

具体的目录结构如下:

scripts
├── backend.tf
├── container-registry.tf
├── database.tf
├── deploy.sh
├── dev
├── kubernetes-cluster.tf
├── microservices.tf
├── modules
│   └── microservice
│       └── main.tf
├── private-key.tf
├── providers.tf
├── rabbit.tf
├── resource-group.tf
├── terraform.tfstate
└── variables.tf
5. 手动部署的重要性

手动部署 FlixTube 到生产环境虽然在自动化时代看似繁琐,但却有着不可忽视的重要性:
- 开发测试 :在开发部署脚本时,通常是逐步进行的。手动部署可以方便地测试脚本,获取反馈并修复问题。
- 问题排查 :如果未来发现持续部署(CD)管道出现问题,具备手动部署的技能可以在开发环境中运行部署脚本,从而找出并解决问题。

6. 持续部署展望

手动部署只是 FlixTube 部署流程的第一步,最终目标是建立一个持续部署(CD)管道,每当将更新后的代码推送到托管代码仓库时,自动将其部署到生产环境。以下是实现 CD 管道的大致步骤:
1. 代码仓库 :选择一个合适的代码托管平台,如 GitHub 或 GitLab。
2. 构建工具 :使用工具如 Jenkins、GitLab CI/CD 或 Travis CI 来自动化构建过程。
3. 部署脚本 :优化现有的 Terraform 脚本,使其能够在 CD 管道中自动运行。
4. 监控和反馈 :设置监控工具,如 Prometheus 和 Grafana,实时监控应用程序的性能,并在出现问题时及时反馈。

持续部署的流程可以用以下 mermaid 流程图表示:

graph LR
    A[代码仓库] --> B[构建工具]
    B --> C[部署脚本]
    C --> D[生产环境]
    D --> E[监控工具]
    E --> A[代码仓库]
7. 总结

FlixTube 的视频流处理和视频上传功能通过多个微服务协同工作,实现了高效的视频存储、传输和展示。手动部署到生产环境虽然具有挑战性,但为后续的持续部署提供了坚实的基础。通过理解和掌握这些技术,我们可以更好地管理和维护 FlixTube 应用程序,确保其在生产环境中的稳定运行。

在实际应用中,还可以根据具体需求对视频流处理和上传功能进行优化,例如使用更高效的视频编码格式、优化网络传输等。同时,持续部署的实现可以提高开发效率,减少人为错误,使应用程序能够更快地响应市场需求。

希望本文对您理解 FlixTube 的技术架构和部署流程有所帮助,祝您在开发和部署过程中取得成功!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值