在进行微信小程序开发时,常常会在微信的文档中看到一段话前端
本接口应在服务器端调用,详细说明参见服务端API。本接口支持云调用。需开发者工具版本 >= 1.02.1904090(最新稳定版下载),wx-server-sdk >= 0.4.0node
这里提到的云调用,就是微信提供的小程序Serverless云开发服务,包括云函数、云数据库、文件存储等一系列后端服务。在小程序中使用云开发服务,可让开发人员更专一于代码和业务自己,不用关心服务器和底层的运维设施,而且它还有着比服务器端更方便的鉴权步骤,可让开发人员更快更容易的开发小程序。ios
Serverless 架构是指大量依赖第三方服务(也叫作后端即服务,即“BaaS”)或暂存容器中运行的自定义代码(函数即服务,即“FaaS”)的应用程序,函数是无服务器架构中抽象语言运行时的最小单位。在这种架构中,咱们并不看重运行一个函数须要多少 CPU 或 RAM 或任何其余资源,而是更看重运行函数所需的时间,咱们也只为这些函数的运行时间付费。
Serverless是一个从大约2016年被开发者所关注的架构,从他的发展趋势来看,直到如今,它都还保持着上升的势头,这是一个很是有潜力的架构。从字面上看,Serverless架构,即无服务器架构,这并非说真的没有没有服务器,而是对物理服务器进行了抽象和虚拟化。Serverless架构主要有如下特色。程序员
这实际上是开发人员长久以来一直在作的事,为了解决各类环境问题,想出了一系列的隔离方法。从虚拟机、虚拟环境到docker等容器技术,利用这些技术,将代码和运行代码的硬件以及操做系统隔离开,将应用操做和服务器操做隔离开。这样作以后,就避免了出现bug时还要先排查环境问题的窘境。Serverless架构就能够很好地隔离操做系统,甚至更深层的技术细节。在Serverless架构的应用中,开发者只须要专一于业务逻辑的实现,而彻底不须要操心底层的运维等工做。web
与隔离一样的,虚拟化也是一个发展已久的技术。但与隔离的目的不一样,虚拟化是云计算的重要技术,主要用于物力资源的池化,从而能够弹性地分配给用户。物力资源包括服务器,网络和存储。虚拟化的思想能够追溯到IBM机器的逻辑分区,即把一台机器划分红若干台逻辑的服务器,每台逻辑服务器拥有独占的计算资源(CPU、内存、硬盘、网卡),能够单独安装和运行操做系统。划分为更小的计算单元,大大减小了资源的浪费,提升了生产效率。云计算是经过使计算分布在大量的分布式计算机上,而非本地计算机或远程服务器中,企业数据中心的运行将与互联网更类似。这使得企业可以将资源切换到须要的应用上,根据需求访问计算机和存储系统。对于云计算来讲,虚拟化是必不可少的。随着云计算的的流行和发展,虚拟化技术也日渐成熟,咱们已经能够自动管理虚拟化的计算资源。在Serverless架构中,应用是真正的按需使用,只有请求到来的时候,应用才开始运行计算。docker
事件驱动编程(英语:Event-driven programming)是一种电脑程序设计模型。这种模型的程序运行流程是由用户的动做(如鼠标的按键,键盘的按键动做)或者是由其余程序的消息来决定的。相对于批处理程序设计(batch programming)而言,程序运行的流程是由程序员来决定。批量的程序设计在初级程序设计教学课程上是一种方式。然而,事件驱动程序设计这种设计模型是在交互程序(Interactive program)的状况下孕育而生的。
Serverless只有在请求到来的时候才开始计算,这就是一种事件驱动编程。也就是说,这和咱们在编写GUI程序,好比桌面程序和web应用时同样,经过监听用户的操做,才开始进行相应的处理。Serverless则是在用户使用的时候,才会开始对用户的行为进行响应。数据库
Serverless包含的两部份内容Baas和Faas,Baas严重或彻底依赖第三方应用程序/服务(好比云平台)管理服务器端逻辑和状态,Faas也须要将服务器端的应用逻辑(微服务甚至粒度更小的服务)以事件驱动的方式运行在无状态的临时的容器中,而且这些容器、计算资源都是由第三方管理。所以,Serverless架构对于云平台或第三方服务的依赖度很是高。国外的主要平台如AWS Lambda,国内也有阿里云和腾讯云等服务。因为Serverless的运行特性,这些第三方服务商也大都是按运行时间和内存来进行收费,实际的开销并不大,用得少甚至不要钱。npm
serverless deploy
就能完成部署或更新,在微信云函数上只要点击部署就能够。因为这些特性,Serverless主要被应用于一些实时性要求不高,且不会长期大量使用的场景。如通知分发,定时任务,一些轻量级api或者初创公司的产品上。编程
进入正题,微信云开发。微信云开发就是微信为小程序提供的Serverless服务。小程序在不少时候都被用做一个导流工具,其中的通知和消息的功能就很适合用Serverless来进行处理。而且使用云开发,会减小不少请求校验的流程,开发人员能够更专一于业务逻辑。微信云开发中的Serverless主要包括了如下三个功能。json
同时,小程序还提供了两个环境,区分线上和测试。开通云开发功能后,就能够建立环境和选择配额。若是小程序访问量不大,选择基础的配额,是不须要付费的。开启云开发的功能后,就能够开始愉快的写云函数了。首先要建立云函数的目录,通常来讲,存放云函数的文件夹最好和小程序源码平行,好比云函数的文件夹叫functions
,小程序的文件夹叫miniprogram
,而后在project.config.json
中分别定义这两个目录。这样结构更清晰,而且小程序运行时也不会加载无关代码。
这三个功能均可以经过小程序直接调用,也能够经过api由本身的服务器调用,不过固然这须要必定的鉴权。同时微信还提供了云调用功能,能够在云函数中调用数据库和文件存储。接下来主要要讲云函数的功能。
在新建云函数的时候,系统会默认建立一个package.json
文件。这也是云函数的一个特色,每个函数都有一个package.jaon
,它们的依赖项也是相互独立的。你能够选择本地安装npm依赖,也能够选择去云端安装依赖,这取决你是否要在本地调试。
每个云函数都有一个惟一的main函数做为入口,传入参数有两个,一个是event
对象,一个是context
对象。event
指的是触发云函数的事件,当小程序端调用云函数时,event
就是小程序端调用云函数时传入的参数。context
对象包含了此处调用的调用信息和运行状态,能够用它来了解服务运行的状况。因此一个简单的云函数就像这样。
// ... exports.main = async (event, context) => { // ... return { sum: event.a + event.b } }
在小程序中调用云函数,要先将云函数部署到云端,这时就能够选择是否在云端安装依赖。部署完成后,经过wx.cloud.callFunction
来调用云函数。
wx.cloud.callFunction({ // 云函数名称 name: 'add', // 传给云函数的参数 data: { a: 1, b: 2, }, success: function(res) { console.log(res.result.sum) // 3 }, fail: console.error })
或者用Promise风格的调用。
wx.cloud.callFunction({ // 云函数名称 name: 'add', // 传给云函数的参数 data: { a: 1, b: 2, }, }) .then(res => { console.log(res.result) // 3 }) .catch(console.error)
云函数全部的调用日志,微信也都存着,排查问题也比较方便。固然这里也有一个问题,部署好的云函数,就无法在服务端进行调试了,好比打断什么的更是不可能的。若是出现错误,要么看日志,要么就只有不停添加console.log
而后部署,而后再触发,很是不方便。
首先在开发者工具中配置用云函数处理客服消息。能够选择处理特定的消息类型,这里选择了小程序卡片和进入客服会话事件,那么就只有这两种消息会发送给云函数进行处理,其余消息仍是发给客服或者服务器处理。
要调用微信客服消息接口,因此要先在package.json
中加上依赖项"wx-server-sdk":"latest"
,同时在index.js
中引入wx-server-sdk
,这是一个能够在云函数中操做数据库、存储以及调用其余云函数的微信提供的库。而后咱们就能够用微信的sdk来获取用户活动信息,而且调用openapi进行回复。
// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() // 云函数入口函数 exports.main = async(event, context) => { const wxContext = cloud.getWXContext() console.log(event); await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: 'text', text: { content: '收到', } }) return 'success' }
在云函数中,也能够发送网络请求,借助http
、request
或axios
等库,就跟在node.js中发送请求同样。这样,咱们就能够根据用户消息中带上的参数来回复特定的内容。例如,在小程序卡片的pagePath
或者是进入会话事件中的session-from
字段中,带上须要的参数。这里用request-promise
来作网络请求,一样的,先在package.json
中添加依赖项"request-promise": "^4.2.5"
。
const cloud = require('wx-server-sdk') const rp = require('request-promise'); cloud.init() exports.main = async(event, context) => { const wxContext = cloud.getWXContext() if (event.MsgType === 'miniprogrampage') { await rp({ uri: 'url', method: 'POST', body: JSON.parse(event.pagePath.split('=')[1]), json: true }).then(async res => { await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: 'link', link: { title: 'title', description: 'description', url: res.result.url, thumb_url: res.result.imageUrl } }) }) } else if (event.MsgType === 'event') { console.log(JSON.parse(event.SessionFrom)); } return 'success' }
目前没有试过云开发中的数据库和存储,只是初探了云函数的使用。云函数在处理一些简单的业务逻辑上很是方便,微信也给云函数开了一些绿色通道,好比各类校验,可是也有一个很大的缺陷,就是调试的问题。本地调试没什么问题,远程调试只能一次次加console.log而后部署而后看日志,不知道会不会有更方便的办法。