一、物联网与立可得
立可得是一个基于物联网概念下的智能售货机项目。
物联网(IoT:Internet of Things)简单来说,就是让各种物品通过互联网连接起来,实现信息的交换和通信。
这个概念听起来可能有点抽象,但我们可以把它想象成一个超级大的社交网络。不过,这个网络里的成员不是人类,而是各种物品。比如,你的冰箱、洗衣机、甚至是你的汽车,它们都可以通过互联网互相交流信息,就像是它们自己在聊天一样。
总的来说物联网将现实物体赋予感知、通信和智能化的能力,为人们提供更加智能化和便利的生活和工作环境。
我们本次课程讲的就是智能售货机它是物联网技术的一个典型应用,具有以下几个特点
实时监控与管理:通过物联网技术,智能售货机能够实现远程监控,管理人员可以通过电脑或手机实时了解售货机的状态,包括商品库存、销售情况等,从而及时做出补货和维护决策。
设备绑定与管理:每个智能售货机都与特定的维护人员或服务团队绑定,一旦设备出现问题,相关人员可以迅速响应并解决问题,确保售货机的高效运行。
线上线下融合:智能售货机支持线上线下购物的无缝连接,顾客可以在线上浏览商品信息,然后在售货机上直接购买,或者在售货机上发现感兴趣的商品后,选择在线上下单,这种模式为顾客提供了更加灵活和便捷的购物方式。
应用场景:智能家居、共享充电桩、智能售货机等等
二、核心技术总结
一、前端移动端采用的技术
Vue.js和Element UI 、Echarts、Taro、React、Flutter、腾讯地图
1.Vue.js是一个渐进式的JavaScript 框架,用于构建用户界面,以其轻量级、易学易用和响应式数据绑定等特点,使得我们项目的前端开发更加灵活和高效。
2.Element UI 提供了大量的高质量组件,帮助我们快速搭建起美观的管理界面。
3.Echarts帮助我们统计、渲染图表数据。
4.React采用虚拟 DOM 和组件化的设计理念,能够高效地构建复杂且交互式的用户界面。
5.Taro是一个跨端跨框架的解决方案,允许程序员使用React或Vue等熟悉的语法编写代码,然后将其编译为不同平台的应用。
7.Flutter 使用 Dart 语言,通过自绘引擎在不同平台上实现高性能的用户界面渲染,它还能够在不牺牲太多性能的前提下,实现跨平台的应用开发,大大缩短开发周期。
8.腾讯地图可以帮助我们进行售货机的定位以及让客户进行搜索,方便客户使用。
二、微服务采用的技术
ES GEO、EasyExcel、Consul、Gateway、Mybatis-plus、XXL-JOB、Spring Boot、Spring Cloud
1.ES 是一个分布式、可扩展、实时的搜索和分析引擎。GEO功能可以支持地理位置数据的存储、检索和分析。我们可以将每台售货机的位置信息存储在ES中,方便管理和定位。
2.EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目,由阿里巴巴团队开发。在我们的项目中,开发人员可以快速使用EasyExcel实现数据的导入导出功能,缩短项目开发周期。
3.Consul类似于Nacos用于服务注册和发现,配置管理和健康检查等功能。
4.Gateway的作用是服务网关,在智能售货机系统中,网关作为整个系统的统一入口,所有外部请求都首先到达网关。网关可以对请求进行流量控制,限制请求的速率和并发数,防止过多的请求对后端微服务造成压力,从而保证系统的稳定性和可靠性。
5.Mybatis-plus它是基于MyBatis框架的增强工具。提供了强大的内置通用Mapper接口,涵盖了基本的增删改查操作。
6.XXL-JOB是一款基于Java开发的分布式任务调度框架,它可以用于定时任务和异步任务的调度,是一个轻量级分布式任务调度平台。
7.Spring Boot是一款java的开发框架,它基于Spring框架,旨在简化Spring 应用的初始搭建以及开发过程。它的自动配置功能极大地简化了应用的配置过程。在智能售货机系统开发中,开发人员无需像传统 Spring 应用那样手动配置大量的XML文件或Java配置类。
8.Spring Cloud在Spring Cloud采用了Nacos作为服务注册中心和配置中心,使用了OpenFeign作为服务调用组件,使用了Gateway来做服务网关,使用了Sentinel来做服务的保护。
三、持久层消息中间件
MySQL、EMQ、Logstash、Redis、MinIO
1.MySQL是一款广泛使用的开源关系型数据库管理系统。他存储了智能售货机中售卖的各类商品信息,如商品名称、价格、库存数量、描述、图片路径等。
2.EMQ是开源社区中最流行的MQTT消息服务器。在我们的项目中主要使用EMQ实现了服务器和物联网设备之间的信息传输,而且使用EMQ作为消息队列产品实现了各个微服务之间的数据传、传输。
3.Logstash是一个开源的服务器端数据处理管道,能够同时从多个来源采集数据,对数据进行转换、丰富等操作,然后将其发送到诸如 Elasticsearch 等存储或分析系统。
4.Redis是一个开源的、基于内存的数据存储系统,通常被用作数据库、缓存和消息中间件。在我们的项目中可以将频繁展示的商品信息缓存在Redis中,可以显著加快查询速度,也避免了频繁查询数据库,减轻了数据库的负担。
5.MinIO 是一个高性能、开源的对象存储服务器。可以存储、加密和共享数据。
三、五大产品终端及终端操作对象
(一)企业管理端
总结:售货机所属企业的管理人员使用,主要负责基础数据的维护
操作人员:平台管理员
主要业务流程:
点位管理:首先创建区域、创建合作商,然后在区域下添加点位,并为点位指定合作商
设备管理:创建设备类型,创建设备,并为设备分配点位
人员管理:新建运维和运营人员
商品管理:商品类型、创建商品、为设置的货道配置商品
订单管理:查询售后机产生的详细订单
对账管理:查询销售金额以及跟合作商的分成情况
工单管理:创建投放工单,由运维人员开始投放售货机;创建补货工单,由运营人员开始对售货机进行补货
(二)机子设备端
总结:安装在每个售货机中,主要负责处理出货请求
(三)用户小程序端
总结:消费者在手机微信应用中使用,主要完成购物操作
操作人员:消费者
主要业务流程:
消费者就是指在售货机上买货的人,它有两种方式可以买货:
通过扫描售货机二维码跳转到微信小程序,然后选择商品进行下单,支付成功后在售货机取货
用户在售货机上选择商品,然后售货机弹出商品的支付码,微信支付成功后在售货机取货
(四)运维运营app端
总结:供售货机所属企业的运维(上架、下架、修机子)和运营人员(补货)使用,主要作用是处理工单业务
操作人员:运维人员
主要业务流程:
运维人员主要负责对售货机进行安装、撤机和维修
这些操作需要由平台管理员通过后台管理系统创建工单,然后将工单分配给指定的运维人员处理
接受工单后在指定的投放点安装售货机,安装完毕后选择安装完成
拒绝工单该运维人员的工单结束
操作人员:运营人员
主要业务流程:
运营人员主要负责对售货机进行补货
补货工单可以由平台管理员手动创建,也可以由系统自动触发,然后分配给指定的运营人员处理
接受工单后在指定的售货机的商品进行补货,完毕后选择完成
拒绝工单该运营人员的工单结束
(五)合作商管理端
总结:供合作商(售货机租借地归属者)使用,主要作用是合作商查看自己点位的分成
操作人员:合作商
主要业务流程:
查看售货机收益情况,和出售情况
四、三大核心模块
工单模块
工单是一种专业名词,是指用于记录、处理、跟踪一项工作的完成情况。
立可得工单分为两大类 :运营工单和运维工单。
运营工单:运营人员来维护售货机货物,即补货工单
运维工单:运维人员来维护售货机设备,即投放工单、撤机工单、维修工单
工单的状态有四种:待处理、进行中(已接受)、已取消(作废单)、已完成
手动创建工单
手动创建工单是由平台管理员创建工单的过程,时序图如下
前端发送请求到工单微服务,请求创建工单
工单微服务调用售货机微服务,查询工单对应售货机的信息,并校验验售货机的状态与工单类型是否相符
如果是投放工单,状态必为未投放否则抛出异常
如果是补货工单,状态必为运营状态否则抛出异常
如果是撤机工单,状态必为运营状态则抛出异常
校验这台设备是否有未完成的同类型工单,如果存在则不能创建
调用用户微服务查询并校验执行工单的工作人员是否存在(根据工单类型和区域来选择工人)
保存工单信息
如果是补货工单,向工单明细表插入记录
自动创建工单
对于维修工单和补货工单,其实我们是可以实现自动化创建的
自动维修工单:售货机定时扫描自己状态,一旦发现故障,系统就要自动创建维修工单
自动补货工单:系统定时扫描售货机库存,一旦发现低于警戒线,就要自动创建补货工单
自动维修工单
售货机中使用嵌入式语言写一个定时任务,定时上报自己的状态信息到MQ中
售货机微服务监听MQ,当某台售货机上报的设备状态出现异常时,更改自己的运营的状态(运行异常、运行正常)
工单微服务监听MQ,当某台售货机上报的设备状态出现异常时,自动创建工单,并分配给指定的运维人员
自动补货工单
在售货机微服务中开启一个定时任务,每天凌晨2点扫描货道数据表,将缺货情况上报的MQ中
工单微服务监听MQ,接收到消息后,自动创建运营工单,并分配给指定的运营人员
如何确定工单执行人
创建工单时,在不跨区域的情况下,要尽量保证每个工人接受的工单数量大体均匀,也就是创建工单时,要优先分配给目前持有工单最少的员工
此时可以使用Redis的ZSET数据结构来实现,每个员工在分配工单后,都会增加在redis中的这个工单数,如果取消则减少工单数
对应上面的数据结构,我们需要执行的操作有如下三个:
每日工单量初始化:由定时任务负责调用,每日凌晨生成当天的所有员工工单数列表,初始量都为0
获取工单执行人时:直接根据key获取第一个元素就行(它就是任务量最少得员工),然后分配订单给他
分配订单时:创建工单时和取消工单时,需要提供对工单员工的score进行 +1 和 -1 操作
分片广播
系统中有大量的售货机,如果将所有的售货机全部轮询一遍,并且为每一台需要补货的机器创建补货工单,可能是一个比较耗时的过程
为了缩短这个自动创建补货工单的总时间,就需要我们并行的去做这件事情,我们可以部署多份扫描售货机的微服务,每一个节点只扫描一部分
这样就能充分利用起服务器集群的能力,把庞大的工作由原来的一个人拆解之后交给多个人去做了。我们可以使用XXL-JOB的集群分片广播来实现上述逻辑
分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务
实现思路: SELECT * FROM tb_vending_machine WHERE MOD(售货机id值,售货机执行器总数量)=当前售货机执行器索引
-- 假设 当前售货机微服务数量:3个
SELECT * FROM `tb_vending_machine` WHERE MOD(id,3)=0
SELECT * FROM `tb_vending_machine` WHERE MOD(id,3)=1
SELECT * FROM `tb_vending_machine` WHERE MOD(id,3)=2
处理工单
工单处理需要运维或者运营人员通过app端操作,主要就是四种操作
接受工单:待处理--(接受)--已接受
拒绝工单:待处理--(拒绝)--已取消
取消工单:已接受--(取消)--已取消
完成工单:已接受--(完成)--已完成
工单处理操作主要是修改订单的状态,但是对于完成工单,还要额外修改售货机状态
投放工单:完成后将售货机状态更改为 运营 状态
撤机工单:完成后将售货机状态更改为 撤机状态
维修工单:完成后不做处理
补货工单:完成后要更新售货机中货道的库存
这里需要工单微服务处理工单状态,售货机微服务处理售货机状态,也就是说一个业务需要2个微服务的参与
这时可以选择的方案:
使用基于Feign的同步方式,就是工单微服务完成后调用售货机微服务的接口,优点:可以即时获得返回结果 缺点:代码耦合,效率较低
使用基于MQ的异步方式,就是工单微服务完成后向MQ投递一个消息,售货机微服务订阅消息 优点:代码解耦,效率较高 缺点:无法即时获得返回结果
综合考虑,我们应该选择MQ来实现这个功能,在物联网项目中,使用最广的一款MQ是EMQ,它是一款基于MQTT协议开发的消息中间件
订单模块
下单流程
商品下单指的就是根据用户选择的商品创建订单,并且从微信官网申请支付连接,生成支付二维码的过程
而售货机分为有屏幕和无屏幕两种,根据这个售货机种类的不同,对应的购买流程也也略有差别,下面我们分两种情况来分析一下
无屏幕售货机
无屏幕售货机,用户购买商品时的流程如下:
用户使用微信扫描售货机上的二维码
手机上会弹出相关的微信小程序
在小程序中完成商品选择,并完成支付
售货机通过在接受到支付成功后,会将商品出货
有屏幕售货机
有屏幕版售货机,用户购买商品时的流程如下:
用户可以在售货机屏幕选择商品
屏幕显示支付二维码
用户使用手机扫描支付二维码完成付款
售货机通过在接受到支付成功后,会将商品出货
下面以有屏幕为例子说一下详细的流程
1.用户在售货机屏幕上选择商品(这需要先查询当前售货机中可以出售的商品进行展示)
2.选择购买商品后,售货机会调用后端小程序网关微服务
3.小程序网关微服务将请求转发到小程序微服务
4.小程序微服务远程调用订单服务创建订单
5.订单服务调用第三方支付平台**(扫码支付-Native支付)**
6.第三方支付平台判断商户信息,如果合法创建支付数据返回支付链接地址
7.订单服务接受第三方支付平台返回的结果
8.小程序微服务将订单返回支付信息封装并继续放回到售货机终端
9.售货机通过支付地址生成支付二维码通过屏幕显示给用户
10.用户使用微信支付扫描售货机屏幕上的支付二维码进行支付
11.微信扫描支付二维码后和第三方支付系统进行交互完成支付
支付结果通知
在用户对商品支付完后,不管是有屏幕版还是无屏幕版,都要获取支付结果,主要有两种方式:
被动等待:第三方支付平台会主动通知商家的应用服务,我们需要提供接口等待通知
主动查询:商家的应用服务也可以主动去第三方支付平台查询用户所支付的结果内容
超时订单处理
当用户在创建订单后, 可能由于各种原因无法完成付款,此时系统需要将这类的订单在10分钟之后自动处理成无效订单
当创建订单完成的时候,向EMQ中投递一个延迟10分钟的消息,消费者10分钟后接到消息,检查当前订单状态,如果依旧是创建状态,就修改为无效
超时订单
定时任务:每隔10分钟运行一下定时任务 一旦发现有订单超过15分钟未支付,直接取消
延迟任务:redisson、rabbitmq延迟插件、EMQ延迟消息
出货模块
出货流程
用户通过售货机购买商品后,由第三方支付系统通知:修改订单状态,完成商品出货,业务如下:
用户支付成功之后:
订单微服务:1. 修改订单的状态 2. 通知售货机微服务扣库存和记流水
售货机微服务:1. 货道库存扣减 2. 记录出货的流水 3. 通知售货机出货
售货机终端:1. 出货 2. 反馈出货结果
拿到出货结果之后:
订单微服务:出货成功:修改订单状态为出货成功 | 出货失败:修改订单状态为出货失败,并使用第三方支付平台进行退款
设备微服务:出货成功:修改出货记录状态为true | 出货失败:并使用对货道库存恢复库存
微服务调用关系
出货
拿到出货结果之后:
订单微服务:出货成功:修改订单状态为出货成功 | 出货失败:修改订单状态为出货失败,并使用第三方支付平台进行退款
设备微服务:出货成功:修改出货记录状态为true | 出货失败:并使用对货道恢复库存
五、系统设计及专有名词
专业名词
点位:机器摆放的具体地点(比如顺义华联1层东侧、天安门西广场),每个点位上可以放置多台售货机
售货机:摆放在点位上,主要用来装载货物、出货、放置广告位
货道:位于售货机的内部,用来摆放商品,每台售货机可以有多个货道,每个货道里可以摆放一类(多件)商品
工单:就是任务单,主要分为运维工单(安装、撤机、维修)和运营工单 (补货)
微服务划分
库表设计
概括:
一个区域可以有多个点位
一个点位可以有多个售货机
一个售货机有多个货道
多个货道可以放置同一样商品
一个商品类型下有多个商品
一个售货机类型下有多个售货机
一个合作商有多个点位
合作商和区域之间没有关系,因为合作商拥有的多个点位可以分布在不同的区域 每个区域下有多个运维和运营人员,他们来负责这个区域下的设备的运维和运营