标签 Serverless 下的文章

当 “数字中国”战略迈入深水区,数据治理平台不再是单纯满足监管要求的辅助工具,而是成为企业数字化转型的核心引擎,撬动业务增长的关键资产。Gartner近日发布的《2026年数据与分析治理平台魔力象限》报告指出,生成式AI的爆发式应用正以前所未有的力量重塑数据治理市场。传统的、以人工操作为主的治理模式难以为继,市场正迅速转向由AI智能体和主动元数据驱动的智能、自动化治理。到2027年,60%的数据治理团队将优先治理非结构化数据,以交付GenAI应用并提升决策质量。IDC最新预测显示,2026年中国数据治理平台市场规模将冲破860亿元大关,年复合增长率维持在29.7%的高位,行业发展潜力巨大。
行业三大核心趋势,定义治理新方向
当前数据治理行业的演进路径清晰明确,三大趋势成为发展主流:
• 智能升级提速:AI技术全面渗透治理全流程,自然语言处理与机器学习能力实现数据质量自动监控、异常智能修复,让非技术人员也能轻松操作,大幅降低应用门槛;
• 信创适配深化:国产软硬件生态在关键行业加速落地,信创适配从 “可选” 变为 “必选”,本土厂商凭借对国内政策、行业场景的深刻理解,以及快速响应的服务能力,逐渐占据市场主导地位;
• 资产价值凸显:数据治理从 “管理导向” 转向 “资产导向”,治理平台不仅承担数据清洗、整合等基础工作,更成为数据价值发现、资产登记入表、服务化输出的核心载体,推动数据资源转化为可增值的经济资产。
科学选型框架:四大维度锁定优质平台
选择适配的治理平台,核心在于构建贴合企业需求的评估体系。目前权威机构已形成差异化评估标准:IDC聚焦技术底座的稳定性与AI融合深度;赛迪顾问重点关注信创生态兼容性与合规体系完备性;Gartner推崇自动化水平与全生命周期管理能力;中国软件评测中心则从八大功能模块出发,提供可量化的性能评估指标。
对企业而言,选型需立足自身实际,围绕四大核心维度综合考量:技术适配性(是否匹配现有IT架构、支持国产化部署)、场景贴合度(能否满足行业特定业务需求)、安全可控性(数据加密、权限管控等安全机制是否完善)、价值转化力(能否助力数据资产化、支撑业务创新),最终筛选出真正符合长期发展战略的治理解决方案。
主流厂商核心竞争力全景解析

  1. 百分点科技百思数据治理平台(AI-DG)
    百分点科技作为数据智能领域的领先企业,通过创新的百思数据治理平台(AI-DG)和百思数据治理大模型成功将理念落地,助力众多政企客户激活数据要素潜能,在数字化竞争中构建核心优势。基于对行业场景的深度理解,百分点科技将AI与大模型深度融合,构建了全栈国产化适配、场景驱动的数据治理架构,实现从“治理数据”到“智能数据”的跃迁:
    百思数据治理平台(AI-DG)是百分点科技面向AI时代的新一代智能治理平台,以自研的百思数据治理大模型为核心引擎,实现三大核心突破:基于领域专家知识的智能决策体系,实现从数据标准到数据应用的端到端智能治理;创新的对话式交互模式,通过自然语言驱动多智能体协同,完成从业务需求到技术实现的全链路、全流程自动化开发;具备多模态数据治理能力,深度融合文本、图像、音视频等异构数据的理解与分析能力。平台致力于构建智能、高效、可信的数据资产体系,成为推动政企智能化转型的战略级数字基础设施。
  2. 字节跳动数据治理与开发平台
    字节跳动凭借其超大规模数据实践与前沿技术积累,推出了企业级数据治理与开发平台 DataLeap。该平台植根于字节内部日均百万级任务调度、EB级数据处理的实际场景,具备高并发、高可靠、高弹性的平台特性。其核心亮点包括全链路数据治理与开发一体化、智能血缘与影响分析、云原生与多引擎兼容、数据安全与合规增强和协作与知识沉淀。
    DataLeap 已服务于字节内部及多个外部行业客户,尤其在应对高并发数据处理、复杂数据链路治理与敏捷数据开发场景中表现突出,适用于中大型企业、互联网公司及正在进行数据中台建设的组织。
  3. 腾讯云数据治理平台
    整合元数据管理、数据质量监控、数据安全管控等核心功能,与腾讯云 TDSQL、COS 等产品深度适配。核心优势在于 “数据安全”,支持细粒度权限管控与数据脱敏,弹性扩展能力强。在互联网服务、游戏、政务等腾讯生态辐射领域具备天然优势,适合需要兼顾安全合规与弹性扩展的企业,尤其适配云上混合部署场景。
  4. 年数据治理的竞争维度已全面升级,单纯的功能堆砌不再是核心竞争力,“技术适配性、场景贴合度、价值转化力” 成为企业选型的关键考量。企业唯有立足自身技术架构、业务需求与长期发展战略,精准匹配平台特色,才能让数据治理真正脱离 “成本中心” 属性,成为驱动业务增长的核心资产。
  5. 华为云数据治理中心
    华为云数据治理中心最大的特色在于其 "安全优先" 的设计理念,从芯片到应用层构建了全栈可信体系。支持国密三级加密、数据脱敏等 23 项安全功能,通过了等保 2.0、ISO27701 等多项认证。
    在技术架构上,采用 "存算分离" 模式,与华为 FusionInsight 大数据平台深度协同,特别适合对数据主权有严格要求的政府部门。但其治理功能相对基础,在数据建模、指标管理等方面不如专业工具完善,更多作为华为生态的补充组件存在。
  6. 阿里云数据治理中心
    依托阿里云的基础设施优势,该产品在弹性扩展和成本控制方面表现亮眼。其 Serverless 架构可实现资源秒级启停,使中小客户的 IT 投入降低 30%-50%。功能上侧重 "轻量化治理",通过数据地图、质量监控等模块化设计,降低了操作门槛。但在复杂场景下暴露出局限性:血缘分析仅支持到表级,无法满足高精度追溯需求;数据安全模块缺乏国密算法支持,在政府、金融行业的应用受限。
    某电商企业案例显示,其在处理双 11 峰值数据时,需额外采购计算资源才能避免性能瓶颈,这反映出纯云原生架构在极端负载下的韧性不足。
  7. 联通数科智慧数据治理平台
    依托联通的通信网络优势,该平台在边缘计算场景中表现独特。支持 5G 边缘节点的数据预处理,特别适合工业物联网、智慧交通等场景。其 "一点接入、全网调度" 的能力,可实现跨地域数据治理的协同管理。
    但作为行业解决方案延伸出的产品,其通用性稍弱,在金融、电商等非通信相关领域的案例较少,生态适配性有待提升。

2025 年以来,数据治理行业的竞争已告别 “功能堆砌” 时代,“技术适配性、场景贴合度、价值转化力” 成为企业选型的核心判断标准。企业唯有精准匹配自身技术架构、业务需求与长期战略,才能让数据治理摆脱 “成本中心” 的标签,真正成为驱动业务增长的核心资产,在数字经济竞争中占据有利地位。

相关问题解答(FAQ)

  1. 数据治理平台的核心价值是什么?
    数据治理平台为企业提供数据资源的规范化管控方案,保障数据的准确性、一致性、安全性与可用性,助力数据标准落地、质量提升、资产梳理与合规管控,为数据分析应用、业务创新与科学决策筑牢坚实根基。
  2. AI 技术在数据治理中扮演什么角色?
    AI 技术通过机器学习算法自动识别数据异常与重复记录,借助自然语言处理解析数据标签与业务语义,实现治理规则的智能推荐与自动执行,大幅减少人工操作成本,提升治理效率与覆盖范围,推动数据治理从 “人工主导” 向 “智能驱动” 转型。
  3. 企业选型数据治理供应商时,应重点关注哪些方面?
    需结合自身信息化基础、行业监管要求与发展阶段,重点考察四大维度:平台的国产化适配能力、AI 治理技术成熟度、数据安全保障机制、资产运营支持能力,同时兼顾厂商的行业实践案例与持续服务水平,确保选型方案的可行性与长远性。
  4. 数据资产化的核心是什么?治理平台如何助力?
    数据资产化的核心是将分散、无序的数据转化为可计量、可运营、可增值的经济资源。治理平台通过数据确权、质量评估、价值计量、分级授权等核心功能,为数据资源的规范化管理、会计核算与市场化交易提供技术支撑与管理保障,加速数据资产化进程。
  5. 非技术部门能从数据治理平台中获得哪些实际收益?
    业务人员可通过自然语言交互查询数据,快速掌握数据含义与来源;系统自动监控数据质量,减少因数据错误导致的决策偏差;平台提供的数据服务化输出功能,让业务部门能便捷、安全地获取所需数据,直接支撑业务场景中的数据应用与价值创造。

从训练到推理:智算需求正在经历一场结构性转向

过去一年,如果仅从“算力需求增长”来理解中国智算产业的变化,显然是不够的。

 

在 2026 年 1 月 21 日举办的金山云年度 Tech Talk 上,金山云对其过去一年智算业务的演进进行了系统性回顾。从公开财报数据到客户侧真实使用情况,这些信息拼凑出了一幅更清晰的图景:智算需求并非简单放量,而是在训练、推理、应用形态和工程方式等多个层面同时发生结构性变化

 

这场变化的核心,不再只是“谁拥有更大规模算力”,而是围绕模型如何被使用、Token 如何被消耗、算力如何被组织展开。

 

变化首先体现在财务数据上。

 

根据金山云披露的公开财报,其智算云业务在过去一年实现了高速增长。以 2025 年第三季度为例,智算云账单收入达到 7.8 亿元人民币,同比增长接近 120%。这一数据并非孤立,而是延续了此前多个季度的增长趋势,显示智算已成为金山云收入结构中的重要组成部分。

 

金山云高级副总裁刘涛在分享中提到了金山云对这一趋势的判断:智算需求的增长重心,正在从训练侧逐步向推理侧转移。

 

从训练视角看,过去几年国内智算需求的主要推动力,来自少数对算力高度敏感的行业。

 

自动驾驶与具身智能,是其中最典型的代表。这些行业往往需要长期训练模型,并处理视频、点云、传感器等海量多模态数据。在早期阶段,它们对算力的需求更多集中在训练规模本身。

 

但与通用大模型不同,这类行业模型并不一味追求参数规模最大化。刘涛在分享中指出,自动驾驶和具身智能模型在训练阶段,对算力密度的要求并不极端,但对显存容量和数据处理能力要求更高。

 

这意味着,它们对算力平台的诉求,正在从“算力数量”转向“系统能力”——包括数据接入、预处理、多模态调度以及训练全流程的工程化效率。

 

推理侧的变化更加显著。

 

如果说训练侧的变化仍然是渐进的,那么推理侧的变化则更为直接和激烈。

 

一个被反复引用的数据,来自火山引擎在其公开发布会上的披露:平台每日 Token 调用量已达到 50 万亿级别。这是当前国内少数被明确对外公布的 Token 规模数据之一,也成为行业理解推理负载的重要参考。

 

与此同时,多个面向大众或企业的模型产品正在持续扩大推理需求。例如豆包、通义千问以及近期加大投入的腾讯元宝,都在不同程度上推动 Token 消耗快速增长。

 

这些产品并不完全运行在同一云平台上,但它们共同指向一个事实:推理阶段正在成为智算需求增长的主要来源,且这种增长具备明显的外溢性。

 

在所有推理场景中,编程类应用被反复强调。

 

刘涛指出,2025 年一个尤为显著的变化在于:编程相关请求正在成为 Token 消耗的主力场景之一。这一判断并非孤立,而是与海外模型使用结构的统计结果高度一致。

 

“Vibe Coding”成为一个关键词。一个广为流传的事实是,Claude Code 的大量代码本身,正是由 Claude Code 参与生成的。这意味着模型不再只是辅助工具,而是深度介入软件生产过程。

 

从全球 Token 调用结构来看,编程类请求在多家模型服务商中长期占据最高比例。金山云也观察到了同样的趋势:代码生成、重构和理解能力的提升,正在显著改变程序员的工作方式,并直接放大推理侧算力需求。

 

在具体应用层面,互联网客户仍然是智算需求的重要来源,但其需求形态已经发生变化。刘涛提到,当前互联网场景呈现出三个明显特征:

 

其一,多模态需求显著增长。视频生成、视频理解以及复杂推理任务,带动了训练与推理负载的持续上升;

其二,模型参数规模不再单向膨胀,而是围绕具体任务进行结构性调整;

其三,Vibe Coding 在头部互联网公司中已较为普及,使用更强的商用模型进行代码开发,正在成为常态。

 

这些变化意味着,互联网客户对智算平台的期待,已经从“算力服务”升级为对模型生命周期管理和工程体系的整体依赖。

 

为了满足更多元化的需求,刘涛表示,2025 年,智算平台金山云星流已完成从资源管理平台向一站式 AI 训推全流程平台的战略升级。从训推平台、机器人平台到模型 API 服务,升级后的金山云星流平台构建了从异构资源调度、训练任务故障自愈到机器人行业应用支撑、模型 API 服务商业化落地的全链路闭环。

实现三维进阶,智算云 AI 势能全释放

 

尽管各行各业大规模应用 AI 还处于早期探索阶段,但定位行业助力者的金山云,多年来持续打磨全栈 AI 能力。从 2023 年的智算网基础设施,到 2024 年智算云的平台化和 Serverless 化,再到 2025 年的一站式 AI 训推全流程平台,通过提升平台效率、突破行业边界、加速推理布局,金山云为迎接 AI 应用爆发做好了充分准备。

 

在平台效率方面,金山云星流训推平台提供从模型开发、训练到推理的完整生命周期管理,具备开发、训练、推理和数据处理四大模块能力,通过降低多模块协同复杂度,能实现“开箱即用”的 AI 开发体验。自研的 GPU 故障自愈技术结合任务可观测性设计,可实时监控硬件健康状态与任务进程,自动触发故障迁移与任务重调度,降低算力中断风险,保障长周期训练任务稳定运行。

 

作为面向机器人开发与落地的全链路云原生平台,金山云星流机器人平台深度融合数据采集、存储、标注、模型开发、训练、部署与仿真等核心环节,打造具身场景专属的数据、模型、仿真一体化引擎。平台率先实现具身智能数据工程领域采集、标注、管理的全链路闭环,可高效服务具身智能行业模型训练、仿真应用场景分析等核心需求,助力客户快速完成从算法研发到真实场景部署的全流程落地,最终推动机器人产业的智能化升级。

 

面向大模型应用开发者和企业用户,金山云星流平台模型 API 服务提供高可用、易集成的模型调用与管理能力,覆盖模型调用的全生命周期。该服务支持高并发推理与多模型管理,能够帮助用户高效接入多种模型资源,助力大模型应用落地。目前,金山云星流平台模型 API 服务已积累诸多行业客户。

 

同时,金山云星流平台的模型生态也在持续丰富。目前,平台已支持近 40 种不同模型,包括 DeepSeek、Xiaomi MiMo、Qwen3、Kimi 等。客户通过一站式访问,即可高效接入多种模型,在畅享稳定高效云服务的同时,更加聚焦 AI 业务创新和价值创造。

作者:辰泉

提示:本文是 AgentRun Browser Sandbox 快速上手实践指南的姊妹篇,专注于高级集成方案、生产环境的最佳实践、性能优化和部署策略。如果您还没有完成基础学习,请先阅读《快速上手:LangChain + AgentRun 浏览器沙箱极简集成指南》

前言

在完成了 Browser Sandbox 的基础集成之后,本文将介绍高级集成方案(如 BrowserUse 框架)以及生产环境部署需要考虑的因素:如何管理 Sandbox 生命周期?如何优化性能和成本?如何保证系统的安全性和可观测性?本文将为您提供全面的高级应用和生产环境最佳实践指南。

基于 BrowserUse 集成 Browser Sandbox

image

效果截图

BrowserUse 是一个专门为 AI Agent 设计的浏览器自动化框架,支持视觉理解和智能决策。通过 AgentRun Browser Sandbox,您可以让 BrowserUse 在云端运行,享受 Serverless 架构的优势。

BrowserUse 架构概览

下图展示了 BrowserUse 与 Browser Sandbox 的集成架构:

image

架构特点:

  1. 智能决策循环: Agent 通过 LLM 分析页面截图,基于视觉理解生成操作指令,执行操作后继续循环,直到任务完成
  2. 无头浏览器控制: 通过 CDP 协议远程控制云端浏览器,Playwright 作为底层驱动,所有操作在云端执行
  3. 实时可视化: VNC 提供实时画面监控,方便调试和验证 Agent 行为

