分享一下产品中的异步任务的实现方式(产品运行五年以上)

PS:(由于实际情况,实现方式存在很多问题,只是简单分享),受到种种因素影响,目前正在改进实现方式。后面会继续分享改进版

大致流程如下:

  1. 不是微服务架构,是属于分布式的主备模式和异地双活的架构(四台后端服务器),共享存储,共享数据库,oracle为三个实例,区分相关实例模块。搜索使用solr.三节点,一主两从(solr为1T内存,直接挂载内存盘),目前正在新加六台服务器来增加效率,由solr5.5.3升级到solr7.2.1过程中
  2. 由于solr更新,和系统存在很多文件导出和相对耗时的业务,都需要用到异步任务进行处理,故而有了自定义的线程池和异步任务的实现。
  3. 系统的异步任务实现和java中的实现大致思路一致,有所区别。
  4. 服务端是多节点部署,存在一张server表(server_id),区别不同服务节点,也是决定异步任务由那台机器执行的重要信息,多节点同时配置开启异步任务即可
  5. 在多节点部署后,启动服务时,都会在spring的初始化操作中,去决定由哪台节点来执行异步任务,这里的实现是用到一张lock表。
  6. Lock用的是java的Timer每15秒进行一次心跳检测,执行完异步任务或服务异常退出都会有释放锁是为了允许其他节点进行锁的争抢,用以一定程度均衡服务器的资源。
  7. 这里的锁,锁的是执行任务的服务器节点,而不是正常理解的锁任务。
  8. 在启动后,根据bean.xml中配置的线程池信息进行实例化线程池
  9. 根据生产者和消费者进行灵活配置具体使用的线程池
  10. 和java线程池类似,也是有具体执行任务的类Worker用以执行具体任务,任务放在一个支持优先级的无界阻塞队列中,当队列执行过程中,锁所在服务器一直持有锁,会定时续租,同样更新锁到期时间(每次续租时间为8秒)
  11. 除了该异步任务的执行方式后,也支持自定义回调,是通过初始化时,将生产者和对应消费者(执行者)存放到map缓存,通过具体实现和抽象类来进行调用(通过Tsak顶级接口和多继承封装来进一步实现)。

下面放一下经过模糊处理的关键实现和代码分享(如有相关不合理处,请联系我,我会及时删除)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. Java Executor Framework:Java Executor Framework是Java提供的线程池框架,可以实现异步任务执行。可以通过以下代码实现线程池和异步任务执行: ``` ExecutorService executor = Executors.newFixedThreadPool(5); // 异步任务 Runnable task = new Runnable() { @Override public void run() { // 执行任务 } }; // 提交任务 executor.submit(task); // 关闭线程池 executor.shutdown(); ``` 2. Spring Task Executor:Spring框架提供了TaskExecutor接口,可以实现异步任务执行。可以通过以下代码实现异步任务执行: ``` @Autowired TaskExecutor taskExecutor; // 异步任务 Runnable task = new Runnable() { @Override public void run() { // 执行任务 } }; // 提交任务 taskExecutor.execute(task); ``` 3. Java Future和Callable:Java提供了Future和Callable接口,可以实现异步任务执行。可以通过以下代码实现异步任务执行: ``` ExecutorService executor = Executors.newFixedThreadPool(5); // 异步任务 Callable<String> task = new Callable<String>() { @Override public String call() throws Exception { // 执行任务 return "任务执行结果"; } }; // 提交任务 Future<String> future = executor.submit(task); // 获取任务执行结果 String result = future.get(); // 关闭线程池 executor.shutdown(); ``` 4. Java CompletableFuture:Java8提供了CompletableFuture类,可以实现异步任务执行。可以通过以下代码实现异步任务执行: ``` // 异步任务 CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { // 执行任务 }); // 获取任务执行结果 future.get(); ``` 5. 自定义线程池:可以通过自定义线程池实现异步任务执行。可以通过以下代码实现异步任务执行: ``` // 自定义线程池 ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); // 异步任务 Runnable task = new Runnable() { @Override public void run() { // 执行任务 } }; // 提交任务 executor.submit(task); // 关闭线程池 executor.shutdown(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值