Day420.商品详细_异步编排优化代码 -谷粒商城

商品详细

一、环境准备

  • C:\Windows\System32\drivers\etc\hosts

添加本地域名解析

Day420.商品详细_异步编排优化代码 -谷粒商城

  • 添加nginx配置

/mydata/nginx/conf

Day420.商品详细_异步编排优化代码 -谷粒商城

docker restart nginx #重启nginx
  • 修改gateway网关

Day420.商品详细_异步编排优化代码 -谷粒商城

        - id: nginx_route
          uri: lb://achangmall-product
          predicates:
            - Host=achangmall.com,item.achangmall.com
  • 启动nacos
startup.cmd -m standalone #单机启动
  • 拉静态文件去product服务,并改名为item.html

Day420.商品详细_异步编排优化代码 -谷粒商城

  • 将静态资源上传至nginx,并创建item文件夹

/mydata/nginx/html/item

Day420.商品详细_异步编排优化代码 -谷粒商城

  • 修改search服务的list.html页面

Day420.商品详细_异步编排优化代码 -谷粒商城


二、商品详细业务代码

  • com.achang.achangmall.product.web.ItemController
@Controller
public class ItemController {
    @Autowired
    private SkuInfoService skuInfoService;

    /**
     * 展示当前sku的详细
     */
    @GetMapping("/{skuId}.html")
    public String skuItem(@PathVariable("skuId") Long skuId, Model model){
        SkuItemVo vo = skuInfoService.item(skuId);

        model.addAttribute("item",vo);
        return "item";
    }

}
  • com.achang.achangmall.product.service.impl.SkuInfoServiceImpl
@Autowired
private SkuImagesService imagesService;

@Autowired
private SpuInfoDescService spuInfoDescService;

@Autowired
private AttrGroupService attrGroupService;

@Autowired
private SkuSaleAttrValueService skuSaleAttrValueService;

@Override
public SkuItemVo item(Long skuId) {
    SkuItemVo skuItemVo = new SkuItemVo();
    SkuInfoEntity info = getById(skuId);
    Long catalogId = info.getCatalogId();
    Long spuId = info.getSpuId();

    skuItemVo.setInfo(info);

    List<SkuImagesEntity> images = imagesService.getImageBySkuId(skuId);
    skuItemVo.setImages(images);

    List<SkuItemVo.ItemSaleAttrVo>  saleAttrVos = skuSaleAttrValueService.getAttrsBySpuId(spuId);
    skuItemVo.setSaleAttr(saleAttrVos);

    SpuInfoDescEntity spuInfoDescServiceById = spuInfoDescService.getById(spuId);
    skuItemVo.setDesp(spuInfoDescServiceById);

    List<SkuItemVo.SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId,catalogId);
    skuItemVo.setGroupAttrs(attrGroupVos);
    return skuItemVo;
}
  • com.achang.achangmall.product.vo.SkuItemVo
@Data
public class SkuItemVo {

    SkuInfoEntity info;

    List<SkuImagesEntity> images;

    List<ItemSaleAttrVo> saleAttr;

    SpuInfoDescEntity desp;

    List<SpuItemAttrGroupVo> groupAttrs;

    @Data
    public static class ItemSaleAttrVo{
        private Long attrId;
        private String attrName;
        private String attrValue;
    }

    @Data
    public static class SpuItemAttrGroupVo{
        private String groupName;
        private List<SpuBaseAttrVo> attrs;
    }

    @Data
    public static class SpuBaseAttrVo{
        private String attrName;
        private String attrValue;
    }
}
  • achangmall-product/src/main/resources/mapper/product/AttrGroupDao.xml
<resultMap id="spuItemAttrGroupVo" type="com.achang.achangmall.product.vo.SkuItemVo$SpuItemAttrGroupVo">
    <result property="groupName" column="attr_group_name"></result>
    <collection property="attrs" ofType="com.achang.achangmall.product.vo.SkuItemVo$SpuBaseAttrVo">
        <result column="attr_name" property="attrName"></result>
        <result column="attr_value" property="attrValue"></result>
    </collection>
</resultMap>
<select id="getAttrGroupWithAttrsBySpuId"
        resultMap="spuItemAttrGroupVo">

    select
    pav.spu_id,
    ag.attr_group_name,
    ag.attr_group_id,
    attr.attr_id,
    attr.attr_name,
    pav.attr_value
    from pms_attr_group ag
    left join pms_attr_attrgroup_relation arr on aar.attr_group_id = ag.attr_group_id
    left join pms_attr attr on attr.attr_id = aar.attr_id
    left join pms_product_attr_value pav on pav.attr_id = attr.attr_id
    where ag.catelog_id = #{catelogId} and pav.spu_id = #{spuId}

