微信小程序雲開發初探

在進行微信小程序開發時,常常會在微信的文檔中看到一段話前端

本接口應在服務器端調用,詳細說明參見服務端API。

本接口支持雲調用。需開發者工具版本 >= 1.02.1904090(最新穩定版下載),wx-server-sdk >= 0.4.0node

這裏提到的雲調用,就是微信提供的小程序Serverless雲開發服務,包括雲函數、雲數據庫、文件存儲等一系列後端服務。在小程序中使用雲開發服務,可讓開發人員更專一於代碼和業務自己,不用關心服務器和底層的運維設施,而且它還有着比服務器端更方便的鑑權步驟,可讓開發人員更快更容易的開發小程序。ios

Serverless

Serverless 架構是指大量依賴第三方服務(也叫作後端即服務,即「BaaS」)或暫存容器中運行的自定義代碼(函數即服務,即「FaaS」)的應用程序,函數是無服務器架構中抽象語言運行時的最小單位。在這種架構中,咱們並不看重運行一個函數須要多少 CPU 或 RAM 或任何其餘資源,而是更看重運行函數所需的時間,咱們也只爲這些函數的運行時間付費。

serverless熱度趨勢
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的優點

  1. 部署方便。得益於第三方服務,Serverless的部署甚至比docker還方便。在AWS上,只要運行serverless deploy就能完成部署或更新,在微信雲函數上只要點擊部署就能夠。
  2. 下降成本。得益於雲計算,Serverless架構須要的成本大大下降了,這個成本包括硬件成本和運維成本。應用Serverless架構,就再也不須要一臺一直運行着的服務器,甚至不須要一臺一直運行着的雲服務器,由於Serverless只有在計算的時候纔算錢。同時,也不須要花時間去搭建和維護服務器,第三方平臺會作好這一切。
  3. 快速上線。不須要管服務器,不須要寫部署腳本,不須要擔憂服務器安全問題,開發人員只須要關注業務邏輯,甚至連測試服務都由第三方服務準備好了,固然整一個迭代的時間都被大大縮短了。
  4. 適應微服務架構。對比微服務,很容易發現,Serverless有不少微服務的特色。一個Serverless其實就是一個微服務的實例。

Serverless的劣勢

  1. 長期來看,雖然維護成本低了,可是長期且大量的請求產生的服務費用會比直接買一臺雲服務器更貴。這就至關於租車和買車的區別。同時因爲強依賴於第三方服務,這就將咱們和服務供應商綁定了,很難再進行切換。若是有切換的需求,在進行開發的時候,可能就要有所注意。同時因爲第三方服務供應商水平有高有低,提供的調試和開發工具也都各有區別,好很差用是一方面,用習慣了要換又會增長適應成本。
  2. 冷啓動時間的問題。傳統應用沒有冷啓動的過程。

因爲這些特性,Serverless主要被應用於一些實時性要求不高,且不會長期大量使用的場景。如通知分發,定時任務,一些輕量級api或者初創公司的產品上。編程

微信雲開發

進入正題,微信雲開發。微信雲開發就是微信爲小程序提供的Serverless服務。小程序在不少時候都被用做一個導流工具,其中的通知和消息的功能就很適合用Serverless來進行處理。而且使用雲開發,會減小不少請求校驗的流程,開發人員能夠更專一於業務邏輯。微信雲開發中的Serverless主要包括瞭如下三個功能。json

  1. 數據庫。雲開發提供了一個JSON數據庫,顧名思義,數據庫中的每條記錄都是一個JSON格式的對象。一個數據庫能夠有多個集合(至關於關係型數據中的表),集合可看作一個JSON數組,數組中的每一個對象就是一條記錄,記錄的格式是JSON對象。
  2. 文件存儲。雲開發提供了一塊存儲空間,提供了上傳文件到雲端、帶權限管理的雲端下載能力,開發者能夠在小程序端和雲函數端經過API使用雲存儲功能。
  3. 雲函數。雲函數是一段運行在雲端的代碼,無需管理服務器,在開發工具內編寫、一鍵上傳部署便可運行後端代碼。也就是關鍵的業務邏輯。雲函數用的是node.js,對於前端開發人員來講再熟悉不過了,大大下降了開發門檻。

同時,小程序還提供了兩個環境,區分線上和測試。開通雲開發功能後,就能夠建立環境和選擇配額。若是小程序訪問量不大,選擇基礎的配額,是不須要付費的。開啓雲開發的功能後,就能夠開始愉快的寫雲函數了。首先要建立雲函數的目錄,通常來講,存放雲函數的文件夾最好和小程序源碼平行,好比雲函數的文件夾叫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'
}

在雲函數中,也能夠發送網絡請求,藉助httprequestaxios等庫,就跟在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而後部署而後看日誌,不知道會不會有更方便的辦法。

相關文章
相關標籤/搜索