并行流适用场景-CPU密集型

本文探讨了一次定时任务在使用并行流向300w用户推送支付宝模板消息时遇到的问题。初步分析指出,由于网络I/O阻塞,服务器CPU利用率仅10%,并未充分利用并行流的优势。通过测试,发现提高并行流线程数能提升效率,但在I/O密集型任务中,线程方式表现更优。总结强调并行流适用于CPU密集型计算,而在处理I/O密集型任务时效果不佳。
摘要由CSDN通过智能技术生成

1. 场景描述

​ 每天有一次定时任务,需要向300w用户推送支付宝模板消息,单台服务器初次尝试30w个消息推送时,耗时4.6个小时,使用的是并行流推送的方式。

2. 原因猜测

​ 通过监控观察到,推送模板消息时,服务器CPU的利用率只在 10% 左右,并没有高效利用起CPU,并行流的优点是将CPU资源调动起来,实现并行处理,一般情况CPU资源应该是被占用得挺多的,假设服务器有四个核,默认并行流会将四个核都同时调用起来,实现真正的并行处理,而不像线程是伪实时,可以将四个核心下的并行流处理单成四个队列,30w任务平均分配在四个队列中,只有前面的任务执行完了,下一个任务才会继续,此时就会面临一个问题了,推送模板消息是发送http请求,涉及到了网络调用,此时每个任务执行过程中是有一个I/O阻塞时间的,下一个任务只能等待前一个完成才会执行,这段I/O阻塞便停滞了CPU资源。

​ 可以通过提高并行流的核心数或者换成线程处理的方式来验证猜测。

3. 测试

@Service
public class ConsumMsg {
   

    @Autowired
    StreamOpt streamOpt;

    /**
     * 初始化任务队列
     * @param count
     * @return
     */
    public List<Integer> initMsg(int count) {
   
        List<Integer> list = Lists.newArrayList();
        for (int i = 0; i < count; i++) {
   
            list.add(i);
        }
        return list;
    }

    /**
     * 并行流处理
     * @param count
     */
    public void parallel(int count) {
   
        List<Integer> list = initMsg(count);
        int successSize = list.parallelStream().mapToInt(streamOpt::sendMsg).sum();
        System.out.println("并行流成功个数:" 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值