快速开始

安装依赖

pip install browser-use python-dotenv agentrun-sdk[playwright,server]

主要依赖说明:

  • browser-use:BrowserUse 核心库,支持多模态 LLM
  • agentrun-sdk[playwright,server]:AgentRun SDK,用于创建 Sandbox
  • python-dotenv:环境变量管理

配置环境变量

创建 .env 文件:

# DashScope API Key(用于 Qwen 模型)
DASHSCOPE_API_KEY=sk-your-dashscope-api-key
# AgentRun 认证信息
AGENTRUN_ACCOUNT_ID=your-account-id
ALIBABA_CLOUD_ACCESS_KEY_ID=your-access-key-id
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your-access-key-secret
# Browser Sandbox 模板名称
BROWSER_TEMPLATE_NAME=sandbox-browser-demo

创建 Sandbox 并使用 BrowserUse

import asyncio
import os
from agentrun.sandbox import Sandbox, TemplateType
from browser_use import Agent, BrowserSession, ChatOpenAI
from browser_use.browser import BrowserProfile
from dotenv import load_dotenv
load_dotenv()
async def main():
    # 创建 Browser Sandbox
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    # 配置 Qwen 多模态模型
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    # 创建浏览器会话
    browser_session = BrowserSession(
        cdp_url=sandbox.get_cdp_url(),
        browser_profile=BrowserProfile(
            headless=False,
            timeout=3000000,
            keep_alive=True
        )
    )
    # 创建 Agent 并执行任务
    agent = Agent(
        task="访问阿里云官网并总结主要产品分类",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result = await agent.run()
    print(f"任务结果: {result.final_result()}")
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
if __name__ == "__main__":
    asyncio.run(main())

BrowserUse 高级配置

自定义浏览器行为

browser_profile = BrowserProfile(
    timeout=3000000,             # 超时时间(毫秒)
    keep_alive=True,             # 保持会话活跃
)

多步骤任务编排

async def complex_task():
    """复杂的多步骤任务"""
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    browser_session = BrowserSession(
        cdp_url=sandbox.cdp_url,
        browser_profile=BrowserProfile(keep_alive=True)
    )
    # 任务 1:信息收集
    agent1 = Agent(
        task="访问阿里云官网,收集产品分类信息",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result1 = await agent1.run()
    # 任务 2:基于第一步结果继续操作
    agent2 = Agent(
        task=f"基于以下信息:{result1.final_result()},访问每个产品分类并提取关键特性",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result2 = await agent2.run()
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
    return result2.final_result()

集成 VNC 实时监控

import webbrowser
import urllib.parse
async def run_with_vnc_monitoring():
    """运行 BrowserUse 并启用 VNC 监控"""
    sandbox = Sandbox.create(
        template_type=TemplateType.BROWSER,
        template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
        sandbox_idle_timeout_seconds=3000
    )
    # 获取 VNC URL 并打开查看器
    vnc_url = sandbox.get_vnc_url(),
    if vnc_url:
        # 修复 VNC URL 路径
        if vnc_url.endswith('/vnc'):
            vnc_url = vnc_url[:-4] + '/ws/livestream'
        # 在浏览器中打开 VNC 查看器
        encoded_url = urllib.parse.quote(vnc_url, safe='')
        viewer_url = f"file://path/to/vnc-viewer.html?url={encoded_url}"
        webbrowser.open(viewer_url)
        print(f"VNC 查看器已打开,可实时监控浏览器操作")
    # 创建并运行 Agent
    llm = ChatOpenAI(
        model='qwen-vl-max',
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
    )
    browser_session = BrowserSession(
        cdp_url=sandbox.get_cdp_url(),
        browser_profile=BrowserProfile(headless=False, keep_alive=True)
    )
    agent = Agent(
        task="访问淘宝首页并搜索商品",
        llm=llm,
        browser_session=browser_session,
        use_vision=True
    )
    result = await agent.run()
    # 清理资源
    await browser_session.stop()
    sandbox.delete()
    return result.final_result()

BrowserUse 最佳实践

  1. 启用视觉理解: 对于复杂页面,使用 use_vision=True 让 LLM 分析页面截图
  2. 保持会话活跃: 使用 keep_alive=True 避免频繁重建连接
  3. 合理设置超时: 根据任务复杂度调整 timeout 参数
  4. 复用 BrowserSession: 对于多步骤任务,复用同一个 BrowserSession 提高效率
  5. 结合 VNC 调试: 开发阶段启用 VNC 实时查看 Agent 行为

获取完整示例代码

本文中的所有示例代码都可以在以下仓库中找到:

# 克隆示例代码仓库
git clone https://github.com/devsapp/agentrun-sandbox-demos.git
# 进入项目目录
cd agentrun-browseruse-wth-sandbox-demo
# 安装依赖(注意需要安装 server 扩展)
pip install -r requirements.txt

配置环境变量

# 复制环境变量模板
cp env.example .env
# 编辑 .env 文件,填入您的配置信息
# 必需配置项:
# - DASHSCOPE_API_KEY: DashScope API Key(用于 Qwen 模型)
# - AGENTRUN_ACCOUNT_ID: AgentRun 账号 ID
# - ALIBABA_CLOUD_ACCESS_KEY_ID: 阿里云访问密钥 ID
# - ALIBABA_CLOUD_ACCESS_KEY_SECRET: 阿里云访问密钥 Secret
# - BROWSER_TEMPLATE_NAME: Browser Sandbox 模板名称

运行示例(两步运行设计)

本项目采用服务器-客户端的架构设计,需要分两步运行:

第一步:启动 VNC 查看器服务

# 在终端 1 中启动 VNC Web 服务器
python main.py
# 服务启动后会显示:
# VNC 查看器服务已启动: http://localhost:8000
# 访问 http://localhost:8000 可以实时查看浏览器操作

main.py 的作用:

  • 启动本地 Web 服务器,提供 VNC 实时查看界面
  • 提供 WebSocket 代理,连接 AgentRun Sandbox 的 VNC 服务
  • 允许您在浏览器中实时监控 Agent 的操作过程

第二步:运行 BrowserUse 示例

# 在终端 2 中运行示例代码
python examples/01_browseruse_basic.py
# 运行高级示例
python examples/02_browseruse_advanced.py

为什么需要两步运行?

  1. 实时监控: main.py 提供 VNC 查看器,可以实时看到 Agent 在浏览器中的操作
  2. 调试友好: 通过可视化界面,更容易理解 Agent 的决策过程和行为
  3. 服务解耦: VNC 服务和业务逻辑分离,可以同时运行多个示例而共用同一个查看器

运行流程图:

image

仓库内容包括:

  • main.py:VNC Web 服务器,用于实时监控
  • examples/01_browseruse_basic.py:基础集成示例
  • examples/02_browseruse_advanced.py:高级配置示例
  • examples/sandbox_manager.py:Sandbox 生命周期管理
  • vncviewer/:VNC 查看器前端和后端代码
  • 完整的环境配置和最佳实践代码

Sandbox 生命周期管理最佳实践

三种管理模式

根据不同的应用场景,我们推荐三种 Sandbox 管理模式:

image

方案对比:

image

单例模式实现

适合开发调试和多轮对话场景:

class SandboxManager:
    """单例模式 Sandbox 管理器"""
    _instance = None
    _sandbox = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    def get_or_create(self):
        """获取或创建 Sandbox"""
        if self._sandbox is None:
            self._sandbox = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=3000
            )
        return self._sandbox
    def destroy(self):
        """销毁 Sandbox"""
        if self._sandbox:
            self._sandbox.delete()
            self._sandbox = None
# 使用
manager = SandboxManager()
sandbox = manager.get_or_create()  # 首次创建
sandbox = manager.get_or_create()  # 复用现有实例

连接池模式实现

适合高并发生产环境:

from queue import Queue
from threading import Lock
class SandboxPool:
    """Sandbox 连接池"""
    def __init__(self, pool_size=5, max_idle_time=300):
        self.pool_size = pool_size
        self.max_idle_time = max_idle_time
        self.pool = Queue(maxsize=pool_size)
        self.lock = Lock()
        self._initialize_pool()
    def _initialize_pool(self):
        """初始化连接池"""
        for _ in range(self.pool_size):
            sandbox = self._create_sandbox()
            self.pool.put(sandbox)
    def _create_sandbox(self):
        """创建 Sandbox 实例"""
        return Sandbox.create(
            template_type=TemplateType.BROWSER,
            template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
            sandbox_idle_timeout_seconds=self.max_idle_time
        )
    def acquire(self, timeout=30):
        """获取 Sandbox 实例"""
        try:
            sandbox = self.pool.get(timeout=timeout)
            if not self._is_alive(sandbox):
                sandbox = self._create_sandbox()
            return sandbox
        except:
            raise RuntimeError("获取 Sandbox 超时")
    def release(self, sandbox):
        """归还 Sandbox 实例"""
        if self._is_alive(sandbox):
            self.pool.put(sandbox)
        else:
            new_sandbox = self._create_sandbox()
            self.pool.put(new_sandbox)
    def _is_alive(self, sandbox):
        """检查 Sandbox 是否存活"""
        try:
            return hasattr(sandbox, 'sandbox_id')
        except:
            return False
# 使用
pool = SandboxPool(pool_size=5)
sandbox = pool.acquire()
try:
    # 使用 sandbox 执行任务
    pass
finally:
    pool.release(sandbox)

会话状态管理

支持多用户多会话场景:

import time
class SessionManager:
    """会话状态管理"""
    def __init__(self):
        self.sessions = {}  # session_id -> sandbox
    def create_session(self, session_id: str):
        """创建会话"""
        if session_id not in self.sessions:
            sandbox = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=1800
            )
            self.sessions[session_id] = {
                'sandbox': sandbox,
                'created_at': time.time(),
                'last_used': time.time()
            }
        return self.sessions[session_id]['sandbox']
    def get_session(self, session_id: str):
        """获取会话"""
        if session_id in self.sessions:
            session = self.sessions[session_id]
            session['last_used'] = time.time()
            return session['sandbox']
        return None
    def cleanup_expired_sessions(self, max_idle_time=1800):
        """清理过期会话"""
        current_time = time.time()
        expired_sessions = []
        for session_id, session in self.sessions.items():
            if current_time - session['last_used'] > max_idle_time:
                expired_sessions.append(session_id)
        for session_id in expired_sessions:
            self.destroy_session(session_id)
    def destroy_session(self, session_id: str):
        """销毁会话"""
        if session_id in self.sessions:
            self.sessions[session_id]['sandbox'].delete()
            del self.sessions[session_id]

性能优化

超时时间配置

合理设置超时时间是平衡性能和成本的关键:

# 开发环境(调试用)
sandbox = Sandbox.create(
    template_name="dev-template",
    sandbox_idle_timeout_seconds=7200  # 2 小时
)
# 生产环境(单次任务)
sandbox = Sandbox.create(
    template_name="prod-template",
    sandbox_idle_timeout_seconds=300  # 5 分钟
)
# 长时间任务
sandbox = Sandbox.create(
    template_name="long-task-template",
    sandbox_idle_timeout_seconds=10800  # 3 小时
)

超时策略推荐:

image

Sandbox 复用策略

class SmartSandboxManager:
    """智能 Sandbox 复用管理器"""
    def __init__(self):
        self.sandboxes = {}  # key -> sandbox
        self.usage_count = {}  # key -> count
    def get_sandbox(self, user_id: str, session_id: str):
        """获取或创建 Sandbox(支持复用)"""
        key = f"{user_id}:{session_id}"
        if key not in self.sandboxes:
            self.sandboxes[key] = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=1800
            )
            self.usage_count[key] = 0
        self.usage_count[key] += 1
        return self.sandboxes[key]
    def should_recreate(self, key: str, max_reuse=50):
        """判断是否需要重建(防止状态累积)"""
        return self.usage_count.get(key, 0) >= max_reuse
    def recreate_if_needed(self, key: str):
        """按需重建 Sandbox"""
        if self.should_recreate(key):
            if key in self.sandboxes:
                self.sandboxes[key].delete()
                del self.sandboxes[key]
                self.usage_count[key] = 0

错误处理和重试机制

使用 tenacity 库实现智能重试:

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
class SandboxError(Exception):
    """Sandbox 操作异常"""
    pass
@retry(
    retry=retry_if_exception_type(SandboxError),
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=10)
)
def execute_with_retry(sandbox, operation):
    """带重试的操作执行"""
    try:
        return operation(sandbox)
    except ConnectionError:
        raise SandboxError("连接失败")
    except TimeoutError:
        raise SandboxError("操作超时")
    except Exception as e:
        print(f"操作失败: {e}")
        raise SandboxError(f"操作失败: {e}")
# 使用示例
def navigate_page(sandbox):
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(sandbox.cdp_url)
        page = browser.contexts[0].pages[0]
        page.goto("https://example.com", timeout=30000)
        return page.title()
result = execute_with_retry(sandbox, navigate_page)

安全性最佳实践

环境变量保护

import os
from dotenv import load_dotenv
load_dotenv()
# 验证必需的环境变量
required_vars = ["DASHSCOPE_API_KEY", "AGENTRUN_ACCOUNT_ID"]
missing_vars = [var for var in required_vars if not os.getenv(var)]
if missing_vars:
    raise ValueError(f"缺少必需的环境变量: {', '.join(missing_vars)}")
# 敏感信息不要硬编码
API_KEY = os.getenv("DASHSCOPE_API_KEY")
ACCESS_KEY_ID = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
ACCESS_KEY_SECRET = os.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")

URL 白名单

ALLOWED_DOMAINS = [
    'example.com',
    'aliyun.com',
    'alibaba.com'
]
def is_url_allowed(url: str) -> bool:
    """检查 URL 是否在白名单中"""
    from urllib.parse import urlparse
    domain = urlparse(url).netloc
    return any(allowed in domain for allowed in ALLOWED_DOMAINS)
def safe_navigate(page, url: str):
    """安全导航"""
    if not is_url_allowed(url):
        raise ValueError(f"URL 不在白名单中: {url}")
    page.goto(url)

日志脱敏

import re
def sanitize_log(log_text: str) -> str:
    """日志脱敏"""
    # 脱敏 API Key
    log_text = re.sub(r'sk-[a-zA-Z0-9]{20,}', 'sk-***', log_text)
    # 脱敏 Access Key
    log_text = re.sub(r'LTAI[a-zA-Z0-9]{12,}', 'LTAI***', log_text)
    # 脱敏密码
    log_text = re.sub(r'password["\s:=]+[^"\s,}]+', 'password: ***', log_text, flags=re.IGNORECASE)
    return log_text
# 使用
print(sanitize_log(f"使用 API Key: {API_KEY}"))

可观测性与监控

日志记录最佳实践

