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

淘宝的秒杀怎么做到客户端和服务器端时间精确同步,如果客户修改本机时间作弊呢?

  •  
  •   paranoidboy · 2015-05-06 15:33:50 +08:00 · 10800 次点击
    这是一个创建于 3493 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,今天在面试中遇到的问题

    23 条回复    2015-05-20 09:44:32 +08:00
    wy315700
        1
    wy315700  
       2015-05-06 15:51:13 +08:00
    以服务器时间为准吧。
    b821025551b
        2
    b821025551b  
       2015-05-06 15:53:37 +08:00
    客户端显示只做参考,真正校验的是服务器时间
    paranoidboy
        3
    paranoidboy  
    OP
       2015-05-06 15:53:47 +08:00
    @wy315700 不是,秒杀是要以客户在浏览器端点击的时间顺序决定谁抢到吧,怎么获取那个精确时间,要知道客户是可以修改本地时间的
    myywin
        4
    myywin  
       2015-05-06 15:58:04 +08:00
    @paranoidboy 以服务器接收到客户端请求的时间为准
    feiyuanqiu
        5
    feiyuanqiu  
       2015-05-06 15:59:04 +08:00
    @paranoidboy 想多了吧...
    秒杀请求到达服务器的时候,检查商品是否已经到了秒杀开始时间,没到就返回错误
    到了时间就检查商品的秒杀状态,如果商品没有被秒杀那这个客户就抢到了,然后更新商品的秒杀状态
    之后的请求来的时候检查商品状态已经被秒杀了,自然也就秒不到了
    learnshare
        6
    learnshare  
       2015-05-06 16:06:01 +08:00
    即使本地时间修改过,服务端也会验证是否到时
    wy315700
        7
    wy315700  
       2015-05-06 16:19:27 +08:00
    @paranoidboy 想多了吧,肯定是要在服务器端判读的啊。

    客户端发起的请求在服务器上排队。
    mcone
        8
    mcone  
       2015-05-06 16:22:04 +08:00
    > 秒杀是要以客户在浏览器端点击的时间顺序决定谁抢到吧

    洗洗睡吧,这样的话如果我抓包模仿一下数据交互协议,我就可以随心所欲了?
    Perry
        9
    Perry  
       2015-05-06 16:29:26 +08:00 via iPhone
    楼主没做过后端么?
    bigdude
        10
    bigdude  
       2015-05-06 16:32:00 +08:00
    模版输出的时候带上timedelta,就是服务器端秒杀时间-当前时间的差,然后用setInterval倒计时。如果本地用了变速齿轮,好像也不行啊。
    关键还是得服务器端验证请求。
    myleon
        11
    myleon  
       2015-05-06 16:37:16 +08:00
    话说后端很难获得客户的时间吧,都是按照服务器时间为准的。前端显示时间也是以服务器时间为准然后进行倒计时的,难道忘了:永远不要相信客户端提交的数据
    a591826944
        12
    a591826944  
       2015-05-06 16:38:48 +08:00
    LZ 想多了
    slixurd
        13
    slixurd  
       2015-05-06 16:41:11 +08:00
    就算是服务器返回时间差也不行吧
    如果一个请求在高并发下返回花了2秒,你原本返回的时间差就和正确时间不同了
    所以还是不停发请求进队列,以服务器时间为准比较靠谱。
    9hills
        14
    9hills  
       2015-05-06 16:43:27 +08:00
    服务端设一个FIFO队列,发的请求如果在秒杀开始时间之前,就拒绝,否则扔到FIFO队列中
    秒杀开始后,从FIFO队列中顺序取出请求处理即可。
    9hills
        15
    9hills  
       2015-05-06 16:43:56 +08:00   ❤️ 1
    不过其实你做成随机选的。。反正用户也发现不了,反而更公平
    ryd994
        16
    ryd994  
       2015-05-06 16:56:54 +08:00
    @9hills 实际上网络延迟已经帮你加上了随机……
    hanwujibaby
        17
    hanwujibaby  
       2015-05-06 18:38:16 +08:00
    好奇怪的问题。我想知道原题是什么样的??不知道LZ能否告知?我不太清楚后端为什么要知道前端的时间,因为完全没有必要啊。一般来说的话这样的秒杀都是在后端用队列做的。FIFO,逐一处理。
    paranoidboy
        18
    paranoidboy  
    OP
       2015-05-06 18:40:50 +08:00
    来自网友akunamotata 的回答:
    客户端时间是绝对不能用的,一般通过ajax获取服务器时间作为秒杀时间吧,或者建立长连接判断时间。
    还有一种思路是使用客户端时间,但是每次进入页面的时候去服务器校对时间,每隔一定时间校对一次。
    paranoidboy
        19
    paranoidboy  
    OP
       2015-05-06 18:42:25 +08:00
    @hanwujibaby 老实说我也不知道怎么描述原题,是今天在阿里巴巴实习二面遇到的,提问者是玉伯,也许是我理解有误
    pandada8
        20
    pandada8  
       2015-05-06 20:06:42 +08:00
    后端直接看请求到达的时间,不管前端(((
    pandada8
        21
    pandada8  
       2015-05-06 20:07:13 +08:00
    @pandada8 然后前端显示的时间从后端取
    loveuqian
        22
    loveuqian  
       2015-05-06 20:51:14 +08:00
    做到完全精确同步基本上是没可能吧
    就算局域网内也是有一点点点点点点点点点的时差的
    为了防止作弊,只能在服务端再做一次时间验证
    lalalanet
        23
    lalalanet  
       2015-05-20 09:44:32 +08:00
    同步毛线啊..... 第一次请求的时候给个剩余毫秒,客户端自己setTimeout去吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5429 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 05:51 · PVG 13:51 · LAX 21:51 · JFK 00:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.