• 前端进阶之旅:https://interview2.poetries.top
  • 博客:https://blog.poetries.top
  • 公众号/小程序:「前端进阶之旅」 每天分享技术干货,学前端不迷路
  • 作者:程序员poetry

根本简介

微信云托管是什么?

  • 微信云托管 是微信团队提供的以云原生为根底的,免运维、高可用服务上云解决方案,无需服务器,1分钟即可部署小程序/公众号服务端。
  • 微信云托管反对目前绝大多数语言/框架我的项目,开发者能够从服务器平滑迁徙;并且微信云托管的主动运维和扩缩容个性,无需开发者关怀服务的可用性,专一于业务,极大节俭人力和服务资源老本。
  • 同时,微信云托管还集成继续交付部署,DevOps自动化,平安鉴权等泛滥能力,致力于帮忙没有深层运维教训的业务开发者和研发团队,用最低的老本,打造出稳定性高,安全性强的后端服务。
  • 最重要的,微信云托管与微信生态深度交融,具备免鉴权,云调用,音讯推送,微信领取等泛滥微信劣势个性,开发者能够十分轻松和高效的实现互通,并且在平安、可靠性方面有微信团队的业余保障。

架构特点

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

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

常见问题

云托管的作用是什么?

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

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

  • 微信云开发和微信云托管都是微信联结腾讯云打造的微信云服务生态的组成部分,都提供了免服务器免运维的能力,开发者能够依据本人的业务特点进行抉择。
  • 微信云开发以云函数提供计算能力,围绕 Node.js 技术栈,适宜前端开发者简略快捷实现后端性能,或全栈开发者一体化开发; 微信云托管以容器提供计算能力,反对任意后端语言和框架,适宜前后端拆散我的项目的后端开发、传统模式后端我的项目迁徙,对团队合作和企业级利用场景更敌对

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

  • 微信云托管和之前云托管的区别除了品牌降级外,还做了独立的控制台。旧的云托管只是云开发的一个模块,只有单纯的容器引擎能力,降级为微信云托管后脱离云开发,成为残缺的后端我的项目托管解决方案。 从代码治理到CI/CD流水线部署公布,提供全链路、低成本、企业级的云原生解决方案,性能更弱小、体验更敌对
  • 云开发中的云托管能力已进行性能更新,仅反对存量业务持续运行。倡议原云开发中的云托管的用户尽快将我的项目迁徙到微信云托管。

微信云托管能够用于APP/网站/其余平台小程序吗?

必须先有微信小程序/公众号才能够开明微信云托管,但部署在微信云托管上的服务能够通过公网拜访,因而能够被APP/网站/其余平台小程序的前端调用,只是无奈享受 callcontainer 外部链路带来的平安防DDoS/申请减速等劣势。

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

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

腾讯云和微信云托管有关系吗?云开发的云托管和微信云托管有什么区别?

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

云托管的工夫相差8个小时?

容器零碎工夫默认为 UTC 协调世界时间 (Universal Time Coordinated),与本地所属时区 CST (上海工夫)相差 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
  1. 从新构建容器镜像,应用新的镜像重新部署。或间接上传含新的 Dockerfile 的代码包重新部署

云托管部署

云托管模板部署

拜访 https://cloud.weixin.qq.com/c...




小程序/公众号中调用

// 在小程序 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" // 发动申请传入的参数  }})

云托管自定义部署nestjs

初始化您的 Nest.js 我的项目

npm i -g @nestjs/clinest new nest-app

在根目录下,执行以下命令在本地间接启动服务。

cd nest-app && npm run start

关上浏览器拜访 http://localhost:3000,即可在本地实现 Nest.js 示例我的项目的拜访。

新建服务

点击公布后,云托管会执行Dockerfile构建流水线,到日志能够查看构建进度


微信云托管部署胜利后,能够在实例列表,点击进入容器看到代码,这里外面的内容不能批改,在容器启动后会笼罩


调试接口

具体示例

CLI工具应用

npm install -g @wxcloud/cliwxcloud -h

获取 CLI 密钥

