谷粒商城-高级-40 商品上架整合 Elasticsearch
一、商品上架
商品服务,库存服务,检索服务
二、库存
三、检索
四、联调
给 商品服务,库存服务,检索服务相关方法打上断点,并使用debug启动。
商品上架插入到ES中:
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]]
原因
field data 的缓存不够用
解决方法
设置fielddata缓存占用jvm内存的40%或更小
PUT /_cluster/settings
{
"persistent": {
"indices.breaker.fielddata.limit": "40%"
}
}
返回结果:
{
"acknowledged": true,
"persistent": {
"indices": {
"breaker": {
"fielddata": {
"limit": "40%"
}
}
}
},
"transient": {}
}
可以使用Postman来发送请求:
然而,修改了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
重新测试:
现在可以看到,ES可以正常运行了。
然后再上架商品,可以插到数据已经进入到ES了:
五、远程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);
}
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做一个逆转处理,返回给我们的是一个对象。
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)