任何可以產(chǎn)生事件,觸發(fā)云函數(shù)執(zhí)行的均可以被稱為觸發(fā)器,而定時觸發(fā)器則是可以處理周期性的事情,比如時報、日報、周報等通知提醒,也可以處理倒計時任務,比如節(jié)假日、紀念日以及你可以指定一個具體時間的倒計時任務,除此之外,定時觸發(fā)器還可以用來周期性處理一些定時任務。比如定期清理一些不必要的數(shù)據(jù),定期更新集合內(nèi)的數(shù)據(jù)。
配置了定時觸發(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": [
{
"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ā)器”。
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秒;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ā)器的使用非常簡單,使用開發(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ā)器的應用非常廣泛,以下僅舉一些常用案例,并加以說明:
這里的消息推送不僅僅只是指訂閱消息,還可以是統(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ā)器在時間上的靈活性了。
有的時候我們的數(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ù)的目的。
在數(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)一些任務的自動化處理。
我們知道云函數(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ā)送任務,幾十分鐘就可以處理完任務。
更多建議: