谷粒商城-高级-40 商品上架整合 Elasticsearch

一、商品上架

商品服务,库存服务,检索服务

二、库存

三、检索

四、联调

给 商品服务,库存服务,检索服务相关方法打上断点,并使用debug启动。

商品上架插入到ES中:
file

Elasticsearch出现circuit_breaking_exception异常:

异常信息:

Elasticsearch exception [type=circuit_breaking_exception, reason=[parent] Data too large, data for [<http_request>] would be [122883430/117.1mb], which is larger than the limit of [90832896/86.6mb], real usage: [122882328/117.1mb], new bytes reserved: [1102/1kb], usages [request=0/0b, fielddata=0/0b, in_flight_requests=1102/1kb, accounting=28291/27.6kb]]

file

原因

field data 的缓存不够用

解决方法

设置fielddata缓存占用jvm内存的40%或更小

PUT /_cluster/settings
{
  "persistent": {
    "indices.breaker.fielddata.limit": "40%"
  }
} 

返回结果:

{
  "acknowledged": true,
  "persistent": {
    "indices": {
      "breaker": {
        "fielddata": {
          "limit": "40%"
        }
      }
    }
  },
  "transient": {}
}

可以使用Postman来发送请求:
file

然而,修改了fielddata的值,还是不起作用,不管查询什么,都会返回:

GET http://192.168.10.10:9200/_cat/health

{
  "error": {
    "root_cause": [
      {
        "type": "circuit_breaking_exception",
        "reason": "[parent] Data too large, data for [<http_request>] would be [120467168/114.8mb], which is larger than the limit of [90832896/86.6mb], real usage: [120467168/114.8mb], new bytes reserved: [0/0b], usages [request=0/0b, fielddata=0/0b, in_flight_requests=0/0b, accounting=28291/27.6kb]",
        "bytes_wanted": 120467168,
        "bytes_limit": 90832896,
        "durability": "PERMANENT"
      }
    ],
    "type": "circuit_breaking_exception",
    "reason": "[parent] Data too large, data for [<http_request>] would be [120467168/114.8mb], which is larger than the limit of [90832896/86.6mb], real usage: [120467168/114.8mb], new bytes reserved: [0/0b], usages [request=0/0b, fielddata=0/0b, in_flight_requests=0/0b, accounting=28291/27.6kb]",
    "bytes_wanted": 120467168,
    "bytes_limit": 90832896,
    "durability": "PERMANENT"
  },
  "status": 429
}

在网上找了一下原因,是由于在安装ES时,分配的内存过小,初始内存 Xms 64M,最大内存Xmx128M,ES运行非常占内存,所以,删掉原来较小的 docker 容器,内存分配扩大一倍,重新安装:

docker ps
ONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                            NAMES
fbd8372062fc        kibana:7.4.2          "/usr/local/bin/dumb…"   4 days ago          Up 2 hours          0.0.0.0:5601->5601/tcp                           kibana
b9c6d899522a        elasticsearch:7.4.2   "/usr/local/bin/dock…"   5 days ago          Up 18 minutes       0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp

删除容器:

docker rm b9c6

重新安装:

#运行ES
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms128m -Xmx256m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2

重新测试:
file

现在可以看到,ES可以正常运行了。

然后再上架商品,可以插到数据已经进入到ES了:
file

五、远程feign响应结果R抽取

com/atguigu/gulimall/product/service/impl/SpuInfoServiceImpl.java

  // TODO:: 1、发送远程调用,库存系统查询是否有库存,远程调用可能有异常,所以,这里使用try捕获异常
        Map<Long, Boolean> stockMap = null;
        try{
            R skuHasStock = wareFeignService.getSkusHasStock(skuIdList);

            TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>(){};

            stockMap = skuHasStock.getData(typeReference).stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item->item.getHasStock()));
        }catch (Exception e){
            log.error("库存服务查询异常:原因:{}", e);

        }

file

R类data响应数据类型进行抽取:

gulimall-common/src/main/java/com/atguigu/common/utils/R.java

/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有,侵权必究!
 */

package com.atguigu.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.apache.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

/**
 * 返回数据
 *
 * @author Mark sunlightcs@gmail.com
 */
public class R extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    // 利用fastjson进行逆转(data方法是为了业务取值方便而自己新增的)
    public <T> T getData(TypeReference<T> typeReference) {
        Object data = get("data"); // 默认是map
        String s = JSON.toJSONString(data);
        T t = JSON.parseObject(s, typeReference);
        return t;
    }

    public R setData(Object data) {
        put("data", data);
        return this;
    }

    public R() {
        put("code", 0);
        put("msg", "success");
    }

    public static R error() {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
    }

    public static R error(String msg) {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
    }

    public static R error(int code, String msg) {
        R r = new R();
        r.put("code", code);
        r.put("msg", msg);
        return r;
    }

    public static R ok(String msg) {
        R r = new R();
        r.put("msg", msg);
        return r;
    }

    public static R ok(Map<String, Object> map) {
        R r = new R();
        r.putAll(map);
        return r;
    }

    public static R ok() {
        return new R();
    }

    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }

    public Integer getCode() {

        return (Integer) this.get("code");
    }
}

这个方法:skuHasStock.getData(typeReference) 会对响应数据Data做一个逆转处理,返回给我们的是一个对象。

为者常成,行者常至