云開發(fā) 定時觸發(fā)器

2020-07-22 15:32 更新

任何可以產(chǎn)生事件,觸發(fā)云函數(shù)執(zhí)行的均可以被稱為觸發(fā)器,而定時觸發(fā)器則是可以處理周期性的事情,比如時報、日報、周報等通知提醒,也可以處理倒計時任務,比如節(jié)假日、紀念日以及你可以指定一個具體時間的倒計時任務,除此之外,定時觸發(fā)器還可以用來周期性處理一些定時任務。比如定期清理一些不必要的數(shù)據(jù),定期更新集合內(nèi)的數(shù)據(jù)。

一、定時觸發(fā)器使用說明

1、定時觸發(fā)器的配置與部署

配置了定時觸發(fā)器的云函數(shù),會在相應時間點被自動觸發(fā),云函數(shù)的返回結(jié)果不會返回給調(diào)用方。在對某個云函數(shù)使用定時觸發(fā)器前,首先要保證該云函數(shù)在小程序端可以調(diào)用成功,更準確的說是能夠在不傳入?yún)?shù)的情況下在云開發(fā)控制臺的云端測試能調(diào)試成功(小程序端調(diào)用有登錄態(tài))。

云函數(shù)目錄里的config.json文件可以用來配置權(quán)限和定時觸發(fā)器,如果你的云函數(shù)目錄下面沒有這個配置文件,可以自己創(chuàng)建一個,創(chuàng)建的結(jié)構(gòu)目錄如下:

test //云函數(shù)目錄
├── config.json //權(quán)限和定時觸發(fā)器等的配置文件
├── index.js    //云函數(shù)
├── package.json  //云函數(shù)的依賴管理

然后再來在配置文件config.json里進行類似如何格式的配置,config.json嚴格遵循配置文件所要求的格式,比如數(shù)組最后一項不能有逗號,;配置文件里不能有注釋

  • triggers 字段是觸發(fā)器數(shù)組,但是目前云函數(shù)只支持一個觸發(fā)器,即數(shù)組只能填寫一個,不可添加多個;

  • name 是觸發(fā)器的名字,最大支持 60 個字符,支持 a-z, A-Z, 0-9, - 和 _,必須以字母開頭;

  • type 為觸發(fā)器類型,timer是定時觸發(fā)器

  • config 是觸發(fā)器的定時配置,里面為cron表達式(后面有介紹),cron有七個必需字段,不能多也不能少(以下為每天早上9點到12點每隔5秒觸發(fā)一次);

{
  "triggers": [
    {
      "name": "tomylove",
      "type": "timer",
      "config": "*/5 * 9-12 * * * *"
    }
  ]
}

當我們在修改觸發(fā)器配置文件config.json后,首先鼠標右鍵config.json選擇“云函數(shù)增量上傳:更新文件”,然后再右鍵config.json選擇“上傳觸發(fā)器”。這里的“云函數(shù)增量上傳:更新文件”是讓云函數(shù)端的觸發(fā)器文件更新;而“上傳觸發(fā)器”則是讓觸發(fā)器開始生效執(zhí)行。如果在云函數(shù)端的觸發(fā)器沒有更新的情況下就“上傳觸發(fā)器”來執(zhí)行定時觸發(fā),文件可能沒有更新,執(zhí)行的還是舊的觸發(fā)器內(nèi)容。當我們想暫停或刪除觸發(fā)器時,可以右鍵選擇“刪除觸發(fā)器”。

2、Cron表達式語法

Cron表達式有七個必填字段,按空格分隔,既不能多寫也不能少寫,每一個字段都有它的含義對應著不同的時間點,表達式的取值都為整數(shù)且為時間制的范圍(注意月在星期的前面):

第一位 第二位 第三位 第四位 第五位 第六位 第七位
秒(0-59 ) 分鐘(0-59) 小時(0-23) 日(1-31) 月(1-12或三個字母的英文縮寫) 星期(0-6或三個字母的英文縮寫) 年(1970\~2099 )

