ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

云原生架构下AI能力集成:Chrome Skills在腾讯云的部署实践

云原生架构下AI能力集成:Chrome Skills在腾讯云的部署实践 1. 项目概述当浏览器长出“AI大脑”最近我参与了一个挺有意思的项目核心是把一个叫“Chrome Skills”的东西部署到了腾讯云上。这名字听起来有点玄乎简单说它不是一个浏览器插件而是一套能让浏览器本身变得更“聪明”的AI能力集。你可以把它想象成给Chrome浏览器装上了一颗“云原生”的AI大脑。过去我们想在浏览器里实现一些智能功能比如自动总结网页、实时翻译、智能填表往往依赖于一个个独立的插件它们各自为战占用资源还涉及隐私问题。而Chrome Skills的思路是将这些通用的AI能力沉淀为浏览器底层可调用的标准化“技能”通过云端统一的架构来提供支持。这次实践的关键词是“云原生架构”。这意味着我们不是简单地把一个AI服务扔到云服务器上就完事了而是充分利用了容器化、微服务、动态编排、服务网格这些云原生的核心思想和工具链来构建一个高可用、弹性伸缩、易于维护的AI能力交付平台。选择腾讯云作为承载平台一方面是看中其在国内完善的云产品生态和稳定的网络环境另一方面也是想探索在公有云上实现这类前沿浏览器增强功能的最佳路径。整个过程涉及从本地原型到云端生产环境的完整链路包括镜像构建、服务部署、网络打通、监控运维等一系列实操环节其中踩过的坑和总结的经验对于任何想将复杂应用云原生化落地的团队都有不小的参考价值。2. 核心架构设计与技术选型2.1 为什么是云原生传统架构的瓶颈在项目初期我们评估过几种方案。最直接的是单体应用部署把所有AI模型和服务打包成一个大的应用扔到一台云服务器上。这种方案简单粗暴但问题很快暴露资源利用率低CPU/GPU负载不均衡、难以扩展一个功能卡住影响全部、升级维护风险高牵一发而动全身。另一种是传统的虚拟机部署微服务虽然解耦了服务但在弹性伸缩、快速部署和统一运维上依然笨重。云原生架构的优势在这里就凸显出来了。它的核心是以容器为交付单元以微服务为架构模式以动态编排为管理手段。对于Chrome Skills这种由多个独立AI技能如OCR、NLP、语音识别组成的系统每个技能都可以作为一个独立的微服务进行开发、部署和伸缩。当用户大量使用翻译技能时我们可以快速扩容翻译服务实例而总结服务可以保持最小副本资源按需分配成本最优。我们选择腾讯云正是因为它提供了完整的云原生技术栈容器服务TKE用于托管和编排我们的微服务容器镜像服务TCR用于安全、高速地存储和分发Docker镜像云监控和日志服务CLS用于洞察系统运行状态再加上负载均衡CLB、私有网络VPC等构成了一个生产就绪的底座。这避免了从零自建Kubernetes集群的运维复杂度让我们能更专注于业务逻辑本身。2.2 Chrome Skills的微服务拆分策略Chrome Skills不是一个单一服务而是一个技能集市。我们的拆分原则遵循“高内聚、低耦合”和“独立伸缩”。技能网关服务这是唯一的入口。它接收来自浏览器扩展一个轻量级的客户端的请求根据请求中的技能标识如skill:summarize将请求路由到后面对应的具体技能微服务。它还负责统一的认证鉴权、限流熔断和请求日志记录。我们使用Go语言编写看重其高并发性能和低资源占用。具体技能微服务文本总结服务基于Transformer模型如BART、T5接收长文本输出摘要。该服务对CPU和内存要求较高尤其在处理长文档时。实时翻译服务集成腾讯云自己的机器翻译TMT API作为后端考虑到效果和合规自身主要做请求代理、格式转换和缓存。这个服务网络I/O密集。智能划词服务结合NLP实体识别和知识图谱对用户选中的文本提供解释、相关链接等。计算量相对较小但要求低延迟。OCR识别服务处理浏览器内截图或上传图片的文字识别。需要GPU支持以获得更快的速度我们使用了腾讯云TKE的GPU节点池。公共支撑服务模型管理服务负责AI模型的版本管理、热加载和A/B测试。当文本总结模型有更新时通过此服务平滑切换到新版本无需重启服务。用户配置与状态服务存储用户的技能偏好设置、使用历史等。采用腾讯云数据库TDSQLMySQL版利用其高可用特性。异步任务队列对于一些耗时的技能如处理超长视频的语音转文字请求会被放入消息队列腾讯云CMQ由后台工作进程异步处理再通过WebSocket通知前端。每个服务都打包成独立的Docker镜像通过GitLab CI/CD流水线自动构建并推送至腾讯云容器镜像服务TCR。2.3 腾讯云产品矩阵的精准选用在腾讯云上我们像搭积木一样选用服务核心原则是“托管服务优先自建次之”。计算与编排TKE 节点池使用腾讯云容器服务TKE托管Kubernetes集群。我们创建了多个节点池一个“常规CPU池”运行网关、配置等服务一个“高CPU池”给文本总结服务一个“GPU池”配备NVIDIA T4卡专供OCR和图像类AI服务。TKE的自动伸缩功能可以根据CPU/GPU利用率动态调整节点数量完美应对流量波动。镜像与交付TCR将Docker镜像存放在腾讯云容器镜像服务TCR的私有命名空间内。TCR与TKE同地域内网访问拉取镜像速度极快且支持安全扫描和镜像同步保障了交付链的安全与高效。网络与暴露VPC CLB Ingress所有资源部署在同一私有网络VPC内确保内网通信安全高速。对外我们使用腾讯云负载均衡CLB四层暴露TKE集群的入口。在集群内部使用Nginx Ingress Controller七层作为技能网关服务的流量入口实现基于路径如/api/skill/summarize的路由和SSL终止。存储与数据TDSQL COS用户结构化数据配置、元数据存入TDSQL for MySQL。用户上传的待处理图片、音频等临时文件则存储到腾讯云对象存储COS并通过预签名URL让技能服务安全访问避免大文件穿透业务服务。可观测性CLS 云监控所有服务的应用日志统一采集到腾讯云日志服务CLS便于故障排查和审计。业务指标如请求量、延迟、错误率通过Prometheus采集并在腾讯云监控上配置仪表盘和告警策略。注意成本优化考量GPU节点成本高昂。我们通过给OCR服务配置HPA水平Pod自动伸缩并设置较低的副本数下限如1个在夜间低峰期自动缩容白天高峰前提前扩容有效控制了成本。同时对于翻译这类调用外部API的服务我们增加了本地缓存层使用Redis对相同内容短时间内的重复请求直接返回缓存结果既降低了延迟又节省了API调用费用。3. 核心实现细节与部署实操3.1 Docker镜像构建的最佳实践镜像构建是云原生应用的起点。我们的目标是构建体积小、层数少、安全的镜像。以文本总结服务Python为例最初的Dockerfile简单粗暴地COPY . /app然后pip install -r requirements.txt。这会导致镜像巨大超过2GB且每次代码变更都会导致整个依赖层重建构建缓慢。优化后的Dockerfile采用多阶段构建# 第一阶段构建依赖 FROM python:3.9-slim as builder WORKDIR /app COPY requirements.txt . RUN pip install --user --no-cache-dir -r requirements.txt # 第二阶段运行环境 FROM python:3.9-slim WORKDIR /app # 从builder阶段拷贝已安装的Python包 COPY --frombuilder /root/.local /root/.local # 确保pip安装的包在路径中 ENV PATH/root/.local/bin:$PATH # 拷贝应用代码 COPY . . # 创建非root用户运行增强安全 RUN useradd -m -u 1000 appuser chown -R appuser:appuser /app USER appuser EXPOSE 8080 CMD [gunicorn, -w, 4, -b, 0.0.0.0:8080, app:app]这样最终的镜像只包含运行所需的Python解释器、依赖包和我们的代码体积缩小了60%以上。requirements.txt文件被精确管理只包含生产环境必需的包。实操心得.dockerignore文件至关重要。一定要创建.dockerignore文件排除.git,__pycache__,*.log,Dockerfile,README.md等无关文件。这能加速构建过程并避免敏感信息如本地配置文件意外打入镜像。3.2 Kubernetes资源配置清单详解将服务部署到TKE需要编写Kubernetes的YAML清单。我们以技能网关服务为例展示一个生产可用的Deployment和Service配置。deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: skills-gateway namespace: production labels: app: skills-gateway spec: replicas: 3 # 初始副本数结合HPA动态调整 selector: matchLabels: app: skills-gateway template: metadata: labels: app: skills-gateway spec: containers: - name: gateway image: ccr.ccs.tencentyun.com/my-namespace/skills-gateway:v1.2.0 # TCR镜像地址 ports: - containerPort: 8080 resources: requests: memory: 256Mi cpu: 250m limits: memory: 512Mi cpu: 500m livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /readyz port: 8080 initialDelaySeconds: 5 periodSeconds: 5 env: - name: REDIS_ADDR valueFrom: configMapKeyRef: name: app-config key: redis.address - name: LOG_LEVEL value: info volumeMounts: - name: config-volume mountPath: /app/config volumes: - name: config-volume configMap: name: gateway-configservice.yaml:apiVersion: v1 kind: Service metadata: name: skills-gateway-svc namespace: production spec: selector: app: skills-gateway ports: - port: 80 # Service对外端口 targetPort: 8080 # 容器端口 protocol: TCP type: ClusterIP # 内部服务发现由Ingress对外暴露关键点解析资源请求与限制requests是调度依据limits是硬性上限。合理设置能提高集群资源利用率防止单个Pod“饿死”邻居或“撑爆”节点。健康检查livenessProbe失败会重启PodreadinessProbe失败会将Pod从Service的负载均衡端点中移除。这是实现服务自愈和零停机部署的关键。配置分离将Redis地址等配置通过ConfigMap注入而非写死在代码或镜像中便于不同环境开发、测试、生产的切换。镜像标签使用明确的版本号v1.2.0而非latest确保每次部署版本可控便于回滚。3.3 Ingress与域名配置实战为了让外部用户能通过域名访问我们的服务我们在TKE集群中部署了Nginx Ingress Controller并配置了Ingress规则。首先在腾讯云TKE控制台的应用市场中一键部署“Nginx Ingress Controller”。它会自动创建一个公网CLB并将CLB的VIP虚拟IP作为入口。然后创建Ingress资源定义ingress.yamlapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: skills-ingress namespace: production annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/proxy-body-size: 20m # 允许上传大文件 spec: tls: - hosts: - skills-api.mycompany.com secretName: skills-tls-secret # 存放SSL证书的Secret rules: - host: skills-api.mycompany.com http: paths: - path: /api/skills(/|$)(.*) pathType: Prefix backend: service: name: skills-gateway-svc port: number: 80这个配置意味着所有发送到https://skills-api.mycompany.com/api/skills/...的请求都会被转发到集群内的skills-gateway-svc服务。我们在腾讯云SSL证书控制台申请了免费证书下载后通过kubectl create secret tls命令创建了skills-tls-secret。最后将域名skills-api.mycompany.com的CNAME记录解析到Ingress Controller对应的CLB的VIP地址。至此公网用户就可以通过HTTPS安全地访问我们的Chrome Skills API了。4. 持续集成与持续部署流水线自动化是云原生实践的灵魂。我们基于GitLab CI/CD构建了从代码提交到生产环境部署的全自动流水线。.gitlab-ci.yml核心阶段如下stages: - test - build - push - deploy-staging - deploy-production variables: IMAGE_TAG: $CI_COMMIT_SHORT_SHA # 使用提交哈希作为镜像标签 # 1. 测试阶段 unit-test: stage: test image: python:3.9-slim script: - pip install -r requirements.txt - pytest tests/ --covapp --cov-reportxml artifacts: reports: coverage_report: coverage_format: cobertura path: coverage.xml # 2. 构建Docker镜像 build-image: stage: build image: docker:20.10 services: - docker:20.10-dind script: - docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG . - docker build -t $CI_REGISTRY_IMAGE:latest . # 同时打latest标签用于开发环境 only: - main - develop # 3. 推送镜像到腾讯云TCR push-image: stage: push image: docker:20.10 services: - docker:20.10-dind script: - echo $TENCENT_REGISTRY_PASSWORD | docker login ccr.ccs.tencentyun.com --username $TENCENT_REGISTRY_USERNAME --password-stdin - docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG - docker push $CI_REGISTRY_IMAGE:latest only: - main - develop # 4. 部署到预发布环境 deploy-staging: stage: deploy-staging image: bitnami/kubectl:latest script: - kubectl config use-context tke-staging-cluster - kubectl set image deployment/skills-gateway gateway$CI_REGISTRY_IMAGE:$IMAGE_TAG -n staging - kubectl rollout status deployment/skills-gateway -n staging --timeout120s environment: name: staging only: - develop # develop分支合并后自动部署到staging # 5. 手动触发部署生产环境 deploy-production: stage: deploy-production image: bitnami/kubectl:latest script: - kubectl config use-context tke-production-cluster - kubectl set image deployment/skills-gateway gateway$CI_REGISTRY_IMAGE:$IMAGE_TAG -n production - kubectl rollout status deployment/skills-gateway -n production --timeout180s environment: name: production when: manual # 生产环境部署需要手动点击触发 only: - main # 仅对main分支生效流水线亮点与避坑点安全凭证管理腾讯云TCR的登录密码、Kubernetes集群的kubeconfig文件都以“变量”的形式存储在GitLab的CI/CD设置中而非代码里。金丝雀发布生产环境部署并非简单的set image。我们后来升级为更高级的策略通过修改Deployment的YAML采用RollingUpdate策略并配置maxSurge和maxUnavailable来控制滚动更新的节奏实现无缝升级。环境隔离我们为 staging 和 production 环境配置了不同的Kubernetes上下文context在流水线中切换确保操作隔离。5. 监控、日志与问题排查实录系统上线后可观测性就成了生命线。我们主要从三个维度进行监控基础设施、应用性能、业务指标。5.1 基础设施监控利用腾讯云监控我们为TKE集群和节点配置了基础告警节点CPU/内存使用率 80% 持续5分钟。节点磁盘使用率 85%。Pod异常重启频繁重启可能意味着应用有bug或内存不足。5.2 应用性能监控我们在每个技能服务的代码中集成了Prometheus客户端库如Python的prometheus_client暴露了如下关键指标http_request_duration_seconds请求耗时直方图用于计算P50, P95, P99延迟。http_requests_total请求总数按状态码分类。skill_processing_duration_seconds具体AI技能的处理耗时。external_api_call_duration调用腾讯云TMT等外部API的耗时。这些指标被集群内部署的Prometheus Server抓取并通过Grafana展示。我们设置了一个核心告警P95延迟超过500ms持续2分钟这往往意味着服务可能正在排队或遇到性能瓶颈。5.3 集中式日志收集所有服务都将日志输出到标准输出stdout和标准错误stderr。TKE的日志采集组件会自动收集这些日志并发送到腾讯云日志服务CLS。在CLS中我们为不同服务创建了不同的日志主题并设置了索引。当用户反馈“翻译失败”时我们可以在CLS控制台选择“翻译服务”日志主题。搜索关键词ERROR或失败请求的request_id。通过上下文查看完整的错误堆栈和当时的请求参数快速定位是网络超时、API密钥失效还是输入内容异常。5.4 典型问题排查案例案例一深夜CPU使用率飙升告警现象凌晨2点收到“文本总结服务CPU使用率超过90%”的告警。排查登录Grafana查看该服务的QPS每秒查询率图表发现请求量并未增加。查看该服务Pod的日志CLS发现大量Out of Memory错误前的GC垃圾回收日志。检查部署配置发现该服务Pod的内存limit设置为1GB但request只有256MB。Kubernetes调度时只保证request该节点可能内存已紧张。进一步检查发现同一个节点上被调度了一个新部署的、内存消耗大的批处理任务Pod。根因与解决根本原因是节点内存资源竞争导致我们的服务因内存不足而被系统频繁终止和重启OOMKilled重启过程消耗大量CPU。解决方案有两个一是调整该服务的memory request到512MB使其调度到更宽松的节点二是为不同优先级的服务配置不同的节点池或使用Kubernetes的priorityClass。经验固化此后我们规定所有服务的request和limit必须经过压测后谨慎设置且两者比值不宜过大通常limit不超过request的2倍。案例二特定用户翻译请求超时现象个别用户反馈翻译功能经常超时但其他用户正常。排查在CLS中用该用户的ID过滤翻译服务日志发现其请求的目标语言多为“藏语”等小语种。检查翻译服务的代码和配置发现我们调用的腾讯云TMT API对于小语种是异步处理的默认超时时间设置较短5秒而异步处理可能超过这个时间。查看服务监控发现调用TMT小语种接口的P99延迟高达8秒。解决调整翻译服务中调用TMT异步接口的超时时间至15秒并在客户端浏览器扩展侧对这类可能耗时的操作增加“处理中”的友好提示避免用户误认为失败。更深层优化我们为小语种翻译增加了本地缓存并将用户频繁翻译的句子即使语种不同也纳入缓存策略进一步降低对API的依赖和延迟。6. 安全与成本治理实践6.1 安全加固措施镜像安全在CI流水线中集成镜像安全扫描工具如Trivy扫描Docker镜像中的已知漏洞只有扫描通过的镜像才能被推送到TCR。网络策略在Kubernetes中启用并配置NetworkPolicy实现微服务间的网络隔离。例如只允许技能网关服务访问具体的技能服务技能服务之间默认不能互相访问。密钥管理腾讯云TMT API的密钥等敏感信息使用腾讯云“密钥管理系统SSM”来存储和管理在Pod启动时通过环境变量注入而非写在配置文件中。API安全技能网关对所有入站请求进行JWT令牌验证并实施基于令牌的速率限制防止API滥用。6.2 成本控制与优化云原生虽好但成本可能失控。我们建立了以下机制资源配额与限制在Kubernetes命名空间级别设置ResourceQuota限制整个Chrome Skills项目可使用的总CPU、内存量防止资源无限扩张。HPA与弹性伸缩为所有无状态服务配置了基于CPU/内存利用率的HPA。但需要谨慎设置阈值避免因瞬间流量毛刺导致集群过度扩容。我们通常将扩容阈值设在70%缩容阈值设在30%并设置稳定窗口时间。GPU资源池化与共享GPU节点成本极高。我们探索了使用NVIDIA MIG技术将一块物理GPU切分给多个Pod使用或者使用基于时间的GPU调度策略让非关键任务在夜间低谷期运行。定期资源审计每月使用腾讯云的成本分析工具查看TKE集群、COS存储、公网流量等各项费用的明细。我们发现日志存储CLS费用增长较快于是调整了日志的保存周期从永久改为30天并对不重要的DEBUG级别日志进行采样收集费用立减40%。将Chrome Skills这套浏览器AI能力以云原生架构部署在腾讯云上是一次从技术理念到工程实践的完整闭环。它不仅仅是“上云”更是通过容器化、微服务、动态编排和丰富的云服务构建了一个弹性、可靠、可观测、可持续进化的现代化应用平台。过程中最大的体会是云原生带来的不仅是部署方式的改变更是团队协作、运维理念和成本意识的全面升级。每一个YAML文件、每一条监控告警、每一次流水线执行都是这个系统稳健运行的基石。对于后来者我的建议是从小处着手定义一个清晰的服务边界重视可观测性建设并始终将安全和成本纳入设计和运维的每一个环节。这条路没有银弹但每一步扎实的实践都会让系统更强大也让团队更从容。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进