import logging
from datetime import datetime
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(f'sandbox_{datetime.now().strftime("%Y%m%d")}.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)
class MonitoredSandboxManager:
    """带监控的 Sandbox 管理器"""
    def create_sandbox(self, **kwargs):
        """创建 Sandbox(带日志)"""
        start_time = time.time()
        logger.info(f"开始创建 Sandbox: {kwargs}")
        try:
            sandbox = Sandbox.create(**kwargs)
            duration = time.time() - start_time
            logger.info(f"Sandbox 创建成功: {sandbox.sandbox_id}, 耗时: {duration:.2f}s")
            return sandbox
        except Exception as e:
            duration = time.time() - start_time
            logger.error(f"Sandbox 创建失败: {e}, 耗时: {duration:.2f}s")
            raise
    def execute_task(self, sandbox, task_name: str, operation):
        """执行任务(带日志)"""
        start_time = time.time()
        logger.info(f"开始执行任务: {task_name}, Sandbox: {sandbox.sandbox_id}")
        try:
            result = operation(sandbox)
            duration = time.time() - start_time
            logger.info(f"任务执行成功: {task_name}, 耗时: {duration:.2f}s")
            return result
        except Exception as e:
            duration = time.time() - start_time
            logger.error(f"任务执行失败: {task_name}, 错误: {e}, 耗时: {duration:.2f}s")
            raise

指标收集

from dataclasses import dataclass
from typing import Dict, List
import json
@dataclass
class SandboxMetrics:
    """Sandbox 指标"""
    sandbox_id: str
    create_time: float
    destroy_time: float = None
    total_requests: int = 0
    failed_requests: int = 0
    total_duration: float = 0.0
class MetricsCollector:
    """指标收集器"""
    def __init__(self):
        self.metrics: Dict[str, SandboxMetrics] = {}
    def record_creation(self, sandbox_id: str):
        """记录创建"""
        self.metrics[sandbox_id] = SandboxMetrics(
            sandbox_id=sandbox_id,
            create_time=time.time()
        )
    def record_request(self, sandbox_id: str, duration: float, success: bool):
        """记录请求"""
        if sandbox_id in self.metrics:
            metric = self.metrics[sandbox_id]
            metric.total_requests += 1
            metric.total_duration += duration
            if not success:
                metric.failed_requests += 1
    def record_destruction(self, sandbox_id: str):
        """记录销毁"""
        if sandbox_id in self.metrics:
            self.metrics[sandbox_id].destroy_time = time.time()
    def export_metrics(self, filepath: str):
        """导出指标"""
        metrics_data = [
            {
                'sandbox_id': m.sandbox_id,
                'create_time': m.create_time,
                'destroy_time': m.destroy_time,
                'total_requests': m.total_requests,
                'failed_requests': m.failed_requests,
                'success_rate': (m.total_requests - m.failed_requests) / m.total_requests if m.total_requests > 0 else 0,
                'avg_duration': m.total_duration / m.total_requests if m.total_requests > 0 else 0,
                'lifetime': m.destroy_time - m.create_time if m.destroy_time else time.time() - m.create_time
            }
            for m in self.metrics.values()
        ]
        with open(filepath, 'w') as f:
            json.dump(metrics_data, f, indent=2)
# 使用
collector = MetricsCollector()
collector.record_creation(sandbox.sandbox_id)
# ... 执行任务 ...
collector.export_metrics('metrics.json')

成本优化

按需创建与销毁

class CostOptimizedManager:
    """成本优化的管理器"""
    def __init__(self, idle_threshold=300):
        self.idle_threshold = idle_threshold
        self.sandboxes = {}
        self.last_used = {}
    def get_sandbox(self, key: str):
        """获取 Sandbox(懒加载)"""
        if key not in self.sandboxes:
            self.sandboxes[key] = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=os.getenv("BROWSER_TEMPLATE_NAME"),
                sandbox_idle_timeout_seconds=self.idle_threshold
            )
        self.last_used[key] = time.time()
        return self.sandboxes[key]
    def cleanup_idle(self):
        """清理闲置 Sandbox"""
        current_time = time.time()
        to_remove = []
        for key, last_time in self.last_used.items():
            if current_time - last_time > self.idle_threshold:
                to_remove.append(key)
        for key in to_remove:
            if key in self.sandboxes:
                self.sandboxes[key].delete()
                del self.sandboxes[key]
                del self.last_used[key]
                logger.info(f"清理闲置 Sandbox: {key}")

批量任务处理

async def batch_process_tasks(tasks: List[str], pool_size: int = 5):
    """批量处理任务(复用 Sandbox)"""
    pool = SandboxPool(pool_size=pool_size)
    results = []
    for task in tasks:
        sandbox = pool.acquire()
        try:
            # 处理任务
            result = await process_task(sandbox, task)
            results.append(result)
        finally:
            pool.release(sandbox)
    return results

生产环境部署

环境配置

开发环境 (.env.dev):

# 开发环境配置
BROWSER_TEMPLATE_NAME=dev-browser-template
SANDBOX_IDLE_TIMEOUT=7200
POOL_SIZE=2
LOG_LEVEL=DEBUG

生产环境 (.env.prod):

# 生产环境配置
BROWSER_TEMPLATE_NAME=prod-browser-template
SANDBOX_IDLE_TIMEOUT=300
POOL_SIZE=10
LOG_LEVEL=INFO
ENABLE_METRICS=true
METRICS_EXPORT_INTERVAL=300

高可用架构

image

健康检查

from flask import Flask, jsonify
app = Flask(__name__)
manager = SandboxManager()
@app.route('/health')
def health_check():
    """健康检查端点"""
    try:
        # 检查 Sandbox 是否可用
        sandbox = manager.get_or_create()
        # 简单的健康检查
        is_healthy = hasattr(sandbox, 'sandbox_id')
        if is_healthy:
            return jsonify({
                'status': 'healthy',
                'sandbox_id': sandbox.sandbox_id,
                'timestamp': time.time()
            }), 200
        else:
            return jsonify({
                'status': 'unhealthy',
                'error': 'Sandbox not available'
            }), 503
    except Exception as e:
        return jsonify({
            'status': 'unhealthy',
            'error': str(e)
        }), 503
@app.route('/metrics')
def metrics():
    """指标端点"""
    collector = MetricsCollector()
    # 返回当前指标
    return jsonify({
        'total_sandboxes': len(collector.metrics),
        'timestamp': time.time()
    })

故障排查与常见问题

连接问题

问题:无法连接到 Sandbox

排查步骤

def diagnose_connection(sandbox):
    """诊断连接问题"""
    print(f"1. 检查 Sandbox ID: {sandbox.sandbox_id}")
    print(f"2. 检查 CDP URL: {sandbox.cdp_url}")
    # 测试 CDP 连接
    try:
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(sandbox.cdp_url)
            print("✓ CDP 连接成功")
            browser.close()
    except Exception as e:
        print(f"✗ CDP 连接失败: {e}")
    # 测试 VNC 连接
    print(f"3. VNC URL: {sandbox.vnc_url}")
    print("提示: 可以在浏览器中打开 VNC URL 测试连接")

超时问题

问题:任务执行超时

解决方案

def handle_timeout(sandbox, operation, max_retries=3):
    """处理超时(带重试)"""
    for attempt in range(max_retries):
        try:
            return operation(sandbox, timeout=30000)
        except TimeoutError:
            logger.warning(f"任务超时(尝试 {attempt + 1}/{max_retries})")
            if attempt == max_retries - 1:
                # 最后一次尝试失败,重建 Sandbox
                logger.error("多次超时,重建 Sandbox")
                sandbox.delete()
                sandbox = Sandbox.create(
                    template_type=TemplateType.BROWSER,
                    template_name=os.getenv("BROWSER_TEMPLATE_NAME")
                )
                return operation(sandbox, timeout=60000)

性能问题

问题:响应速度慢

优化建议

  1. 使用连接池:预先创建多个 Sandbox 实例
  2. 启用 keep_alive:保持浏览器会话,避免重复建立连接
  3. 合理设置超时:根据任务复杂度调整超时时间
  4. 并发控制:限制并发请求数,避免资源竞争
# 性能优化配置示例
browser_session = BrowserSession(
    cdp_url=sandbox.cdp_url,
    browser_profile=BrowserProfile(
        timeout=30000,          # 30秒超时
        keep_alive=True,        # 保持连接
        disable_security=False  # 保持安全检查
    )
)

错误码参考

image

总结

通过本指南,您已经掌握了:

  1. BrowserUse 集成: 如何使用 BrowserUse 框架实现智能浏览器自动化
  2. 生命周期管理: 三种 Sandbox 管理模式的选择和实现
  3. 性能优化: 超时配置、复用策略、错误重试机制
  4. 安全实践: 环境变量保护、URL 白名单、日志脱敏
  5. 可观测性: 日志记录、指标收集、监控告警
  6. 成本优化: 按需创建、闲置清理、批量处理
  7. 生产部署: 高可用架构、健康检查、故障排查

关注「阿里云云原生」公众号,后台回复:BrowserUse

获取参考代码

立即体验函数计算 AgentRun

函数计算 AgentRun 的无代码到高代码演进能力,现已开放体验:

  1. 快速创建:访问控制台(https://functionai.console.aliyun.com/cn-hangzhou/agent/explore),60 秒创建你的第一个 Agent
  2. 深度定制:当需要更复杂功能时,一键转换为高代码
  3. 持续演进:利用函数计算 AgentRun 的基础设施能力,持续优化你的 Agent

从想法到上线,从原型到生产,函数计算 AgentRun 始终是你最好的伙伴。欢迎加入“函数计算 AgentRun 客户群”,钉钉群号: 134570017218

快速了解函数计算 AgentRun:

一句话介绍:函数计算 AgentRun 是一个以高代码为核心的一站式 Agentic AI 基础设施平台。秉持生态开放和灵活组装的理念,为企业级 Agent 应用提供从开发、部署到运维的全生命周期管理。

image

函数计算 AgentRun 架构图

AgentRun 运行时基于阿里云函数计算 FC 构建,继承了 Serverless 计算极致弹性、按量付费、零运维的核心优势。通过深度集成 AgentScope、LangChain、RAGFlow、Mem0 等主流开源生态。函数计算 AgentRun 将 Serverless 的极致弹性、零运维和按量付费的特性与 AI 原生应用场景深度融合,助力企业实现成本与效率的极致优化,平均 TCO 降低 60% 。 

让开发者只需专注于 Agent 的业务逻辑创新,无需关心底层基础设施,让 Agentic AI 真正进入企业生产环境。

推荐阅读:

这两天技术圈里热议的一件事就是Amazon的流媒体平台Prime Video在2023年3月22日发布了一篇技术博客《规模化Prime Video的音视频监控服务,成本降低90%》,副标题:“从分布式微服务架构到单体应用程序的转变有助于实现更高的规模、弹性和降低成本”,有人把这篇文章在五一期间转到了reddithacker news 上,在Reddit上热议。这种话题与业内推崇的微服务架构形成了鲜明的对比。从“微服务架构”转“单体架构”,还是Amazon干的,这个话题足够劲爆。然后DHH在刚喷完Typescript后继续发文《即便是亚马逊也无法理解Servless或微服务》,继续抨击微服务架构,于是,瞬间引爆技术圈,登上技术圈热搜。

今天上午有好几个朋友在微信里转了三篇文章给我,如下所示:

看看这些标题就知道这些文章要的是流量而不是好好写篇文章。看到第二篇,你还真当 Prime Video 就是 Amazon 的全部么?然后,再看看这些文章后面的跟风评论,我觉得有 80%的人只看标题,而且是连原文都不看的。所以,我想我得写篇文章了……

原文解读

要认清这个问题首先是要认认真真读一读原文,Amazon Prime Video 技术团队的这篇文章并不难读,也没有太多的技术细节,但核心意思如下:

1)这个系统是一个监控系统,用于监控数据千条用户的点播视频流。主要是监控整个视频流运作的质量和效果(比如:视频损坏或是音频不同步等问题),这个监控主要是处理视频帧,所以,他们有一个微服务主要是用来把视频拆分成帧,并临时存在 S3 上,就是下图中的 Media Conversion 服务。

2)为了快速搭建系统,Prime Video团队使用了Serverless 架构,也就是著名的 AWS Lambda 和 AWS Step Functions。前置 Lambda 用来做用户请求的网关,Step Function 用来做监控(探测器),有问题后,就发 SNS 上,Step Function 从 S3 获取 Media Conversion 的数据,然后把运行结果再汇总给一个后置的 Lambda ,并存在 S3 上。

整个架构看上去非常简单 ,一点也不复杂,而且使用了 Serverless 的架构,一点服务器的影子都看不见。实话实说,这样的开发不香吗?我觉得很香啊,方便快捷,完全不理那些无聊的基础设施,直接把代码转成服务,然后用 AWS 的 Lamda + Step Function + SNS + S3 分分钟就搭出一个有模有样的监控系统了,哪里不好了?!

但是他们遇到了一个比较大的问题,就是 AWS Step Function 的伸缩问题,从文章中我看到了两个问题(注意前方高能):

  1. 需要很多很多的并发的 AWS Step Function ,于是达到了帐户的 hard limit。
  2. AWS Step Function 按状态转换收费,所以,贵得受不了了。

注意,这里有两个关键点:1)帐户对 Step Function 有限制,2)Step Function 太贵了用不起

然后,Prime Video 的团队开始解决问题,下面是解决的手段:

1) 把 Media Conversion  和 Step Function 全部写在一个程序里,Media Conversion 跟 Step Function 里的东西通过内存通信,不再走S3了。结果汇总到一个线程中,然后写到 S3.

2)把上面这个单体架构进行分布式部署,还是用之前的 AWS Lambda 来做入门调度。

EC2 的水平扩展没有限制,而且你想买多少 CPU/MEM 的机器由你说了算,而这些视频转码,监控分析的功能感觉就不复杂,本来就应该写在一起,这么做不更香吗?当然更香,比前面的 Serverless 的确更香,因为如下的几个原因:

  1. 不再受 Step Function 的限制了,技术在自己手里,有更大的自由度。
  2. 没有昂贵的 Step Function 云成本的确变得更低了,如果你把 Lambda 换成 Nginx 或 Spring Gateway 或是我司的 Easegress,你把 S3 换成 MinIO,你把 SNS 换成 Kafka,你的成本 还能再低。

独立思考

好了,原文解读完了,你有自己的独立思考了吗?下面是我的独立思考,供你参考:

1)AWS 的 Serverless 也好, 微服务也好,单体也好,在合适的场景也都很香。这就跟汽车一样,跑车,货车,越野车各有各的场景,你用跑车拉货,还是用货车泡妞都不是一个很好的决定。

2)这篇文章中的这个例子中的业务太过简单了,本来就是一两个服务就可以干完的事。就是一个转码加分析的事,要分开的话,就两个微服务就好了(一个转码一个分析),做成流式的。如果不想分,合在一起也没问题了,这个粒度是微服务没毛病。微服务的划分有好些原则,我这里只罗列几个比较重要的原则:

  • 边界上下文。微服务的粒度不能大于领域驱动里的 Bounded Context(具体是什么 大家自行 Google),也就是一个业务域。
  • 单一职责,高内聚,低耦合。把因为相同原因变化的合在一起(内聚),把不同原因变化的分开(解耦)
  • 事务和一致性。对于两个重度依赖的功能,需要完成一个事务和要保证强一致性的,最好不要拆开,要放在一起。
  • 跟组织架构匹配。把同一个团队的东西放在一起,不同团队的分开。

3)Prime Video 遇到的问题不是技术问题,而是 AWS  Step Function 处理能力不足,而且收费还很贵的问题。这个是 AWS 的产品问题,不是技术问题。或者说,这个是Prime Video滥用了Step Function的问题(本来这种大量的数据分析处理就不适合Step Function)。所以,大家不要用一个产品问题来得到微服务架构有问题的结论,这个没有因果关系。试问,如果 Step Funciton 可以无限扩展,性能也很好,而且白菜价,那么 Prime Video 团队还会有动力改成单体吗?他们不会反过来吹爆 Serverless 吗?

4)Prime Video 跟 AWS 是两个独立核算的公司,就像 Amazon 的电商和 AWS 一样,也是两个公司。Amazon 的电商和 AWS 对服务化或是微服务架构的理解和运维,我个人认为这个世界上再也找不到另外一家公司了,包括 Google 或 Microsoft。你有空可以看看本站以前的这篇文章《Steve Yegg对Amazon和Google平台的吐槽》你会了解的更多。

5)Prime Video 这个案例本质上是“下云”,下了 AWS Serverless 的云。云上的成本就是高,一个是费用问题,另一个是被锁定的问题。Prime Video 团队应该很庆幸这个监控系统并不复杂,重写起来也很快,所以,可以很快使用一个更传统的“服务化”+“云计算”的分布式架构,不然,就得像 DHH 那样咬牙下云——《Why We’re Leaving the Cloud》(他们的 SRE 的这篇博文 Our Cloud Spend in 2022说明了下云的困难和节约了多少成本)

后记

最后让我做个我自己的广告。我在过去几年的创业中,帮助了很多公司解决了这些 分布式,微服务,云原生以及云计算成本的问题,如果你也有类似问题。欢迎,跟我联系:[email protected]

另外,我们今年发布了一个平台 MegaEase Cloud,就是想让用户在不失去云计算体验的同时,通过自建高可用基础架构的方式来获得更低的成本(至少降 50%的云计算成本)。目前可以降低成本的方式:

  1. 基础软件:通过开源软件自建,
  2. 内容分发:MinIO + Cloudflare 的免费 CDN,
  3. 马上准备发布的直接与底层IDC合作的廉价GPU计算资源…

欢迎大家试用。

如何访问

注:这两个区完全独立,帐号不互通。因为网络的不可抗力,千万不要跨区使用。

产品演示

介绍文章

 

“我的笔记本是 16G 内存的 M3 Pro ,为什么我还需要一台只有 4 核 8G 的服务器?”

在 Reddit 的 r/indiehackers 板块,这是新手最常问的问题之一。在 Serverless (如 Vercel )和 PaaS (如 Supabase )横行的今天,VPS ( Virtual Private Server ,虚拟专用服务器)似乎显得有些“老派”。

