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

想咨询个 PHP 定时的问题

  •  
  •   duguxiaohuai · 2016-11-27 15:22:33 +08:00 · 4134 次点击
    这是一个创建于 2900 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在平台要加入会员机制,会员每个月 5 元钱,最低一个月,想问下如何计算这一个月时间,是将到期的时间计算出来,到了那个时间执行还是如何操作?用户量比较大,大概几十万会员。

    34 条回复    2016-11-29 16:13:17 +08:00
    kchum
        1
    kchum  
       2016-11-27 15:32:46 +08:00 via iPhone
    没有会员的有限时间这个字段咩
    sagaxu
        2
    sagaxu  
       2016-11-27 15:41:14 +08:00
    加索引(is_member, expire_time),每次查 is_member=1 and expire_time < 当前时间的,关闭会员资格。可以每 5 分钟检查一次,每批 limit 10000 条,处理到没有为止。
    xavier007
        3
    xavier007  
       2016-11-27 15:41:34 +08:00
    会员到期一般不都是专门一个字段存储到期日期么? 使用某功能前线判断是否到期
    SlipStupig
        4
    SlipStupig  
       2016-11-27 16:01:08 +08:00
    不知道你用什么数据库,但是大致思路差不多,我认为根本不要,定时去排查到期的,除非你需要去通知到期用户,所以提一下我的一些愚蠢的想法:

    sql:设置一个到期,每次用户登录的时候去检查这个字段就行了,如果他花钱了钱不登录,也就是根本没用你服务,你也不用管他,要考虑一个例外就是用户可能没有付费,这个字段就是-1 或者其他,要去通知的话就是: expired != -1 and today > expired,这样就可以了
    nosql :更好办了,直接弄个 collections ,设置一个到期日期,到时间了 token 自动 drop 掉了,找不到 token 的都是到期了的全是到期了的
    Immortal
        5
    Immortal  
       2016-11-27 16:06:22 +08:00
    1 设置一个到期时间 遇到功能限制的地方 先判断会员等级 再判断时间 如果时间到了 但是会员等级还是高级 update
    2 设置一个任务计划,每天检查一次所有会员是否到期
    eDeeraiD0thei6Oh
        6
    eDeeraiD0thei6Oh  
       2016-11-27 16:19:05 +08:00
    付费会员单独一张表记录
    Curtion
        7
    Curtion  
       2016-11-27 16:48:47 +08:00
    4 楼的不错
    1.只有当这个用户登陆 /操作时才执行查询命令,看会员是否到期
    2.如果是需要会员功能来达到某个功能,那么在实现这个功能之前可以检查一下会员是否到期
    zhaolion
        8
    zhaolion  
       2016-11-27 17:53:56 +08:00
    如果你使用了 redis ,可以用 redis 缓存用户信息,然后支付 vip 时候,使用 redis 命令 EXPIRE 设置一个 vip_key 的过期时间为一个月,然后每次都会检查 redis 缓存里面的这个 vip_key 是否消失了, get 这个 vip_key 为 null 就证明 vip 已经到期了,后续可以做更多操作
    txlty
        9
    txlty  
       2016-11-27 18:05:43 +08:00
    最古老最普通的实现方式,请求时判断。
    ichou
        10
    ichou  
       2016-11-27 18:08:20 +08:00 via iPhone
    @zhaolion 支付类信息放在 redis 的话,记得在数据库里做好冗余或者做好持续化。想想 redis 宕一下的话,那酸爽 😂
    ichou
        11
    ichou  
       2016-11-27 18:09:20 +08:00 via iPhone
    是持久化 上条指误
    raincious
        12
    raincious  
       2016-11-27 18:11:58 +08:00
    这就是用 Model 的好处:

    添加一个字段 expire_time ,然后

    function isExpired(): bool {
    return $this->expireTime < time();
    }

    后面的操作用这个方法就好了。
    zhaolion
        13
    zhaolion  
       2016-11-27 18:17:23 +08:00
    @ichou redis 和数据库都会冗余的,并且肯定做持久化,这是可用性问题
    onlyhot
        14
    onlyhot  
       2016-11-27 19:59:33 +08:00 via iPhone
    请求时验证。
    定时任务跑。
    lianxiaoyi
        15
    lianxiaoyi  
       2016-11-27 20:34:13 +08:00 via Android
    记一个用户到期时间,然后记一个是否开通了 vip 标志,然后 2 分钟去数据库执行一次 update 表 set a=非会员 where time<=当前时间!几十万数据毫秒级别完成!
    jimzhong
        16
    jimzhong  
       2016-11-27 21:04:26 +08:00
    在表中增加用户的会员到期时间,在用户登录和使用会员服务时检查即可。
    还可以写个 cron 脚本,每天午夜扫一次数据库,去掉过期会员的会员标志。
    cncqw
        17
    cncqw  
       2016-11-27 22:20:17 +08:00
    有这么复杂吗,用户表加个会员到期时间字段,每次登录和当前时间判断一下
    techmoe
        18
    techmoe  
       2016-11-27 23:55:52 +08:00 via Android
    请求时验证吧。。逻辑设计好没什么太大问题的
    components
        19
    components  
       2016-11-28 01:37:59 +08:00
    定时任务+redis 跑
    aerostone
        20
    aerostone  
       2016-11-28 08:17:07 +08:00
    几十万用户应该会发通知的吧
    yao978318542
        21
    yao978318542  
       2016-11-28 09:21:50 +08:00
    我猜你们肯定是要发短信或者微信模板或者是邮箱之类的提示用户该交钱了,所以可以再服务器上跑个定时查询!用户开通会员的时候插入一个到期时间的字段,判断这个字段就 ok 了
    XueRainey
        22
    XueRainey  
       2016-11-28 09:43:20 +08:00
    可以考虑授权,通过验证会员接口获得授权 token 然后再去请求会员服务,这样就可以在验证会员接口进行会员到期验证了。那些花了钱不用会员服务的,其实你也不用管他。
    numberwolf
        23
    numberwolf  
       2016-11-28 10:53:03 +08:00
    至于检查的话完全可以跑一个 crontab 检查,反馈到 redis
    hoythan
        24
    hoythan  
       2016-11-28 13:28:22 +08:00
    @cncqw 你们是不是从来都不考虑如果这个用户永远不登录,别人看这个账号永远都是会员的问题?
    realpg
        25
    realpg  
       2016-11-28 15:11:14 +08:00
    分布式解决这个问题
    每次请求自动执行 update user set vip=0 where expire<= {now} limit 1
    cncqw
        26
    cncqw  
       2016-11-28 17:11:13 +08:00
    @hoythan 显示会员状态的时候也要先判断啊,不然你在界面上怎么区分会员和非会员???
    hoythan
        27
    hoythan  
       2016-11-28 18:08:59 +08:00
    @cncqw 你的意思是账号 A 去看账号 B 的状态,还得刷新一次账号 B 的信息?
    账号 B 比如发布了 10 个文章,每个文章都有显示这个人是不是会员的,还得每次都刷新?
    肯定不可能啊
    cncqw
        28
    cncqw  
       2016-11-29 10:18:34 +08:00
    @hoythan 就想问你怎么在页面上判断一个用户是否为会员并显示出来?你不每次在渲染视图的时候判断一下吗。还肯定不可能,麻烦你自己做一遍就知道原理了。
    duguxiaohuai
        29
    duguxiaohuai  
    OP
       2016-11-29 10:21:33 +08:00
    不想每天都要刷新占用内容啊 毕竟每天都需要定时查询的话还是挺麻烦的
    hoythan
        30
    hoythan  
       2016-11-29 11:57:01 +08:00
    @cncqw 重点不是判断用户是不是会员,而是判断会员过期时间更新会员的信息.
    cncqw
        31
    cncqw  
       2016-11-29 12:48:19 +08:00
    @hoythan 如果不考虑性能,加一个会员到期时间字段解决一切问题,是我没说清楚还是你理解有问题?
    hoythan
        32
    hoythan  
       2016-11-29 15:15:58 +08:00
    @cncqw 不考虑性能他还问什么问题?
    cncqw
        33
    cncqw  
       2016-11-29 16:03:03 +08:00
    @hoythan 求你别说了,我没时间跟你玩文字游戏,我说的是逻辑,你连基本的常识都没有就不要主动跟人讨论问题,免得自取其辱,屏蔽不谢。
    hoythan
        34
    hoythan  
       2016-11-29 16:13:17 +08:00
    @cncqw 你神经病吧?一个用户如果是会员的话会有勋章,加亮等等的数据,通过一个到期时间就能解决你这个会员是多简单?你脑路真的这么简单?是我该屏蔽你吧大神?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1292 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:30 · PVG 07:30 · LAX 15:30 · JFK 18:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.