热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

定时器在大型web项目中的运用和完成

在大规模散布式体系中,每一个营业都多是集群,每一个营业机都邑发作定时使命,差异的营业会有差异的使命治理需求,一致的使命调理和治理变得异常有必要。定时怎样正确,大批的定时被同时触发怎

在大规模散布式体系中,每一个营业都多是集群,每一个营业机都邑发作定时使命,差异的营业会有差异的使命治理需求,一致的使命调理和治理变得异常有必要。

  1. 定时怎样正确,大批的定时被同时触发怎样办?

  2. 定时终了的时刻,怎样关照营业机去处置惩罚呢?

  3. 某台营业机下线了怎样办?

  4. 怎样供应使命更新、删除功用?

基础模子以下图:
《定时器在大型web项目中的运用和完成》

定时器在社会中有着普遍的运用,比方天天叫你起床的闹钟。在软件项目中,定时器也被运用到了各方各面,本文将从 web 项目入手,报告定时器,本文的例子都以 node 为例。

为何要用定时器?

没有什么比机械越发准时!在我打仗单片机的时刻,已最先叹息,为何机械时候能够做到这么准!

比方文章的定时宣布、商品的准点最先抢购、运动定时高低架,一定不会是一个又一个治理员在背景帮你点击按钮,完成操纵!体系的准时能够定位到毫秒级,虽然每一个用户能够和效劳器的时候不一致,秒级的差异照样在可接受局限的,然则在某些范畴也会有许多邃密到毫秒级的定时使命需求,比方航空航天、定时炸弹等等。

定时器总类

定时器有两种 intervaltimeout, 对应反复使命和一次性使命。在我的明白里,interval 使命只是在 timeout 的时刻再次注册了本使命。

// 反复性使命
var timer = setInterval(function(){
// do something
}, milliseconds)

// 一次性使命
var timer = setTimeout(function(){
// do something
}, milliseconds)

unix crontab 能处理题目吗?

crontab 并不能准确到秒,crontab 的最小粒度是分,即当第一位是「*/1」时,即最小单元是每分钟执行,(不消除你们有奇淫技能能够做到秒级掌握的)。unix 自身支撑壮大的定时使命治理 crontab,定时的花样也是壮大得令人惊叹。

* * * * * *
┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │ |
│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
│ │ │ │ └───── month (1 - 12)
│ │ │ └────────── day of month (1 - 31)
│ │ └─────────────── hour (0 - 23)
│ └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, optional)

1)Cron 表达式的花样:秒 分 时 日 月 周 年 (可选)。

字段名 许可的值 许可的特别字符
秒 0-59 , – * /
分 0-59 , – * /
小时 0-23 , – * /
日 1-31 , – * ? / L W C
月 1-12 or JAN-DEC , – * /
周几 1-7 or SUN-SAT , – * ? / L C #
年 (可选字段) empty, 1970-2099 , – * /

「?」字符:示意不确定的值

「,」字符:指定数个值

「-」字符:指定一个值的局限

「/」字符:指定一个值的增添幅度。n/m 示意从 n 最先,每次增添 m

「L」字符:用在日示意一个月中的末了一天,用在周示意该月末了一个礼拜 X

「W」字符:指定离给定日期近来的工作日 (周一到周五)

「#」字符:示意该月第几个周 X。6#3 示意该月第 3 个周五

Cron 表达式类型:

每隔 5 秒执行一次:/5 * ?

每隔 1 分钟执行一次:0 /1 ?

天天 23 点执行一次:0 0 23 ?

天天凌晨 1 点执行一次:0 0 1 ?

每个月 1 号凌晨 1 点执行一次:0 0 1 1 * ?

每个月末了一天 23 点执行一次:0 0 23 L * ?

每周礼拜天凌晨 1 点执行一次:0 0 1 ? * L

在 26 分、29 分、33 分执行一次:0 26,29,33 * ?

天天的 0 点、13 点、18 点、21 点都执行一次:0 0 0,13,18,21 ?

每种开辟言语都供应了 crontab 的相干封装,让开辟者挪用起来随心所欲。以 node 为例:


require('crontab').load(function(err, crontab) {
// create with string expression
var job = crontab.create('ls -la', '0 7 * * 1,2,3,4,5');
});

你在 github 搜刮 crontab 能搜到主流言语的完成。

有个题目,定时器不准时!

setInterval 的回调函数并非到时后马上执行,而是等体系盘算资本余暇下来后才会执行。而下一次触发时候则是在 setInterval 回调函数执行终了以后才最先计时,所以假如 setInterval 内执行的盘算过于耗时,或许有其他耗时使命在执行,setInterval 的计时会愈来愈不准, 耽误很厉害。crontab 也是一样的道理。

var startTime = new Date().getTime();
var count = 0;
//耗时使命
setInterval(function(){
var i = 0;
while(i++ <100000000);
}, 0);
setInterval(function(){
count++;
console.log(new Date().getTime() - (startTime + count * 1000));
}, 1000);

效果

126
176
163
112
109
107
203
189
170

固然,不消除你们有奇淫技能能够做到秒级掌握的。

不计其数定时使命时怎样治理?

