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

Golang 开发新手的一个问题

  •  
  •   TimeSea · 2022-07-25 17:16:24 +08:00 via Android · 2318 次点击
    这是一个创建于 837 天前的主题,其中的信息可能已经有所发展或是发生改变。
    楼主的本科生,接到老师派的一个任务,用 golang 写一个分布式的后端。之前从来没接触过类似的开发任务,感觉有些棘手,想问 v 友们一个问题:



    目前主要任务是给外卖员派单,那就需要从数据库里面取出来外卖员的数据,然后再从数据库里面取出来订单的数据,根据这些数据来给外卖员派单。开始的想法是把这些数据都加载到内存中遍历,但在数据量大的时候显然行不通。问老师,老师说可以用一个 active list ,要有一个 buffer ,但也是挺笼统的,不知所云。想问问 v 友有没有啥好的解决办法
    22 条回复    2022-07-26 03:59:28 +08:00
    cctv1005s927
        1
    cctv1005s927  
       2022-07-25 17:20:05 +08:00
    不需要那么麻烦吧?
    为什么要把所有数据都取出来到内存呢?直接用 SQL 去 Match 对应的外卖员和订单不就行了吗?
    blankmiss
        2
    blankmiss  
       2022-07-25 17:21:01 +08:00
    确实 你是不是忘了有个东西叫 database
    someonedeng
        3
    someonedeng  
       2022-07-25 17:29:54 +08:00
    数据库里 join 一下?
    thetbw
        4
    thetbw  
       2022-07-25 17:37:05 +08:00
    @someonedeng
    @cctv1005s927
    可能楼主描述得有问题,我的理解。楼主说的是派单,我点了外卖,这个数据存了起来,外卖员上线,更新了数据库状态。他俩没有直接关系,我是配送站得运营,我把这单拍给某某外卖员,外卖订单的 id 才和外卖员关联。
    如果是自动派单的话,有点类似游戏的匹配逻辑了。不懂
    Chinsung
        5
    Chinsung  
       2022-07-25 17:41:50 +08:00
    一个接口查询就能搞定吧,根据外卖员 UID 拿到城市区域对应信息,然后从数据库取出来待派单的数据。
    再然后分布式锁,或者数据库乐观锁去做抢单的 update 操作。
    如果要用 Golang 单服务直接模拟分布式情况,那就用信号量之类的做分布式锁,不然就 redis 这种中间件
    Chinsung
        6
    Chinsung  
       2022-07-25 17:44:40 +08:00
    @Chinsung #5 如果是主动派单,可以写一个生产者和消费者模型,具体的分配可以使用根据订单 ID 的做 Key%服务 id 来决定哪个服务处理哪些订单,再复杂点就搞个类似一致性 hash 的模式,或者节点通知直接全量重新计算自己需要派单的路由 id 。消费者消费到某个派单的时候,就直接循环去找符合条件的外卖员根据优先级派单
    noyidoit
        7
    noyidoit  
       2022-07-25 17:52:24 +08:00
    > 把这些数据都加载到内存中遍历,数据量大的时候显然行不通
    设计目标具体是多大的量?如果设计是按照 GB/TB 级做,实际上只有 KB/MB ,除非是为了学习高并发大数据,否则非常没必要

    acting list 我猜是活跃订单和活跃外卖员,buffer 我猜是放在内存(比如 redis)的更活跃的热点缓冲数据

    一点愚见
    xx6412223
        8
    xx6412223  
       2022-07-25 17:56:10 +08:00
    放到内存里?
    你这个数据肯定不是只读的啊。
    iosyyy
        9
    iosyyy  
       2022-07-25 18:05:37 +08:00
    遇事不决消息队列 订单生成后直接放到消息队列 然后根据地点不同再分给不同的消费者(说实话我没太懂你啥意思..具体需求可能还得改只是给个思路)
    iosyyy
        10
    iosyyy  
       2022-07-25 18:06:33 +08:00
    如果快递员在线的话直接推送给快递员也行都是一样的 推送以后快递员绑定订单(加锁)
    TimeSea
        11
    TimeSea  
    OP
       2022-07-25 18:20:53 +08:00 via Android
    说的确实有问题[捂脸]。这个项目其实是一个对外卖送单的模拟,并不是真正上线的一个系统,也没有做用户端(包括外卖员和点餐的用户),所有的订单都是自动生成的。整个项目的思路就是前端发送订单请求,请求中包含点餐的用户的地址,然后系统接到订单之后,从数据库中 available 的外卖员中选出来距离用户最近的外卖员,然后把这个订单派给他,再修改订单和外卖员的状态。因为要计算所有 available 的外卖员与订单对应的用户之间的距离,所以有些不知所措 QAQ ,就来问 v 友有没有什么好的办法
    TimeSea
        12
    TimeSea  
    OP
       2022-07-25 18:26:11 +08:00 via Android
    @noyidoit 老师要求是能应对相当大数量的订单,但现在的话这个项目刚开始,就想先做小一点😂
    SenLief
        13
    SenLief  
       2022-07-25 18:42:58 +08:00 via iPhone
    我的一个想法

    把区域划分成块,如果块还大,就继续往下拆。

    当用户下单后先匹配到块,然后利用用户的坐标划算,找到圈内的快递员再筛选最近的那一个派单。

    当然具体的还要考虑路线是否匹配,骑手能不能同时接更多的单,而不是单一的单。
    MoYi123
        14
    MoYi123  
       2022-07-25 18:47:57 +08:00
    外卖单存一个表, 外卖员来取的时候带上自己的地址位置和筛选条件, 需要弄个支持 gis 的数据库, mysql,postgresql,redis 都行.
    FYFX
        15
    FYFX  
       2022-07-25 19:09:15 +08:00   ❤️ 1
    我感觉你可以先看看现有的派单系统一般是怎么做的,毕竟真的是高并发的话更多的应该是架构问题,不过搜了一下国内的美团 /滴滴 在架构选型方面说的都比较少,不过国外就有各种关于 uber 系统设计的文章,htps://medium.com/@narengowda/uber-system-design-8b2bc95e2cfe ,大概可以参考一下吧
    Hstar
        16
    Hstar  
       2022-07-25 19:14:23 +08:00
    可以先说说你们老师所谓的『相当大数量』是多大量级,这边老哥给你提一些百万并发的解决方案你也用不着是吧
    TimeSea
        17
    TimeSea  
    OP
       2022-07-25 20:11:49 +08:00
    @FYFX 十分感谢
    TimeSea
        18
    TimeSea  
    OP
       2022-07-25 20:44:05 +08:00
    @Hstar 这个啊 QAQ ,我刚开始做的话要求肯定没那么高,但他希望的是能做成百万量级的
    dilu
        19
    dilu  
       2022-07-25 20:49:40 +08:00
    我觉得可能是你老师接了个外包,让你做他收钱。。。。。

    所以所谓的并发 估计是 0-1 吧
    TimeSea
        20
    TimeSea  
    OP
       2022-07-25 22:06:26 +08:00
    @dilu 从他的意思来看,业界确实是有这样一个需求,然后让我做做看看,锻炼锻炼。不过我估计他要真的是接了外包的话,应该会找他的研究生去做,我一个本科生能做出来啥。。。
    TimeSea
        21
    TimeSea  
    OP
       2022-07-25 22:21:01 +08:00
    @SenLief 有道理哎,我试一下,非常感谢!
    harmless
        22
    harmless  
       2022-07-26 03:59:28 +08:00 via iPhone
    订单和外卖员都有坐标属性(x,y),假设订单的坐标是(x1,y1), 外卖员的坐标是(x2,y2)。要找最近的外卖员时,可以预先定义一个可接受的最大距离,根据这个距离算出外卖员坐标与订单坐标的最大差值 n ,然后就可以去数据库里直接查坐标在 x1-n<x2<x1+n && y1-n<y2<y1+n 范围内的所有外卖员,最后再计算一次查出的所有外卖员与订单的距离,取最短的就好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   950 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 20:53 · PVG 04:53 · LAX 12:53 · JFK 15:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.