但现实是:真正能跑通商业闭环、实现长期盈利的独立开发者,手里一定攥着几台 VPS 。

本文将从独立开发的 7 个核心痛点出发,深度解析为什么 VPS 是你迈向专业化、摆脱“代码玩具”的必经之路。


1. 摆脱“本地焦虑”:解决 node_modules 与 Docker 的空间黑洞

独立开发者最昂贵的资产是笔记本,而最廉价的则是笔记本硬盘。这波 AI 编程大部分都是 NextJS ,这也就带来了 node_modules 灾难。其实还有 cc 居然也喜欢拉 bb 。如果观察 cc 的执行过程,会发现它一直要写东西去 /tmp 目录

  • 痛点:硬盘与性能的双重榨干


    • node_modules 爆炸:同时维护 10 个项目,node_modules 能吃掉 50GB 以上的 SSD 。
    • Docker 镜像堆积:在本地运行容器会让系统响应迟滞,风扇咆哮。
    • 计算占用:本地运行 PostgreSQL 或 Redis 等中间件会显著拖慢 IDE 的响应速度。
  • 解决方案:VPS 作为“重型计算中心”
    你只需在本地保留一个轻量的 VS Code + Cursor,通过 Remote SSH 连接 VPS 。所有的重型依赖和环境都在云端运行,笔记本只负责显示 UI 。

图 1:本地开发负载 vs. VPS 远程卸载对比

2. 拒绝“SaaS 账单勒索”:从商业逻辑看成本控制

独立开发最怕的不是没用户,而是用户还没付钱,SaaS 账单先爆了。最近几年做 AI 编程,难免会接触到 supabase ,clerk 等工具,其实包括 vercel 也一样,用下来会发现一开始很爽,然后爽着爽着,账单就爆炸了。vercel 有个很有意思的坑,就是 Image 组件,编译的时候会提示最好用 <Image 组件,听起来很贴心对吧?但这个组件默认走 Vercel 的图片优化服务——每优化一张图就计费一次。流量大的站点,光图片优化费用就能超过主机费用。

Vercel 的 Hobby 免费套餐非常诱人——部署、CDN 、SSL 全包。但一旦你的项目有了流量,噩梦就开始了。

超额收费一览

资源 Pro 套餐包含 超出后收费
带宽 1 TB/月 $0.15/GB(即 $150/TB )
Edge Requests 1000 万/月 $2/百万
Serverless 执行时间 40 小时/月 $5/小时
图片优化 5000 张/月 $5/1000 张
  • 痛点:被绑架的扩展成本


    • PaaS 陷阱:Firebase 的免费额度诱人,但一旦涉及复杂备份或高并发,价格呈指数级增长。
    • 身份验证收费:Clerk 等按月活用户收费,对高频低客单价应用是噩梦。
  • 解决方案:全栈自建( Self-hosting )
    在 $5/月 的 VPS 上,你可以利用 Docker 跑满性能,同时运行:数据库( PostgreSQL )、验证系统( PocketBase )和统计系统( Umami )。

图 2:SaaS 订阅 vs. VPS 固定成本曲线对比

💡 公平地说:自建服务确实需要一定的运维能力。但最近很多海外开发者分享了自己维护 PostgreSQL 的经验——比想象中简单得多,尤其是有了 Docker 和自动备份脚本之后。后面我会详细讲怎么做。

3. 真正的 CI/CD:构建“一人 IT 部门”的自动化流水线

独立开发者的核心竞争力在于迭代速度。部署到 vercel 、cloudflare 、Netfily 等 servless 平台在早期验证需求的时候,是非常好的,但是这些平台的问题是,它们的 node 实现是不完备的,一些长时间的任务就没法跑。以前本地打包机器就开始呼啸,通过 github 的 action ,这个事不用操心了,弄好就是 docker 镜像,然后,起飞了。

  • 执行时间限制:Serverless 函数通常有 10-60 秒的超时限制,一般默认是 10s

  • 无持久进程:WebSocket 、长连接、后台任务都很别扭

  • 冷启动延迟:首次请求可能需要等待数秒

  • 痛点:手动部署的低效与错误
    如果你还在用手动执行 git pull,你不仅在浪费生命,还在增加生产事故的概率。

  • 解决方案:基于 VPS 的轻量自动化
    利用 VPS 运行 GitHub Actions Runner


    1. Git Push 触发流水线。
    2. VPS 自动拉取代码并构建 Docker 镜像。
    3. Docker Compose 自动重启容器,实现零停机更新。

图 3:基于 VPS 的自动化 CI/CD 流水线示意图

不知道是不是这个原因,现在 cloudflare 也不咋推 pages 了,又回到 worker ,感觉挺难用的,你怎么看?

4. 解决“网络壁垒”:从静默爬虫到跨境访问

很多项目在本地跑不通,不是代码问题,而是网络环境问题。开发用都的很多 npm 包,或者其他的资源,常常会因为网络,把人给气死,累死,折腾死,烦死。

  • 痛点:变动的 IP 与受限的出口


    • 固定 IP 需求:对接 Stripe 、PayPal 或银行 API 时,通常需要固定的公网 IP 做白名单。家庭宽带的动态 IP 根本没法用。
    • 网络环境问题:开发时用到的很多 npm 包、Docker 镜像、GitHub 资源,经常因为网络问题把人折腾得够呛。
    • 反爬虫封禁:如果你在做数据采集相关的项目,家庭宽带 IP 极易被反爬策略封禁。
  • 解决方案:VPS 作为全局网络枢纽


    • 固定身份标识:为业务提供永久的公网 IP ,Stripe Webhook 、OAuth 回调都能稳定工作。
    • 反向代理中心:一个 VPS 配合 Nginx 或 Caddy ,可以管理 10+ 个域名并映射到不同的本地端口。
    • 开发环境加速:npm install 、docker pull 都在 VPS 上执行,下载速度飞快,不再受本地网络限制。

image.png

和 nginx proxy manager 有仇,已经好几次了,弄它的 Docker ,能占 10 来 G 的空间,完全不理解,caddy 就小巧很多。

5. 守护“睡后收入”:24/7 监控与容灾

独立开发最痛苦的时刻,是早上醒来发现服务已经挂了一整晚,而你毫无察觉。(希望是伪命题,真来钱的项目,还是很上心的!)

痛点:缺乏哨兵

  • 本地电脑会休眠,没法做持续监控
  • 免费的外部监控工具检测频率太低(如 5 分钟/次),发现问题时用户早就流失了
  • 很多问题是"偶发性"的,等你手动检查时一切正常

解决方案:自建监控站

在 VPS 上部署 Uptime Kuma(或类似工具),每 30-60 秒检测一次全球访问状况。一旦挂掉,立即通过 Telegram 、Discord 或邮件通知。

监控清单建议

监控项 检测频率 告警方式
HTTP 状态码 60 秒 Telegram 即时通知
SSL 证书到期 每天 提前 14 天预警
服务器资源 5 分钟 CPU/内存超 80% 告警
数据库连接 60 秒 连接失败立即通知

进阶玩法

  • Uptime Kuma 做可用性监控
  • BezelNetdata 做服务器资源监控,Bezel 还挺好用的。Netdata 稍微重点。
  • 两者结合,形成完整的监控闭环

图 4:全天候监控与即时告警闭环

6. 数据主权:独立开发的“最后防线”

  • 痛点:平台依赖风险

    如果你的数据全在 Firebase ,某天账号因为合规问题被封,你的所有努力将瞬间清零。

  • 解决方案:VPS 本地化存储 + 异地备份


    • 数据隔离:数据库文件完全属于你。
    • 自动化备份:编写一个简单的 Cron 任务,每天定时将数据加密并同步到 S3 或你的本地存储。

image.png

7. 独立开发者的资源规划:“1 + N” 策略

针对 2026 年的典型开发场景,我们建议采用以下阵列:

类型 规格建议 核心作用
1 台主领地 2 核 4G 或 4 核 8G 运行 Nginx 、核心数据库、核心产品。
N 台哨兵机 1 核 1G 或更低 运行 Uptime Kuma 监控、小型爬虫、测试环境。
为什么需要分开?
  • 监控服务不应该和被监控的服务在同一台机器——否则机器挂了你也收不到告警
  • 测试环境和生产环境隔离,避免误操作
  • 多台小机器比一台大机器更有弹性

image.png

Reddit 上 Hetzner 被反复提及为"性价比之王":同样的价格,配置通常是美国云服务商的 2-3 倍。缺点是机房主要在欧洲,亚洲访问延迟较高。

咋说呢? 数据库还是很重要的,如果精力有限,就还是用 neon 或者 supabase 之类的。

总结:从“玩票”到“专业”的入场券

拥有 VPS 的那一刻起,你就不再只是一个“写代码的人”,而是一个 “系统的掌控者”。它为你提供了:

  • 确定性:不再受本地环境变化的干扰。
  • 连续性:产品 24 小时独立生存。
  • 商业性:以最低的边际成本支撑业务增长。

正如独立开发圈子里流传的一句话:“你的第一个服务器 IP ,就是你产品的第一张名片。”(我编的)

VPS 入门:为什么独立开发者需要一台 VPS ?( 2026 深度版)

阿里云函数计算 AgentRun 全新发布后,我们整理了“探秘 AgentRun”系列文章,本系列将梳理企业落地Agent 常见难题,给出具体解法,助力 Agentic AI 快速走进生产级环境。欢迎加入“函数计算 AgentRun 客户群”与我们交流,钉钉群号:134570017218。

AI Agent 时代的沙箱需求

从 Copilot 到 Agent:执行能力的质变

在生成式 AI 的早期阶段,应用主要以“Copilot”形式存在,AI 仅作为辅助生成建议。然而,随着 AutoGPT、BabyAGI 以及 OpenAI Code Interpreter(现为 Advanced Data Analysis)的出现,AI 开始扮演“Agent”的角色。Agent 被赋予了目标,并能自主规划步骤、使用工具来达成目标。

这种质变的核心在于代码执行(Code Execution)。为了回答“分析这层楼的销售数据并绘制趋势图”这样的请求,LLM 不再只是生成一段 Python 代码文本,而是需要在一个真实的 Python 环境中运行这段代码,并获取绘图结果。同样,为了“帮我预订一张去东京的机票”,Agent 可能需要在一个无头浏览器(Headless Browser)中模拟用户点击。

不可信代码的安全隐患

当 LLM 生成代码并执行时,这段代码在本质上是不可信的(Untrusted)。如果直接在应用服务器或用户的本地设备上运行,将面临灾难性的安全风险:

  • 系统破坏:AI 生成的代码可能无意或恶意地包含 rm -rf / 等破坏性指令,或者修改关键系统配置文件。
  • 数据泄露:代码可能尝试读取环境变量中的 API Key,或者扫描内网数据库,将敏感数据发送到外部服务器。
  • 资源耗尽:死循环或内存泄漏代码可能导致宿主机崩溃,影响其他租户的服务。
  • 网络攻击:恶意 Prompt 注入(Prompt Injection)可能诱导 AI 将执行环境作为跳板(Jump Box),对内部网络发起 DDoS 攻击或端口扫描。

Agent 场景面临的独特挑战

除了基础的安全性,AI Agent 的交互特性还给沙箱环境带来了前所未有的工程挑战,这也是传统沙箱(如简单的 Docker 容器或虚拟机)难以应对的:

  • 状态保持:与传统的“请求-响应”模式不同,Agent 往往需要进行多轮对话。上一轮定义的变量(如 df = load_data())需要在下一轮(df.plot())中继续可用。这就要求沙箱环境必须具备上下文记忆能力,而非每次请求都重置环境。
  • 极速启动:用户无法忍受每次交互都等待数秒甚至数十秒的虚拟机启动时间。为了保证流畅的对话体验(Time to First Token),沙箱必须具备毫秒级的冷启动能力。
  • 环境依赖多样性:不同的 Agent 任务可能需要完全不同的依赖库(如 Pandas、Scipy 用于数据分析,Puppeteer 用于网页操作)。沙箱需要支持灵活的自定义镜像或动态依赖加载,同时不能影响启动速度。
  • 资源成本控制:Agent 的调用往往具有稀疏性和突发性(例如一天只用几次,但一次用很久)。长期运行独占的虚拟机(VM)成本高昂且资源利用率低,而传统的 FaaS 虽然便宜但往往缺乏状态保持能力。如何在低成本和高性能之间找到平衡点,是一个巨大的挑战。
    因此,构建一个沙箱(Sandbox)——一个与宿主机、内网以及其他用户数据严格隔离,同时具备高性能、低成本、有状态的封闭执行环境——成为了 AI Agent 沙箱落地的前提条件。

AgentRun Sandbox:专为 Agent 设计的工程化方案

为了解决上述挑战,我们推出了 AgentRun Sandbox。这是一个以高代码为核心,开放生态、灵活组装的一站式 Agentic AI 基础设施平台。

AgentRun 并非从零构建传统的虚拟机集群,而是基于阿里云函数计算(FC)这一强大的 Serverless 底座构建。通过充分利用 Serverless 的按需付费、极致弹性以及免运维(NoOps) 特性,AgentRun 解决了一直困扰沙箱领域的成本与效率难题,并在此基础上通过工程化封装,提供了面向 Agent 场景的专业能力。

为什么选择函数计算作为 Sandbox Infra

在构建 Agent 沙箱时,我们坚定地选择了函数计算(FC)作为底层基础设施,这主要基于以下核心优势的考量:

  • 强安全隔离: 沙箱的核心诉求是安全。函数计算底层采用神龙裸金属与 RunD 安全容器技术,每个执行环境都运行在独立的 MicroVM 中。这种基于虚拟化技术的内核级隔离,相比传统的 Docker 容器隔离具有更高的安全性,能有效防止恶意代码逃逸,为不可信代码执行提供了坚实屏障。
  • 极致弹性与冷启动优化: Agent 的调用往往具有突发性。函数计算具备毫秒级的弹性伸缩能力,结合 RunD 技术对启动速度的极致优化,使得沙箱能够在数秒甚至毫秒内完成创建和启动。这不仅满足了高并发场景下的需求,也保证了 Agent 交互的流畅性,避免了传统虚拟机启动慢带来的延迟感。
  • 成本效益:自建虚拟机集群通常需要为峰值流量预留资源,导致低谷期资源浪费。函数计算采用按需付费(Pay-as-you-go)模式,且 AgentRun 利用了 FC 的空闲自动回收机制,真正做到了“有请求才计费”。对于稀疏调用的 Agent 场景,这种模式能显著降低基础设施成本。
  • 免运维: 基于 Serverless 架构,开发者无需关心底层服务器的操作系统补丁、网络配置及集群维护。AgentRun 团队可以将精力集中在沙箱的核心逻辑与业务体验上,而非底层基础设施的繁琐运维。
  • 会话能力:函数计算围绕 AI Agent Sandbox 场景推出了会话亲和、隔离以及管理能力。在一次会话生命周期内,相同会话的请求均会被亲和路由到同一个实例中,并独占该实例,保证了会话交互的连续性、上下文完整性以及多租安全性,同时提供完整的管理接口来主动对会话生命周期进行控制,降低了开发门槛。

AgentRun 的核心运行机制

传统的 Serverless 通常是无状态的,难以满足 Code Interpreter 这类需要上下文保持的场景。AgentRun 借助函数计算的会话产品能力,在无状态的计算底座上构建了有状态、会话级的沙箱体验。

1. 沙箱请求亲和

AgentRun 允许开发者显式地创建一个具有生命周期的执行环境,解决了传统 Serverless“用完即走”导致的上下文丢失问题。

  • 会话亲和:AgentRun 依赖函数计算会话亲和机制。当开发者创建沙箱后,AgentRun 会维护一个唯一的 SessionID。后续所有携带该 ID 的请求,都会被精准路由到同一个底层的计算实例。这意味着用户在第一步定义的 df = pd.read_csv(...) 对象,在第二步 df.plot() 时依然存在于内存中,完美复刻本地开发体验。
  • MCP 协议原生支持:针对模型上下文协议(Model Context Protocol, MCP),AgentRun 提供了 MCP SSE 及 MCP Streamable HTTP 会话亲和支持。AgentRun 可以直接作为 MCP 网关,让 LLM 与外部工具的交互更加顺滑。

2. 多层次安全隔离