</select>
  • com.achang.achangmall.product.service.impl.SkuImagesServiceImpl
    @Override
    public List<SkuImagesEntity> getImageBySkuId(Long skuId) {
        return baseMapper.selectList(new QueryWrapper<SkuImagesEntity>().eq("sku_id",skuId));
    }
  • com.achang.achangmall.product.service.impl.AttrGroupServiceImpl
    @Override
    public List<SkuItemVo.SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuId(Long spuId,Long catalogId) {
        List<SkuItemVo.SpuItemAttrGroupVo> vos = baseMapper.getAttrGroupWithAttrsBySpuId(spuId,catalogId);
        return vos;
    }
  • com.achang.achangmall.product.service.impl.SkuSaleAttrValueServiceImpl
@Override
public List<SkuItemVo.ItemSaleAttrVo> getAttrsBySpuId(Long spuId) {
    List<SkuItemVo.ItemSaleAttrVo> itemSaleAttrVos = baseMapper.getSaleAttrsBySpuId(spuId);
    return itemSaleAttrVos;
}
  • achangmall-product/src/main/resources/mapper/product/SkuSaleAttrValueDao.xml
<select id="getSaleAttrsBySpuId" resultType="com.achang.achangmall.product.vo.SkuItemVo$ItemSaleAttrVo">
    select
    ssav.attr_id attr_id,
    ssav.attr_name attr_name,
    GROUP_CONCAT(DISTINCT ssav.attr_value) attr_values
    from pms_sku_info info
    left join pms_sku_sale_attr_value ssav on ssav.sku_id = info.sku_id
    where info.spu_id = #{spuId}
    group by ssav.attr_id , ssav.attr_name
</select>

三、优化:异步编排

通过昨天学习的CompletableFuture, 【 之前的学习笔记总结

  • 业务线程池

com.achang.achangmall.product.conf.ThreadPoolConfig

@Configuration
public class ThreadPoolConfig {

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            pool.getCoreSize(),
            pool.getMaxSize(),
            pool.getKeepAliveTime(),
            TimeUnit.SECONDS, new LinkedBlockingDeque<>(100000),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());
        return threadPoolExecutor;
    }

}
  • com.achang.achangmall.product.conf.ThreadPoolConfigProperties
@Component
@ConfigurationProperties(prefix = "achangmall.thread")
@Data
public class ThreadPoolConfigProperties {
    private Integer coreSize;
    private Integer MaxSize;
    private Integer keepAliveTime;
}
  • achangmall-product/pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
  • achangmall-product/src/main/resources/application.yaml
achangmall:
  thread:
    core-size: 20
    max-size: 200
    keep-alive-time: 20
  • com.achang.achangmall.product.service.impl.SkuInfoServiceImpl

通过CompletableFuture异步编排

@Autowired
private SkuImagesService imagesService;

@Autowired
private SpuInfoDescService spuInfoDescService;

@Autowired
private AttrGroupService attrGroupService;

@Autowired
private SkuSaleAttrValueService skuSaleAttrValueService;

@Autowired
private ThreadPoolExecutor executor;

@Override
public SkuItemVo item(Long skuId) {
    SkuItemVo skuItemVo = new SkuItemVo();

    CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
        SkuInfoEntity infoEntity = getById(skuId);
        skuItemVo.setInfo(infoEntity);
        return infoEntity;
    }, executor);

    CompletableFuture<Void> acceptAsync = infoFuture.thenAcceptAsync(res -> {
        List<SkuImagesEntity> images = imagesService.getImageBySkuId(skuId);
        skuItemVo.setImages(images);
    });


    CompletableFuture<Void> voidCompletableFuture = infoFuture.thenAcceptAsync(res -> {
        List<SkuItemVo.ItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getAttrsBySpuId(res.getSpuId());
        skuItemVo.setSaleAttr(saleAttrVos);
    }, executor);

    CompletableFuture<Void> completableFuture = infoFuture.thenAcceptAsync(res -> {
        SpuInfoDescEntity spuInfoDescServiceById = spuInfoDescService.getById(res.getSkuId());
        skuItemVo.setDesp(spuInfoDescServiceById);
    }, executor);

    CompletableFuture<Void> thenAcceptAsync = infoFuture.thenAcceptAsync(res -> {
        List<SkuItemVo.SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
        skuItemVo.setGroupAttrs(attrGroupVos);
    }, executor);

    //等待所有任务都完成
    try {
        CompletableFuture.allOf(infoFuture,acceptAsync,voidCompletableFuture,completableFuture,thenAcceptAsync).get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

    return skuItemVo;
}
上一篇:如何搭建个人博客网站(Mac)


下一篇:Java-购物车实践与应用