记一次使用共享单车的糟糕体验,讨论一下从业务流程上如何避免此类事故的发生 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
CismonX
V2EX    程序员

记一次使用共享单车的糟糕体验,讨论一下从业务流程上如何避免此类事故的发生

  •  < href="Javascript:" Onclick="downVoteTopic(680196);" class="vote">
  •   CismonX 2020-06-10 01:10:54 +08:00 3691 次点击
    这是一个创建于 1957 天前的主题,其中的信息可能已经有所发展或是发生改变。

    事件经过

    今晚下班打算骑共享单车回家,但是未能成功开锁,在一段时间的等待后,APP 提示网络错误。

    看到周围很多人也在扫该品牌共享单车,但是无一成功,看来是单车服务出现了故障,于是我打算改为步行回家。然而步行十分钟以后,再次打开 APP,发现我的状态是骑行中。没办法,只好折返去找那辆车,但不出我所料,那辆车已经不在原地了,大概率是被别人骑走了。

    于是我在 APP 中寻找相应问题的处理流程,但是没有找到。最接近的选项是 "扫码锁未开但已开始计费",这个选项会将我带到报修页面,但报修提交后仍需要手动关锁,且 "强制关锁" 选项仅用于处理 "关锁后未结束计费" ,并要求对有问题的锁环拍照。

    这种情况下,人工客服介入是很有必要的。但 APP 里并没有接入人工客服的入口,机器人客服也只能展示那几个常见的问题选项。此时,问题陷入了一个死局,摆在面前的只有一条路,强制关锁,上传报错截图,并说明问题。但这个操作是不规范的,实际上并没有关锁,审核人员多半不会相信我的说辞,判定为忘记关锁,面临高额罚款的同时,还有可能影响个人信用。到时候想要维权也很难举证。即使是调路边摄像头,也不一定看得出锁开没开。

    不知不觉中,一个多小时过去了,正在我准备点强制关锁时,APP 提示骑行结束。应该是骑走这辆车的人关了锁。此次事故有惊无险地结束了,但它浪费了我宝贵的休息时间,也暴露出了该品牌单车业务上存在的缺陷。

    问题分析

    事故发生后应该有所思考,是什么导致了事故的发生。如果我要搞共享单车的开发,我又应该如何避免此类事故的发生呢?

    第一种可能:开锁请求失败,但用户点击 "我知道了" 之后,客户端又自动重新尝试发起请求。后续的请求成功,车开锁。这种业务流程显然是不合理的,我认为这种规模的公司不会犯这样的低级错误。

    第二种可能:请求是异步的。先发起开锁请求,然后不断轮询,等待服务端更新开锁状态。开锁的请求发送成功,但由于某些原因,后续的轮询请求没有得到服务端的及时响应。而由于车锁没有打开,说明单车没有收到服务端的开锁请求,这有可能是因为网络故障,有可能是开锁请求还在消息队列中排队,也有可能两者都是。但一段时间后,服务恢复正常,车锁成功打开,客户端也成功从服务端得到了状态更新。

    解决方案讨论

    虽然不是内部人员,不了解实现细节,但大致可以认为是上面说的第二种可能。基于这种假设,我认为从两方面可以改进:

    首先是客户端的文案。当告知用户 "开锁失败",应该意味着客户端和服务端都已经确认了这次失败,用户可以选择放心地离开去做其他的事情,或者重新尝试开锁。所以如果开锁的请求成功,但在轮询开锁状态时没有得到服务端的响应,应该告诉用户 "服务忙,请耐心等待",同时页面应保持不可交互,直到服务端响应。这样,用户知道自己的操作处于一个中间状态,过一会儿车锁可能会开,因此会更多地选择等待,而不是离开。

    其次,服务端也应该考虑到这样的特殊情况。消息队列中的消息时效应该合理设置。现实中没有人会愿意为一辆共享单车等好几分钟,所以当一条开锁的消息在队列中积压了超过一分钟甚至半分钟未被消费(如果有消费失败重新入队的机制,这个起始时间应该从首次入队算起),就应该抛弃掉。

    如果上面这两件事能做好,基本上就不会出现锁开了而人不在的情况。

    有关客服

    好歹也算半个大厂,竟然连人工客服的入口也没有。当年用过的其他几款现在已经凉了的共享单车,虽然排队时间长,服务质量也参差不齐,但至少可以接入人工客服。在遇到无法自助处理的紧急问题时,不至于陷入僵局。

    22 条回复    2020-06-11 21:06:54 +08:00
    Anshay
        1
    Anshay  
       2020-06-10 01:14:38 +08:00
    不错的贴子,大佬在公司任什么职务,架构吗?
    also24
        2
    also24  
       2020-06-10 01:49:03 +08:00   1
    有一种开锁方案是基于短信的(我不太确定当前单车厂商是否仍在使用)


    以速度排序,常见的开锁方式:
    1 、服务端下发短效开锁密钥,手机客户端使用 BLE 方式直接开锁。
    开锁成功 / 失败信息,手机和车锁均会返回给服务端。

    优点:因为服务端只需要下发密钥给手机,开锁速度贼快
    缺点:需要构建密钥机制,存在一定风险,智能锁需要具备 BLE 功能

    2 、车锁通过 GPRS 等信道进行 长连接 / 长轮询 / 轮询,根据轮询到的结果执行指令。
    开锁成功 / 失败信息,由车锁通过网络返回给服务端,可以直接在长连接里,也可以是单独的 Web API 。

    优点:低物料成本、低开发成本,能覆盖绝大部分场景
    缺点:长连接 可靠性差,容易退化为轮询导致开锁用时更长,由于连接可靠性差,可能会丢失信息,需要设计相应机制。

    3 、服务端直接通过 发送短信 的方式将开锁信息下发给车锁,车锁收到信息时立即执行指令。
    开锁成功 / 失败信息,由车锁通过类似的 短信 / DTMF 通道返回,或者通过 Web API 返回。

    优点:超强的"可靠性",能打电话发短信的信号就足够,网络方面成本最低。
    缺点:已经发出的短信,完全不受自己控制。短信延迟也完全不受自己控制。可承载的数据量很小。


    以上几种开锁方式里,1 、2 两种,开锁任务是可以在消息队列进行管理的。
    想要取消一个开锁任务,只需要保证车锁端获取不到即可。

    但是 3 就很烦人了,短信形式的开锁指令,你发出去以后压根不知道车锁会什么时候收到。
    如果运气不好恰好短信延迟了 3 分钟,就会出现车锁响应了 3 分钟前的开锁指令的情况。
    理论上来说,此时应该可以通过让短信中携带失效时间来保证任务不会被超期执行。
    但是问题来了:车锁是否具备校时的能力呢?

    因为情况 3 是数据网络不好时出现的,那先排除掉基于数据网络的 NTP 服务,
    印象中 CDMA 和 GSM 都有授时功能,但是似乎是看运营商的实现的。
    所以这里我认为车锁并不能 "稳定的" 进行校时。

    综上,消息队列的正确处理,确实能够解决 1 、2 两种场景。
    但是对于场景 3,还是有一些困难需要克服。
    also24
        3
    also24  
       2020-06-10 01:56:51 +08:00
    补充一下,关于场景 3,其实还有一种解决方案是:
    当用户被通知开锁失败,点击 『我知道了』 按钮时,再发送一条 『取消开锁』 信息。

    但这仍然无法做到 『可靠』:

    问题 1 、短信的收取顺序可能与发送顺序并不一致。

    如果需要解决,就需要设定一定的缓存机制,当收到 『取消 30#开锁请求』 的短信,却又没有找到 『 30# 开锁请求』 的时候,将取消请求暂时缓存,直到收到相应的开锁请求或者超时再删除。

    问题 2 、开锁是个很快速的,而且 『开弓没有回头箭』的操作。
    共享单车车锁的一个特点就是,可以通过电信号控制打开,但不能通过电信号控制上锁。
    那么即便是两条短信相继收到,只要中间的时间差不是极小,那么收到取消请求时,开锁指令已经执行完毕,无法撤销了。

    如果要解决,可能就需要在收到开锁指令的时候,设立 『冷静期』,例如 10 秒后再开锁,但是这样操作好像又让用户多等了不少时间。
    xy2020
        4
    xy2020  
       2020-06-10 08:03:32 +08:00 via Android
    这个问题其实很容易解决
    只是共享单车企业前景不乐观,解决了不会增加营收,不解决也不会有太大影响,所以就选择了低成本的假装不知道而已。同时,因为要低成本,所以没有人工客服。
    tankren
        5
    tankren  
       2020-06-10 08:19:52 +08:00
    timeout 直接丢弃序列
    xiaowei007
        6
    xiaowei007  
       2020-06-10 08:39:46 +08:00
    之前遇到过哈喽单车关锁但是却未结算的问题,费用挺高的,后来找到客服,说明情况,客服确认了下我骑车的始发的和目的地。帮我处理成,正常的计费方式了。
    wanwaneryide
        7
    wanwaneryide  
       2020-06-10 08:52:02 +08:00
    mobai 单车曾经出现扫 A 车,却给附近的 B 了开锁了,关键是附近几十辆车,完全找不到,又是下班的时候,找不到客服,当时还要押金的,提心吊胆的等了一晚上,上班立马就给 400 打电话,总算是把骑行费和车子给我处理好了。
    sujin190
        8
    sujin190  
       2020-06-10 09:31:33 +08:00
    没有客服显然是问这个问题的人太多了,客服多费钱啊,那我就不留了这不就省钱又省事了

    自行车为了省电,现在估计都改用发短信通知开锁了吧,所以这都不算事,反正也没几块钱,你提个异常开锁,直接给你免单就是,想那么多干嘛

    但是重点是楼主居然为了这小毛病离开十分钟还折回去,然后花了一个小时折腾这事,真实佩服佩服
    bloceanc
        9
    bloceanc  
       2020-06-10 09:39:48 +08:00
    PaddyPang
        10
    PaddyPang  
       2020-06-10 09:42:54 +08:00
    Mobai 还好,最搞笑的是哈罗,在蓝色区域外解锁的车,必须得骑回蓝色区域以内,要不然就收调度费,每次只能联系客服处理
    paulee
        11
    paulee  
       2020-06-10 10:36:03 +08:00
    现在哈罗也取消了人工客服,所以已经成为普遍问题了
    sfz97308
        12
    sfz97308  
       2020-06-10 10:46:29 +08:00
    前几天我也遇到了这个开锁失败错误,扫了几辆车都是 errordomain,旁边的人也扫不开。唯一不同的是后续锁也没有被打开,所以没遭遇这些麻烦。
    yuwangG
        13
    yuwangG  
       2020-06-10 10:51:27 +08:00
    青桔也有问题,特别是在景区门口,一扫码就显示不在蓝色区域内无法开锁,要把车搬回蓝色区域内才能开锁。 意思是我得给你抬回蓝色区域内在扫码么? 你直接做一个不让蓝色区域关锁不久完了
    evilvoy
        14
    evilvoy  
       2020-06-10 12:16:51 +08:00
    细节真的很重要。
    遇到这样的估计后面就不想用了
    marcong95
        15
    marcong95  
       2020-06-10 12:33:06 +08:00
    美团现在的单车的响应速度凭感觉应该已经不用短信开锁了?所以会不会有可能是下一个用户正常开锁,但是把订单算到了你的账号上。各共享单车的技术水平有时候真的是不敢恭维,都是些蹭风口赶出来的小公司,然后被 TMD 收编。

    @sujin190 #8 直觉觉得 BLE 耗电应该怎么都比 GSM 模块小吧,印象中 CR2032 都能撑几个月的
    also24
        16
    also24  
       2020-06-10 14:08:38 +08:00
    @marcong95 #15
    固定密钥的 BLE 开锁安全性太差,存在很大的被破解可能。
    动态密钥纯 BLE 开锁的技术成本高,需要做相应的密钥体系出来。

    所以 BLE 开锁往往需要配合 GPRS 走网络下发密钥。

    可以参考下这篇文章:
    https://www.jianshu.com/p/c0ed5d3737d4
    sujin190
        17
    sujin190  
       2020-06-10 14:14:26 +08:00
    @marcong95 #15 短信本来就很快,美团单车又没做到秒开,五六秒足够短信到达了

    BLE 是比 GSM 耗电低,但是怎么着也需要单车能联网,GSM 必须的,那么少一个 BLE 模块不香么,GSM 模块还附带基站点位,GPS 都省略了

    这不是技术水平的问题,这是成本的问题,有钱谁做不出好东西啊,但是就一两块钱的事情真花那么多钱想着优化毛用没有用户体验才是真傻叉,而且硬件不比软件,各种奇奇怪怪的问题总是超过想象,所以吧现在的共享单车低校验高容错低成本的系统可以说是非常科学了
    johnniang
        18
    johnniang  
       2020-06-10 14:35:12 +08:00 via Android
    我刚刚还联系到了人工客服啊。

    在服务门户页面中,选择其他问题,会提示在线客服的选项,点击之后就能直接接入客服了。
    efaun
        19
    efaun  
       2020-06-10 15:09:08 +08:00
    所以开锁应该使用 TCP 连接而不是 UDP ?
    MiBAO
        20
    MiBAO  
       2020-06-10 18:21:00 +08:00
    其实一般这种情况我都是直接点强制关锁,然后随便找一辆车给他拍一下。这种情况已经不是一两次了,上次我上一秒扫失败下一秒那个车就被别人骑走了,最后我发现我是骑行中。
    RicardoY
        21
    RicardoY  
       2020-06-11 01:29:10 +08:00 via iPhone
    别的不说..美团单车应该是有人工客服的
    kingcos
        22
    kingcos  
       2020-06-11 21:06:54 +08:00 via iPhone
    Sorry,刚刚看到帖子反馈。

    1. 首先客服是存在的哈,可以在订单页点击进入详情直接联系客服,也可以在单车页面右上角个人中心的右上角耳机图标点击进入(似乎是这样的图标并不够醒目告知用户是客服?)
    2. 出现这个问题如果您能提供个联系方式,我们可以尝试看下具体原因
    3. 错误提示的问题确实不够人性化,有些「硬核」,新版本已经优化
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2641 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 08:09 PVG 16:09 LAX 01:09 JFK 04:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86