• 项目性能优化 - 并发编程合并文章详情页的 HTTP 请求次数


    目录

    1. 原始文章详情页

    2. 为什么要使用并发编程升级文章详情页

    3. 如何使用并发编程升级文章详情页

    3.1 配置线程池

    3.2 合并前端请求

    3.3 合并后端接口,使用多线程并发执行

    4. 项目相关链接


    1. 原始文章详情页

    【前端代码】

    前端主要做了这四件事:

    1. 初始化文章详情;
    2. 初始化当前文章底下爱的评论列表;
    3. 请求文章详情页时, 阅读量 + 1;
    4. 获取当前用户的登录信息(是否显示登录人,是否显示删除按钮).

    后端  controller  分别写 4 个接口处理相应的请求即可.

    2. 为什么要使用并发编程升级文章详情页

            🍁根据前面的前端代码,我们可以看出来,每次访问文章详情页,都会调用 4 个方法,而每一个方法的调用就是一次 HTTP 请求,而 HTTP 请求又是基于 TCP 协议的,所以每一次请求都需要进行 3 次握手,4 次挥手,那么 4 次请求,就需要进行 12 次握手,和 16 次挥手;

            🍁这样肯定是不如发送一次 HTTP 请求的性能高的,只不过合并 4 次请求,会使得建立连接和断开连接的时间比原来长那么一点,但是在计算响应的时候,使用了 4 个线程并发执行的,所以整体来说,性能还是可以提升不少的.

    3. 如何使用并发编程升级文章详情页

    3.1 配置线程池

    1. @Configuration
    2. public class ThreadPoolConfig {
    3. @Bean
    4. public ThreadPoolTaskExecutor taskExecutor() {
    5. ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    6. taskExecutor.setCorePoolSize(5); // 核心线程数
    7. taskExecutor.setMaxPoolSize(10); // 最大线程数
    8. taskExecutor.setQueueCapacity(10000); // 任务队列的大小
    9. taskExecutor.setThreadNamePrefix("my-thread-pool-"); // 前缀名
    10. taskExecutor.initialize();
    11. return taskExecutor;
    12. }
    13. }

    3.2 合并前端请求

    3.3 合并后端接口,使用多线程并发执行

    1. /**
    2. * 详情页接口初始化合并方法
    3. * @param aid
    4. * @return
    5. */
    6. @RequestMapping("/total_init")
    7. public Object totalInit(Integer aid, HttpServletRequest request) throws ExecutionException, InterruptedException {
    8. // 1.非空效验
    9. if(aid == null && aid <= 0) {
    10. return AjaxResult.fail(-1, "非法参数! ");
    11. }
    12. // 2.创建多个任务,放到线程池中进行执行
    13. // 2.1 得到文章详情
    14. FutureTask getArticleInfo = new FutureTask<>(() -> {
    15. // 查询数据库中的文章信息
    16. ArticleInfoVo articleInfoVo = articleService.getDetail(aid);
    17. if(articleInfoVo != null) {
    18. // 组装数据: 查询当前用户发表的文章总数
    19. articleInfoVo.setArtCount(articleService.artCount(articleInfoVo.getUid()));
    20. // 查询图片
    21. UserInfo userInfo = userService.getById(articleInfoVo.getUid());
    22. articleInfoVo.setPhoto(userInfo.getPhoto());
    23. }
    24. return articleInfoVo;
    25. });
    26. // 2.2 得到当前文章的评论列表
    27. FutureTask> getCommentList = new FutureTask<>(() -> {
    28. return commentInfoService.getList(aid);
    29. });
    30. // 2.3 给当前文章的阅读量 + 1
    31. FutureTask updateRCount = new FutureTask<>(() -> {
    32. return articleService.addRCount(aid);
    33. });
    34. // 2.4 当前登录用户的信息返回给前端
    35. FutureTask getSession = new FutureTask<>(() -> {
    36. return SessionUtil.getLoginUser(request);
    37. });
    38. // 将任务放到线程池中并发执行
    39. taskExecutor.submit(getArticleInfo);
    40. taskExecutor.submit(getCommentList);
    41. taskExecutor.submit(updateRCount); // 只操作后端,不需要等待执行完
    42. taskExecutor.submit(getSession);
    43. // 等待任务执行完
    44. ArticleInfoVo articleInfoVo = getArticleInfo.get(); // 阻塞至执行完
    45. List commentList = getCommentList.get();
    46. UserInfo userInfo = getSession.get();
    47. // 3.组装并发执行的结果,返回给前端
    48. HashMap resultMap = new HashMap<>();
    49. resultMap.put("articleinfo",articleInfoVo);
    50. resultMap.put("commentList",commentList);
    51. resultMap.put("userinfo",userInfo);
    52. return AjaxResult.success(resultMap);
    53. }

    【注意】后端合并接口后,新的接口需要在拦截器里面设置放行,否则分页列表页查看详情页就会没有权限.

    4. 项目相关链接

     项目仓库:https://gitee.com/xiaobite_hl/JAVA/tree/master/Big-work/mycnblog_ssm_2

    项目博客:https://blog.csdn.net/xaiobit_hl/article/details/128727219 

    项目 web 自动化测试: https://blog.csdn.net/xaiobit_hl/article/details/129903816


  • 相关阅读:
    Linux目录结构+文件类型
    WPF依赖属性概述
    SpringCloud基础5——elasticsearch
    构建LangChain应用程序的示例代码:48、如何使用非文本生成工具创建多模态代理
    【转】浅谈威胁狩猎(Threat Hunting)
    git使用
    【软考软件评测师】2012综合知识历年真题
    Android Settings解析
    服务器硬件基础知识
    数据库上机实验7 数据库设计
  • 原文地址:https://blog.csdn.net/xaiobit_hl/article/details/132897908