You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constexpress=require('express');constpkg=require('./package.json');constapp=express();functionvalidateCronRequest(req,res,next){console.log('X-Appengine-Cron',req.get('X-Appengine-Cron'),typeofreq.get('X-Appengine-Cron'));if(req.get('X-Appengine-Cron')!=='true'){returnres.status(403);}next();}app.get('/version',(req,res)=>{res.send(`version: ${pkg.version}`);});app.get('/cronjob/sync',validateCronRequest,(req,res)=>{res.sendStatus(200);});constPORT=process.env.PORT||8080;app.listen(PORT,()=>{console.log(`Server listening on port ${PORT}...`);});
app.yaml:
runtime: nodejs8service: cronjob-sec-unit
cron.yaml:
cron:
- description: 'sync job'url: /cronjob/syncschedule: every 1 secondstarget: cronjob-sec-unit
首先部署GAEservice:
gcloud app deploy
部署成功后,去GCP console - App Engine查看
紧接着部署GAE定时作业:
gcloud app deploy ./cron.yaml
报错
ERROR: (gcloud.app.deploy) An error occurred while parsing file: [/Users/ldu020/workspace/nodejs-gcp/src/app-engine/cron-jobs-second-unit-schedule/cron.yaml]
Unable to assign value 'every 1 seconds' to attribute 'schedule':
schedule 'every 1 seconds' failed to parse: line 1:8 mismatched input u'second' expecting set None
in "/Users/ldu020/workspace/nodejs-gcp/src/app-engine/cron-jobs-second-unit-schedule/cron.yaml", line 4, column 15
☁ cron-job-second-unit-schedule [master] ⚡ gcloud container clusters create nodejs-gcp --num-nodes=3
Creating cluster nodejs-gcp in us-west1-a... Cluster is being health-checked (master is healthy)...done.
Created [https://container.googleapis.com/v1/projects/shadowsocks-218808/zones/us-west1-a/clusters/nodejs-gcp].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-west1-a/nodejs-gcp?project=shadowsocks-218808
kubeconfig entry generated for nodejs-gcp.
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
nodejs-gcp us-west1-a 1.11.7-gke.12 35.199.144.38 n1-standard-1 1.11.7-gke.12 3 RUNNING
为kubectl命令设置默认集群,将kubectl的context设置为新创建的这个cluster
☁ cron-job-second-unit-schedule [master] ⚡ gcloud container clusters get-credentials nodejs-gcp
Fetching cluster endpoint and auth data.
kubeconfig entry generated for nodejs-gcp.
部署k8s cron job:
☁ cron-job-second-unit-schedule [master] ⚡ kaf ./k8s/cronjobs/update-db.yaml
cronjob.batch "update-db" created
实现GAE和GKE k8s cron job的秒级调度单位
问题
如何实现Google App Engine和Google Kubernetes Engine定时作业(
cron job
)的秒级调度(schedule
)单位?不同于
node-schedule
拥有秒级调度单位,可以将定时作业精确在某一秒执行。GAE
和GKE
的定时作业只能精确到分钟(min
)。在
GAE
的定时作业文档中,schedule
格式可以知道,时间单位的有效值包括:minutes
或mins
hours
在
GKE
的定时作业文档中,CronJob 使用所需的schedule
字段,该字段接受 Unix 标准crontab
格式的时间。所有 CronJob 时间均采用世界协调时间 (UTC):以及k8s Cron Job文档中的调度(schedule)都是Unix标准
crontab
格式的时间,GKE
使用kubernetes
,简称k8s
,来管理compute engine
集群(kubernetes
集群)。解决方案
GAE
cron job我们可以先尝试设置
GAE
定时作业的schedule
为every 1 seconds
,看看是什么效果。server.js
:app.yaml
:cron.yaml
:首先部署
GAE
service
:部署成功后,去
GCP
console - App Engine查看紧接着部署
GAE
定时作业:报错
错误说“不能将
every 1 seconds
赋值给schedule
,解析every 1 seconds
失败”。可见,GAE
定时作业schedule
并不支持秒级单位。修改
cron.yaml
,将schedule
设置为every 1 mins
:再次部署,部署成功后查看
GCP
控制台:查看该定时作业在
Stackdriver Logging
中的logs,验证该定时作业运行是否正常。通过日志的时间戳可以看到,该定时作业每分钟执行一次。
查看
App Engine
部署的service的logs:该service运行正常,路由
/cronjob/sync
每分钟被定时作业调用一次。接下来实现秒级调度单位的定时作业,本质上是将定时作业的最小调度单位——1分钟,再次划分成一系列秒级时间序列。对
Node.js
异步流程控制库async熟悉的同学可以马上想到用timeSeries
函数。我们这里将定时作业设置为10秒执行一次,修改后的代码如下:server.js
:部署后,查看
App Engine
service的日志:可以看到,我们的调度任务每10秒执行一次,通过
async.timeSeries
方法将GAE
定时作业的schedule
(1分钟),划分出了6段。GKE cron job
同理,我们也可以在
GKE
的定时作业上实现秒级调度单位。src/index.js
:示例代码和
GAE
例子的代码差不多,去掉了express
启动的HTTP
server的代码。k8s/cronjobs/update-db.yaml
:设置
schedule
为*/1 * * * *
,表示每分钟执行一次作业,具体执行什么作业?执行容器CMD
指令指定的启动脚本,即npm start
,即node ./src/index.js
。Dockerfile
:package.json
:下面关于打包
docker
image
,还有GKE
的使用和k8s cron job
的部署简单说下。打包
docker
image
:docker build -t cron-job-second-unit-schedule:1.1 .
设置
docker
tag
push
该docker
image
到GCR
registry:使用
gcloud
命令行工具创建kubernetes cluster
:为
kubectl
命令设置默认集群,将kubectl
的context
设置为新创建的这个cluster
☁ cron-job-second-unit-schedule [master] ⚡ gcloud container clusters get-credentials nodejs-gcp Fetching cluster endpoint and auth data. kubeconfig entry generated for nodejs-gcp.
部署
k8s
cron job:☁ cron-job-second-unit-schedule [master] ⚡ kaf ./k8s/cronjobs/update-db.yaml cronjob.batch "update-db" created
部署完成后,去
GCP
控制台查看:查看
update-db
定时作业的container logs
:可以看到该定时作业每10秒执行一次。
源码地址
GAE
: https://github.com/mrdulin/nodejs-gcp/tree/master/src/app-engine/cron-jobs-second-unit-scheduleGKE
: https://github.com/mrdulin/nodejs-gcp/tree/master/src/kubernetes-engine/cron-job-second-unit-schedule顺便推荐个工具:https://crontab.guru/ - 输入
*/1 * * * *
这样的crontab风格的schedule
,会输出文字表述的时间。The text was updated successfully, but these errors were encountered: