在使用单实例Redis时, 我们可以使用./redis-cli -h redis_ip -p redis 6379 --ldb --eval script.lua somekey , arg1 arg2
命令轻松的进入debug模式调试lua脚本
在正常情况下, 进入debug模式后可以使用一系列命令来执行控制脚本的执行, 使用help命令应该可以看到如下界面
Redis中的时间计算
在使用Redis时, 通常会使用EXPIRE
, PEXPIRE
系列函数设置生存时间, 当需要获取超时时间时使用TTL
, PTTL
获取剩余的生存时间。
同样的, 还可以使用EXPIREAT
, PEXPIREAT
以unix timestamp格式设置超时时间点, 但需要注意的是, Redis 7.0 之前没有函数能获取设置timestamp, 只能使用TTL
, PTTL
获取剩余的生存时间。
在实际使用中, 经常需要比较新旧生存周期的大小来决定是否更新数据, 如果你很幸运的使用7.0及之后的版本, 可以使用EXPIREAT
, PEXPIREAT
配合GT
参数来设置过期时间, 如果新的过期时间小于已有过期时间, 则会返回0
。
那么老版本的Redis该如何实现这种功能呢?
terraform使用jsonencod输出json字符串
在terraform中,常见的输出json字符串或创建json文件的手段是使用流式标记, 如下代码所示:
1 | resource "user" "admin" { |
但是这样的写法不仅繁琐,也容易出错,由于字符串中夹杂大量的变量引用,DATA
标记中间的内容很难提供语法检查
常见的错误包括:
- 最后一个元素不能带逗号
- 引号及括号没有闭合
- 夹杂中文字符
并且这些错误属于json语法问题,在terraform plan
甚至apply
期间是无法发现的,等到resource部署之后才被发现,可能会造成无法挽回的结果。
上述代码的json中便缺失一个逗号,读者是否有看出来呢?
为了解决这些问题,建议大家使用jsonencode
函数代替直接编写字符串,得益于tf在语法上的良好兼容,从json迁移到jsonencode
并不需要多少工作。
例如上述代码使用jsonencode可以简单的写成如下形式
1 | resource "user" "admin" { |
可以看到几乎就是简单的使用jsonencode讲原来的内容包了起来。
更进一步的,可以整理成如下形式
1 | resource "service" "portal" { |
或者
1 | resource "service" "portal" { |
由于tf语法对逗号非常宽容,因此不论写不写逗号都不会影响输出的json,同时就算有语法错误,在plan阶段也可以轻易发现,还能少写很多引号。
因此推荐大家在输出json时都使用这种方法。
acme使用AliyunDNS验证
安装acme
1 | curl https://get.acme.sh | sh -s [email protected] |
使用阿里云dns认证方式
文档: https://github.com/acmesh-official/acme.sh/wiki/dnsapi
1 | export Ali_Key="xxxxxxxxxxxxxxxx" |
安装密钥
1 | acme.sh --install-cert -d your.domain.com --key-file /etc/nginx/your.domain.com.key --fullchain-file /etc/nginx/your.domain.com.pem --reloadcmd "sudo systemctl restart nginx" |
谨慎使用CREATE-SELECT语句复制表数据
在复制表时,可以使用CREATE-SELECT来同时复制表结构和数据
1 | CREATE TABLE new_table SELECT * FROM old_table; |
但这样做实际上是有问题的
原因在于,CREATE-SELECT在创建新表时仅复制了字段类型,但是不会设置主键子增等属性。
因此,在复制表时,最好还是使用CREATE-LIKE和INSERT来复制
1 | CREATE TABLE new_table LIKE old_table; |
一次线上数据库结构修改
由于早期数据库设计不合理,需要修改线上数据库表结构,比较麻烦的是新设计将原来的一个表拆成了两个表,并且允许了表之间存在一对多关系。
配置一个Jetbrain风格的MacOS Terminal
word文档参考文献按引用顺序自动调整编号
最近在写毕业论文,因为不断的修改添加了大量了引用,导致编号非常混乱,显得非常不美观,
又恰逢女朋友学校强制要求引用目录按照引用顺序排序,因此不得已开发了一个程序来对引用进行自动编号,
开发过程一波三折,难度也比一开始的设想大了很多,
因为需要处理书签引用和纯手写的引用,本来是想使用PyDocX的,测试后发现PyDocX读取书签引用有问题,
最后只能手写个简单的代码解析docx,虽然很麻烦但是总算是搞定了。
记一次rpc接口无返回调试经历
现象描述
偶然发现一个线上服务不返回的badcase,在输入特定一张图片时,分析服务会直接断开连接而不返回任何数据,这种情况是非常罕见的,因为通常来说即便是内部服务报错的情况下,也会被框架捕获从而返回一组错误码,而不会直接断开连接不返回任何数据。
初步分析
考虑到这个现象可以被特定数据触发,且触发后业务依旧可以正常处理后续请求,因此认为是业务逻辑的问题,但是还不清楚业务逻辑是如何影响框架导致连接被关闭的。
初步调试
现象能稳定复现,应该是比较容易调试的,我首先将一台线上服务熔断,手动登录后打开日志调试。
请求后惊奇的发现业务逻辑没有任何报错
,由于业务逻辑不是我写的,所以整个逻辑对我来说如同黑箱一样。
为了找到问题的原因,我将一张正常图片产生的日志和问题图片产生的日志都记录下来,并逐行对比,遗憾的是没有发现任何不同
。
再次分析
到这一步已经是山穷水尽了,因为通过日志打点分析,整个业务逻辑是正常return的,现在只能将目光转向框架层,但是遗憾的是框架层同样是一个黑箱,并且通过分析框架层的日志,也没有发现任何异常。
结合连接直接断开的现象,我怀疑框架层中的worker在返回请求时崩溃,并且被自动重启了。而导致崩溃的原因,只能是在业务逻辑中返回的response结构体上。
大胆猜测,是返回值被设置了特殊值导致框架层崩溃的。
再次调试
将设置response的代码全部注释后,果然可以正常返回空结构体,确认了之前的猜测。
之后通过二分注释的方法,确认了问题出在一个float字段上,当float字段被设置为Nan时,会导致无返回的现象发生,至此问题确认。
总结
protobuf本身是支持nan作为值的,因此是框架层自己的兼容性问题,但是这种一言不合就暴毙的问题排查,着实令人头疼。