ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java高并发专题之27、实战:你的接口太慢了需要优化

2022-05-04 21:01:00  阅读:160  来源: 互联网

标签:map 27 Java throws 商品 goodsId goods id 太慢


电商接口案例讲解

电商app都有用过吧,商品详情页,需要给他们提供一个接口获取商品相关信息:

  1. 商品基本信息(名称、价格、库存、会员价格等)
  2. 商品图片列表
  3. 商品描述信息(描述信息一般是由富文本编辑的大文本信息)

数据库中我们用了3张表存储上面的信息:

  1. 商品基本信息表:t_goods(字段:id【商品id】、名称、价格、库存、会员价格等)
  2. 商品图片信息表:t_goods_imgs(字段:id、goods_id【商品id】、图片路径),一个商品会有多张图片
  3. 商品描述信息表:t_goods_ext(字段:id,goods_id【商品id】、商品描述信息【大字段】)

这需求对于大家来说很简单吧,伪代码如下:

  1. public Map<String,Object> detail(long goodsId){
  2. //创建一个map
  3. //step1:查询商品基本信息,放入map
  4. map.put("goodsModel",(select * from t_goods where id = #gooldsId#));
  5. //step2:查询商品图片列表,返回一个集合放入map
  6. map.put("goodsImgsModelList",(select * from t_goods_imgs where goods_id = #gooldsId#));
  7. //step3:查询商品描述信息,放入map
  8. map.put("goodsExtModel",(select * from t_goods_ext where goods_id = #gooldsId#));
  9. return map;
  10. }

上面这种写法应该很常见,代码很简单,假设上面每个步骤耗时200ms,此接口总共耗时>=600毫秒,其他还涉及到网络传输耗时,估计总共会在700ms左右,此接口有没有优化的空间,性能能够提升多少?我们一起来挑战一下。

在看一下上面的逻辑,整个过程是按顺序执行的,实际上3个查询之间是没有任何依赖关系,所以说3个查询可以同时执行,那我们对这3个步骤采用多线程并行执行,看一下最后什么情况,代码如下:

  1. package com.itsoku.chat26;
  2. import java.util.Arrays;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.concurrent.*;
  7. /**
  8. * 跟着阿里p7学并发,微信公众号:javacode2018
  9. */
  10. public class Demo1 {
  11. /**
  12. * 获取商品基本信息
  13. *
  14. * @param goodsId 商品id
  15. * @return 商品基本信息
  16. * @throws InterruptedException
  17. */
  18. public String goodsDetailModel(long goodsId) throws InterruptedException {
  19. //模拟耗时,休眠200ms
  20. TimeUnit.MILLISECONDS.sleep(200);
  21. return "商品id:" + goodsId + ",商品基本信息....";
  22. }
  23. /**
  24. * 获取商品图片列表
  25. *
  26. * @param goodsId 商品id
  27. * @return 商品图片列表
  28. * @throws InterruptedException
  29. */
  30. public List<String> goodsImgsModelList(long goodsId) throws InterruptedException {
  31. //模拟耗时,休眠200ms
  32. TimeUnit.MILLISECONDS.sleep(200);
  33. return Arrays.asList("图1", "图2", "图3");
  34. }
  35. /**
  36. * 获取商品描述信息
  37. *
  38. * @param goodsId 商品id
  39. * @return 商品描述信息
  40. * @throws InterruptedException
  41. */
  42. public String goodsExtModel(long goodsId) throws InterruptedException {
  43. //模拟耗时,休眠200ms
  44. TimeUnit.MILLISECONDS.sleep(200);
  45. return "商品id:" + goodsId + ",商品描述信息......";
  46. }
  47. //创建个线程池
  48. ExecutorService executorService = Executors.newFixedThreadPool(10);
  49. /**
  50. * 获取商品详情
  51. *
  52. * @param goodsId 商品id
  53. * @return
  54. * @throws ExecutionException
  55. * @throws InterruptedException
  56. */
  57. public Map<String, Object> goodsDetail(long goodsId) throws ExecutionException, InterruptedException {
  58. Map<String, Object> result = new HashMap<>();
  59. //异步获取商品基本信息
  60. Future<String> gooldsDetailModelFuture = executorService.submit(() -> goodsDetailModel(goodsId));
  61. //异步获取商品图片列表
  62. Future<List<String>> goodsImgsModelListFuture = executorService.submit(() -> goodsImgsModelList(goodsId));
  63. //异步获取商品描述信息
  64. Future<String> goodsExtModelFuture = executorService.submit(() -> goodsExtModel(goodsId));
  65. result.put("gooldsDetailModel", gooldsDetailModelFuture.get());
  66. result.put("goodsImgsModelList", goodsImgsModelListFuture.get());
  67. result.put("goodsExtModel", goodsExtModelFuture.get());
  68. return result;
  69. }
  70. public static void main(String[] args) throws ExecutionException, InterruptedException {
  71. long starTime = System.currentTimeMillis();
  72. Map<String, Object> map = new Demo1().goodsDetail(1L);
  73. System.out.println(map);
  74. System.out.println("耗时(ms):" + (System.currentTimeMillis() - starTime));
  75. }
  76. }

输出:

  1. {goodsImgsModelList=[图1, 图2, 图3], gooldsDetailModel=商品id:1,商品基本信息...., goodsExtModel=商品id:1,商品描述信息......}
  2. 耗时(ms):208

可以看出耗时200毫秒左右,性能提升了2倍,假如这个接口中还存在其他无依赖的操作,性能提升将更加显著,上面使用了线程池并行去执行3次查询的任务,最后通过Future获取异步执行结果。

整个优化过程

  1. 先列出无依赖的一些操作
  2. 将这些操作改为并行的方式

用到的技术有

  1. 线程池相关知识
  2. Executors、Future相关知识

总结

  1. 对于无依赖的操作尽量采用并行方式去执行,可以很好的提升接口的性能
  2. 大家可以在你们的系统中试试这种方法,感受一下效果,会让你感觉很爽
来源:http://itsoku.com/course/1/27

标签:map,27,Java,throws,商品,goodsId,goods,id,太慢
来源: https://www.cnblogs.com/konglxblog/p/16222379.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有