CLI工具的登录采纳了密钥模式,在应用前须要返回微信云托管控制台 - 设置 -CLI 密钥生成,生成时须要账号管理员扫码,能够新建多个密钥,用于在不同中央应用。

传入微信 APPID 和CLI密钥,操作登录

wxcloud login [OPTIONS]

查看登录账号下所有的环境列表

wxcloud env:list [OPTIONS]

查看指定环境下的所有服务列表

wxcloud service:list [OPTIONS]

云托管本地调试

本地docker调试

  • 装置docker
  • 装置微信开发者工具最新版
  • 装置vscode Docker拓展
  • 在 VSCode 拓展栏搜寻 weixin-cloudbase 而后装置

以koa作为后端演示

全局装置 koa-generator 脚手架.

npm install -g koa-generator

创立我的项目

# 应用ejs引擎koa2 -e wxcloud-debug-koa
cd wxcloud-debug-koa // 进入我的项目根目录npm install // 装置我的项目依赖
  • 批改www/bin中的端口为9000
  • 批改routes/index中代码为
router.get('/', async (ctx, next) => {  ctx.body = {    message: '申请头',    header: ctx.header  }})

关上浏览器拜访 http://localhost:9000,即可在本地实现 koa 示例我的项目的拜访。

编写dockerfile

FROM daocloud.io/library/node:14.7.0# 设置时区ENV TZ=Asia/Shanghai \    DEBIAN_FRONTEND=noninteractiveRUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata && rm -rf /var/lib/apt/lists/*RUN mkdir -p /app# 指定工作目录WORKDIR /app# 复制以后代码到/app工作目录COPY . ./# npm 源,选用国内镜像源以进步下载速度RUN npm config set registry https://registry.npm.taobao.org/# npm 装置依赖RUN npm install # 启动服务CMD node app.jsEXPOSE 9000
如只在 VSCode 中同时编辑调试一个服务,可间接关上服务代码目录作为根目录(暂不反对 VSCode Workspace 工作区),保障根目录下有 Dockerfile 文件,插件面板中会显示该服务的名字


调试过程中因须要获取微信信息,会应用云托管 CLI Key,因而需在 VSCode 插件配置填入小程序 appid 和 cli key,点击插件面板的 ⚙ 图标关上配置:

构建镜像,启动容器

右键服务名,抉择 start,将构建镜像并启动容器

能够看到构建过程

启动容器须要相应的容器配置信息(.cloudbase/container/debug.json),如果没有会提醒创立,配置文件字段和含意如下:

其中需特地留神端口号 containerPortDockerfile 门路 dockerfilePath、自定义环境变量 envParams

此时出现异常,咱们批改.cloudbase/container/debug.json中的containerPort为koa服务中定义的9000端口,从新构建即可


容器构建和启动胜利后,在插件面板状态 icon 会相应更新:

也能够通过docker ps查看已启动的服务

咱们在云托管后盾能够看到此时默认启动了一个调试服务,咱们不要去批改它

此时能够申请容器了,在插件面板旁会展现两个端口号,通过第一个端口拜访容器会带有微信相干信息(header 中蕴含 appid 等),通过第二个端口拜访容器不会带有微信相干信息而是间接申请到容器外部,右键服务抉择 Open in browser (via WX server) 和 Open in browser (no WX auth) 能够在浏览器中关上,别离对应这两种状况,也能够写代码或通过 POSTMAN 等工具申请

申请不通过微信服务器返回:http://127.0.0.1:27081/

不带微信信息的端口,间接拜访即可,适宜在浏览器调试

申请通过微信服务器返回:http://127.0.0.1:27082/

微信端口,申请时会模仿微信用户信息的 Header,如 x-wx-openid,适宜微信开发者工具中应用

在微信开发者工具中,能够抉择连贯到 VSCode 启动的容器,从而在小程序模拟器中拜访本地云托管容器

此能力须要应用微信开发者工具 v1.05.2202242 及以上版本,并更新 VSCode 插件到 v1.0.12 以上。

创立一个小程序测试项目

在 微信开发者工具 的 Docker 面板中,找到 「Running Containers」,右击容器名称,抉择 Attach Weixin Devtools,即可在小程序代码中,应用 wx.cloud.callContainer 拜访容器。

