前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版

微信云托管入门与实践

首页2022-06-19 12:30:41Front-End
部署云托管小程序Docker

给小程序做后端,最烦的从来不是写业务,是那一堆跟业务无关的事。买服务器、配 nginx、申请 HTTPS 证书、写进程守护、处理 access_token 的获取和续期、做接口鉴权。真正写代码的时间可能只占三分之一。

微信云托管想解决的就是这段。你给它一个 Dockerfile,它负责构建、部署、扩缩容、日志、域名和 HTTPS。更关键的是,跑在上面的服务能直接免鉴权调微信开放接口,access_token 由平台推到容器里,你从文件读一下就能用,不用自己维护有效期,也不用把密钥带在身上。

这篇是我把一个 koa 服务从本地调试跑到云托管上线的完整记录。包括模板部署、自定义部署、CLI 工具、VSCode 里的本地 docker 调试和实时开发,以及云调用怎么用来访问内容安全接口、调小程序云函数、生成小程序码。中间标出了几个真的卡住过我的地方,比如调试容器端口对不上、X-WX-SERVICE 填错、云调用白名单前缀怎么写。

在本篇文章中,我们将从浅入深,和大家一起学习以下知识:

  • 微信云托管和微信云开发的定位差别,什么项目该选哪个
  • 容器时区差 8 小时的成因和 Dockerfile 里的修法
  • 模板一键部署,以及小程序端 wx.cloud.callContainer 怎么调
  • 自定义部署 Nestjs 的完整流程,构建日志怎么看
  • CLI 工具的密钥怎么生成,能做哪些事
  • VSCode 插件本地起容器调试,两个端口分别是干嘛的
  • 微信开发者工具 Attach 到本地容器,在模拟器里调真实链路
  • Live Coding 实时开发,改代码不用重建容器
  • 云调用的原理,access_token 挂载在容器哪个路径
  • 用云调用访问文字安全检测、小程序云函数、获取小程序码三个实例

# 一、微信云托管是什么

# 定位和能力

  • 微信云托管 是微信团队提供的以云原生为基础的,免运维、高可用服务上云解决方案,无需服务器,1分钟即可部署小程序/公众号服务端。
  • 微信云托管支持目前绝大多数语言/框架项目,开发者可以从服务器平滑迁移;并且微信云托管的自动运维和扩缩容特性,无需开发者关心服务的可用性,专注于业务,极大节省人力和服务资源成本。
  • 同时,微信云托管还集成持续交付部署,DevOps自动化,安全鉴权等众多能力,致力于帮助没有深层运维经验的业务开发者和研发团队,用最低的成本,打造出稳定性高,安全性强的后端服务。
  • 最重要的,微信云托管与微信生态深度融合,具有免鉴权,云调用,消息推送,微信支付等众多微信优势特性,开发者可以非常轻松和高效的完成互通,并且在安全、可靠性方面有微信团队的专业保障。

这四条里,我认为真正拉开差距的是最后一条。前面三条本质是运维托管,别的云厂商也能提供;「与微信生态深度融合」这件事只有微信自己能做,具体落到免鉴权的云调用上,后面第六节会专门展开。

微信云托管的产品能力概览

这张图是官方的能力概览,容器托管、存储、微信生态、监控告警这几块的划分能建立个整体印象。看不清细节没关系,下面每一块后面都会实际用到。

# 架构特点

微信云托管以容器服务为核心,提供方便易用的存储体系、微信生态、安全鉴权等服务能力;搭配简单易懂的操作面板,集成资源监控,资源告警,流水线等自动化功能,是一站式的后端云服务。

微信云托管使用目前主流的容器平台Docker以及容器编排技术Kubernetes(简称K8S),来管理你的项目

微信云托管基于 Docker 和 Kubernetes 的架构图

「底层是 Docker 加 K8S」这句话对使用者来说有几个实际含义,值得展开。

第一,你的部署单位是镜像,构建规则写在 Dockerfile 里,所以本地能用 docker build 跑起来的东西,基本原样就能上云托管。迁移成本极低,这是它相对云函数最大的优势。

第二,实例是可以被随时销毁重建的。K8S 按负载扩缩容,流量下来了实例会被回收。所以你的服务必须是无状态的,本地文件系统里写的东西随时会没,session 不能存在内存里。