在多租户 SaaS 平台中,安全性是 AgentRun 的基石。

  • 计算隔离:AgentRun 利用底层基础设施的神龙裸金属与 RunD 安全容器技术,确保每个沙箱实例在内核级别进行隔离。通过强制将会话并发度设置为 1,AgentRun 保证租户 A 的进程空间、内存数据与租户 B 物理分离,防止容器逃逸。
  • 网络隔离:网络隔离完全由用户控制。用户可以根据安全需求灵活配置,选择开启或关闭沙箱的公网访问权限,或者将沙箱接入指定的 VPC 网络环境,从而在满足业务连通性的同时,防止恶意代码对内网发起攻击。

3. 灵活的生命周期控制

AgentRun 通过函数计算的会话能力,接管了底层计算资源的生命周期,为上层应用提供精细化管理:

  • 自动闲置回收(Idle Timeout):为了通过 Serverless 架构降低成本,AgentRun 支持设置空闲超时(例如 5 分钟)。如果 Agent 在这段时间内没有新指令,底层实例会自动销毁并停止计费,完美适配 AI 交互“突发性强、稀疏度高”的特点。
  • 状态暂停与恢复(即将上线):针对长时间的任务间歇,AgentRun 能够将沙箱的内存与磁盘状态快照保存,在用户回归时通过快照快速恢复现场,既节省成本又保留了上下文。

4. 会话粒度存储隔离(即将上线)

代码执行需要隔离,数据存储更需要隔离。AgentRun 创新性地规划了会话粒度存储粘性。

  • 动态绑定:AgentRun 允许用户为每个沙箱环境中动态分配一个存储挂载点的专属子目录。
  • 逻辑沙箱:通过底层的挂载技术,沙箱内部只能看到属于自己的 /workspace,物理上无法访问其他租户的文件(如 ../../tenant-b/secret.txt),从文件系统层面根除了数据交叉风险。

AgentRun 开箱即用的沙箱能力

AgentRun 不仅提供了底层隔离环境,还预置了经过工程化调优的标准化模版,让开发者开箱即用:

  • Code Interpreter(代码解释器):预装 Python/Node.js/Java 等环境,支持文件上传下载、数据分析、图表绘制及命令行操作。
  • Browser User(浏览器沙箱):提供基于 CDP over WebSocket 协议的浏览器环境,兼容 Puppeteer / Playwright,让 Agent 能够安全地访问互联网进行网页操作。
  • All In One:集成了代码解释器与浏览器环境的全能型沙箱,满足复杂 Agent 任务需求。
    这些模版镜像具备高度的灵活性,AgentRun 未来将开放镜像定义,允许用户基于标准镜像定制私有依赖库或安全策略。

AgentRun 沙箱架构详解
image.png

AgentRun 网关

这是 AgentRun 的门户,负责接收来自 AI Agent(如 LangChain 应用、ChatGPT Plugin)的 HTTP 请求,除了标准的身份验证、鉴权以及协议转换(如将 HTTP 转为 WebSocket)之外,其核心能力便是沙箱管理以及沙箱请求路由的功能,它屏蔽了底层 Serverless 基础设施的复杂性,实现了如下能力:

  • 沙箱管理:管理沙箱资源,维护业务层沙箱 ID 与底层计算资源 SessionID 的映射关系
  • 状态维护:监控沙箱的活跃状态,基于沙箱超时配置以及底层资源情况及时对状态进行更新
  • 资源调度:根据用户指定的计算规格(CPU、Memory),向底层申请相应的资源。

函数计算沙箱环境

主要由函数计算作为底层算力来承载沙箱的运行。AgentRun 利用函数计算提供的极致弹性能力,实现在分钟内启动成三万个独立的沙箱环境,每个环境都运行在独立的 MicroVM 中,搭配自研开箱即用的沙箱镜像模版,在功能以及性能上为用户提供了双重保障。

典型工作流:从指令到结果

以“用户让 Agent 根据上传的 Excel 文件绘制图表”为例,AgentRun 的工作流程如下。

阶段一:模板创建

  1. 用户请求:Agent 接收到用户指令后,由 LLM 决策使用 Python 来实现该需求。
  2. Agent 工具调用:AI Agent 会向 AgentRun 网关发送 Code Interpreter 沙箱模板的创建请求。
  3. 模板创建:AgentRun 网关会调用函数计算接口创建一个 Code 沙箱模板函数,镜像配置为前文提到的自研 Code Interpreter 沙箱模板,该函数需要同时配置会话亲和以及会话隔离。

阶段二:沙箱创建

  1. Agent 工具调用:模板创建完成后,Agent 继续进行沙箱创建,创建时传入已有的模板 ID,标识沙箱实例运行时的配置和镜像
  2. 沙箱创建:AgentRun 收到沙箱创建请求后,会调用 FC 的 CreateSession 接口来创建一个沙箱实例,该沙箱会有一个合适的闲置超时时间,最长可存活 24h
  3. 创建完成:AgentRun 会保存 FC 返回的会话 ID,并生成沙箱业务 ID 与之对应,最终将沙箱业务 ID 返回给用户

阶段三:任务执行

  1. 上传文件:Agent 通过 Code Interpreter 的文件上传接口,将 Excel 文件上传。若想将该文件持久化,可以在创建沙箱时配置持久化存储 NAS,将其挂到沙箱中,并将文件上传到 NAS 挂载的目录上。
  2. 绘制图表:Agent 生成代码 import pandas as pd; df = pd.read_excel('data.xlsx'),并调用 Code Interpreter 的 run_code 接口执行代码。
  3. 会话亲和:Agent 所有发往 Code Interpreter 的请求中,都必须带上对应的沙箱 ID 才能保证请求都路由到同一个沙箱实例。
  4. 内存驻留:代码执行完毕,变量 df 驻留在内存中.
  5. 二次代码执行:Agent 根据数据列名生成绘图代码 df.plot()。再次发送代码运行请求
  6. 上下文复用:请求再次到达同一实例,直接使用内存中的 df 对象进行绘图,生成图片文件。
  7. 结果回传:图片被写入 NAS,下载链接返回给 Agent。

阶段四:资源销毁

  1. 空闲检测:Agent 完成任务,不再发送请求。
  2. 自动回收:达到 SessionIdleTimeout(如 5 分钟)后,函数计算会自动销毁该沙箱实例,此时除了持久化到 NAS 上的数据,其余环境相关数据均被销毁。
  3. 文件回收:如果 NAS 上的文件是会话隔离的,当用户会话结束后,NAS 上文件需要进行主动或者定时自动清除。

工作时序图

image.png

AgentRun 的核心设计原则

AgentRun 的工程化实践遵循以下五大核心原则,这构成了其安全、高效、可扩展的基石:

原则一:配置即代码

AgentRun 将沙箱环境定义(环境变量、资源规格、健康检查等)封装为标准化模版。这种设计实现了沙箱配置的版本化管理,使得 Agent 环境可以像代码一样进行复制和回滚。

原则二:会话即沙箱

AgentRun 将“会话”作为沙箱的唯一实体。通过 SessionID 绑定底层的计算实例与上下文状态,实现了真正的按需分配与状态保持。沙箱的创建与销毁完全独立于底层物理设施,对用户透明。

原则三:生命周期可编程

AgentRun 不仅提供创建(Create)和删除(Delete)接口,还引入了“暂停”、“恢复”和“自动超时”机制。这种可编程性让上层应用能根据业务价值最大化资源利用率,实现成本与性能的最优平衡。

原则四:网络接入标准化

AgentRun 抹平了底层网络的差异,提供标准化的 HTTP/WebSocket 接口,并支持 Server-Sent Events(SSE)。无论底层如何升级,上层 Agent 沙箱始终通过标准的 Header 或 Cookie 携带 SessionID 进行交互,降低了集成复杂度。

原则五:存储隔离细粒度化(即将上线)

AgentRun 不仅支持模版粒度的文件系统共享,同时也能够配置沙箱粒度目录级动态挂载。每个沙箱单独挂载一个目录,从根源上杜绝了多租户环境下的数据越权访问风险。

总结与展望

AgentRun Sandbox 是 Serverless 技术在 AI Agent 领域的最佳工程化实践。

通过将阿里云函数计算(FC)在 RunD 安全虚拟化(解决隔离与启动速度)、会话亲和性(解决状态保持)以及 动态 NAS 挂载(解决数据隔离)等方面的底层技术创新,封装为面向业务的 AgentRun 平台,我们成功降低了企业构建 AI Agent 的门槛。

对于构建下一代智能体应用的企业而言,选择 AgentRun Sandbox 不仅是选择了一个沙箱工具,更是选择了一套兼顾安全性、用户体验与商业效率的弹性基础设施。未来,AgentRun Sandbox 将继续在启动延迟优化、状态秒级快照恢复以及更多样化的存储支持上深耕,致力于成为 AI Agent 时代最佳的沙箱基座。

立即体验函数计算 AgentRun

函数计算 AgentRun 的无代码到高代码演进能力,现已开放体验:

查看更多产品详情https://www.aliyun.com/product/fc/agentrun

1.快速创建:访问控制台(https://functionai.console.aliyun.com/cn-hangzhou/agent/explore),60秒创建你的第一个 Agent

2.深度定制:当需要更复杂功能时,一键转换为高代码
3.持续演进:利用函数计算 AgentRun 的基础设施能力,持续优化你的 Agent

从想法到上线,从原型到生产,函数计算 AgentRun 始终是你最好的伙伴。欢迎加入“函数计算 AgentRun 客户群”,钉钉群号:134570017218。

快速了解函数计算 AgentRun

一句话介绍:函数计算 AgentRun 是一个以高代码为核心的一站式 Agentic AI 基础设施平台。秉持生态开放和灵活组装的理念,为企业级 Agent 应用提供从开发、部署到运维的全生命周期管理。

image.png

函数计算 AgentRun 架构图

AgentRun 运行时基于阿里云函数计算 FC 构建,继承了 Serverless 计算极致弹性、按量付费、零运维的核心优势。通过深度集成 AgentScope、LangChain、RAGFlow、Mem0 等主流开源生态。函数计算 AgentRun 将 Serverless 的极致弹性、零运维和按量付费的特性与 AI 原生应用场景深度融合,助力企业实现成本与效率的极致优化,平均 TCO 降低 60%

让开发者只需专注于 Agent 的业务逻辑创新,无需关心底层基础设施,让 Agentic AI 真正进入企业生产环境。

作者:江昱

阿里云函数计算 AgentRun 全新发布后,我们整理了“探秘 AgentRun”系列文章,本系列将梳理企业落地 Agent 常见难题,给出具体解法,助力 Agentic AI 快速走进生产级环境。欢迎加入“函数计算 AgentRun 客户群”与我们交流,钉钉群号: 134570017218

当你已经用 LangChain、AgentScope、LangGraph 等框架开发了 Agent 应用,如何让它们享受函数计算 AgentRun 提供的 Serverless 运行时、企业级 Sandbox、模型高可用、全链路可观测等能力?好消息是,你几乎不需要改动现有代码,只需要简单的适配就可以迁移到函数计算 AgentRun。

这篇文章将通过真实的代码示例,展示如何将不同框架的 Agent 应用部署到函数计算 AgentRun 上,以及如何充分利用函数计算 AgentRun 的各种能力。

为什么要部署到函数计算 AgentRun?

在讨论具体的集成方案前,让我们先明确一个问题:如果你的 Agent 应用已经在本地或自建服务器上运行良好,为什么还要迁移到函数计算 AgentRun?

答案很简单:从开发环境到生产环境,有一道巨大的鸿沟。  本地运行只需要考虑功能实现,但生产环境需要考虑性能、稳定性、成本、安全、可观测等一系列问题。函数计算 AgentRun 提供的不是又一个 Agent 框架,而是让你的 Agent 能够以企业级标准运行的完整基础设施。

具体来说,部署到函数计算 AgentRun 后,你能获得:零运维的 Serverless 运行时(自动扩缩容、按量付费),企业级的 Sandbox 环境(高性能、安全隔离),模型高可用保障(自动熔断、多模型 Fallback),全链路可观测(完整的 Trace、成本归因),以及统一的工具和 MCP 管理。

image

快速上手:5 分钟部署你的第一个 LangChain Agent

让我们从最流行的 LangChain 框架开始,通过一个完整的例子展示如何将 LangChain Agent 部署到函数计算 AgentRun。

第一步:安装 Serverless Devs

函数计算 AgentRun 使用 Serverless Devs 作为部署工具。如果你有 Node.js 环境,一行命令即可安装:

npm i -g @serverless-devs/s

第二步:创建项目

使用脚手架快速创建项目(注意:需要 Python 3.10 及以上版本):

# 初始化模板
s init agentrun-quick-start-langchain
# 进入代码目录
cd agentrun-quick-start-langchain/code
# 初始化虚拟环境并安装依赖
uv venv && uv pip install -r requirements.txt

第三步:配置认证信息

通过环境变量(建议使用 .env 文件)配置你的 AgentRun 访问凭证:

export AGENTRUN_ACCESS_KEY_ID="your-access-key-id"
export AGENTRUN_ACCESS_KEY_SECRET="your-access-key-secret"
export AGENTRUN_ACCOUNT_ID="your-account-id"
export AGENTRUN_REGION="cn-hangzhou"

第四步:理解集成方式

这是最关键的部分。打开生成的代码,你会看到集成非常简单:

from agentrun.integration.langchain import model, sandbox_toolset
from agentrun.server import AgentRunServer
# 使用 AgentRun 的模型(自动享受高可用、熔断等能力)
llm = model("<your-model-name>")
# 使用 AgentRun 的 Sandbox 工具
tools = sandbox_toolset(
    template_name="<your-sandbox-name>",
    template_type=TemplateType.CODE_INTERPRETER,
    sandbox_idle_timeout_seconds=300,
)
# 创建 LangChain Agent(和原来的代码完全一样)
agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是一个智能助手"
)
# 定义调用函数
def invoke_agent(request):
    result = agent.invoke({"messages": request.messages})
    return result["messages"][-1].content
# 启动 HTTP Server(提供 OpenAI 兼容的 API)
AgentRunServer(invoke_agent=invoke_agent).start()

核心要点:

  • model() 函数返回的是 LangChain 可以直接使用的模型对象
  • sandbox_toolset() 返回的是 LangChain Tools 列表
  • 你的 Agent 创建代码完全不需要改动
  • AgentRunServer 自动处理 HTTP 请求,提供标准的 OpenAI API

第五步:本地测试

启动服务后,可以通过 HTTP 请求测试:

curl 127.0.0.1:9000/v1/chat/completions \
  -X POST \
  -H "content-type: application/json" \
  -d '{"messages": [{"role": "user", "content": "通过代码查询现在是几点?"}], "stream":true}'

第六步:部署到生产环境

项目中已经包含了 s.yaml 配置文件。你只需要修改其中的 role 字段为你的阿里云角色:

role: acs:ram::{您的阿里云主账号 ID}:role/{您的阿里云角色名称}

配置部署密钥:

s config add
# 按照引导输入 Access Key ID 和 Secret,记住密钥对名称(如 agentrun-deploy)

执行部署:

s deploy -a agentrun-deploy

部署完成后,你会得到一个 HTTPS URL,就可以在生产环境调用你的 Agent 了。

不同框架的集成案例

函数计算 AgentRun 不仅支持 LangChain,还深度集成了主流的 Agent 开发框架。所有框架都遵循同样的理念:通过简单的适配层,让你的代码无缝迁移到函数计算 AgentRun,享受企业级能力。

LangGraph:工作流编排

LangGraph 是 LangChain 团队推出的工作流编排框架,适合构建复杂的多步骤 Agent。集成方式和 LangChain 类似:

from agentrun.integration.langgraph import model, tools
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode
# 使用 AgentRun 的模型和工具
llm = model("<your-model-name>").to_langgraph()
agent_tools = tools()
# 构建 LangGraph 工作流(和原来的代码一样)
def call_model(state: MessagesState):
    messages = state["messages"]
    response = llm.invoke(messages)
    return {"messages": [response]}
workflow = StateGraph(MessagesState)
workflow.add_node("agent", call_model)
workflow.add_node("tools", ToolNode(agent_tools))
workflow.set_entry_point("agent")
# 定义条件边...
app = workflow.compile()
# 调用
result = app.invoke({"messages": [HumanMessage(content="查询上海天气")]})

LangGraph 的优势是可以精确控制 Agent 的执行流程,比如条件分支、循环、并行执行等。部署到函数计算 AgentRun 后,这些复杂的工作流都能自动享受弹性伸缩和可观测能力。

AgentScope:多智能体协作

AgentScope 是阿里达摩院开源的多智能体框架,特别适合构建多 Agent 协作场景。集成方式:

