比如一款商城系统中风控模块中的敏感词库如果让用户一个一个的录入是非常不合理的设计,那么我们可以让用户在excel文件中编辑好的大量敏感词然后在系统中直接导入这样可以大大的提高用户体验。

那么excel文件的数据有100W的大量数据我们该如何高效率的把这些数据导入到系统中呢?

此时我们服务划分可以分为【风控中心微服、任务中心微服】用户导入数据时向【任务中心微服】发起请求由该服务分片解析文件后分片异步调用【风控中心微服】多线程处理完成(因为是分片请求,那么如何知道什么情况时导入完成状态呢,后续会讲到解决方案)导入敏感词组数据到系统后再发送MQ消息到【任务中心微服】更新导入成功和失败详情等信息。

任务表字段结构

excel java 多线程 java多线程读取excel_excel java 多线程

敏感词库表字段结构


excel java 多线程 java多线程读取excel_微服务_02

优势:

有效利用服务节点资源,例如【风控中心微服】部署了三个方便是F1、F2、F3,如果是传统的导入的话请求直接打到【风控中心微服】由F1、F2、F3其中一个节点去处理导入数据,其它的两个服务空闲着,那么采取先请求【任务中心微服】后分片异步分发到F1、F2、F3去处理,这样可以达到多个服务节点处理一个任务

缺点:

开发成本高、需要考虑到很多情况对技术员要求比较高等

技术难点:

1、分布式事务问题

【风控中心微服】导入完成后【任务中心微服】更新任务记录失败时造成的任务记录数据异常

解决方案:采取可靠消息最终一致性处理,由【风控中心微服】发送可靠MQ消息通知【任务中心微服】更新任务记录数据

注意:可靠消息最终一致性引发的MQ幂等性问题(业务上不会产生脏数据无需处理幂等性问题)

2、【风控中心微服】怎么知道何时处理完一个任务后发送MQ

因为【任务中心微服】分成了多个请求到【风控中心微服】所以【风控中心微服】每处理完一个请求都无法知道该请求是否是最后一个请求。

解决方案:对比完成数和请求数(大致判断何时处理完成)

【任务中心微服】分发请求前统计好请求数储存到redis缓存中,【风控中心微服】每处理完一次请求都往redis缓存中记录完成数+1操作(缓存事务需要处理好)后对比完成数和请求数可以知道某个任务已经处理完成

注意:这只能大致判断何时处理完成。如果【任务中心微服】某个请求中断无法达到【风控中心微服】的情况时完成数和请求数是永远不会一样的了,就算【任务中心微服】减去中断的请求数也无法保证比如是请求超时的情况请求数-1但是【风控中心微服】已经收到该请求了