第三,多实例之间不共享内存。定时任务这类逻辑要小心,三个实例各跑一份定时器,任务就被执行了三次。

# 几个常见问题

# 云托管的作用是什么?

代替服务器部署小程序/公众号后端。

# 微信云托管和微信云开发的区别是什么,如何选择?

  • 微信云开发和微信云托管都是微信联合腾讯云打造的微信云服务生态的组成部分,都提供了免服务器免运维的能力,开发者可以根据自己的业务特点进行选择。
  • 微信云开发以云函数提供计算能力,围绕 Node.js 技术栈,适合前端开发者简单快捷实现后端功能,或全栈开发者一体化开发; 微信云托管以容器提供计算能力,支持任意后端语言和框架,适合前后端分离项目的后端开发、传统模式后端项目迁移,对团队协作和企业级应用场景更友好

这两个我都用过一段时间,说说我自己的判断标准。

一个人做小程序、后端逻辑不复杂、只要增删改查加几个业务函数,云开发更快。它连数据库和存储都一起给你了,前端页面里直接 wx.cloud.callFunction 就能调,中间一层网络都不用管。

有独立后端、用了 Nest 或者 Egg 这种框架、有中间件和依赖注入这一套、或者压根不是 Node 而是 Java Go,那就是云托管。另外一个信号是团队规模,云函数那种一个函数一个目录的组织方式,人一多就乱了,而云托管本质是跑一个正常的后端服务,工程实践跟平常没区别。

我自己现在的项目是混着用的,主服务在云托管,一些边角逻辑还留在云开发的云函数里,后面第六节会演示云托管怎么反过来调云函数。关于云开发那一套的用法我单独写过 CloudBase 云开发总结,需要的话可以对照看。

# 微信云托管和云开发中的云托管有何区别?

  • 微信云托管和之前云托管的区别除了品牌升级外,还做了独立的控制台。旧的云托管只是云开发的一个模块,只有单纯的容器引擎能力,升级为微信云托管后脱离云开发,成为完整的后端项目托管解决方案。 从代码管理到CI/CD流水线部署发布,提供全链路、低成本、企业级的云原生解决方案,功能更强大、体验更友好
  • 云开发中的云托管能力已停止功能更新,仅支持存量业务继续运行。建议原云开发中的云托管的用户尽快将项目迁移到微信云托管。

# 微信云托管可以用于APP/网站/其他平台小程序吗?

必须先有微信小程序/公众号才可以开通微信云托管,但部署在微信云托管上的服务可以通过公网访问,因此可以被APP/网站/其他平台小程序的前端调用,只是无法享受 callcontainer 内部链路带来的安全防DDoS/请求加速等优势。

# 微信云托管的环境可以在微信开发者工具的云开发控制台中看到吗?

微信云托管和微信云开发是两套独立体系,微信云托管的环境只能在微信云托管控制台看到,在微信开发者工具的云开发控制台中不能看到

# 腾讯云和微信云托管有关系吗?

微信云托管是整合了腾讯云底层资源和微信生态链路的综合解决方案。原云开发中的云托管独立出来,升级为微信云托管,补充数据库、ci/cd、灰度发布等更多完整后端功能和企业级devops能力。

# 云托管的时间为什么差 8 个小时?

这个问题几乎每个人都会碰到,单独说清楚。

容器系统时间默认为 UTC 协调世界时间 (Universal Time Coordinated),与本地所属时区 CST (上海时间)相差 8 个小时:

根因在基础镜像。node、centos 这些官方镜像为了通用性都用 UTC,容器里跑 new Date() 拿到的就是 UTC 时间。写进数据库的 createTime 全是早 8 小时的,日志时间戳跟用户反馈的时间对不上,排查问题时特别折磨人。

在构建基础镜像或在基础镜像的基础上制作自定义镜像时,在 Dockerfile 中创建时区文件即可解决单一容器内时区不一致问题,且后续使用该镜像时,将不再受时区问题困扰。

  1. 打开 Dockerfile 文件。
  2. 写入以下内容,配置时区文件
FROM centos as centos  COPY --from=centos  /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo "Asia/Shanghai" > /etc/timezone
@前端进阶之旅: 代码已经复制到剪贴板

这段是官方文档里的写法,三条指令被挤在一行里了,实际写进 Dockerfile 要分行。原理是从一个带完整时区数据库的镜像里把上海时区文件复制到 /etc/localtime,再写一份 /etc/timezone 告诉系统当前时区是哪个。