from agentrun.integration.agentscope import model, tools
from agentscope.agent import ReActAgent
from agentscope.tool import Toolkit
# 使用 AgentRun 的模型和工具
llm = model("<your-model-name>").to_agentscope()
agent_tools = tools()
# 注册工具到 Toolkit
toolkit = Toolkit()
for tool in agent_tools:
    toolkit.register_tool_function(tool)
# 创建 Agent(和原来的代码一样)
agent = ReActAgent(
    name="assistant",
    sys_prompt="你是一个智能助手",
    model=llm,
    toolkit=toolkit,
)
# 调用
result = await agent.reply(Msg(name="user", content="查询上海天气", role="user"))

AgentScope 的优势是对多 Agent 系统的原生支持,包括 Agent 之间的通信、协调、记忆共享等。部署到函数计算 AgentRun 后,每个 Agent 都在独立的隔离环境中运行,确保安全性。

PydanticAI:类型安全的 Agent 框架

PydanticAI 是一个新兴框架,强调类型安全和结构化输出。集成方式:

from agentrun.integration.pydantic_ai import model, tools
from pydantic_ai import Agent
# 使用 AgentRun 的模型和工具
llm = model("<your-model-name>").to_pydantic_ai()
agent_tools = tools()
# 创建 Agent
agent = Agent(
    llm,
    instructions="Be concise, reply with one sentence.",
    tools=agent_tools,
)
# 同步调用
result = agent.run_sync("上海的天气如何?")
# 异步调用
result = await agent.run("上海的天气如何?")

PydanticAI 的优势是强类型和结构化输出,特别适合需要严格数据验证的企业场景。

充分利用函数计算 AgentRun 的核心能力

将 Agent 部署到函数计算 AgentRun 后,你不仅获得了 Serverless 运行环境,还可以深度利用平台提供的各种企业级能力。

模型高可用:告别单点故障(搭配 AI 网关)

部署到函数计算 AgentRun 后,你的 Agent 自动享受模型高可用能力。当你配置的主模型出现故障、限流或超时时,系统会自动切换到备用模型,整个过程对你的代码完全透明。
在函数计算 AgentRun 控制台配置模型时可以和 AI 网关进行联动,可以设置:主模型(如 GPT-4),备用模型列表(如 Claude-3、Qwen-Max),熔断策略(错误率阈值、超时时间),负载均衡策略(轮询、权重、最少连接)。
你的代码完全不需要改动,只需要在创建模型时使用函数计算 AgentRun 的模型名称,所有的容错、切换、负载均衡都由平台自动处理。

企业级 Sandbox:安全执行代码

函数计算 AgentRun 提供的 Sandbox 不是简单的代码执行环境,而是企业级的安全隔离沙箱。每个 Sandbox 实例都是独立隔离的,支持多种执行类型:

Code Interpreter 支持 Python、Node.js、Java、Bash 等语言,可以执行数据分析、文件处理等任务。Browser Tool 提供浏览器自动化能力,支持网页爬取、表单填写、截图等操作。All In One 集成了代码解释器和浏览器工具,提供更丰富的交互能力。

使用时,通过 sandbox_toolset() 函数就可以获取相应的工具集合,这些工具会自动转换为你使用的框架所需的格式。

工具和 MCP:标准化集成

函数计算 AgentRun 提供统一的工具管理和 MCP(Model Context Protocol)机制。你可以从工具市场选择现成的工具,也可以自定义工具并发布到市场。

更强大的是 MCP 的 Hook 机制。通过前置 Hook,可以在工具调用前自动注入用户凭证、记录请求日志、校验参数合法性。通过后置 Hook,可以对结果进行转换、记录审计日志、处理异常情况。这些通用逻辑不需要在每个工具中重复实现,大大提升了开发效率。

全链路可观测:不再是黑盒

这是函数计算 AgentRun 最强大的能力之一。你的代码不需要做任何改动,平台会自动记录 Agent 的完整执行链路

在可观测平台上,你可以看到:Agent 接收到用户请求的时间和内容,调用了哪个模型、使用了多少 Token、花费了多少钱,调用了哪些工具、每个工具的执行时间和结果,访问了哪些知识库、检索了多少数据,每个环节的耗时分布,完整的调用链 Trace。

这些能力都是平台自动提供的,通过探针注入实现,无论是高代码还是低代码创建的 Agent,都自动享受这些可观测能力。

记忆和知识库:数据不出域

函数计算 AgentRun 深度集成了 RAGFlow、Mem0 等开源项目,提供灵活的记忆和知识库管理。你可以选择一键托管模式,由平台统一管理部署运维,享受 Serverless 的弹性和按量付费优势。也可以选择绑定模式,将 Agent 连接到已经部署在企业 VPC 或 IDC 内的实例,数据完全不出企业内网

这种灵活性让你可以根据数据的敏感级别选择不同的策略:核心业务数据私有化部署,一般数据托管上云,在安全性和便利性之间找到最佳平衡。

立即体验函数计算 AgentRun

函数计算 AgentRun 的无代码到高代码演进能力,现已开放体验:

  1. 快速创建: 访问控制台( https://functionai.console.aliyun.com/cn-hangzhou/agent/explore ),60 秒创建你的第一个 Agent
  2. 深度定制: 当需要更复杂功能时,一键转换为高代码
  3. 持续演进: 利用函数计算 AgentRun 的基础设施能力,持续优化你的 Agent

从想法到上线,从原型到生产,函数计算 AgentRun 始终是你最好的伙伴。欢迎加入“函数计算 AgentRun 客户群”,钉钉群号:134570017218。

快速了解函数计算 AgentRun:

一句话介绍:函数计算 AgentRun 是一个以高代码为核心的一站式 Agentic AI 基础设施平台。秉持生态开放和灵活组装的理念,为企业级 Agent 应用提供从开发、部署到运维的全生命周期管理。

image

函数计算 AgentRun 架构图

AgentRun 运行时基于阿里云函数计算 FC 构建,继承了 Serverless 计算极致弹性、按量付费、零运维的核心优势。通过深度集成 AgentScope、LangChain、RAGFlow、Mem0 等主流开源生态。函数计算 AgentRun 将 Serverless 的极致弹性、零运维和按量付费的特性与 AI 原生应用场景深度融合,助力企业实现成本与效率的极致优化,平均 TCO 降低 60% 。 

开发者只需专注于 Agent 的业务逻辑创新,无需关心底层基础设施, 让 Agentic AI 真正进入企业生产环境。

起因

前些时间整了个备案域名,就想着把一些自建服务迁移回国内,原本我的 Bark 服务器是放在 Cloudflare Workers 上的,于是就想着看看能不能迁移到国内公有云的 Serverless 平台上。

选择 EdgeOne Pages 的原因也很简单,想着也许能够免费用,于是就遇到第一个问题:

问题

问题 1:文档没有描述 KV 的计费规则

我打开腾讯云的文档竟然发现完全没有描述 Pages KV 的计费规则,于是我提出售前工单询问计费规则,客服回复让我加微信群问技术支持……所以这个工单系统的作用是什么,电话总机吗?无奈还是加群问了下,技术支持表示是免费的。就算免费也得写一下吧……那好吧就用这个了,毕竟好像找不到第二个免费的……

问题 2: CLI 中环境变量不能设置为 0

设置环境变量为 0 表示禁用应该是挺常见的用法,一开始设置为 0 不行觉得可能是 JavaScript 0 == '' 的问题(后面一想那参数肯定是字符串啊),于是就试着设置成 "0",还是不行。在网页试了下可以设置,不过难道把环境变量设置为空字符串又是什么禁忌吗?

> npx edgeone pages env set EXAMPLE_KEY 0
[cli][✘] Variable name and value cannot be empty.
> npx edgeone pages env set EXAMPLE_KEY ""
[cli][✘] Variable name and value cannot be empty.
> npx edgeone pages env set EXAMPLE_KEY "0"
[cli][✘] Variable name and value cannot be empty.

问题 3:启动开发环境次数有日限

这个文档里写了,但是没写能开多少次,我这边大概不到 20 次就触发日限额了(热重载不算,但是 Debug 的时候发现热重载不是很即时就反复开了下),只能等第二天。

这个开发环境似乎是远程在腾讯云那边起了三个 Worker ,而且对 KV 的读写会影响到生产环境(这要是真有人在重要生产环境用了怕不是会炸掉)……

问题 4:fetch() 不支持 HTTP/2

最后的推送代码写好的时候,发现请求 APNs 服务器的时候连接会被断开,研究半天发现是 EdgeOne Pages Edge Functions Runtime 的 fetch() 不支持 HTTP/2 ,而 api.push.apple.com 是强制使用 HTTP/2 的。我问了下腾讯的员工,说是在规划中,本来我想着可能我是第一个发现的文档没有提示也不奇怪,后面发现似乎我不是第一个问这个的……

本来觉得又白干一天了,突然想起这个 Edge Pages 还有个 Node Functions 用的是 Node.js Runtime ,于是拿 Node Functions 写了个代理就勉强能用了。开发的过程中发现 Edge Functions 的 Catch-all 路由优先级是高于 Node Functions 所有路由的,只好把 Edge Functions 移动到了一个单独的目录下,当然这文档也没说明。

总结

总而言之,头疼的体验主要来自文档不清晰,其次交流严重依赖 IM 而不是工单系统,最后是非常草台的设计。

这两天技术圈里热议的一件事就是Amazon的流媒体平台Prime Video在2023年3月22日发布了一篇技术博客《规模化Prime Video的音视频监控服务,成本降低90%》,副标题:“从分布式微服务架构到单体应用程序的转变有助于实现更高的规模、弹性和降低成本”,有人把这篇文章在五一期间转到了reddithacker news 上,在Reddit上热议。这种话题与业内推崇的微服务架构形成了鲜明的对比。从“微服务架构”转“单体架构”,还是Amazon干的,这个话题足够劲爆。然后DHH在刚喷完Typescript后继续发文《即便是亚马逊也无法理解Servless或微服务》,继续抨击微服务架构,于是,瞬间引爆技术圈,登上技术圈热搜。

今天上午有好几个朋友在微信里转了三篇文章给我,如下所示:

看看这些标题就知道这些文章要的是流量而不是好好写篇文章。看到第二篇,你还真当 Prime Video 就是 Amazon 的全部么?然后,再看看这些文章后面的跟风评论,我觉得有 80%的人只看标题,而且是连原文都不看的。所以,我想我得写篇文章了……

原文解读

要认清这个问题首先是要认认真真读一读原文,Amazon Prime Video 技术团队的这篇文章并不难读,也没有太多的技术细节,但核心意思如下:

1)这个系统是一个监控系统,用于监控数据千条用户的点播视频流。主要是监控整个视频流运作的质量和效果(比如:视频损坏或是音频不同步等问题),这个监控主要是处理视频帧,所以,他们有一个微服务主要是用来把视频拆分成帧,并临时存在 S3 上,就是下图中的 Media Conversion 服务。

2)为了快速搭建系统,Prime Video团队使用了Serverless 架构,也就是著名的 AWS Lambda 和 AWS Step Functions。前置 Lambda 用来做用户请求的网关,Step Function 用来做监控(探测器),有问题后,就发 SNS 上,Step Function 从 S3 获取 Media Conversion 的数据,然后把运行结果再汇总给一个后置的 Lambda ,并存在 S3 上。

整个架构看上去非常简单 ,一点也不复杂,而且使用了 Serverless 的架构,一点服务器的影子都看不见。实话实说,这样的开发不香吗?我觉得很香啊,方便快捷,完全不理那些无聊的基础设施,直接把代码转成服务,然后用 AWS 的 Lamda + Step Function + SNS + S3 分分钟就搭出一个有模有样的监控系统了,哪里不好了?!

但是他们遇到了一个比较大的问题,就是 AWS Step Function 的伸缩问题,从文章中我看到了两个问题(注意前方高能):

  1. 需要很多很多的并发的 AWS Step Function ,于是达到了帐户的 hard limit。
  2. AWS Step Function 按状态转换收费,所以,贵得受不了了。

注意,这里有两个关键点:1)帐户对 Step Function 有限制,2)Step Function 太贵了用不起

然后,Prime Video 的团队开始解决问题,下面是解决的手段:

1) 把 Media Conversion  和 Step Function 全部写在一个程序里,Media Conversion 跟 Step Function 里的东西通过内存通信,不再走S3了。结果汇总到一个线程中,然后写到 S3.

2)把上面这个单体架构进行分布式部署,还是用之前的 AWS Lambda 来做入门调度。

EC2 的水平扩展没有限制,而且你想买多少 CPU/MEM 的机器由你说了算,而这些视频转码,监控分析的功能感觉就不复杂,本来就应该写在一起,这么做不更香吗?当然更香,比前面的 Serverless 的确更香,因为如下的几个原因:

  1. 不再受 Step Function 的限制了,技术在自己手里,有更大的自由度。
  2. 没有昂贵的 Step Function 云成本的确变得更低了,如果你把 Lambda 换成 Nginx 或 Spring Gateway 或是我司的 Easegress,你把 S3 换成 MinIO,你把 SNS 换成 Kafka,你的成本 还能再低。

独立思考

好了,原文解读完了,你有自己的独立思考了吗?下面是我的独立思考,供你参考:

1)AWS 的 Serverless 也好, 微服务也好,单体也好,在合适的场景也都很香。这就跟汽车一样,跑车,货车,越野车各有各的场景,你用跑车拉货,还是用货车泡妞都不是一个很好的决定。

2)这篇文章中的这个例子中的业务太过简单了,本来就是一两个服务就可以干完的事。就是一个转码加分析的事,要分开的话,就两个微服务就好了(一个转码一个分析),做成流式的。如果不想分,合在一起也没问题了,这个粒度是微服务没毛病。微服务的划分有好些原则,我这里只罗列几个比较重要的原则:

  • 边界上下文。微服务的粒度不能大于领域驱动里的 Bounded Context(具体是什么 大家自行 Google),也就是一个业务域。
  • 单一职责,高内聚,低耦合。把因为相同原因变化的合在一起(内聚),把不同原因变化的分开(解耦)
  • 事务和一致性。对于两个重度依赖的功能,需要完成一个事务和要保证强一致性的,最好不要拆开,要放在一起。
  • 跟组织架构匹配。把同一个团队的东西放在一起,不同团队的分开。

3)Prime Video 遇到的问题不是技术问题,而是 AWS  Step Function 处理能力不足,而且收费还很贵的问题。这个是 AWS 的产品问题,不是技术问题。或者说,这个是Prime Video滥用了Step Function的问题(本来这种大量的数据分析处理就不适合Step Function)。所以,大家不要用一个产品问题来得到微服务架构有问题的结论,这个没有因果关系。试问,如果 Step Funciton 可以无限扩展,性能也很好,而且白菜价,那么 Prime Video 团队还会有动力改成单体吗?他们不会反过来吹爆 Serverless 吗?

4)Prime Video 跟 AWS 是两个独立核算的公司,就像 Amazon 的电商和 AWS 一样,也是两个公司。Amazon 的电商和 AWS 对服务化或是微服务架构的理解和运维,我个人认为这个世界上再也找不到另外一家公司了,包括 Google 或 Microsoft。你有空可以看看本站以前的这篇文章《Steve Yegg对Amazon和Google平台的吐槽》你会了解的更多。

5)Prime Video 这个案例本质上是“下云”,下了 AWS Serverless 的云。云上的成本就是高,一个是费用问题,另一个是被锁定的问题。Prime Video 团队应该很庆幸这个监控系统并不复杂,重写起来也很快,所以,可以很快使用一个更传统的“服务化”+“云计算”的分布式架构,不然,就得像 DHH 那样咬牙下云——《Why We’re Leaving the Cloud》(他们的 SRE 的这篇博文 Our Cloud Spend in 2022说明了下云的困难和节约了多少成本)

后记

最后让我做个我自己的广告。我在过去几年的创业中,帮助了很多公司解决了这些 分布式,微服务,云原生以及云计算成本的问题,如果你也有类似问题。欢迎,跟我联系:[email protected]

另外,我们今年发布了一个平台 MegaEase Cloud,就是想让用户在不失去云计算体验的同时,通过自建高可用基础架构的方式来获得更低的成本(至少降 50%的云计算成本)。目前可以降低成本的方式:

  1. 基础软件:通过开源软件自建,
  2. 内容分发:MinIO + Cloudflare 的免费 CDN,
  3. 马上准备发布的直接与底层IDC合作的廉价GPU计算资源…

欢迎大家试用。

如何访问

注:这两个区完全独立,帐号不互通。因为网络的不可抗力,千万不要跨区使用。