Crontab 存在使命上限(实在我也不晓得上限是多少,晓得的贫苦通知我),使命的同步、备份治理都比较贫苦,也会有比较多的并发题目须要处置惩罚。在散布式体系中,零丁去布置一个定时使命机械也是可行的。不过使命调理、定时终了关照客户端也须要蛮多工作量的。

unix 的 crontab 不再是我们的第一挑选,每种编程能够都有定时使命治理的相干框架。比方 java 的 Quartz,Python 的 APScheduler。nodejs 的 node-schedule。然则这些东西是否能真的满足你的需求呢?

So,我们须要一个定时使命治理平台。

思绪和完成

目的

  1. 营业方能够定义定时时候、时候终了的触发使命

  2. 营业方能够更新或许删除已宣布的定时使命

  3. 定时使命治理平台一致吸收和调理使命

重要处理两个题目:

  1. 设置正确的定时时候

  2. 时候终了触发客户端,不能反复消耗

redis 在 2.8.X 版本能够开启了键空间关照,更多相干请移步 Redis Keyspace Notifications。(默许不开启,3.x 版本彷佛就失效了。),redis 支撑的许多键空间事宜,比方:DEL,RENAME,EXPIRE等等,redis 自身能够定义某个键的逾期时候,ttl key。

这个值恰好用来设置为定时使命的时候。更多相干请移步 Redis Keyspace Notifications。假如客户端定阅了某种划定规矩的键关照,比方逾期,那末在某个键逾期的时刻就会收到一个关照,这个事宜就是定时终了,能够通知营业机能够开启使命了。

可假如有多个 redis 客户端定阅了某个键的逾期时候,那末使命照样会被触发许屡次。 由于每一个客户端
都是同等的,你能定阅,我一样能够定阅。处理办法就是 生产者和消耗者形式。同一个逾期音讯只能被消耗一次。

重点来了

把一切的定时使命根据定时开启的时候倒序分列,存入 sorted Sets , 把时候设置为 score。如许就会构成一个根据时候排好序的鸠合,能够根据时候前后顺次掏出一切的使命,须要新增和修正使命,也是能够经由过程 redis 的敕令完成的。

定时治理效劳器每 1000ms 去取 sorted sets 顶部的数据,假如获取到的 task 离触发小于 1s,那末就能够执行 pop() 操纵,示意这个使命最先被调理执行,由于 redis 的 pop() 是原子性的,同一个 task 永久只会被消耗一次。如许就处理了 redis 键空间关照会被反复消耗的题目。

伪代码以下:

var taskSorts = new Sets(task1, task2, task3); // 在 redis 中竖立按时候排序的鸠合
// 每隔一秒执行一下操纵,
var newOne= taskSorts.zrank(-1); // 获取到最快发作的使命
if(newOne.time <1000){ // 假如满足消耗前提
newOne= taskSorts.pop(); // 消耗该使命,反复此轮回,继承消耗下一个使命
setTimeout(function(){
// dosomething
}, newOne.time)
}

使命触发

  1. 使命的提交和触发都应该在营业方完成。定时使命治理平台只是协助治理和调理使命。在定义的使命内里定义好使命执行的回调参数和接口。

  2. 客户端定义使命的时刻,同时注册好定时终了的回调接口,或许应该在项目启动的时刻,就注册好一切回调的接口。由于同一个营业的 A 机械提交了使命,触发的时刻能够 A 机械下线了,只能定时使命平台只能去触发营业 A 的 B 机械了。

  3. 引入跨效劳长途挪用。营业和定时使命治理平台能够不在同一个机械,能够散布在差异的 ip。听起来很庞杂,实际上跨言语的挪用挪用体式格局有许多,比方 REST API、音讯行列、RPC。我的团队挑选了 Thrift(Facebook 开源的,跨言语的,如今同享给了 Apache 基金)。以上的体式格局都能够完成使命只被触发了一次,长途关照给客户端(使命注册方)。

制品 &#8212; nodejs 的完成 cron-redis

https://github.com/MZMonster/cron-redis
重要依靠 bull 完成了使命行列的治理功用完成的定时使命治理东西。

demo:

// 就如许定义,3 秒钟以后,hello 函数将被执行。
function hello (x, y){
console.log(new Date());
console.log(x + ' + '+ y +' = %s', x+y);
}
// 我是一个使命
var task1 = {
method: hello.name, // 使命回调的函数
params: [2, 3], // 使命执行的参数
rule: moment().add(3, 's').toDate() // 使命执行距离,支撑 crontab 花样
}
queue.register(hello)
queue.publish(task1);

假如你请求不高,unix 自带的 crontab 也充足你折腾了。运用 redis 来完成定时也是一种极好的思绪,cron-redis 值得你去试一试。

该库只是一个定时使命的库,实际上能够经由过程以上的思绪完成微效劳————定时使命治理平台。经由过程 cron-redis 组合长途效劳挪用 thrift、效劳的注册发明东西 zookeeper,定时使命治理平台分分钟就被搭建了(等我下一篇文章吧,分分钟搭建微效劳)。


推荐阅读
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了在使用vue和webpack进行异步组件按需加载时可能出现的报错问题,并提供了解决方法。同时还解答了关于局部注册组件和v-if指令的相关问题。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
author-avatar
书友64457430
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有