首页 > 编程知识 正文

xxl-job 5分钟调用service service调用阻塞

时间:2023-11-19 07:45:54 阅读:289260 作者:BDEY

如何解决xxl-job 5分钟调用service service调用阻塞问题?

一、xxl-job和Spring Cloud的问题

在使用xxl-job调用Spring Cloud微服务时,可能会出现阻塞的情况。这是因为xxl-job的调用方式是http请求,而Spring Cloud使用了ribbon负载均衡和Hystrix熔断器,如果在超时时间内没有响应,则会触发Hystrix的短路机制,导致服务阻塞。

解决方法是可以设置超时时间,如下:

@Bean
public RestTemplate restTemplate() {
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setConnectTimeout(5000);
    requestFactory.setReadTimeout(5000);
    return new RestTemplate(requestFactory);
}

二、调整xxl-job的线程池

在使用xxl-job的过程中,可能会出现调用服务阻塞的情况。可以通过调整xxl-job的线程池大小来缓解此问题。线程池大小越大,可以同时处理的请求数就越多,从而减少阻塞的情况。

可以通过在配置文件中配置以下属性来调整线程池大小:

xxl.job.executor.threadpool.core-size=100
xxl.job.executor.threadpool.max-size=200

三、使用异步调用方式

使用异步调用方式是解决这个问题的常用方法。可以在service中使用CompletableFuture异步调用xxl-job任务。

例如,如下是一个调用xxl-job任务的示例:

@Service
public class JobService {
    @Autowired
    private JobClient jobClient;
    
    public CompletableFuture<JobResult> runJobAsync(long jobId, String param) {
        return CompletableFuture.supplyAsync(() -> jobClient.run(jobId, param));
    }
}

然后,在controller中就可以使用异步调用方式调用service:

@RestController
@RequestMapping("/job")
public class JobController {
    @Autowired
    private JobService jobService;
    
    @PostMapping("/runAsync")
    public CompletableFuture<JobResult> runJobAsync(@RequestParam long jobId, @RequestParam String param) {
        return jobService.runJobAsync(jobId, param);
    }
}

四、增加日志输出

增加日志输出可以帮助我们更好地定位问题,了解程序运行的情况。在xxl-job的调用过程中,可以增加日志输出来查看调用情况、参数、返回值等信息。

例如,在jobHandler中可以增加日志输出,如下:

@XxlJob("MyJobHandler")
public ReturnT<String> execute(String param) throws Exception {
    log.info("start MyJobHandler...param:{}", param);
    // do something
    log.info("end MyJobHandler...result:{}", result);
    return ReturnT.SUCCESS;
}

五、使用分布式事务

如果xxl-job的任务需要对数据库进行操作,需要使用分布式事务来保证数据的一致性。使用分布式事务可以避免数据操作不一致、服务阻塞等问题。

常见的分布式事务解决方案有TCC、XA、Seata等。

例如,使用Seata可以在服务中增加@GlobalTransactional注解,实现分布式事务的管理,如下所示:

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AccountClient accountClient;

    @Override
    @GlobalTransactional
    public void transfer(String userId, String targetUserId, BigDecimal amount) {
        // 扣除用户余额
        accountClient.reduceBalance(userId, amount);

        // 增加目标用户的余额
        accountClient.addBalance(targetUserId, amount);

        // 更新用户的交易记录
        userMapper.updateUser(userId, targetUserId, amount);
    }
}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。