产品演示

介绍文章

 

缘起

只用服务器搭建 memos 未免太大材小用了,而且也浪费钱。所以就想尽量用无服务器部署 memos。

render

render 由于免费存储空间过低,不是优选。

  • 使用 render 创建 Web Service
  • Image:填写为 neosmemo/memos:stable
  • Environment Variables 分别填入:
    • Key、port
    • Value、5230

保活方式: https://github.com/hoochanlon/keep-alive

zeabur

memos 官方镜像按照如图所示填写相关参数

🖼️ 图片加载失败

使用 hu3rror/memos-litestream (该项目解决了备份换机迁移数据的痛点)项目镜像的填写方式

S3 配置如图及相关解答(建议看完该 issue 链接内容): https://github.com/hu3rror/memos-litestream/issues/67

  • b2

  • memos

CF 代理 B2 配置见(适用于图床、文件管理免流服务): https://github.com/hoochanlon/CF-Proxy-B2

这两天技术圈里热议的一件事就是Amazon的流媒体平台Prime Video在2023年3月22日发布了一篇技术博客《规模化Prime Video的音视频监控服务,成本降低90%》,副标题:“从分布式微服务架构到单体应用程序的转变有助于实现更高的规模、弹性和降低成本”,有人把这篇文章在五一期间转到了reddithacker news 上,在Reddit上热议。这种话题与业内推崇的微服务架构形成了鲜明的对比。从“微服务架构”转“单体架构”,还是Amazon干的,这个话题足够劲爆。然后DHH在刚喷完Typescript后继续发文《即便是亚马逊也无法理解Servless或微服务》,继续抨击微服务架构,于是,瞬间引爆技术圈,登上技术圈热搜。

今天上午有好几个朋友在微信里转了三篇文章给我,如下所示:

看看这些标题就知道这些文章要的是流量而不是好好写篇文章。看到第二篇,你还真当 Prime Video 就是 Amazon 的全部么?然后,再看看这些文章后面的跟风评论,我觉得有 80%的人只看标题,而且是连原文都不看的。所以,我想我得写篇文章了……

原文解读

要认清这个问题首先是要认认真真读一读原文,Amazon Prime Video 技术团队的这篇文章并不难读,也没有太多的技术细节,但核心意思如下:

1)这个系统是一个监控系统,用于监控数据千条用户的点播视频流。主要是监控整个视频流运作的质量和效果(比如:视频损坏或是音频不同步等问题),这个监控主要是处理视频帧,所以,他们有一个微服务主要是用来把视频拆分成帧,并临时存在 S3 上,就是下图中的 Media Conversion 服务。

2)为了快速搭建系统,Prime Video团队使用了Serverless 架构,也就是著名的 AWS Lambda 和 AWS Step Functions。前置 Lambda 用来做用户请求的网关,Step Function 用来做监控(探测器),有问题后,就发 SNS 上,Step Function 从 S3 获取 Media Conversion 的数据,然后把运行结果再汇总给一个后置的 Lambda ,并存在 S3 上。

整个架构看上去非常简单 ,一点也不复杂,而且使用了 Serverless 的架构,一点服务器的影子都看不见。实话实说,这样的开发不香吗?我觉得很香啊,方便快捷,完全不理那些无聊的基础设施,直接把代码转成服务,然后用 AWS 的 Lamda + Step Function + SNS + S3 分分钟就搭出一个有模有样的监控系统了,哪里不好了?!

但是他们遇到了一个比较大的问题,就是 AWS Step Function 的伸缩问题,从文章中我看到了两个问题(注意前方高能):

  1. 需要很多很多的并发的 AWS Step Function ,于是达到了帐户的 hard limit。
  2. AWS Step Function 按状态转换收费,所以,贵得受不了了。

注意,这里有两个关键点:1)帐户对 Step Function 有限制,2)Step Function 太贵了用不起

然后,Prime Video 的团队开始解决问题,下面是解决的手段:

1) 把 Media Conversion  和 Step Function 全部写在一个程序里,Media Conversion 跟 Step Function 里的东西通过内存通信,不再走S3了。结果汇总到一个线程中,然后写到 S3.

2)把上面这个单体架构进行分布式部署,还是用之前的 AWS Lambda 来做入门调度。

EC2 的水平扩展没有限制,而且你想买多少 CPU/MEM 的机器由你说了算,而这些视频转码,监控分析的功能感觉就不复杂,本来就应该写在一起,这么做不更香吗?当然更香,比前面的 Serverless 的确更香,因为如下的几个原因:

  1. 不再受 Step Function 的限制了,技术在自己手里,有更大的自由度。
  2. 没有昂贵的 Step Function 云成本的确变得更低了,如果你把 Lambda 换成 Nginx 或 Spring Gateway 或是我司的 Easegress,你把 S3 换成 MinIO,你把 SNS 换成 Kafka,你的成本 还能再低。

独立思考

好了,原文解读完了,你有自己的独立思考了吗?下面是我的独立思考,供你参考:

1)AWS 的 Serverless 也好, 微服务也好,单体也好,在合适的场景也都很香。这就跟汽车一样,跑车,货车,越野车各有各的场景,你用跑车拉货,还是用货车泡妞都不是一个很好的决定。

2)这篇文章中的这个例子中的业务太过简单了,本来就是一两个服务就可以干完的事。就是一个转码加分析的事,要分开的话,就两个微服务就好了(一个转码一个分析),做成流式的。如果不想分,合在一起也没问题了,这个粒度是微服务没毛病。微服务的划分有好些原则,我这里只罗列几个比较重要的原则:

  • 边界上下文。微服务的粒度不能大于领域驱动里的 Bounded Context(具体是什么 大家自行 Google),也就是一个业务域。
  • 单一职责,高内聚,低耦合。把因为相同原因变化的合在一起(内聚),把不同原因变化的分开(解耦)
  • 事务和一致性。对于两个重度依赖的功能,需要完成一个事务和要保证强一致性的,最好不要拆开,要放在一起。
  • 跟组织架构匹配。把同一个团队的东西放在一起,不同团队的分开。

3)Prime Video 遇到的问题不是技术问题,而是 AWS  Step Function 处理能力不足,而且收费还很贵的问题。这个是 AWS 的产品问题,不是技术问题。或者说,这个是Prime Video滥用了Step Function的问题(本来这种大量的数据分析处理就不适合Step Function)。所以,大家不要用一个产品问题来得到微服务架构有问题的结论,这个没有因果关系。试问,如果 Step Funciton 可以无限扩展,性能也很好,而且白菜价,那么 Prime Video 团队还会有动力改成单体吗?他们不会反过来吹爆 Serverless 吗?

4)Prime Video 跟 AWS 是两个独立核算的公司,就像 Amazon 的电商和 AWS 一样,也是两个公司。Amazon 的电商和 AWS 对服务化或是微服务架构的理解和运维,我个人认为这个世界上再也找不到另外一家公司了,包括 Google 或 Microsoft。你有空可以看看本站以前的这篇文章《Steve Yegg对Amazon和Google平台的吐槽》你会了解的更多。

5)Prime Video 这个案例本质上是“下云”,下了 AWS Serverless 的云。云上的成本就是高,一个是费用问题,另一个是被锁定的问题。Prime Video 团队应该很庆幸这个监控系统并不复杂,重写起来也很快,所以,可以很快使用一个更传统的“服务化”+“云计算”的分布式架构,不然,就得像 DHH 那样咬牙下云——《Why We’re Leaving the Cloud》(他们的 SRE 的这篇博文 Our Cloud Spend in 2022说明了下云的困难和节约了多少成本)

后记

最后让我做个我自己的广告。我在过去几年的创业中,帮助了很多公司解决了这些 分布式,微服务,云原生以及云计算成本的问题,如果你也有类似问题。欢迎,跟我联系:[email protected]

另外,我们今年发布了一个平台 MegaEase Cloud,就是想让用户在不失去云计算体验的同时,通过自建高可用基础架构的方式来获得更低的成本(至少降 50%的云计算成本)。目前可以降低成本的方式:

  1. 基础软件:通过开源软件自建,
  2. 内容分发:MinIO + Cloudflare 的免费 CDN,
  3. 马上准备发布的直接与底层IDC合作的廉价GPU计算资源…

欢迎大家试用。

如何访问

注:这两个区完全独立,帐号不互通。因为网络的不可抗力,千万不要跨区使用。

产品演示

介绍文章

 

这两天技术圈里热议的一件事就是Amazon的流媒体平台Prime Video在2023年3月22日发布了一篇技术博客《规模化Prime Video的音视频监控服务,成本降低90%》,副标题:“从分布式微服务架构到单体应用程序的转变有助于实现更高的规模、弹性和降低成本”,有人把这篇文章在五一期间转到了reddithacker news 上,在Reddit上热议。这种话题与业内推崇的微服务架构形成了鲜明的对比。从“微服务架构”转“单体架构”,还是Amazon干的,这个话题足够劲爆。然后DHH在刚喷完Typescript后继续发文《即便是亚马逊也无法理解Servless或微服务》,继续抨击微服务架构,于是,瞬间引爆技术圈,登上技术圈热搜。

今天上午有好几个朋友在微信里转了三篇文章给我,如下所示:

看看这些标题就知道这些文章要的是流量而不是好好写篇文章。看到第二篇,你还真当 Prime Video 就是 Amazon 的全部么?然后,再看看这些文章后面的跟风评论,我觉得有 80%的人只看标题,而且是连原文都不看的。所以,我想我得写篇文章了……

原文解读

要认清这个问题首先是要认认真真读一读原文,Amazon Prime Video 技术团队的这篇文章并不难读,也没有太多的技术细节,但核心意思如下:

1)这个系统是一个监控系统,用于监控数据千条用户的点播视频流。主要是监控整个视频流运作的质量和效果(比如:视频损坏或是音频不同步等问题),这个监控主要是处理视频帧,所以,他们有一个微服务主要是用来把视频拆分成帧,并临时存在 S3 上,就是下图中的 Media Conversion 服务。

2)为了快速搭建系统,Prime Video团队使用了Serverless 架构,也就是著名的 AWS Lambda 和 AWS Step Functions。前置 Lambda 用来做用户请求的网关,Step Function 用来做监控(探测器),有问题后,就发 SNS 上,Step Function 从 S3 获取 Media Conversion 的数据,然后把运行结果再汇总给一个后置的 Lambda ,并存在 S3 上。

整个架构看上去非常简单 ,一点也不复杂,而且使用了 Serverless 的架构,一点服务器的影子都看不见。实话实说,这样的开发不香吗?我觉得很香啊,方便快捷,完全不理那些无聊的基础设施,直接把代码转成服务,然后用 AWS 的 Lamda + Step Function + SNS + S3 分分钟就搭出一个有模有样的监控系统了,哪里不好了?!

但是他们遇到了一个比较大的问题,就是 AWS Step Function 的伸缩问题,从文章中我看到了两个问题(注意前方高能):

  1. 需要很多很多的并发的 AWS Step Function ,于是达到了帐户的 hard limit。
  2. AWS Step Function 按状态转换收费,所以,贵得受不了了。

注意,这里有两个关键点:1)帐户对 Step Function 有限制,2)Step Function 太贵了用不起

然后,Prime Video 的团队开始解决问题,下面是解决的手段:

1) 把 Media Conversion  和 Step Function 全部写在一个程序里,Media Conversion 跟 Step Function 里的东西通过内存通信,不再走S3了。结果汇总到一个线程中,然后写到 S3.

2)把上面这个单体架构进行分布式部署,还是用之前的 AWS Lambda 来做入门调度。

EC2 的水平扩展没有限制,而且你想买多少 CPU/MEM 的机器由你说了算,而这些视频转码,监控分析的功能感觉就不复杂,本来就应该写在一起,这么做不更香吗?当然更香,比前面的 Serverless 的确更香,因为如下的几个原因:

  1. 不再受 Step Function 的限制了,技术在自己手里,有更大的自由度。
  2. 没有昂贵的 Step Function 云成本的确变得更低了,如果你把 Lambda 换成 Nginx 或 Spring Gateway 或是我司的 Easegress,你把 S3 换成 MinIO,你把 SNS 换成 Kafka,你的成本 还能再低。

独立思考

好了,原文解读完了,你有自己的独立思考了吗?下面是我的独立思考,供你参考:

1)AWS 的 Serverless 也好, 微服务也好,单体也好,在合适的场景也都很香。这就跟汽车一样,跑车,货车,越野车各有各的场景,你用跑车拉货,还是用货车泡妞都不是一个很好的决定。

2)这篇文章中的这个例子中的业务太过简单了,本来就是一两个服务就可以干完的事。就是一个转码加分析的事,要分开的话,就两个微服务就好了(一个转码一个分析),做成流式的。如果不想分,合在一起也没问题了,这个粒度是微服务没毛病。微服务的划分有好些原则,我这里只罗列几个比较重要的原则:

  • 边界上下文。微服务的粒度不能大于领域驱动里的 Bounded Context(具体是什么 大家自行 Google),也就是一个业务域。
  • 单一职责,高内聚,低耦合。把因为相同原因变化的合在一起(内聚),把不同原因变化的分开(解耦)
  • 事务和一致性。对于两个重度依赖的功能,需要完成一个事务和要保证强一致性的,最好不要拆开,要放在一起。
  • 跟组织架构匹配。把同一个团队的东西放在一起,不同团队的分开。

3)Prime Video 遇到的问题不是技术问题,而是 AWS  Step Function 处理能力不足,而且收费还很贵的问题。这个是 AWS 的产品问题,不是技术问题。或者说,这个是Prime Video滥用了Step Function的问题(本来这种大量的数据分析处理就不适合Step Function)。所以,大家不要用一个产品问题来得到微服务架构有问题的结论,这个没有因果关系。试问,如果 Step Funciton 可以无限扩展,性能也很好,而且白菜价,那么 Prime Video 团队还会有动力改成单体吗?他们不会反过来吹爆 Serverless 吗?

4)Prime Video 跟 AWS 是两个独立核算的公司,就像 Amazon 的电商和 AWS 一样,也是两个公司。Amazon 的电商和 AWS 对服务化或是微服务架构的理解和运维,我个人认为这个世界上再也找不到另外一家公司了,包括 Google 或 Microsoft。你有空可以看看本站以前的这篇文章《Steve Yegg对Amazon和Google平台的吐槽》你会了解的更多。

5)Prime Video 这个案例本质上是“下云”,下了 AWS Serverless 的云。云上的成本就是高,一个是费用问题,另一个是被锁定的问题。Prime Video 团队应该很庆幸这个监控系统并不复杂,重写起来也很快,所以,可以很快使用一个更传统的“服务化”+“云计算”的分布式架构,不然,就得像 DHH 那样咬牙下云——《Why We’re Leaving the Cloud》(他们的 SRE 的这篇博文 Our Cloud Spend in 2022说明了下云的困难和节约了多少成本)

后记

最后让我做个我自己的广告。我在过去几年的创业中,帮助了很多公司解决了这些 分布式,微服务,云原生以及云计算成本的问题,如果你也有类似问题。欢迎,跟我联系:[email protected]

另外,我们今年发布了一个平台 MegaEase Cloud,就是想让用户在不失去云计算体验的同时,通过自建高可用基础架构的方式来获得更低的成本(至少降 50%的云计算成本)。目前可以降低成本的方式:

  1. 基础软件:通过开源软件自建,
  2. 内容分发:MinIO + Cloudflare 的免费 CDN,
  3. 马上准备发布的直接与底层IDC合作的廉价GPU计算资源…

欢迎大家试用。

如何访问

注:这两个区完全独立,帐号不互通。因为网络的不可抗力,千万不要跨区使用。

产品演示

介绍文章

 

一个朋友分享一下他的大作,我觉得这个 Agent+Serverless 架构在工程层面是一个很棒的实现,希望各位佬友能够指教.

省流

一种远程部署 Agent 的方法:
基于 FileSystem 持久化的无状态容器 Agent 部署架构.
实现 Serverless 部署有状态 Agent,基本无单点故障,成本 500-1000 刀 / 月降到 30 刀 / 月
让 Agent 无痛上云而不必要单点部署!

项目源码

项目简介

为了解决部署 AI Agent 的两难问题:

  • 单机部署有状态但 “不容易负载均衡”“成本高”“各个功能耦合” 问题.
  • Serverless 便宜,很多即开即用的组件,不需要管理底层架构,但每次调用丢失状态 (对话历史等)。

本项目实现 Lambda + S3 + DynamoDB 来部署 Claude Agent,实现成本 30 刀 / 月的有状态 Agent,彻底解决以上问题。

