并发查询优化接口查询速度

一、controller

 /**
     * java并发查询数据实战 提高接口响应速度
     * @param userId
     * @return
     */
    @GetMapping("/get/data")
    @ResponseBody
    public UserBehaviorDataDTO getUserData(Long userId) {
        System.out.println("UserController的线程:" + Thread.currentThread());
        long begin = System.currentTimeMillis();
        UserBehaviorDataDTO userAggregatedResult = myFutureTask.getUserAggregatedResult(userId);
        long end = System.currentTimeMillis();
        System.out.println("===============总耗时:" + (end - begin) / 1000.0000 + "秒");
        return userAggregatedResult;
    }

二、MyFutureTask



import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.*;

/**
 * 一个页面有多达10个左右的一个用户行为数据,
 * 比如:点赞数,发布文章数,点赞数,消息数,关注数,收藏数,粉丝数,卡券数,红包数等等!
 */
@Slf4j
@Component
public class MyFutureTask {
    @Resource
    UserService userService;

    /**
     * 核心线程 8 最大线程 20 保活时间30s 存储队列 10 有守护线程 拒绝策略:将超负荷任务回退到调用者
     */
    private static ExecutorService executor = new ThreadPoolExecutor(20,
            50,
            30L,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public UserBehaviorDataDTO getUserAggregatedResult(final Long userId) {
        System.out.println("MyFutureTask的线程:" + Thread.currentThread());
        try {
            // 发布文章数
            CompletableFuture<List<String>> articleCountFT = CompletableFuture.supplyAsync(() -> userService.countArticleCountByUserId(userId), executor);
            // 点赞数
            CompletableFuture<Long> LikeCountFT = CompletableFuture.supplyAsync(() -> userService.countLikeCountByUserId(userId), executor);
            // 粉丝数
            CompletableFuture<Long> fansCountFT = CompletableFuture.supplyAsync(() -> userService.countFansCountByUserId(userId), executor);
            //消息数
            CompletableFuture<Long> msgCountFT = CompletableFuture.supplyAsync(() -> userService.countMsgCountByUserId(userId), executor);
            //收藏数
            CompletableFuture<Long> collectCountFT = CompletableFuture.supplyAsync(() -> userService.countCollectCountByUserId(userId), executor);
            //关注数
            CompletableFuture<Long> followCountFT = CompletableFuture.supplyAsync(() -> userService.countFollowCountByUserId(userId), executor);
            //红包数
            CompletableFuture<Long> redBagCountFT = CompletableFuture.supplyAsync(() -> userService.countRedBagCountByUserId(userId), executor);
            //卡券数
            CompletableFuture<Long> couponCountFT = CompletableFuture.supplyAsync(() -> userService.countCouponCountByUserId(userId), executor);


            // 聚合所有的查询 等所有的查询都查询完 时间为其中耗时最大的一条线程时间(也可以不用设置时间)
//            CompletableFuture.allOf(articleCountFT, LikeCountFT, fansCountFT, msgCountFT, collectCountFT, followCountFT, redBagCountFT, couponCountFT);
            CompletableFuture.allOf(articleCountFT, LikeCountFT, fansCountFT, msgCountFT, collectCountFT, followCountFT, redBagCountFT, couponCountFT).get(20, TimeUnit.SECONDS);
            UserBehaviorDataDTO userBehaviorData = UserBehaviorDataDTO.builder().articleCount(articleCountFT.get())
                    .likeCount(LikeCountFT.get())
                    .fansCount(fansCountFT.get())
                    .msgCount(msgCountFT.get())
                    .collectCount(collectCountFT.get())
                    .followCount(followCountFT.get())
                    .redBagCount(redBagCountFT.get())
                    .couponCount(couponCountFT.get())
                    .build();
            return userBehaviorData;
        } catch (Exception e) {
            log.error("get user behavior data error", e);
            return new UserBehaviorDataDTO();
        }
    }

}

三、service


import java.util.List;

public interface UserService {
    Long countFansCountByUserId(Long userId);

    Long countMsgCountByUserId(Long userId);

    Long countCollectCountByUserId(Long userId);

    Long countFollowCountByUserId(Long userId);

    Long countRedBagCountByUserId(Long userId);

    Long countCouponCountByUserId(Long userId);

    List<String> countArticleCountByUserId(Long userId);

    Long countLikeCountByUserId(Long userId);
}

四、serviceImpl

package com.woniu.demo.concurrent;


import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Override
    public Long countFansCountByUserId(Long userId) {
        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("获取FansCount===睡眠:" + 10 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("UserService获取FansCount的线程  " + Thread.currentThread().getName());
        return 520l;
    }

    @Override
    public Long countMsgCountByUserId(Long userId) {
        System.out.println("UserService获取MsgCount的线程  " + Thread.currentThread().getName());
        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("获取MsgCount===睡眠:" + 10 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 618L;
    }

    @Override
    public Long countCollectCountByUserId(Long userId) {
        System.out.println("UserService获取CollectCount的线程  " + Thread.currentThread().getName());
        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("获取CollectCount==睡眠:" + 10 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 6664L;
    }

    @Override
    public Long countFollowCountByUserId(Long userId) {
        System.out.println("UserService获取FollowCount的线程  " + Thread.currentThread().getName());
        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("获取FollowCount===睡眠:" + 10 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 102L;
    }

    @Override
    public Long countRedBagCountByUserId(Long userId) {
        System.out.println("UserService获取RedBagCount的线程  " + Thread.currentThread().getName());
        try {
            TimeUnit.SECONDS.sleep(4);
            System.out.println("获取RedBagCount===睡眠:" + 4 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 99L;
    }

    @Override
    public Long countCouponCountByUserId(Long userId) {
        System.out.println("UserService获取CouponCount的线程  " + Thread.currentThread().getName());
        try {
            TimeUnit.SECONDS.sleep(8);
            System.out.println("获取CouponCount===睡眠:" + 8 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 66L;
    }

    @Override
    public List<String> countArticleCountByUserId(Long userId) {

        List<String> list = new ArrayList<>();
        System.out.println("UserService获取ArticleCount的线程  " + Thread.currentThread().getName());
        try {
            list.add("1");
            list.add("2");
            TimeUnit.SECONDS.sleep(8);
            System.out.println("获取ArticleCount===睡眠:" + 8 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public Long countLikeCountByUserId(Long userId) {
        System.out.println("UserService获取likeCount的线程  " + Thread.currentThread().getName());
        try {
            TimeUnit.SECONDS.sleep(8);
            System.out.println("获取likeCount===睡眠:" + 8 + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 46L;
    }
}
posted @ 2024-04-29 15:13  牛奶配苦瓜  阅读(88)  评论(0)    收藏  举报