如何设计一个程序员都不知道执行时机的定时计划?

2019-03-29 13:52:33 +08:00
 kidteaing

最近有一个这样的需求,想和大家探讨一下。 需求:有一笔资金进入系统时,即为该笔资金创建一个 30 天内随机时间点的定时购买计划。 但要求在代码中和数据库中,所有开发都无法知晓具体的时间点,只知道在某个时间段会随机执行一次计划。 执行后,计划即完成。 这样的计划同一天大概有几百个到几千条在等待被执行中。

方案 1.加密数据库,但开发一定会获得数据库权限 结论:不可行

方案 2.把创建的时间点用私钥加密存在数据库中,但由于开发一定会获得的私钥 结论:不可行

方案 3.把创建的时间点在内存中常驻,但性能不知道会不会受影响,且服务器重启,似乎只能重新安排一次计划…

求各位指教

3588 次点击
所在节点    程序员
35 条回复
jingxyy
2019-03-29 14:01:01 +08:00
方案 2 挺好的鸭~开发时用一套密钥,生产时用另一套,生产环境密钥不给开发就好了。
libook
2019-03-29 14:03:18 +08:00
信息安全里有一个法则,就是没有物理隔离的前提下任何措施都是不安全的。

所以不管用什么方案,开发和运营环境完全隔离才是信息安全的基础,比如开发环境全部是假数据假交易,而正是环境程序和数据库跑在一个封闭的局域网内,只对外开放有限的业务接口,而任何人员在没有经过授权的时候不能进入到这个局域网内。
geelaw
2019-03-29 14:04:58 +08:00
开发没有数据库的权限。

此外你还可以用一个随机过程模拟此事,也就是动态决定发生的时机。数据库里记录操作内容和截止时间,把时间量化,比如要求在未来 720 小时内必须进行某个操作,时间量子是 1 小时,那么过了第一个小时后以 1/720 的概率执行操作,如果决定执行则执行并删除记录;否则,再过一个小时后以 1/719 的概率执行操作;如此类推。
ryd994
2019-03-29 14:07:39 +08:00
为什么开发一定会获得数据库权限?
你们不做代码审计么?你们没有权限控制么?开发在开发期间有临时权限,之后如果需要在线维护就只能通过审计后拿到一个短时间的权限。
而且真的涉及重要数据的话,开发者本身就要经过背调。

还可以做数据分离。worker 需要创建时间时通知 controller。等到时间点到了 controller 才通知 worker 执行。对 controller 进行更严格的安全审计。
Kirscheis
2019-03-29 14:16:27 +08:00
有的是方法。。

1. 生产环境不给开发权限就可以

2. 如果一定要给开发权限,可以用外部随机源临时决定执行

2. 或者,如果不想用外部随机源,可以学习 bitcoin。即计划设定者给出的不是具体的时间,而是有一定难度的问题,一旦问题被解出就执行。这样就没有人知道问题被解出的准确时间,只能知道其分布。
zqx
2019-03-29 14:53:31 +08:00
房屋装修的时候,装修工人用一把钥匙,业主用一把钥匙,验收后施工队的钥匙自动失效,可以参考这个思路,让开发环境的秘钥在生产环境失效
kidteaing
2019-03-29 15:35:13 +08:00
@geelaw 这个算法每个小时的概率都是平均的吗 感觉上好像是越到后面几率越大的分布
keepeye
2019-03-29 15:36:20 +08:00
那就不要先算出时间点 每隔一段时间 随机一下是否要执行任务 再随机取 0~1 个任务
liqingcan
2019-03-29 15:42:35 +08:00
“无法知晓具体的时间点,只知道在某个时间段会随机执行一次计划。”这个时间段具体到某一天但是不知道哪一个时间行不行。可以的话能不能这样:
资金入库的时候随机生成计划执行的日期( 30 天内的随机某一天)然后每天有个定时任务在跑,作用是把今天(包含今天之前)还没有执行的数据拿出来,然后给这些数据设置一个今天内随机的时间点执行的定时任务来处理这条数据。

我的一个简单的想法。不知道可不可行。
ldm0
2019-03-29 15:54:04 +08:00
@kidteaing 是平均的,随便计算一下就知道了。
exiledkingcc
2019-03-29 15:54:40 +08:00
很简单的方案。
1,生成一个随机时间,以秒为单位。
2,加盐并且 hash
3,每一秒计算对比。
不过可能存在性能问题,不过看题目描述的数量量并不大。
或者改进一下,先按小时 hash,每个小时先筛选一部分,再每一秒去对比。
exiledkingcc
2019-03-29 16:01:58 +08:00
还可以设计一个函数 F(X),使它满足对于任意输入,在有限次的迭代后会得到一个确定值 K。比如“ 3x+1 ”问题。
这个可能需要设计使得这个有限次不超过一个固定的值,毕竟这里要求 30 天之内。
方案就是这样:
1.对于每个任务生成一个随机数
2.然后以一定的速度遍历所有的任务的随机值,进行迭代
3.如果结果为 K,则执行任务,否则存下结果,后面继续迭代。
no1xsyzy
2019-03-29 16:02:57 +08:00
@exiledkingcc 如果没有性能问题那么直接跑个 BF 就知道了,因为接下来的时间就是字典。
你这样 hash 唯一的办法就是用强密码验证手段,跑一个需要一时间粒度,那么跑出来的时间正好发生。
但还是架不住堆量和专用电路。
chenliang0571
2019-03-29 16:14:18 +08:00
资金进入系统立即创建定时购买计划,但是这个计划对任何人都不可见。
这跟下面这个方案有什么区别:
任务定时触发,随机选择某些资金进行购买。
linKnowEasy
2019-03-29 16:17:06 +08:00
方案 2.把创建的时间点用私钥加密存在数据库中,但由于开发一定会获得的私钥 结论:不可行

非对称加密, 生成 一对 公钥, 私钥
用 公钥 加密. 程序员只知道 公钥
至于解密的时候, 使用私钥进行解密

或许还可以加上 , 私钥 + 分割方法 , 分割给 N 个人(产品 开发 技术总监)保存.

需要私钥的时候. 每个人都给出自己保存的字段, 然后进行组合

类似 私钥 asdfghjkl
分割为 asd17 fgh27 jkl37
asd 1 7
fgh 2 7
jkl 3 7
私钥分割 组装序号 分割方法
kidteaing
2019-03-29 16:21:21 +08:00
@exiledkingcc 只要我知道盐 就能提前穷举每一秒 算出数据库里的密文时间了
exiledkingcc
2019-03-29 16:25:28 +08:00
@no1xsyzy @kidteaing
hash 这个方案确实存在这样的问题,我还是觉得前面随机的方案最好。
jinhan13789991
2019-03-29 16:25:47 +08:00
养一只鸡,搞个手环记录鸡每天的步数,用 步数%30 作为执行天数倒计时,,步数 %24 作为执行小时倒计时,步数%60 作为执行分钟倒计时...
kidteaing
2019-03-29 16:26:08 +08:00
@geelaw 的确是的 感觉自己高中数学白学了…
sznewbee096
2019-03-29 16:34:07 +08:00
时间随机的算法,客户买和中彩票概率的方式,30 天内就是可能无法买到。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/549911

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX