记录-new Date() 我忍你很久了!
Posted 林恒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录-new Date() 我忍你很久了!相关的知识,希望对你有一定的参考价值。
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
大家平时在开发的时候有没被new Date()折磨过?就是它的诸多怪异的设定让你每每用的时候,都可能不小心踩坑。造成程序意外出错,却一下子找不到问题出处,那叫一个烦透了…… 下面,我就列举它的“四宗罪”及应用思考
可恶的四宗罪
1. Safari浏览器不兼容YYYY-MM-DD这样的格式
new Date(\'2023-1-1\');
这行代码无论在Macbook中还是iPhone中的Safari浏览器,返回的都是Invalid Date, Safari浏览器目前还理解不了YYYY-MM-DD这样的格式,只支持YYYY/MM/DD。这就造成你在Windows环境下的代码正常原型,而你的其他部分用户异常显示;
2、月份的索引是以0为起点的,而年份、日期却不是
new Date(2023,1,1);
得到的是一个反直觉的结果:2023年2月1日!!!
Wed Feb 01 2023 00:00:00 GMT+0800 (中国标准时间)
同样的,对应的方法.setMonth()也是从0开始设置的。就……很无语!
3、年份小于100,默认以19xx或20xx开头
一般的应用可能碰不到这样的情况,毕竟现在是21世纪了,我们在应用中看到的大部分时间都是现代的。但是当你需要格式化公元元年-公元100年之间的时间,你就该懵了!
举个栗子:
new Date(2023,1,1);
能正常返回时间对象
Wed Feb 01 2023 00:00:00 GMT+0800 (中国标准时间)
但是当年份调到了东汉时期,公元50年2月1日
new Date(50,2,1);
恭喜你,你直接迎接了新中国!见证了历史:
Wed Mar 01 1950 00:00:00 GMT+0800 (中国标准时间)
是的,Date直接帮你加了1900年的时间!如果需要获得公元50年2月1日,得这么写
new Date(\'0050-02-01\');
返回:
Tue Feb 01 0050 08:05:43 GMT+0805 (中国标准时间)
请千万不要尝试添加时间,因为你又要裂开了……
new Date(\'0050-02-01 00:00:00\');
返回:
Wed Feb 01 1950 00:00:00 GMT+0800 (中国标准时间)
你就说,它任性吧?!别气馁,别忘了标题还有20xx的情况
new Date(\'10-11-12\');
返回:
Thu Oct 11 2012 00:00:00 GMT+0800 (中国标准时间)
就是说,当年份为2位数的时候,这种字符串格式的,构造函数把最后面那个当作年份,而且默认它为20xx年
4、日期初始化不统一,存在时区差异
你相信吗?\'2018-01-01\'和\'2018/01/01\'是不同的,存在一定时差
new Date(\'2018-01-01\');
返回:
Mon Jan 01 2018 08:00:00 GMT+0800 (中国标准时间)
然而……
new Date(\'2018/01/01\');
返回:
Mon Jan 01 2018 00:00:00 GMT+0800 (中国标准时间)
看到差异了吗?两种格式返回的时间是不同的,查了个北京时间与格林尼治时间的时差,8个小时啊!
应用思考
在日常开发中,我们应用new Date()无非就是对时间运算及时间的格式化。
1. 时间的计算
需要方便对比两个时间的早晚,可以分别对年份、月份、日期、小时等进行单独比较。而我们现有的操作还比较麻烦。
比如,我想知道2003年7月13日北京申奥成功到2008年8月8日北京奥运开幕中间差了几天,如何快速计算?这样的计算在日常开发中还比较常见,特别是电商网站对抢购环节的倒计时。
还有诸如,当前时间在100天以后又是几月几号呢?
2. 时间的比较
给定两个时间,判断哪个在前,哪个在后;给定一个时间返回,判断某个时间是不是在这两者之间。
3. 时间的格式化
在网站开发中,我们最常见的就是对后台返回时间戳的格式化显示。而原生带来的仅有年份如何获取,月份如何获取,日期如何获取的方法,就方便的无非就是toISOString()这样的方法,但是返回的却不一定是你要的格式。如何快速实现自定义格式化字符串,这也是一门技术。
困境的解决
想必大家日常中也用过 moment.js、dayjs、data-format这些工具吧?确实挺好用的,我也就顺便说一下而已。因为我要开始打广告了……面对着new Date()各种无语的坑,我慢慢的也弄了一个不大的库(250行左右代码)。
你要说我的库和前面的几个库对比,有啥改进的或者有啥特点的吗?
Redis哨兵原理,我忍你很久了!
Redis 主从复制的作用中有这么一句话“主从复制是高可用的基石”,那什么是高可用呢?高可用就是减少系统不能提供的时间,也就是常听到的以 6 个 9 为基准。实现高可用必不可少的就是哨兵和集群。
什么是哨兵
哨兵的作用
如何配置哨兵
哨兵工作原理
总结
centos 7.3
redis 4.0
redis 工作目录 /usr/local/redis
在虚拟机进行模拟操作
什么是哨兵
当主节点宕机后主从复制就没有存在的意义了,数据为王的时代没有了数据何谈什么高可用。
哨兵,英文名 Sentinel,是一个分布式系统,用于对主从结构中的每一台服务器进行监控,当主节点出现故障后通过投票机制来挑选新的主节点,并且将所有的从节点连接到新的主节点上。
哨兵的作用
监控:监控谁?支持主从结构的工作一个是主节点一个是从节点,那肯定就是监控这俩个了。监控主节点和从节点是否正常运行;检测主节点是否存活,主节点和从节点运行情况。
通知:哨兵检测的服务器出现问题时,会向其他的哨兵发送通知,哨兵之间就相当于一个微信群,每个哨兵发现的问题都会发在这个群里。
如何配置哨兵
准备工作
我们开始配置哨兵,开启八个客户端,三个哨兵、一个主节点、俩个从节点、一个主节点客户端、一个从节点客户端。
sentinel.conf 配置解读
哨兵使用的配置文件是 sentinel.conf,如下图:
我们来对 sentinel.conf 配置信息进行解读:
但是大多数都是注释,这里给大家提供一个命令来过滤这些无用信息:
cat sentinel.conf | grep -v '#' | grep -v '^$'
②dir /tmp:存储哨兵的工作信息。
③sentinel monitor mymaster 127.0.0.1 6379 2:监控的是谁,名字可以自定义,后边的 2 代表的是,如果有俩个哨兵判断这个主节点挂了那这个主节点就挂了,通常设置为哨兵个数一半加一。
④sentinel down-after-milliseconds mymaster 30000:哨兵连接主节点多长时间没有响应就代表挂了。后边 30000 是毫秒,也就是 30 秒。
⑤sentinel parallel-syncs mymaster 1:这个配置项是指在故障转移时,最多有多少个从节点对新的主节点进行同步。
这个值越小完成故障转移的时间就越长,这个值越大就意味着越 多的从节点因为同步数据而不可用。
⑥sentinel failover-timeout mymaster 180000:在进行同步的过程中,多长时间完成算有效,系统默认值是 3 分钟。
开始配置
使用命令 cat sentinel.conf | grep -v '#' | grep -v '^$' > ./data/sentinel-26379.conf 把 sentinel.conf 过滤后的信息移到 /usr/local/redis/conf 下。
再快速的复制两个哨兵配置文件,端口为 26380 和 26381:
sed 's/26379/26381/g' sentinel-26379.conf > sentinel-26381.conf
测试主从复制处于正常工作状态,启动三台 redis 服务器,端口分别为 6379、6380、6381:
lag 的值为 0 和 1 都属于正常。
测试主节点添加一个 hash 值,hset kaka name kaka:
经过测试我们的主从结构是正常运行的,如下图:
启动一个哨兵 redis-sentinel 26379-sentinel.conf:
连接 26379 哨兵,主要是最后一行,监控的主节点名为 mymaster,状态正常,从节点有俩个,哨兵数量为 1 个。
再来查看一下 26379 的哨兵配置信息,这个时候已经改动了:
在启动一个 26380 的哨兵,redis-sentinel 26380-sentinel.conf,这里注意一下最后一行多了一条信息,这个 id 就是我们 26379 配置文件新增的 id。
然后我们来到哨兵 26379 的客户端,同样也是新增的 26380 哨兵的 id:
这个时候我们再查看一下 26379 哨兵的配置文件,第一次查看配置文件是没有配置 26380 哨兵的,第二次查看时配置了 26380 哨兵后添加的信息。
直到这里我们对哨兵的配置就结束了,接下来我们把主节点 Master 给宕掉。
等待 30 秒后我们来到 26379 哨兵的客户端,这里新增了一些信息,那么这些信息都做了什么呢?让我们细细道来。
当我们在重新把 6379 的 redis 服务器上线后,就可以看到哨兵服务端响应了俩句。一句是去除 6379 的下线。最后一句就是重连 6379 到新的主节点上。
在新的主节点 6380 添加 list 类型:
在 6379 和 6381 获取这个值,至此,我们的哨兵模式就配置完成了。
哨兵工作原理
监控工作流程
通知工作流程
sentinel 会给主从的所有节点发送命令获取其状态,并且会把信息发布到哨兵的订阅里。
故障转移原理
这时哨兵已经检测到问题所在了,那么到底是那个哨兵去负责推选新的主节点呢!不能是张三也去,李四也去,王五也去,这样就乱套了、于是就需要在所有的哨兵里选出领头的,那么是如何选的呢!请看下图。
假如 sentinel1 发的早,那么 sentinel2 的票就会投给 sentinel1。
假设说是 sentinel1 的票数满足总哨兵数量的一半之多后,sentinel1 就会当选。这个时候就进行到了下一个阶段。
先把不在线的干掉:
响应慢的干掉,sentinel 会给所有的 redis 发送信息,响应速度慢的就会被干掉。
首先会根据优先级,如果优先级一样在进行其他判断。
判断 offset 偏移量,判断数据同步性,假如说 slave4 的 offset 为 90,slave5 偏移量为 100。
那么哨兵就会认为 slave4 的网络是不是有问题,于是就会选 slave5 为新的主节点。那如果说是 slave4 和 slave5 的 offset 相同呢!还有最后一个判断。
-
最后一步就是判断 runid 了,也就是职场中的论资排辈了,也就说根据 runid 的创建时间来判断,时间早的上位。
选出新的主节点后就要对所有的节点发送指令了。
总结
首先进行监控,并且所有的哨兵同步信息。
哨兵向订阅里边发布信息。
故障转移:哨兵发现主节点下线→哨兵开启投票竞选负责人→由负责人推选新的主节点→新的主节点断开原主节点,并且其他的从节点连接新的主节点,原主节点上线后作为从节点连接。
简介:从业三年,从搬砖一样的生活方式换成了现在有“单”而居的日子。当然这个单不是单身的单!虽然极尽苛刻的技术学习但也远不及客户千奇百怪的要求。进入了朝九晚六,虽然躲过了风吹日晒,但是仍然很享受那些熬得只剩下黑眼圈的日子。坚持学习、坚持写博、坚持分享是咔咔从业以来一直所秉持的信念。希望在诺大互联网中咔咔的文章能带给你一丝丝帮助。
编辑:陶家龙
征稿:有投稿、寻求报道意向技术人请联络 editor@51cto.com
精彩文章推荐:
以上是关于记录-new Date() 我忍你很久了!的主要内容,如果未能解决你的问题,请参考以下文章