须要退出再次Detach Weixin Devtools

调用时,须要留神 Header 中的 X-WX-SERVICE 须要与容器名保持一致

批改小程序app.js代码

// app.jsApp({  onLaunch: async function () {    await wx.cloud.init({      // env: "其余云开发环境,也能够不填"    // 此处 init 的环境 ID 和微信云托管没有作用关系,没用就留空    });    const res = await wx.cloud.callContainer({      config: {        env: "prod-xx", // 微信云托管环境ID,不能为空,替换本人的      },      path: '/',       method: 'GET',      header: {        'X-WX-SERVICE': 'wxcloud-debug-koa', // 替换老本地要调试的容器名称      }    });    console.log(res); // 在控制台里查看打印  }})

查看申请日志

或者通过docker logs查看

进入终端

如果须要进入到容器外部终端调试定位问题,能够右键服务名抉择 Attach Shell 进入容器内终端

本地docker实时调试

通过微信云托管 VSCode 插件,能够实现实时开发,即代码变动时,不须要从新构建和启动容器,即可查看变动后的成果。

抉择 Live Coding

右键点击须要调试的容器,抉择 Live Coding,将主动生成 Dockerfile.developmentdocker-compose.yml 2 个文件并启动容器。

如果生成失败,咱们须要自行配置

开发模式的 docker-compose.yml

# 开发模式的 docker-compose.yml# 实时开发将应用我的项目目录下的 docker-compose.yml 将当前目录映射到容器中。# 大多数状况下,插件将依据我的项目的 Dockerfile 主动生成本文件,不须要手动编写。version: '3'services:  app:    build:       context: . # 构建上下文      dockerfile: Dockerfile.development    volumes:      - .:/app # 须要映射的目录(即代码目录)      - /app/node_modules # 映射 node_modules 目录,如果有构建产物与代码目录同级,须要独自映射防止无奈运行    ports:      - 27081:9000 # 监听端口,主机端口:容器端口 批改为koa服务端口    container_name: wxcloud_wxcloud-debug-koa # 容器名称    labels: # 容器标签,个别不需改变      - wxPort=27082      - hostPort=27081      - wxcloud=wxcloud-debug-koa      - role=container    environment:      # 应用本地调试 MySQL 时,须要填入如下环境变量,并启动 MySQL 代理服务      - MYSQL_USERNAME=      - MYSQL_PASSWORD=      - MYSQL_ADDRESS=networks:  default:    external:      name: wxcb0 # 容器网络买通,个别不需改变

批改端口 9000

ports:  - 27081:9000 # 监听端口,主机端口:容器端口 批改为koa服务端口

实时开发应用我的项目目录下的 Dockerfile.development

# Dockerfile.development# 实时开发应用我的项目目录下的 Dockerfile.development 作为开发期间的容器的 Dockerfile# 大多数状况下,插件将依据我的项目的 Dockerfile 主动生成本文件,不须要手动编写。# 开发模式的 Dockerfile 与正式模式的 Dockerfile 的区别在于:# 单阶段构建# 将编译命令转换为启动命令,如 Spring Boot 模板的 mvn package 会转换为 spring-boot:run# 拉取实时开发的工具套件,装置到 /usr/bin 下# 通过实时开发工具套件启动用户程序,在代码产生更改时,主动重启过程。# Auto-generated by weixin cloudbase vscode extensionFROM ccr.ccs.tencentyun.com/weixincloud/wxcloud-livecoding-toolkit:latest AS toolkitFROM node:lts-slimCOPY --from=toolkit nodemon /usr/bin/nodemon# 设置时区RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata && rm -rf /var/lib/apt/lists/*WORKDIR /appCOPY package*.json ./# --only=production 只装置生产环境的依赖RUN npm install --only=production && npm install pm2 -gCOPY . ./# 批改nest启动入口 node bin/wwwCMD [ "nodemon", "-x", "node bin/www", "-w", "/app", "-e", "java, js, mjs, json, ts, cs, py, go" ]
批改koa启动入口 node www/bin

启动实时服务

批改本地代码,不必重启容器即可查看成果