下面是cron表達式的案例,以及我們需要了解一下cron表達式里的通配符以及直接寫數(shù)字的含義:

  • ,,表示并集,在時間的表述里是“”的意思,比如在“小時”字段中, 1,2,3表示1點、2點和3點;

  • -,指定范圍的所有值,在時間的表述里是“”的意思,比如在“日”字段中,1-15包含指定月份的1號到15號;

  • *,表示所有值,在時間的表述里是“”的意思,比如在“小時”字段中,*表示每小時;

  • /,指定步長,在時間的表述里是“”的意思,比如在“秒”字段中,*/5表示每隔5秒;

  • 直接寫數(shù)字,在時間的表述里是“”(時間點)的意思,比如在“月”字段中,5表示每月的第5日;

//表示每隔5秒觸發(fā)一次,
*/5  *  *  *  *  *  * 


//表示在每月的1日的凌晨2點觸發(fā)
0  0  2  1  *  *  * 


//表示在周一到周五每天上午10:15觸發(fā)
0  15  10  *  *  MON-FRI * 


//表示在每天上午10點,下午2點,4點觸發(fā)
0  0  10,14,16  *  *  *  * 


//表示在每天上午9點到下午5點內(nèi)每半小時觸發(fā)
0  */30  9-17  *  *  *  * 


//表示在每個星期三中午12點觸發(fā)
0  0  12  *  *  WED * 

定時觸發(fā)器的Cron語法沒法實現(xiàn)每隔90秒鐘或90分鐘發(fā)送一次這樣的效果,因為90秒超過了秒的時間制上限60,而cron在跨位組合(比如90秒需要結(jié)合秒和分)上無法覆蓋所有的時間;除此之外,云開發(fā)的觸發(fā)器暫時不支持多個定時觸發(fā)器的疊加;在 Cron 表達式中的“日”和“星期”字段同時指定值時,兩者為“或”的關(guān)系,即兩者的條件均生效;值得一提的是,盡管云函數(shù)的時區(qū)為UTC+0 時區(qū),但是定時觸發(fā)器的時間還是北京時間。

二、用定時觸發(fā)器調(diào)用云函數(shù)

定時觸發(fā)器的使用非常簡單,使用開發(fā)者工具新建一個云函數(shù)比如trigger,然后在index.js里輸入以下代碼:

const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
})
exports.main = async (event, context) => {
  console.log(event)
  return event
}

再在trigger云函數(shù)目錄下的config.json(如果沒有這個文件,就創(chuàng)建一個),然后輸入以下觸發(fā)器,為了調(diào)試方便,我們可以每隔5秒觸發(fā)一次:

{
  "permissions": {
    "openapi": [
    ]
  },
  "triggers": [
    {
      "name": "tomylove",
      "type": "timer",
      "config": "*/5 * * * * * *"
    }
  ]
}

然后分別右鍵index.js和config.json,選擇“云函數(shù)增量上傳:更新文件”,然后再來右鍵config.json選擇“上傳觸發(fā)器”。云函數(shù)就會每隔5秒自動觸發(fā),相關(guān)的日志我們可以在開發(fā)者工具的云開發(fā)控制臺以及騰訊云云開發(fā)網(wǎng)頁控制臺的云函數(shù)的日志里查看。

注意小程序端調(diào)用trigger云函數(shù)返回的event對象,和使用定時觸發(fā)器返回的event對象的不同,用定時觸發(fā)器觸發(fā)云函數(shù)是獲取不到openId的,同時這里有一個Time時間是時區(qū)為UTC+0 的時間,比北京時間晚8個小時:

//在小程序端調(diào)用trigger云函數(shù)之后返回的event對象
{
  "userInfo":{
  "appId":"wxda99******7046",
  "openId":"oUL-m5F******buEDsn8"
  }
}