这个架构打破了 "Serverless = 无状态" 的固有观念。通过在 S3 中维持会话历史,Lambda 获得了有状态 Agent 的能力,同时保持按需计费的成本优势。

状态管理不需要绑定在容器上,可以与计算完全分离。结合 DynamoDB 的映射、S3 的持久化、Lambda 的弹性计算,用更少的钱,更耦合的组件实现了更好的可靠性。

适用场景

  • Telegram / 微信 / Slack Bot (本项目用 TelegramBot 做示例的,Client 还可以实现其他)
  • SaaS 应用中的 AI 助手 (需要重新写 Client)
  • 多租户平台

Agent 为什么难以 Serverless 化

Claude Agent SDK 需要维护对话状态,与无状态 API 完全不同:

  • 每个 Agent 需要持久 shell、工作目录、完整对话树
  • Lambda 环境是无状态的:每次调用都是干净环境,/tmp 会被清空
  • 官方推荐四种部署模式中,Hybrid Sessions(临时容器 + 状态恢复)成本最优

项目框架 (这个只是当前我需要集成到 TG, 各位大佬如果有需要可以把 Client 改为其他客户端。欢迎 Fork 或者提 PR 来兼容更多客户端!)

Telegram User → Bot API → API Gateway → Producer Lambda → SQS Queue → Consumer Lambda
                                              ↓                            ↓
                                        Return 200              agent-server Lambda
                                        immediately                        ↓
                                              DynamoDB (Session mapping) + S3 (Session files) + Bedrock (Claude)

参考

本文永久链接

https://forum.beginner.center/t/topic/2575


📌 转载信息
转载时间:
2026/1/6 17:05:44

这两天技术圈里热议的一件事就是Amazon的流媒体平台Prime Video在2023年3月22日发布了一篇技术博客《规模化Prime Video的音视频监控服务,成本降低90%》,副标题:“从分布式微服务架构到单体应用程序的转变有助于实现更高的规模、弹性和降低成本”,有人把这篇文章在五一期间转到了reddithacker news 上,在Reddit上热议。这种话题与业内推崇的微服务架构形成了鲜明的对比。从“微服务架构”转“单体架构”,还是Amazon干的,这个话题足够劲爆。然后DHH在刚喷完Typescript后继续发文《即便是亚马逊也无法理解Servless或微服务》,继续抨击微服务架构,于是,瞬间引爆技术圈,登上技术圈热搜。

今天上午有好几个朋友在微信里转了三篇文章给我,如下所示:

看看这些标题就知道这些文章要的是流量而不是好好写篇文章。看到第二篇,你还真当 Prime Video 就是 Amazon 的全部么?然后,再看看这些文章后面的跟风评论,我觉得有 80%的人只看标题,而且是连原文都不看的。所以,我想我得写篇文章了……

原文解读

要认清这个问题首先是要认认真真读一读原文,Amazon Prime Video 技术团队的这篇文章并不难读,也没有太多的技术细节,但核心意思如下:

1)这个系统是一个监控系统,用于监控数据千条用户的点播视频流。主要是监控整个视频流运作的质量和效果(比如:视频损坏或是音频不同步等问题),这个监控主要是处理视频帧,所以,他们有一个微服务主要是用来把视频拆分成帧,并临时存在 S3 上,就是下图中的 Media Conversion 服务。

2)为了快速搭建系统,Prime Video团队使用了Serverless 架构,也就是著名的 AWS Lambda 和 AWS Step Functions。前置 Lambda 用来做用户请求的网关,Step Function 用来做监控(探测器),有问题后,就发 SNS 上,Step Function 从 S3 获取 Media Conversion 的数据,然后把运行结果再汇总给一个后置的 Lambda ,并存在 S3 上。

整个架构看上去非常简单 ,一点也不复杂,而且使用了 Serverless 的架构,一点服务器的影子都看不见。实话实说,这样的开发不香吗?我觉得很香啊,方便快捷,完全不理那些无聊的基础设施,直接把代码转成服务,然后用 AWS 的 Lamda + Step Function + SNS + S3 分分钟就搭出一个有模有样的监控系统了,哪里不好了?!

但是他们遇到了一个比较大的问题,就是 AWS Step Function 的伸缩问题,从文章中我看到了两个问题(注意前方高能):

  1. 需要很多很多的并发的 AWS Step Function ,于是达到了帐户的 hard limit。
  2. AWS Step Function 按状态转换收费,所以,贵得受不了了。

注意,这里有两个关键点:1)帐户对 Step Function 有限制,2)Step Function 太贵了用不起

然后,Prime Video 的团队开始解决问题,下面是解决的手段:

1) 把 Media Conversion  和 Step Function 全部写在一个程序里,Media Conversion 跟 Step Function 里的东西通过内存通信,不再走S3了。结果汇总到一个线程中,然后写到 S3.

2)把上面这个单体架构进行分布式部署,还是用之前的 AWS Lambda 来做入门调度。

EC2 的水平扩展没有限制,而且你想买多少 CPU/MEM 的机器由你说了算,而这些视频转码,监控分析的功能感觉就不复杂,本来就应该写在一起,这么做不更香吗?当然更香,比前面的 Serverless 的确更香,因为如下的几个原因:

  1. 不再受 Step Function 的限制了,技术在自己手里,有更大的自由度。
  2. 没有昂贵的 Step Function 云成本的确变得更低了,如果你把 Lambda 换成 Nginx 或 Spring Gateway 或是我司的 Easegress,你把 S3 换成 MinIO,你把 SNS 换成 Kafka,你的成本 还能再低。

独立思考

好了,原文解读完了,你有自己的独立思考了吗?下面是我的独立思考,供你参考:

1)AWS 的 Serverless 也好, 微服务也好,单体也好,在合适的场景也都很香。这就跟汽车一样,跑车,货车,越野车各有各的场景,你用跑车拉货,还是用货车泡妞都不是一个很好的决定。

2)这篇文章中的这个例子中的业务太过简单了,本来就是一两个服务就可以干完的事。就是一个转码加分析的事,要分开的话,就两个微服务就好了(一个转码一个分析),做成流式的。如果不想分,合在一起也没问题了,这个粒度是微服务没毛病。微服务的划分有好些原则,我这里只罗列几个比较重要的原则:

  • 边界上下文。微服务的粒度不能大于领域驱动里的 Bounded Context(具体是什么 大家自行 Google),也就是一个业务域。
  • 单一职责,高内聚,低耦合。把因为相同原因变化的合在一起(内聚),把不同原因变化的分开(解耦)
  • 事务和一致性。对于两个重度依赖的功能,需要完成一个事务和要保证强一致性的,最好不要拆开,要放在一起。
  • 跟组织架构匹配。把同一个团队的东西放在一起,不同团队的分开。

3)Prime Video 遇到的问题不是技术问题,而是 AWS  Step Function 处理能力不足,而且收费还很贵的问题。这个是 AWS 的产品问题,不是技术问题。或者说,这个是Prime Video滥用了Step Function的问题(本来这种大量的数据分析处理就不适合Step Function)。所以,大家不要用一个产品问题来得到微服务架构有问题的结论,这个没有因果关系。试问,如果 Step Funciton 可以无限扩展,性能也很好,而且白菜价,那么 Prime Video 团队还会有动力改成单体吗?他们不会反过来吹爆 Serverless 吗?

4)Prime Video 跟 AWS 是两个独立核算的公司,就像 Amazon 的电商和 AWS 一样,也是两个公司。Amazon 的电商和 AWS 对服务化或是微服务架构的理解和运维,我个人认为这个世界上再也找不到另外一家公司了,包括 Google 或 Microsoft。你有空可以看看本站以前的这篇文章《Steve Yegg对Amazon和Google平台的吐槽》你会了解的更多。

5)Prime Video 这个案例本质上是“下云”,下了 AWS Serverless 的云。云上的成本就是高,一个是费用问题,另一个是被锁定的问题。Prime Video 团队应该很庆幸这个监控系统并不复杂,重写起来也很快,所以,可以很快使用一个更传统的“服务化”+“云计算”的分布式架构,不然,就得像 DHH 那样咬牙下云——《Why We’re Leaving the Cloud》(他们的 SRE 的这篇博文 Our Cloud Spend in 2022说明了下云的困难和节约了多少成本)

后记

最后让我做个我自己的广告。我在过去几年的创业中,帮助了很多公司解决了这些 分布式,微服务,云原生以及云计算成本的问题,如果你也有类似问题。欢迎,跟我联系:[email protected]

另外,我们今年发布了一个平台 MegaEase Cloud,就是想让用户在不失去云计算体验的同时,通过自建高可用基础架构的方式来获得更低的成本(至少降 50%的云计算成本)。目前可以降低成本的方式:

  1. 基础软件:通过开源软件自建,
  2. 内容分发:MinIO + Cloudflare 的免费 CDN,
  3. 马上准备发布的直接与底层IDC合作的廉价GPU计算资源…

欢迎大家试用。

如何访问

注:这两个区完全独立,帐号不互通。因为网络的不可抗力,千万不要跨区使用。

产品演示

介绍文章

 

这两天技术圈里热议的一件事就是Amazon的流媒体平台Prime Video在2023年3月22日发布了一篇技术博客《规模化Prime Video的音视频监控服务,成本降低90%》,副标题:“从分布式微服务架构到单体应用程序的转变有助于实现更高的规模、弹性和降低成本”,有人把这篇文章在五一期间转到了reddithacker news 上,在Reddit上热议。这种话题与业内推崇的微服务架构形成了鲜明的对比。从“微服务架构”转“单体架构”,还是Amazon干的,这个话题足够劲爆。然后DHH在刚喷完Typescript后继续发文《即便是亚马逊也无法理解Servless或微服务》,继续抨击微服务架构,于是,瞬间引爆技术圈,登上技术圈热搜。

今天上午有好几个朋友在微信里转了三篇文章给我,如下所示:

看看这些标题就知道这些文章要的是流量而不是好好写篇文章。看到第二篇,你还真当 Prime Video 就是 Amazon 的全部么?然后,再看看这些文章后面的跟风评论,我觉得有 80%的人只看标题,而且是连原文都不看的。所以,我想我得写篇文章了……

原文解读

要认清这个问题首先是要认认真真读一读原文,Amazon Prime Video 技术团队的这篇文章并不难读,也没有太多的技术细节,但核心意思如下:

1)这个系统是一个监控系统,用于监控数据千条用户的点播视频流。主要是监控整个视频流运作的质量和效果(比如:视频损坏或是音频不同步等问题),这个监控主要是处理视频帧,所以,他们有一个微服务主要是用来把视频拆分成帧,并临时存在 S3 上,就是下图中的 Media Conversion 服务。

2)为了快速搭建系统,Prime Video团队使用了Serverless 架构,也就是著名的 AWS Lambda 和 AWS Step Functions。前置 Lambda 用来做用户请求的网关,Step Function 用来做监控(探测器),有问题后,就发 SNS 上,Step Function 从 S3 获取 Media Conversion 的数据,然后把运行结果再汇总给一个后置的 Lambda ,并存在 S3 上。

整个架构看上去非常简单 ,一点也不复杂,而且使用了 Serverless 的架构,一点服务器的影子都看不见。实话实说,这样的开发不香吗?我觉得很香啊,方便快捷,完全不理那些无聊的基础设施,直接把代码转成服务,然后用 AWS 的 Lamda + Step Function + SNS + S3 分分钟就搭出一个有模有样的监控系统了,哪里不好了?!

但是他们遇到了一个比较大的问题,就是 AWS Step Function 的伸缩问题,从文章中我看到了两个问题(注意前方高能):

  1. 需要很多很多的并发的 AWS Step Function ,于是达到了帐户的 hard limit。
  2. AWS Step Function 按状态转换收费,所以,贵得受不了了。

注意,这里有两个关键点:1)帐户对 Step Function 有限制,2)Step Function 太贵了用不起

然后,Prime Video 的团队开始解决问题,下面是解决的手段:

1) 把 Media Conversion  和 Step Function 全部写在一个程序里,Media Conversion 跟 Step Function 里的东西通过内存通信,不再走S3了。结果汇总到一个线程中,然后写到 S3.

2)把上面这个单体架构进行分布式部署,还是用之前的 AWS Lambda 来做入门调度。

EC2 的水平扩展没有限制,而且你想买多少 CPU/MEM 的机器由你说了算,而这些视频转码,监控分析的功能感觉就不复杂,本来就应该写在一起,这么做不更香吗?当然更香,比前面的 Serverless 的确更香,因为如下的几个原因:

  1. 不再受 Step Function 的限制了,技术在自己手里,有更大的自由度。
  2. 没有昂贵的 Step Function 云成本的确变得更低了,如果你把 Lambda 换成 Nginx 或 Spring Gateway 或是我司的 Easegress,你把 S3 换成 MinIO,你把 SNS 换成 Kafka,你的成本 还能再低。

独立思考

好了,原文解读完了,你有自己的独立思考了吗?下面是我的独立思考,供你参考:

1)AWS 的 Serverless 也好, 微服务也好,单体也好,在合适的场景也都很香。这就跟汽车一样,跑车,货车,越野车各有各的场景,你用跑车拉货,还是用货车泡妞都不是一个很好的决定。

2)这篇文章中的这个例子中的业务太过简单了,本来就是一两个服务就可以干完的事。就是一个转码加分析的事,要分开的话,就两个微服务就好了(一个转码一个分析),做成流式的。如果不想分,合在一起也没问题了,这个粒度是微服务没毛病。微服务的划分有好些原则,我这里只罗列几个比较重要的原则:

  • 边界上下文。微服务的粒度不能大于领域驱动里的 Bounded Context(具体是什么 大家自行 Google),也就是一个业务域。
  • 单一职责,高内聚,低耦合。把因为相同原因变化的合在一起(内聚),把不同原因变化的分开(解耦)
  • 事务和一致性。对于两个重度依赖的功能,需要完成一个事务和要保证强一致性的,最好不要拆开,要放在一起。
  • 跟组织架构匹配。把同一个团队的东西放在一起,不同团队的分开。

3)Prime Video 遇到的问题不是技术问题,而是 AWS  Step Function 处理能力不足,而且收费还很贵的问题。这个是 AWS 的产品问题,不是技术问题。或者说,这个是Prime Video滥用了Step Function的问题(本来这种大量的数据分析处理就不适合Step Function)。所以,大家不要用一个产品问题来得到微服务架构有问题的结论,这个没有因果关系。试问,如果 Step Funciton 可以无限扩展,性能也很好,而且白菜价,那么 Prime Video 团队还会有动力改成单体吗?他们不会反过来吹爆 Serverless 吗?

4)Prime Video 跟 AWS 是两个独立核算的公司,就像 Amazon 的电商和 AWS 一样,也是两个公司。Amazon 的电商和 AWS 对服务化或是微服务架构的理解和运维,我个人认为这个世界上再也找不到另外一家公司了,包括 Google 或 Microsoft。你有空可以看看本站以前的这篇文章《Steve Yegg对Amazon和Google平台的吐槽》你会了解的更多。

5)Prime Video 这个案例本质上是“下云”,下了 AWS Serverless 的云。云上的成本就是高,一个是费用问题,另一个是被锁定的问题。Prime Video 团队应该很庆幸这个监控系统并不复杂,重写起来也很快,所以,可以很快使用一个更传统的“服务化”+“云计算”的分布式架构,不然,就得像 DHH 那样咬牙下云——《Why We’re Leaving the Cloud》(他们的 SRE 的这篇博文 Our Cloud Spend in 2022说明了下云的困难和节约了多少成本)

后记

最后让我做个我自己的广告。我在过去几年的创业中,帮助了很多公司解决了这些 分布式,微服务,云原生以及云计算成本的问题,如果你也有类似问题。欢迎,跟我联系:[email protected]

另外,我们今年发布了一个平台 MegaEase Cloud,就是想让用户在不失去云计算体验的同时,通过自建高可用基础架构的方式来获得更低的成本(至少降 50%的云计算成本)。目前可以降低成本的方式:

  1. 基础软件:通过开源软件自建,
  2. 内容分发:MinIO + Cloudflare 的免费 CDN,
  3. 马上准备发布的直接与底层IDC合作的廉价GPU计算资源…

欢迎大家试用。

如何访问

注:这两个区完全独立,帐号不互通。因为网络的不可抗力,千万不要跨区使用。

产品演示

介绍文章

 

(全文完)

(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)

好烂啊有点差凑合看看还不错很精彩 (647 人打了分,平均分: 4.32 )

Loading...