AGV中控项目架构改造思路分析 --- 车辆信息处理

信息接受处理

改造原因

原中控针对车辆信息,采用一个后台线程获取全部车辆信息,一次性处理所有车辆的信息

  • 优点:节省资源,单线程工作
  • 缺点:处理速度慢,当涉及I/O问题,对其余车辆的处理速度有很大影响,当车辆数目上升时,无法做出有效的响应速度提升措施

改造后

借鉴nettyreactor模型,对车辆的信息处理,有一个Boss线程和2^n个worker线程

  • 优点:可接受的AGV数量提升明显(测试100辆AGV同时上报,上报间隔500ms,响应时间在1s以内,没有试过极限),而且可以按照实际场景使用不同比例(worker:AGV),提升系统接纳数量与响应速度
  • 缺点:依然存在阻塞其余车辆的风险,但是只会影响少部分AGV

Boss线程

Boss有一个有限队列,当接受到车辆上报的信息后(Tomcat的线程接受到AGV的HTTP报文),放入Boss的队列中

然后Boss会根据AGV的唯一ID做一次散列函数,选择一个worker来处理AGV的信息

注:当选择后,AGV与worker的关系也就固定了下来,不会出现AGV上报速度过快,导致的同一时刻有多条线程同时处理同一个AGV的信息,最终导致系统的状态混乱。

worker线程

真正处理AGV信息的线程,会将AGV信息进行打包,放在一个上下文中,然后再传递给AGV状态机进行信息处理

注:worker的个数一般比AGV的数量少,在测试时,8条worker对100辆AGV,平均一个worker需要处理12.5辆车。所以在信息处理中涉及I/O部分,多采取快速失败或者第三方解耦的方法,不然会阻塞其他车辆的处理


AGV状态管理

改造原因

原中控没有对AGV的状态进行同一管理,只是简单地判断AGV的前后状态,任务或者空闲

缺点:AGV的状态混乱,一旦出现异常,追查困难

改造后

对AGV的任务和空闲状态建模,设立三个状态FreeTaskError

然后将这三个状态装进简单的状态机中,并以AGV上报的状态,推动状态机向前演变。

优点:对AGV的状态做出明确的划分,有利于后期异常查找;出现异常时,方便事务回滚;状态机是被动演变,方便系统永久保存状态


AGV信息链式处理

改造原因

原中控的信息处理是一个后台线程对所有的车辆进行统一处理,处理函数是一个非常长的巨大函数

  • 缺点:几乎写死了所有的业务逻辑,当需要在原有基础上新增或删除某些功能时,修改非常困难,而且缺少状态管理,无法针对某一状态插入功能,会造成处理函数的体积暴增或者出现三层以上的逻辑嵌套,难以维护。

改造后

spring的拦截器和netty的出入站链获得思路,将所有可扩展业务代码切分为一个个拦截器,并且依赖于AGV状态机的状态变迁,将任务的生命周期切分成四个阶段

然后针对不同的任务类型(信号量)和不同的阶段,将拦截器依附在状态机的运转上,从而达到灵活地新增业务,而不会对原有业务造成太大影响

任务生命周期的推进,依赖于AGV状态的变迁,比如,当车辆接收到任务,从空闲变成任务中时,对应于任务生命周期的等待任务接收阶段,而且只会触发一次,然后对该时刻而信息处理,就根据当时的信号量和阶段获取相应的处理链(拦截链),对信息进行处理,并将处理结果存放在AGV的上下文中

任务生命周期的阶段,等待任务接收任务结束属于只会触发一次的阶段,任务获取任务进行中是长时间存在的阶段

  • 优点:新增功能容易,维护容易
  • 缺点:业务代码变得较为零散,一个完整的业务功能会被拆分为数个拦截器共同完成,需要对链执行的过程熟悉,才能预判功能的执行效果

整体流程总结

  1. 将获取到的AGV上报信息,投递到BOSS队列
  2. BOSS将信息检查后,选择一个WORKER并投递到它的队列中
  3. WORKER将信息打包上下文后,传递给状态机
  4. 状态机根据信息进行演进,获取到最终的处理链
  5. 处理结果存放在上下文中,作为AGV下次上报的响应

改造后的系统,可以用较少资源承受更多的AGV,并且更加容易对业务新增或维护,能够对任务的不同阶段做出响应

posted @ 2022-05-22 18:44  huang1993  阅读(434)  评论(0)    收藏  举报