# **背景** - 卡口拍摄前端设备会将拍摄的图片以及结构信息(车牌、颜色、时间等)存放到多个共享存储目录中,文件名字格式如下,time_id.jpg, time_id.txt,txt文件存储结构化信息,每天记录千万条级别。 - 现需将这些图片信息上传到dpss系统,故需开发分布式上传服务,定时扫描共享目录,读取jpg和txt上传到dpss,上传成功后删除文件 # **架构设计** - UploadDispatcher定时扫描目录生成job存放到内存中的队列中,以http方式提供consumejob接口 - 多节点UploadWorker定时向UploadDispatcher获取任务 # **UploadDispatcher详细设计** - **FolderMonitor线程** 1. 定时扫描目录里的文件,解析文件名可以得到文件生成时间,比较文件生成时间和上次目录扫描时间,如果文件的生成时间大于上传扫描时间,表明文件是新的,添加一条job到内存队列中 2. 如果文件生成时间小于上次扫描时间-300秒,表明该文件已经被添加过job,但是还没处理,或者UploadWorker处理失败,重新创建一条job 3. 同一个文件对应job重复无关系,UploadWorker处理job是冥等的 - **HTTPServer线程** 1. 实现/job/consume接口,如果任务队列有任务就popjob,返回job参数,如果没有任务,就返回空 2. 实现/页面,相当于程序的仪表板 3. 实现/conf页面,动态调整日志级等 4. 实现/help页面,查看平时收集的问题集合,方便现场人员解决问题,经常遇到不同地方的现场让你帮它定位同样的问题,无法让别人改进,那就把改进自己,其实公司层面应该为现场处理的问题建立问答系统 # **UploadWorker详细设计** - **Worker线程** 1. 定时向UploadDispatcher获取任务,获取到任务就处理,处理结束后马上再次获取任务,如果没有任务,暂停几秒后再向UploadDispatcher查询任务 - **HTTPServer线程** 1. 实现/页面,相当于程序的仪表板 2. 实现/conf页面,动态调整日志级、让worker下线不工作、上线 3. 实现/help页面 # **高可用** - UploadDispatcher和UploadWorker都是无状态的服务。 - UploadDispatcher和UploadWorker都由dlang开发一个小工具ProcessSupervisor.exe监控 - UploadDispatcher将任务放在内存中,没有持久化,因为重启时,上次扫描时间为0,能处理共享目录里所有文件,不会遗漏文件 - UploadWorker连接不上dpss系统时,不会向UploadDispatcher申请任务 - UploadWorker崩溃时想要不漏文件,通常一种方式是UploadWorker处理job成功后再调用deletejob,而这儿主要靠 UploadDispatcher补救 # 设计改进 - 测试下来发现遗留了一些txt文件没有被删除(删除txt时失败了),发现生成txt和jpg两个文件,虽然方便人阅读,但是不方便程序,故改进为将元信息和jpg数据放一个文件里,元信息放在文件头,jpg放后面,文件名字格式改为time_jpgdatalen_recordid.jpg - 当UploadWorker与下游的dpss连接断开时,不会向UploadDispatcher申请任务,但是UploadDispatcher的扫描线程还是在不停的插入任务,故UploadDispatcher的内部任务队列增加了一个最大数量限制,超过时,扫描线程就不扫描 # 动态配置 - UploadDispatcher 1. 队列的最大限额数 - UploadWorker 1. 设置上线、下线 2. 调整内部worker线程数(方便调优,调整worker,可以知道某台电脑启动多少个worker合适) 3. 不向dpss发送数据(方便测试,下游的dpss测试环境经常不可用) # 页面     
背景
架构设计
UploadDispatcher详细设计
UploadWorker详细设计
高可用
设计改进
动态配置
页面