V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kidteaing
V2EX  ›  程序员

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

  •  
  •   kidteaing · 2019-03-29 13:52:33 +08:00 · 3543 次点击
    这是一个创建于 2048 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    求各位指教

    第 1 条附言  ·  2019-03-29 15:27:16 +08:00

    感激大家的踊跃参与 这个题的本意应该是 任何人 都不知道该时间点 包括所有开发 技术总监 产品经理 而不是针对某个开发

    35 条回复    2019-03-30 16:38:39 +08:00
    jingxyy
        1
    jingxyy  
       2019-03-29 14:01:01 +08:00
    方案 2 挺好的鸭~开发时用一套密钥,生产时用另一套,生产环境密钥不给开发就好了。
    libook
        2
    libook  
       2019-03-29 14:03:18 +08:00   ❤️ 1
    信息安全里有一个法则,就是没有物理隔离的前提下任何措施都是不安全的。

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

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

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

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

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

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

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

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

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

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

    类似 私钥 asdfghjkl
    分割为 asd17 fgh27 jkl37
    asd 1 7
    fgh 2 7
    jkl 3 7
    私钥分割 组装序号 分割方法
    kidteaing
        16
    kidteaing  
    OP
       2019-03-29 16:21:21 +08:00
    @exiledkingcc 只要我知道盐 就能提前穷举每一秒 算出数据库里的密文时间了
    exiledkingcc
        17
    exiledkingcc  
       2019-03-29 16:25:28 +08:00
    @no1xsyzy @kidteaing
    hash 这个方案确实存在这样的问题,我还是觉得前面随机的方案最好。
    jinhan13789991
        18
    jinhan13789991  
       2019-03-29 16:25:47 +08:00 via Android   ❤️ 1
    养一只鸡,搞个手环记录鸡每天的步数,用 步数%30 作为执行天数倒计时,,步数 %24 作为执行小时倒计时,步数%60 作为执行分钟倒计时...
    kidteaing
        19
    kidteaing  
    OP
       2019-03-29 16:26:08 +08:00
    @geelaw 的确是的 感觉自己高中数学白学了…
    sznewbee096
        20
    sznewbee096  
       2019-03-29 16:34:07 +08:00
    时间随机的算法,客户买和中彩票概率的方式,30 天内就是可能无法买到。
    reus
        21
    reus  
       2019-03-29 16:37:02 +08:00
    为什么要记录?生成随机数,落到某个范围就触发,这样也没有任何人可以确定,不需要记录。
    kidteaing
        22
    kidteaing  
    OP
       2019-03-29 16:50:19 +08:00
    @geelaw @sznewbee096 目前被概率论的反直觉绕住了 目前两种算法 一种是每过一小时 分母减 1,一种是每小时都是 1/720,如果没有执行,则在最后一个小时执行购买 确保没有漏买
    用第一种方法似乎会有越到后面 跟买赢率越大的感觉 虽然第一种算法比例是一样的 但会引入了“你知道前面的部分没有成功执行”的因素
    kidteaing
        23
    kidteaing  
    OP
       2019-03-29 16:51:39 +08:00
    @reus 因为这个计划在时间区间内是一定要被执行的 生成随机数落到范围内触发 似乎不太可行
    kidteaing
        24
    kidteaing  
    OP
       2019-03-29 16:52:55 +08:00
    @jinhan13789991 有才 但你只是了一个随机数发生器 还是得记录下来判断什么时候应该执行[滑稽]
    ThirdFlame
        25
    ThirdFlame  
       2019-03-29 16:57:22 +08:00
    入库时产生一个 0-720 之间的随机数,保存。 然后每小时对每个任务生成 0-720 之间的随机数,如果和入库的随机数相等,则执行。
    如果到了最后一个小时,还没有执行,则最后一个小时执行。

    非要说这个有问题的话,那么确实有 1/720 的任务 ,会在倒数第二个小时后知道 将在最后一个小时内执行。这个是没有办法的。 你要求必须在 30 天内完成。
    sznewbee096
        26
    sznewbee096  
       2019-03-29 17:09:46 +08:00
    @kidteaing 定时购买的任务也必须是不可见的吗?
    tomczhen
        27
    tomczhen  
       2019-03-29 17:27:54 +08:00
    去看看 DND 的桌游找下灵感就行了。

    需要检定事件结果时,双方投骰子,加上各自修正值。所有机制、规则都是公开透明的,但检定结果只有投出骰子之后才能知道。
    limuyan44
        28
    limuyan44  
       2019-03-29 17:47:47 +08:00 via Android
    每天定时把 n 天内的随机抽取一部分购买不就好了。只要保证最终把 30 天内数据都跑完就好了啊。不就是不想让开发知道购买时间吗。。或者把每天任务的时间也随机了。需求是不可知又不是必须做到随机事件。
    yidinghe
        29
    yidinghe  
       2019-03-29 17:53:12 +08:00 via Android
    既然任何人都不能知道具体的执行时间,那就不要预先定下来了,每分钟取一次随机数,满足条件就执行。
    yidinghe
        30
    yidinghe  
       2019-03-29 17:54:20 +08:00 via Android
    几率是可以递增的,越接近期末几率越高,这样保证时间段内一定会执行。
    conn4575
        31
    conn4575  
       2019-03-29 19:28:21 +08:00 via Android
    感觉不让任何人知道是不可能的,特别涉及资金变动,我不信你们不打 log …
    no1xsyzy
        32
    no1xsyzy  
       2019-03-29 19:36:41 +08:00
    @jinhan13789991 不行,三者的熵部分取自同一部分信息。
    @ThirdFlame 你这也被概率论绕住了。
    no1xsyzy
        33
    no1xsyzy  
       2019-03-29 19:37:57 +08:00
    其实就是《编程珠玑》第 12 章 第 12.5 节 问题 第 10 问
    把它反过来做,并且你恰好知道 n 而已。
    test0x01
        34
    test0x01  
       2019-03-30 09:47:38 +08:00 via Android
    多简单呐。弄个随机定时器没过几分钟起来随机抽取并执行点任务。
    EscYezi
        35
    EscYezi  
       2019-03-30 16:38:39 +08:00 via iPhone
    好奇一下为什么会有这种需求......
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1005 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 21:09 · PVG 05:09 · LAX 13:09 · JFK 16:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.