//使用定時觸發(fā)器觸發(fā)云函數(shù)之后返回的event對象
{
  "Message":"",
  "Time":"2020-06-11T11:43:35Z",
  "TriggerName":"tomylove",
  "Type":"timer",
  "userInfo":{
    "appId":"wxda99********46"
    }
}

三、定時觸發(fā)器的應用

定時觸發(fā)器的應用非常廣泛,以下僅舉一些常用案例,并加以說明:

1、結(jié)合消息推送

這里的消息推送不僅僅只是指訂閱消息,還可以是統(tǒng)一服務消息、公眾號的消息(可以用云函數(shù)開發(fā)微信公眾號)、小程序內(nèi)自己開發(fā)的通知(只是用戶只有在打開小程序時才能看到)、Email郵件等等。

比如用戶訂閱了日報、周報、月報等周期性的通知提醒或者我們需要給用戶發(fā)送一些匯總信息,就可以固定寫一個定時觸發(fā)器,比如我們需要給指定用戶發(fā)送工作周報,每周五晚上17點30分就定時從數(shù)據(jù)庫獲取數(shù)據(jù)發(fā)送消息,cron表達式寫法如下:

*  30  17  *  *  FRI  * 

還可以用來處理一些倒計時(指定時間點)的任務,比如節(jié)假日、紀念日以及一些活動時間節(jié)點(定時觸發(fā)器目前只能一個云函數(shù)配一個觸發(fā)器,但是可以提前管理),比如我們希望在六一兒童節(jié)的早上9點調(diào)用云函數(shù)給指定用戶群體發(fā)送消息:

0  0  9  1  6  *  * 

當然這樣的具體時間點顯得過于的不靈活,但是如果把時間與云開發(fā)數(shù)據(jù)庫結(jié)合起來,靈活性就會大很多,比如在運營上每天早上11點是你們用戶訪問最多的時間點,你只需要寫一個云函數(shù),把所有的活動都在這個時間點來推送,讓定時觸發(fā)器每天這個時間點都觸發(fā),有活動(數(shù)據(jù)庫里有數(shù)據(jù))就會發(fā)消息,如果沒有就不發(fā)(云函數(shù)調(diào)用一次的成本極低)。

如果是實時數(shù)據(jù),我們還可以把定時觸發(fā)器的頻率調(diào)高,每5秒就觸發(fā)一次,比如我們的數(shù)據(jù)庫只要有最新的數(shù)據(jù),就會發(fā)消息給指定用戶。盡管不是完全的實時,但是5秒的頻率和實時的差別也就不大了。你也可以根據(jù)情況,來調(diào)整觸發(fā)器的頻率,畢竟5秒和1分鐘的頻率給用戶的體驗差異并沒有太大,但是成本卻是12倍的關(guān)系。

可能你還希望在指定的時間段才觸發(fā)云函數(shù),比如你只希望在工作日、或者在早上9點到晚上18點才觸發(fā),在指定的時間段才觸發(fā)既可以讓觸發(fā)更精準不擾民,也可以節(jié)約成本,比如下面的觸發(fā)器就是工作日早上9點到12點和下午14點到18點這個時間段,每5秒觸發(fā)一次。

*/5  *  9-12,14-18 * MON,TUE,WED,THU,FRI * 

從以上案例我們可以了解到,云函數(shù)的定時觸發(fā)可以來自于cron表達式的配置,我們可以指定時間點時間段和頻率來達到我們想要的效果,同時這個時間“也可以來自于數(shù)據(jù)庫的配置”(偽裝),意思是我們可以設(shè)置觸發(fā)器的時間段或頻率,如果數(shù)據(jù)庫里有數(shù)據(jù)就發(fā)送,沒有數(shù)據(jù)就不發(fā)送,這樣就可以達到觸發(fā)器在時間上的靈活性了。

2、實時獲取數(shù)據(jù)

有的時候我們的數(shù)據(jù)并不是來自于數(shù)據(jù)庫,而是來自于第三方服務,比如前面介紹過的歷史上的今天的API,天氣的API,知乎日報的API等等,以及一些webhook,這些API和第三方服務提供的是json格式的文件,API的數(shù)據(jù)也會隨時更新,但是它們更新了卻并不會主動通知我們,這時我們可以使用定時觸發(fā)器向這些API發(fā)起請求,如果數(shù)據(jù)出現(xiàn)更新,我們就可以將更新的數(shù)據(jù)存儲到我們的數(shù)據(jù)庫或者進行其他處理,比如企業(yè)微信的機器人等機器人通知服務就是如此。

當然定期獲取的數(shù)據(jù)還可以是爬蟲,比如我們可以定期抓取指定關(guān)鍵詞的新聞或者指定網(wǎng)站的動態(tài),當爬蟲獲取到了不同的數(shù)據(jù)的時候,就將最新的動態(tài)以機器人消息或者其他方式進行及時的處理。

也就是說,我們無法實時監(jiān)聽到第三方API或者網(wǎng)站數(shù)據(jù)的變動,但是可以用定時觸發(fā)器來發(fā)起請求或者爬蟲抓取數(shù)據(jù),通過數(shù)據(jù)的變化來達到“實時”獲取數(shù)據(jù)的目的。

3、自動化處理

在數(shù)據(jù)庫的設(shè)計里,我們就提到有時候需要對數(shù)據(jù)庫里的數(shù)據(jù)進行定期的備份與刪除等清理維護工作,比如超過一定時間的日志,具有很強時效性的活動數(shù)據(jù),以及為了性能考慮而做的虛假刪除(數(shù)據(jù)庫性能與優(yōu)化有介紹)等,畢竟數(shù)據(jù)庫有一定的存儲成本而且過多無用數(shù)據(jù)也會影響數(shù)據(jù)庫的性能,我們可以寫一個云函數(shù)用定時觸發(fā)器來執(zhí)行此類任務。

我們還可以在用戶并發(fā)比較少的時間段(比如凌晨幾點)來處理一些比較耗云函數(shù)、數(shù)據(jù)庫性能的任務,比如圖片的審核與裁剪、縮略等處理,用戶評論是否包含敏感詞匯(盡管經(jīng)過安全處理,但是有時候我們還會設(shè)置特別的敏感詞),數(shù)據(jù)的匯總,云存儲里廢棄文件的刪除,用戶信息是否完整等等。

也就是說,結(jié)合定時觸發(fā)器,我們可以實現(xiàn)一些任務的自動化處理。

4、密集型任務分流

我們知道云函數(shù)在處理一些復雜性的任務時是有一些限制的,一是執(zhí)行時間的限制,建議在設(shè)置時執(zhí)行時間一般不要超過20s,最長不要超過60s;二是并發(fā)的限制,云函數(shù)最大的并發(fā)為1000;三是云函數(shù)在查詢數(shù)據(jù)庫時一次可以獲取最多1000條的數(shù)據(jù),面對這三個限制,我們應該如何處理密集型的任務呢,比如發(fā)送100萬封郵件,導出幾百萬條數(shù)據(jù)到Excel,發(fā)送十萬級的訂閱消息或消息等等,這個時候就可以使用到定時觸發(fā)器來處理了。

借助于定時觸發(fā)器,我們可以將需要耗時較長、對并發(fā)要求較高以及數(shù)據(jù)庫請求等的任務進行分批處理,比如我們要給100萬人發(fā)郵件:云函數(shù)發(fā)起數(shù)據(jù)庫請求,一次只請求1000條未發(fā)送過郵件的用戶(用where條件查詢某個字段,比如status:false),然后將郵件發(fā)給1000個人(可以參考前面的郵件發(fā)送),發(fā)完郵件并對這1000條數(shù)據(jù)進行標記(比如使用更新指令將status改為true),這樣下次查詢未發(fā)送過郵件的用戶時,就不會重復發(fā)送了。通過定時觸發(fā)器,每2秒執(zhí)行一次發(fā)送任務,幾十分鐘就可以處理完任務。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號