Debian 系的基础镜像(比如 node:14)更常见的写法是这样,后面本地调试那节的 Dockerfile 用的就是它。

ENV TZ=Asia/Shanghai \
    DEBIAN_FRONTEND=noninteractive
RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone \
    && dpkg-reconfigure --frontend noninteractive tzdata
@前端进阶之旅: 代码已经复制到剪贴板

DEBIAN_FRONTEND=noninteractive 不能省,dpkg-reconfigure 默认会弹一个选时区的交互菜单,构建过程没人按回车就一直卡着。

  1. 重新构建容器镜像,使用新的镜像重新部署。或直接上传含新的 Dockerfile 的代码包重新部署

顺便说一句,改时区只解决了容器内部的显示问题。如果你的数据库是另一个服务,它自己也有时区设置,两边不一致同样会错。稳妥的做法是数据库统一存 UTC 时间戳,展示层再按用户所在时区转换,不过那是另一个话题了。

# 二、把服务部署上去

# 模板部署

先走模板,好处是不用准备任何代码就能把整条链路跑通,确认账号、环境、调用方式都没问题。

访问 https://cloud.weixin.qq.com/cloudrun/onekey

云托管一键部署页面的模板列表

这个页面列的是各语言的模板,Node、Java、Go、PHP 都有。选跟你技术栈匹配的那个,选错了后面改起来还不如重来。

选择要部署的小程序和环境

这一步要绑定小程序。云托管必须依附于一个已有的小程序或公众号,没有的话得先去注册一个,这是硬前提。绑定之后会创建一个环境,环境 ID 形如 prod-xxxxxxx,后面小程序端调用要用,记下来。

模板部署的构建进度

点确认之后平台开始构建。这里跑的就是模板自带的 Dockerfile,第一次构建要拉基础镜像,慢一点正常。

部署完成后的服务详情页

看到服务状态是运行中,并且给出了访问地址,就算部署成功了。这个地址是公网可访问的 HTTPS 地址,浏览器直接打开能看到模板的默认页面。

先在浏览器里访问一遍确认服务活着,再去小程序里调。这个顺序能帮你把「服务挂了」和「小程序调用姿势不对」两类问题分开。

小程序/公众号中调用

// 在小程序 app.js中初始化云托管
onLaunch() {
    if (!wx.cloud) {
      console.error('请使用 2.2.3 或以上的基础库以使用云能力')
    } else {
      wx.cloud.init({
        env: 'xxx', // 填入云托管环境ID
      })
    }
}

@前端进阶之旅: 代码已经复制到剪贴板
// 在小程序中调用云托管服务
wx.cloud.callContainer({
  "config": {
    "env": "prod-xx" // 填入云托管环境ID
  },
  "path": "/api/count", // 云托管服务请求路径
  "header": {
    "X-WX-SERVICE": "express-4bnl" // 云托管服务名称
  },
  "method": "POST",
  "data": {
    "action": "inc" // 发起请求传入的参数
  }
})
@前端进阶之旅: 代码已经复制到剪贴板

这两段代码是小程序端接入的全部内容,看着简单,但有几个点第一次用一定会卡住。

fe
  • 一、微信云托管是什么
    • 定位和能力
    • 架构特点
    • 几个常见问题
      • 云托管的作用是什么?
      • 微信云托管和微信云开发的区别是什么,如何选择?
      • 微信云托管和云开发中的云托管有何区别?
      • 微信云托管可以用于APP/网站/其他平台小程序吗?
      • 微信云托管的环境可以在微信开发者工具的云开发控制台中看到吗?
      • 腾讯云和微信云托管有关系吗?
      • 云托管的时间为什么差 8 个小时?
  • 二、把服务部署上去
    • 模板部署
    • 自定义部署 Nestjs
  • 三、CLI 工具
  • 四、本地调试
    • 本地 docker 调试
    • Live Coding 实时开发
    • 本地调试中使用「开放接口服务」
  • 五、云调用
    • 配置云调用权限
    • 实例一,文字安全检测接口
    • 实例二,调用小程序云函数
    • 实例三,获取小程序码
  • 总结
  • 参考

← 云开发CloudBase实践总结从CLI到Framework一键部署Serverless 部署前后端项目实践,腾讯云 SCF 全流程笔记 →