本地调试中应用「凋谢接口服务」

  • 在 VSCode 拓展栏搜寻 weixin-cloudbase 而后装置
  • 实现配置后,在左侧 Docker 面板内,右击 Proxy nodes for VPC access 中的 api.weixin.qq.com,点击启动(Start
  • 右击用户容器,点击启动(Start),容器内即可拜访本地云调用

填入环境ID

启动api.weixin.qq.com服务

启动本人的业务服务,在业务服务运行过程中,启动 vpc 中的 api.weixin.qq.com 服务

插件将会在你的云托管环境中开启一个代理服务,用于和本地 api.weixin.qq.com 服务,同时和业务服务共享同一个网络,就实现了本地的「凋谢接口服务」,须要留神,本地调试中只是模仿了业务服务的所处环境,不是实在的线上部署状况。

云托管中应用云调用

  • 云调用
  • 服务端接口

云调用是具备「免鉴权调用微信凋谢服务接口」个性的能力,是云开发/云托管中微信生态的一部分。

在云调用呈现之前,微信凋谢服务接口的失常调用,须要开发者应用密钥信息获取access_token,并本人保护 token 的有效期和平安。而获取access_token,波及到密钥交互申请,容易暴漏密钥导致被盗用,对开发者和微信服务都有消极的影响。

云调用次要打造免鉴权,也就是免密钥,全程不暴漏任何信息,开发者无需保护access_token,那对于接口申请的合法性断定,齐全由与微信同链路的微信云托管参加施行。

配置云调用权限

返回控制台 - 云调用 - 云调用权限配置,依照本人的业务须要配置接口。

比方你要在服务中调用文字平安检测接口

此接口的调用地址如下:https://api.weixin.qq.com/wxa/msg_sec_check?access_token=ACCESS_TOKEN

在配置时,只须要 api.weixin.qq.com 之后,?参数之前的局部,所以应该在配置输入框里填写如下

/wxa/msg_sec_check

在云托管服务中,微信后盾周期性的将凋谢接口所必须要的 access_token,推送到服务的容器实例中。在应用时只须要从容器本地读取令牌,就能够包装申请去调用了:

access_token 推送的工夫距离为 10 分钟,令牌的有效期为 30 分钟; 挂载门路为:/.tencentcloudbase/wx/cloudbase_access_token; 在同一个环境中所有的容器实例,推送的 access_token 雷同

接口调用凭证 https://developers.weixin.qq....

查看容器内access_token


如果须要获取容器内的access_token调试接口,须要在接口中填入cloudbase_access_token=容器内的access_token

// https://developers.weixin.qq.com/miniprogram/dev/wxcloudrun/src/guide/weixin/token.htmlconst fs = require('fs')const request = require('request')// 容器内的access_tokenconst token = fs.readFileSync('/.tencentcloudbase/wx/cloudbase_access_token', 'utf-8')return new Promise((resolve, reject) => {  request({    method: 'POST',    // 可本地调试用cloudbase_access_token    url: `https://api.weixin.qq.com/wxa/msg_sec_check?cloudbase_access_token=${token}`,    body: JSON.stringify({      openid: '用户的openid', // 能够从申请的 header 中间接获取 req.headers['x-wx-openid']      version: 2,      scene: 2,      content: '平安检测文本'    })  },function (error, response) {    console.log('接口返回内容', response.body)    resolve(JSON.parse(response.body))  })})

云托管内调用服务端文字检测接口

npm i request request-promise -S

服务端接口地址

在代码routes/home中增加

router.get('/msg_sec_check', async (ctx, next) => {  let ACCESS_TOKEN = ''  let data = await rp({    method: 'POST',    // 在云托管容器环境中,能够拿到access_token,而且免鉴权、这里不须要填写    // https://developers.weixin.qq.com/miniprogram/dev/wxcloudrun/src/guide/weixin/open.html    // 这里填http协定、在云托管中不须要填access_token、须要在云托管-云调用中填写接口白名单前缀、开启侧边栏proxy代理后能够免输出本地调试    uri: `http://api.weixin.qq.com/wxa/msg_sec_check`,    body: {      openid: ctx.header['x-wx-openid'],  // 用户的openid 能够从申请的 header 中间接获取 req.headers['x-wx-openid']      version: 2,      scene: 2,      content: '平安检测文本'    },    json: true  }).catch(error=>{    ctx.body = {      code: -1,      message: error    }    throw error  })  ctx.body = {    data,    code: 200  }})

在云托管权限控制台增加接口权限

开启 api.poetries.top 本地调试服务

通过微信服务器模仿小程序申请


也能够在小程序中拜访

云托管内调用服务端云函数接口

接口地址

在代码routes/home中增加

// 云托管内调用云函数router.get('/call-fn-banner', async (ctx, next) => {  const ACCESS_TOKEN = ''  const weappEnvId = 'poetry-prod-6gj3fpxa137552a6' // 小程序云开发envId  const data = await rp({    method: 'POST',    // 在云托管容器环境中,能够拿到access_token,而且免鉴权、这里不须要填写    // https://developers.weixin.qq.com/miniprogram/dev/wxcloudrun/src/guide/weixin/open.html    // 这里填http协定、在云托管中不须要填access_token、须要在云托管-云调用中填写接口白名单前缀、开启侧边栏proxy代理后能够免输出本地调试    uri: `http://api.weixin.qq.com/tcb/invokecloudfunction?env=${weappEnvId}&name=banner`,    body: {      $url: 'queryBanner',      ...ctx.request.query    },    json: true  }).then(async res=>{    console.log('callCloudFn res', res)    if(res && res.errcode === 40001) {      throw error    }    let data = res.resp_data ? JSON.parse(res.resp_data) : {}    return data  }).catch(error=>{    ctx.body = {      code: error.errcode,      message: error.errmsg    }    throw error  })  ctx.body = data})

小程序云函数banner代码

// 云函数入口文件const cloud = require('wx-server-sdk')cloud.init({  env: 'poetry-prod-xx' // 环境ID})const TcbRouter = require('tcb-router')const db = cloud.database()const bannersCollection = db.collection('banners') // banners汇合// 云函数入口函数exports.main = async (event, context) => {  const app = new TcbRouter({event})   // banner列表   app.router('queryBanner', async (ctx,next)=>{     const {pageSize = 20, pageNum = 1, orderBy, sort} = event     try {        let data = await bannersCollection.skip(Number((pageNum - 1)*pageSize)).limit(Number(pageSize)).orderBy(orderBy || 'createTime', sort || 'desc').get().then(res=>res.data)        let {total} = await bannersCollection.count()        ctx.body = {          message: '查问胜利',          code: 200,          data: {            list: data,            total,            pageSize,            pageNum          }        }     } catch (error) {        ctx.body = { message: error, code: -1 }      }  })  return app.serve()}

在云托管权限控制台增加接口权限

开启 api.poetries.top 本地调试服务

通过微信服务器模仿小程序申请


也能够在小程序中拜访

云托管内调用服务端获取小程序码接口

接口地址

在代码routes/home中增加

// 云托管内获取小程序码router.get('/getweappCode', async (ctx, next) => {  let ACCESS_TOKEN = ''  let buffer = await rp({    method: 'POST',    // 在云托管容器环境中,能够拿到access_token,而且免鉴权、这里不须要填写    // https://developers.weixin.qq.com/miniprogram/dev/wxcloudrun/src/guide/weixin/open.html    // 这里填http协定、在云托管中不须要填access_token、须要在云托管-云调用中填写接口白名单前缀、开启侧边栏proxy代理后能够免输出本地调试    uri: `http://api.weixin.qq.com/wxa/getwxacode`,    body: {      path: '/pages/article/index'    },    json: true  }).catch(error=>{    ctx.body = {      code: -1,      message: error    }    throw error  })  ctx.body = {    data: buffer,    code: 200  }})

在云托管权限控制台增加接口权限

开启 api.poetries.top 本地调试服务

通过微信服务器模仿小程序申请

也能够在小程序中拜访

文档

  • 微信云托管开发者文档
  • CLI工具
  • 本地调试
  • 云托管官网GitHub
  • tencent云开发知识库首页
  • 微信学堂疾速上手微信云托管

本文由mdnice多平台公布