谷粒商城学习笔记

这篇具有很好参考价值的文章主要介绍了谷粒商城学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、项目简介

1、项目背景

1)、电商模式

谷粒商城笔记,学习,java,微服务

2)、谷粒商城

谷粒商城是一个 B2C 模式的电商平台,销售自营商品给客户。

2、项目架构图

1、项目微服务架构图

谷粒商城笔记,学习,java,微服务

2、微服务划分图

谷粒商城笔记,学习,java,微服务

3、项目技术&特色

谷粒商城笔记,学习,java,微服务

4、项目前置要求

谷粒商城笔记,学习,java,微服务

二、分布式基础概念

2、集群&分布式&节点

分布式是指将不同的业务分布在不同的地方。
集群指的是将几台服务器集中在一起,实现同一业务。
例如:京东是一个分布式系统,众多业务运行在不同的机器,所有业务构成一个大型的业务集群。每一个小的业务,比如用户系统,访问压力大的时候一台服务器是不够的。我们就 应该将用户系统部署到多个服务器,也就是每一个业务系统也可以做集群化; 分布式中的每一个节点,都可以做集群。 而集群并不一定就是分布式的。 节点:集群中的一个服务器

4、负载均衡

谷粒商城笔记,学习,java,微服务

7、服务熔断&服务降级

1)、服务熔断 a. 设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开 启断路保护机制,后来的请求不再去调用这个服务。本地直接返回默认 的数据
2)、服务降级 a. 在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业 务降级运行。降级:某些服务不处理,或者简单处理【抛异常、返回 NULL、 调用 Mock 数据、调用 Fallback 处理逻辑】。

三、项目架构

架构图

谷粒商城笔记,学习,java,微服务

微服务划分图

谷粒商城笔记,学习,java,微服务

四、环境搭建

docker

centos安装docker

https://docs.docker.com/engine/install/centos/

设置开机自启

systemctl enable docker

设置开机自启docker容器mysql服务

docker update mysql --restart=always

配置阿里云镜像加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-‘EOF’
{
“registry-mirrors”: [“https://76ra8yjq.mirror.aliyuncs.com”]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

docker安装mysql

启动docker镜像

docker run -p 3306:3306
–name mysql
-v /mydata/mysql/log:/var/log/mysql
-v /mydata/mysql/data:/var/lib/mysql
-v /mydata/mysql/conf:/etc/mysql
-e MYSQL_ROOT_PASSWORD=root
-d mysql:5.7
参数说明-p 3306:3306:将容器的 3306 端口映射到主机的 3306 端口 -v /mydata/mysql/conf:/etc/mysql:将配置文件夹挂载到主机 -v /mydata/mysql/log:/var/log/mysql:将日志文件夹挂载到主机 -v /mydata/mysql/data:/var/lib/mysql/:将配置文件夹挂载到主机 -e MYSQL_ROOT_PASSWORD=root:初始化 root 用户的密码

进入docker容器

docker exec -it f1178d5b0bd8 /bin/bash

修改mysql配置文件

vi /mydata/mysql/conf/my.cnf

[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect=‘SET collation_connection = utf8_unicode_ci’
init_connect=‘SET NAMES utf8’
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

使配置文件生效

docker ps
docker restart mysql

docker安装redis

挂载可能会把文件当成目录,所以预先创建好文件

mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

连接容器内redis客户端

docker exec -it redis redis-cli

当前数据保存在内存中,需要配置持久化规则

vim /mydata/redis/conf/redis.conf
appendonly yes
docker restart redis

maven

谷粒商城笔记,学习,java,微服务

git使用ssh连接

谷粒商城笔记,学习,java,微服务

git管理仓库
谷粒商城笔记,学习,java,微服务

开发生产者模型:开发在dev分支,开发完成合并到master分支

idea新建项目
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

创建微服务项目

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
从模块中复制一个pom文件放在根目录下,进行修改

可以取消这两个勾选,它会检查分析代码,包括TODO
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

数据库设计

谷粒商城笔记,学习,java,微服务

整合人人开源-后台管理系统

下载

https://gitee.com/renrenio 下载renren-fast和renren-fast-vue
快速搭建后台管理系统:renren-fast整合到gulimall项目中;vscode打开renren-fast-vue配置开发环境
npm install npm run dev

配置前端运行环境

node.js

谷粒商城笔记,学习,java,微服务

代码生成器(逆向工程)

下载:https://gitee.com/renrenio/renren-generator.git

整合进gulimall项目,修改配置文件,先生成product模块基本文件谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务
运行服务,访问localhost,点击生成下载.zip压缩文件,解压放进gulimall-product
谷粒商城笔记,学习,java,微服务
缺失很多依赖,创建common模块,引入依赖和renren-fast中的部分依赖文件
shift+f6修改模块名称
修改逆向工程,不使用shiro依赖,重新生成代码
谷粒商城笔记,学习,java,微服务

分布式组件

服务注册

1、引入依赖
谷粒商城笔记,学习,java,微服务
2、开启服务注册
谷粒商城笔记,学习,java,微服务
3、编写配置文件
谷粒商城笔记,学习,java,微服务

feign

1、导入依赖
谷粒商城笔记,学习,java,微服务
2、开启支持feign远程调用
谷粒商城笔记,学习,java,微服务

3、编写声明式接口
谷粒商城笔记,学习,java,微服务

配置中心

如何使用nacos作为配置中心统一管理配置

1、引入依赖

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

2、创建一个bootstrap.properties文件
spring.application.name=guli-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

3、需要给配置中心默认添加一个叫 数据集(Data Id)guli-coupon.properties。默认规则:应用名.properties

4、给 应用名.properties添加任何配置

5、动态获取配置
@RefreshScope:动态获取并刷新配置
@Value(“${配置项的名称}”):获取配置
配置中心优先级>本地配置优先级

gateway

前端内容

ES6

ECMAScript 6.0(以下简称 ES6,ECMAScript 是一种由 Ecma 国际(前身为欧洲计算机制造商 协会,英文名称是 European Computer Manufacturers Association)通过 ECMA-262标准化的脚本 程序设计语言)是 JavaScript 语言的下一代标准

模块化

vue

1、文件夹内终端敲入命令:npm init -y
2、npm install vue
3、引入vue,script中src=“./node_modules/vue/dist/vue.js”
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

vue模块化开发

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

目录结构

谷粒商城笔记,学习,java,微服务

项目开发

商品服务

1、数据库导入数据
2、运行renren-vue和后台

配置网关

请求转发Service Unavailable问题

https://blog.csdn.net/kitahiragawa/article/details/124229580

原因:这是由于版本不兼容引发的问题,我当前使用的springcloud alibaba版本为2021.0.1.0,而springcloud alibaba在2020版之后不支持ribbon,而springcloud gateway使用ribbon,就导致了gateway无法路由到目标服务

跨域问题

不是简单请求就需要发送一个Options方式的预检请求

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

谷粒商城笔记,学习,java,微服务

解决跨域

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

product模块逻辑删除

1)、配置全局的逻辑删除规则(省略)
2)、配置逻辑删除的组件Bean(省略)
3)、给Bean加上逻辑删除注解@TableLogic

商品服务-三级分类

商品服务-品牌管理

oss上传

根据github上springCloudAlibaba演示demo引入
https://github.com/alibaba/spring-cloud-alibaba

谷粒商城笔记,学习,java,微服务


nacos config配置:
yml文件配置
谷粒商城笔记,学习,java,微服务

注意点:需要加如下依赖

<!–cloud新版本默认将bootstrap移除了,所以需要添加如下依赖–>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

table显示图片

table->自定义模板->在里面配置template,scope内容自定义显示
谷粒商城笔记,学习,java,微服务
异常排查:
谷粒商城笔记,学习,java,微服务

1、main.js是否引入elementui
2、main.js引入的是src下的elementui
3、elemnetui/index.js中没有引入image
4、去element官网快速上手配置引入image

jsr303数据校验

JSR303
1)、给Bean添加校验注解:javax.validation.constraints,并定义自己的message提示
2)、开启校验功能@Valid
效果:校验错误以后会有默认的响应;
3)、给校验的bean后紧跟一个BindingResult,就可以获取到校验的结果
4)、分组校验(多场景的复杂校验)
1)、 @NotBlank(message = “品牌名必须提交”,groups = {AddGroup.class,UpdateGroup.class})
给校验注解标注什么情况需要进行校验
2)、@Validated({AddGroup.class})
3)、默认没有指定分组的校验注解@NotBlank,在分组校验情况@Validated({AddGroup.class})下不生效,只会在@Validated生效;
5)、自定义校验
1)、编写一个自定义的校验注解
2)、编写一个自定义的校验器 ConstraintValidator
3)、关联自定义的校验器和自定义的校验注解

统一异常处理

统一的异常处理
@ControllerAdvice
1)、编写异常处理类,使用@ControllerAdvice。
2)、使用@ExceptionHandler标注方法可以处理的异常。

spu、sku

SPU:Standard Product Unit(标准化产品单元)
SKU:Stock Keeping Unit(库存量单位)

iphoneX 是 SPU、MI 8 是 SPU
iphoneX 64G 黑曜石 是 SKU
MI8 8+64G+黑色 是 SKU

Object划分

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

项目运行内存配置

1、新建、配置compound
谷粒商城笔记,学习,java,微服务
2、配置最大占用内存
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

@Transactional分析

断点执行看不到之前代码的入库数据:

1、因为事务没有提交之前,数据是读不出来的;
2、mysql默认的隔离级别是可重复读,就是最起码读到已经提交了的数据,为了测试方便,将当前会话的隔离级别等级设置为读未提交
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
3、然后就可以很方便得查看数据库变化

让@Transactional事务遇到异常不回滚

1、可以使用try catch捕获异常
2、
谷粒商城笔记,学习,java,微服务

库存&采购流程

采购需求->合并整单->采购单->库存

谷粒商城笔记,学习,java,微服务

基础篇总结

#谷粒商城笔记,学习,java,微服务

分布式高级篇

ElasticSearch

官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html 社区中文: https://es.xiaoleilu.com/index.html http://doc.codingdict.com/elasticsearch/0/

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

1、下载镜像文件

docker pull elasticsearch:7.4.2 存储和检索数据
docker pull kibana:7.4.2 可视化检索数据

2、创建实例

1、ElasticSearch

mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
echo “http.host: 0.0.0.0” >> /mydata/elasticsearch/config/elasticsearch.yml
chmod -R 777 /mydata/elasticsearch/ 保证权限
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e “discovery.type=single-node”
-e ES_JAVA_OPTS=“-Xms64m -Xmx512m” \
-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

http.host: 0.0.0.0 : es可以被远程任何机器访问
-e:配置参数
-p:暴露端口-9200是我们给es的restAPI发请求的端口-9300是es在分布式集群状态下的节点通信端口
discovery.type:单节点模式
ES_JAVA_OPTS:不指定的话es一启动会将内存全部占用,虚拟机就卡死了
-d:后台启动

以后再外面装好插件重启即可;
特别注意: -e ES_JAVA_OPTS=“-Xms64m -Xmx256m” \ 测试环境下,设置 ES 的初始内存和最大内存,否则导 致过大启动不了 ES

查看日志:docker logs elasticsearch

访问:http://192.168.233.141:9200/

2、Kibana

docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.233.141:9200 -p 5601:5601 \ -d kibana:7.4.2

访问:http://192.168.233.141:5601/app/kibana#/dev_tools/console?_g=()

初步检索

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
_seq_no可以作乐观锁
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

样本数据 acounts.json

https://github.com/elastic/elasticsearch/blob/7.5/docs/src/test/resources/accounts.json

进阶检索

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/getting-started-search.html

启动docker容器

docker ps -a
docker start containerId
开机自启
docker update containerId --restart=always

mapping

type是keyword类型:不会进行全文检索,只会精确匹配
type是text类型的:全文检索,保存数据的时候进行分词,检索的时候按照分词进行匹配

ES5.0及以后的版本取消了string类型,将原先的string类型拆分为text和keyword两种类型。它们的区别在于text会对字段进行分词处理而keyword则不会进行分词。
也就是说如果字段是text类型,存入的数据会先进行分词,然后将分完词的词组存入索引,而keyword则不会进行分词,直接存储。
text类型的数据被用来索引长文本,例如电子邮件主体部分或者一款产品的介绍,这些文本会被分析,在建立索引文档之前会被分词器进行分词,转化为词组。经过分词机制之后es允许检索到该文本切分而成的词语,但是text类型的数据不能用来过滤、排序和聚合等操作。
keyword类型的数据可以满足电子邮箱地址、主机名、状态码、邮政编码和标签等数据的要求,不进行分词,常常被用来过滤、排序和聚合

安装ik分词器

1、下载https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v6.4.2
2、解压到plugin文件夹,装在ik目录中
谷粒商城笔记,学习,java,微服务
3、进入es容器:docker exec -it 容器id /bin/bash,elasticsearch-plugin list
谷粒商城笔记,学习,java,微服务
4、重启容器
docker restart elasticsearch

docker安装nginx

谷粒商城笔记,学习,java,微服务

es自定义词库

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

springboot整合es

为什么不用js直接操作es
1、安全性
2、js对es支持度低

分析:
1、方便检索
{
skuId:1
spuId:11
skuTitle:华为xx
price:998
saleCount:99
attrs:[{尺寸:4寸},{CPU:高通945},{分辨率:全高清}]
}
冗余:100w商品 每个商品20个属性,假设合起来2kb数据 100w2kb=2000MB=2G 商城系统多了2G
2、
sku索引{
skuId:1
spuId:11
xxxxxx
}
attr索引{
spuId:11
attrs:[{尺寸:4寸},{CPU:高通945},{分辨率:全高清}]
}
问题: 搜索’小米’ 粮食、手机、电器
1w个 4k个spu
分步:4k个spu对应的所有可能属性
esClient请求搜索4k个spuId,每个都是long型数据 4k
8=32000byte=32kb
1w人在商城检索商品:1w*32kb=320MB 一次光数据传输320mb,高并发情况下会网络阻塞
总结:空间和时间不能二者兼得,所以我们这里选择第一种设计模型

PUT product
{
“mappings”: {
“properties”: {
“skuId”: {
“type”: “long”
},
“spuId”: {
“type”: “keyword”
},
“skuTitle”: {
“type”: “text”,
“analyzer”: “ik_smart”
},
“skuPrice”: {
“type”: “keyword”
},
“skuImg”: {
“type”: “keyword”,
“index”: false,
“doc_values”: false
},
“saleCount”: {
“type”: “long”
},
“hasStock”: {
“type”: “boolean”
},
“hotScore”: {
“type”: “long”
},
“brandId”: {
“type”: “long”
},
“catalogId”: {
“type”: “long”
},
“brandName”: {
“type”: “keyword”,
“index”: false,
“doc_values”: false
},
“brandImg”: {
“type”: “keyword”,
“index”: false,
“doc_values”: false
},
“catalogName”: {
“type”: “keyword”,
“index”: false,
“doc_values”: false
},
“attrs”: {
“type”: “nested”,
“properties”: {
“attrId”: {
“type”: “long”
},
“attrName”: {
“type”: “keyword”,
“index”: false,
“doc_values”: false
},
“attrValue”: {
“type”: “keyword”
}
}
}
}
}
}
index:false 表示该属性不可用来被检索
doc_values: true 表示可以用来作聚合、排序、脚本等操作,进行空间节省
“type”: “nested” 表示属性子对象中的某些值进行检索

nginx+windows搭建域名访问环境

谷粒商城笔记,学习,java,微服务

域名解析:我们在浏览器上敲gulimall.com,windows如何知道哪个域名对应哪个ip地址?
1、查看系统内部系统映射规则(网卡带我们转过去)
2、如果系统没告诉gulimall.com在哪个地址,那就去网络上的dns(比如114.114.114.114,8.8.8.8),解析出域名(dns中保存了每个域名对应每个ip地址,在公网保存),查看ip映射规则

谷粒商城笔记,学习,java,微服务

1、配置hosts
192.168.233.141 gulimall.com,http://gulimall.com:9200/测试配置是否成功
2、配置nginx配置文件,请求发到网关
谷粒商城笔记,学习,java,微服务
3、在网关配置转发策略
谷粒商城笔记,学习,java,微服务
4、域名请求依然是404
谷粒商城笔记,学习,java,微服务
因为nginx代理给网关的时候,会丢失请求的host信息
配置proxy_set_header Host $host
谷粒商城笔记,学习,java,微服务

压力测试

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

java内存模型

压测数据

压测内容 路径 压测线程数 吞吐量/s 90%响应时间 99%响应时间
Nginx http://192.168.233.141:80/ 50 2335 11 944
Gateway http://localhost:88/ 50 10367 8 31
简单服务 localhost:10000/hello 50 11341 8 17
首页一级菜单渲染 localhost:10000 50 270(db,thymeleaf) 267 365
首页渲染(thymeleaf开缓存) localhost:10000 50 290 251 365
首页渲染(thymeleaf开缓存、 优化数据库、降低日志级别日 志(关日志)) localhost:10000 50 700 105 183
三级分类数据获取 localhost:10000/index/catalog.json 50 2(db)/8(加索引)
三级分类(优化业 务,减少与数据库的交互) localhost:10000/index/catalog.json 50 111 571 896
三 级 分 类 ( 使 用 redis 作为缓存) localhost:10000/index/catalog.json 50 411 153 217
首页全量数据获取 localhost:10000 50 7(静态资源)
Nginx+Gateway 50
Gateway+简单服务 localhost:88/hello 50 3126 30 125
全链路 gulimall.com/hello 50 800 88 310

监控内存使用率等数据:docker stats

测nginx
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
简单服务
谷粒商城笔记,学习,java,微服务

首页全量数据获取
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
开thymeleaf缓存、优化数据库、关日志、nginx动静分离
效果还是不明显,吞吐量从7-11
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务开thymeleaf缓存、优化数据库、关日志、nginx动静分离、调节内存
谷粒商城笔记,学习,java,微服务

-Xms 堆内存的初始大小,默认为物理内存的1/64
-Xmx 堆内存的最大大小,默认为物理内存的1/4
-Xmn 堆内新生代的大小。通过这个值也可以得到老生代的大小:-Xmx减去-Xmn
-Xss 设置每个线程可使用的内存大小,即栈的大小

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

测试服务崩溃
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
三 级 分 类 ( 使 用 redis 作为缓存)
谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务
问题:压测报错
谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务

解决:
TODO:压测产生堆歪内存溢出:OutOfDirectMemoryError
1):springboot2.0以后默认使用lettuce作为操作redis的客户端,它使用netty来进行网络通信
2):lettuce的bug导致netty堆外内存溢出 -Xmx300m netty如果没有指定堆外内存,默认使用-Xmx300m
可以通过-Dio.netty.maxDirectMemory进行设置
解决方案:不能使用-Dio.netty.maxDirectMemory只去调大堆外内存(调大内存只能延缓报错的时间)
1、升级lettuce客户端
2、切换使用jedis客户端
谷粒商城笔记,学习,java,微服务

总结:
1、中间件越多,性能损失越大,大多都损失在网络交互了;
2、业务:
 Db(MySQL 优化)  模板的渲染速度(缓存)  静态资源

优化数据库
新建索引
谷粒商城笔记,学习,java,微服务

动静分离

1、在nginx的html文件夹中新建static文件夹
2、将guli-product中的index下静态资源复制到static文件夹下
3、将href和<script src =""等各路径指向的静态资源加/static路径
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

4、修改nginx配置文件(这里的share文件夹是因为拷贝的es分词器的,应该是docker默认路径)
谷粒商城笔记,学习,java,微服务

缓存与分布式锁

ttl命令:查看key剩余的过期时间

会产生数据一致性问题

谷粒商城笔记,学习,java,微服务

redisTemplate和Lettuce、Jedis关系
Lettuce、Jedis都是操作redis的底层客户端,spring再次封装成redisTemplate
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

所以不管是Lettuce还是Jedis连接redis,都是兼容的

高并发下缓存失效问题

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

本地锁

本地锁在分布式场景下锁不住所有的服务

本地锁:synchronized、JUC(Lock),在分布式场景下,想要锁住所有的服务,必须使用分布式锁
这里this锁对象指向当前的serviceImpl对象,分布式场景下每个this都不一样
谷粒商城笔记,学习,java,微服务

问题:本地锁压力测试,测试结果:依然多次查询了数据库(锁的时序问题)

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
解决:当前锁时序
谷粒商城笔记,学习,java,微服务
当前是在释放锁后存进redis
谷粒商城笔记,学习,java,微服务
真正完整合理的逻辑:查数据库和存入缓存应该是一个原子操作,也就是在同一把锁内完成,否则就会有释放锁的时序问题,导致多次查询数据库
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

分布式锁_redis

本地锁在分布式场景下的问题

1、谷粒商城笔记,学习,java,微服务

2、启动多个服务,压力测试
gulimall.com->nginx->gateway负载均衡
谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务

3、现象:
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

redis分布式锁

setnx是原子性的

xshell发送命令到全部客户端,docker exec -it redis redis-cli,进入redis容器的客户端命令行,发送setnx命令
谷粒商城笔记,学习,java,微服务
版本一:
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
版本二:

如果getDataFromDb出现异常,又或者服务掉线,导致锁未释放,发生死锁
谷粒商城笔记,学习,java,微服务
设置过期时间
又为了防止在获取到锁和设置过期时间之间发生宕机,使用setnx ex原子性操作
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

版本三
谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务
版本四

如果由于业务时间很长,锁自己过期了,我们直接删除,有可能把别人正在持有的锁删除了
解决: 占锁的时候,值指定为uuid,每个人匹配是自己 的锁才删除。
谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务

版本五

1、如果正好判断是当前值,正要删除锁的时候,锁已经过期(网络延时), 别人已经设置到了新的值。那么我们删除的是别人的锁
解决: 删除锁必须保证原子性。使用redis+Lua脚本完成

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

redis分布式锁两个核心:
1、加锁保证原子性
2、解锁保证原子性
3、key过期时间放长一点

分布式锁_redisson

谷粒商城笔记,学习,java,微服务

文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95

可重入锁:a、b方法都加锁,加的是一样的锁,a获取到的锁b可以用,也就等于b方法直接执行
不可重入锁:a、b方法都加锁,加的一样的锁,b需要等a释放锁才可以执行,导致死锁

读写锁

读锁要等写锁释放才可以读取数据,写锁要排队,读锁不用排队

读 + 读 :相当于无锁,并发读,只会在Redis中记录好,所有当前的读锁。他们都会同时加锁成功
写 + 读 :必须等待写锁释放
写 + 写 :阻塞方式
读 + 写 :有读锁。写也需要等待

闭锁

相当于juc中的CountDownLatch

缓存一致性

缓存保证的是最终一致性,不是强一致,实时一致

双写模式
谷粒商城笔记,学习,java,微服务
失效模式
谷粒商城笔记,学习,java,微服务
解决方案
谷粒商城笔记,学习,java,微服务

springCache

@EnableConfigurationProperties

@EnableConfigurationProperties的作用是把springboot配置文件中的值与我们的xxxProperties.java的属性进行绑定,需要配合@ConfigurationProperties使用 我们这里是获取properties的配置文件数据然后将数据和CacheProperties属性对应

检索服务

搭建页面环境

谷粒商城笔记,学习,java,微服务

1、将html中搜索页index.html复制进gulimall-search的template目录,将./改成/static/search/
谷粒商城笔记,学习,java,微服务
(1、导入thymeleaf依赖,否则路径访问请求不到index.html页面;2、打包指定yml文件,否则报错Param ‘serviceName’ is illegal)
2、将其他静态资源放进nginx的/mydata/nginx/html/static/search目录
3、hosts文件配置search.gulimall.com映射,nginx配置文件配置server_name
谷粒商城笔记,学习,java,微服务
4、在gateway配置search.gulimall.com的host映射
谷粒商城笔记,学习,java,微服务
5、访问http://search.gulimall.com/
谷粒商城笔记,学习,java,微服务

检索服务

1、skuPrice的类型改成double,否则range区间过滤有问题

# 创建索引
PUT gulimall_product
{
  "mappings": {
	"properties": {
		"attrs": {
			"properties": {
				"attrId": {
					"type": "long"
				},
				"attrName": {
					"type": "keyword"
				},
				"attrValue": {
					"type": "keyword"
				}
			},
			"type": "nested"
		},
		"brandId": {
			"type": "long"
		},
		"brandImg": {
			"type": "keyword"
		},
		"brandName": {
			"type": "keyword"
		},
		"catalogId": {
			"type": "long"
		},
		"catalogName": {
			"type": "keyword"
		},
		"catelogId": {
			"type": "long"
		},
		"catelogName": {
			"type": "keyword"
		},
		"hasStock": {
			"type": "boolean"
		},
		"hosStock": {
			"type": "boolean"
		},
		"hotScore": {
			"type": "long"
		},
		"saleCount": {
			"type": "long"
		},
		"skuId": {
			"type": "long"
		},
		"skuImg": {
			"type": "keyword"
		},
		"skuPrice": {
			"type": "keyword"
		},
		"skuTitle": {
			"type": "text"
		},
		"spuId": {
			"type": "long"
		}
	}
  }
}
#检索服务
#模糊匹配、复合类型字段查询
#过滤(按照属性、分类、品牌、价格区间、库存)
#排序、分页、高亮
#聚合分析
GET /gulimall_product/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "skuTitle": "华为"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "catalogId": "225"
          }
        },
        {
          "terms": {
            "brandId": [
              "1",
              "2",
              "9"
            ]
          }
        },
        {
          "nested": {
          "path": "attrs",
          "query": {
            "bool": {
              "must": [
                {
                  "term": {
                    "attrs.attrId": {
                      "value": "15"
                    }
                  }
                },
                {
                  "terms": {
                    "attrs.attrValue": [
                      "海思(Hisilicon)",
                      "以官网信息为准"
                    ]
                  }
                }
              ]
            }
          }
        }
        },
        {
          "term":{
            "hasStock":{
              "value":"true"
            }
          }
        },
        {
          "range":{
            "skuPrice":{
              "gte":0,
              "lte":6000
            }
          }
        }
      ]
    }
  },
  "sort": [
    {
      "skuPrice": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 5,
  "highlight": {
    "fields": {
      "skuTitle":{}},
    "pre_tags":"<b style='color:red'>",
    "post_tags":"</b>"
  }
}

异步&线程池

面试: 一个线程池 core 7; max 20 ,queue:50,100 并发进来怎么分配的;
先有 7 个能直接得到执行,接下来 50 个进入队列排队,在多开 13 个继续执行。现在 70 个 被安排上了。剩下 30 个默认拒绝策略。

初始化线程的 4 种方式

1、初始化线程的 4 种方式
 1)、继承 Thread
 2)、实现 Runnable 接口
 3)、实现 Callable 接口 + FutureTask (可以拿到返回结果,可以处理异常)
 4)、线程池 给线程池直接提交任务
区别:
 1、2不能得到返回值,3可以获取返回值
 1、2、3都不可以控制资源
 4可以控制资源,系统稳定,无论面对多高的并发,不会耗尽资源,让系统崩溃

线程池七大参数

  1. corePoolSize:核心线程数【一直存在,除非设置了allowCoreThreadTimeOut】;线程池创建好以后就准备就绪的线程数量,就等待来接受异步任务去执行
  2. maximumPoolSize:最大线程数量,控制资源
  3. keepAliveTime:存活时间。如果当前正在运行的线程数量大于core数量,释放空闲的线程。只要线程空闲大于指定的keepAliveTime
  4. unit:时间单位
  5. BlockingQueue<Runnable> workQueue:阻塞队列。如果任务有很多,就会将目前多的任务放在队列里面。只要有线程空闲,就会去队列里面去除新的任务继续执行
  6. threadFactory:线程的创建工厂
  7. RejectedExecutionHandler handler:如果队列满了,按照我们指定的拒绝策略拒绝执行任务

工作顺序:

1、线程池创建,准备好 core 数量的核心线程,准备接受任务
2、新的任务进来,用 core 准备好的空闲线程执行。
  (1) 、core 满了,就将再进来的任务放入阻塞队列中。空闲的 core 就会自己去阻塞队 列获取任务执行
  (2) 、阻塞队列满了,就直接开新线程执行,最大只能开到 max 指定的数量
  (3) 、max 都执行好了。Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自 动销毁。最终保持到 core 大小
  (4) 、如果线程数开到了 max 的数量,还有新任务进来,就会使用 reject 指定的拒绝策 略进行处理
3、所有的线程创建都是由指定的 factory 创建的。

拒绝策略

谷粒商城笔记,学习,java,微服务
1、丢弃队列中最老的任务
2、直接拒绝新来的任务,会抛异常
3、直接调用run方法,异步变同步
4、直接拒绝,不抛异常

常见的 4 种线程池

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
1、core是0,所有都可回收
2、固定大小,core=max,所有都不可回收
3、定时任务的线程池
4、单线程池,后台从队列里面获取任务,挨个执行

CompletableFuture 异步编排

1、2、3可以并发查,4、5、6可以并发查,4、5、6依赖1返回的spuId
谷粒商城笔记,学习,java,微服务

商品详情

1、配置hosts的item.gulimall.com,nginx的路由,gateway网关(nginx之前配置过*.gulimall.com,所以不用再配置了)
2、将详情的静态资源文件传到nginx的html/item目录下
3、修改html访问路径,访问http://item.gulimall.com/

自定义配置线程池

异步查询商品详情

认证服务

配置auth.gulimall.com,nginx不用配置,将登陆、注册页面的静态资源文件复制进reg、login文件夹下

谷粒商城笔记,学习,java,微服务
jsr303校验

1、实体类加限制
2、加@Valid注解
3、BindingResult result接收错误
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

OAuth2.0协议

OAuth2.0:对于用户相关的 OpenAPI(例如获取用户信息,动态同步,照片,日志,分 享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向 用户征求授权。

谷粒商城笔记,学习,java,微服务

微博登录

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

分布式session

1、导入依赖
2、yml文件配置
3、@EnableRedisHttpSession
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
问题:
1、不能跨不同域名共享
2、同一个服务,复制多份,session不同步问题
3、不同服务,session不能共享问题

1、session存到redis,
2、解决子域session共享问题
3、使用json序列化的方式来序列化对象到redis
谷粒商城笔记,学习,java,微服务
需要在gulimall域名下也可以访问
谷粒商城笔记,学习,java,微服务

jdk默认的序列化方式存储到redis
谷粒商城笔记,学习,java,微服务
json序列化的方式
谷粒商城笔记,学习,java,微服务

单点登录

不用使用springSession域名放大
谷粒商城笔记,学习,java,微服务

购物车

谷粒商城笔记,学习,java,微服务

ThreadLocal

每个线程互不干扰
谷粒商城笔记,学习,java,微服务

消息队列

消息中间件应用场景:
1、异步处理
2、应用解耦(B服务修改接口,A调用B也就需要修改接口)
3、流量控制
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

RabbitMQ概念
谷粒商城笔记,学习,java,微服务

Docker安装RabbitMQ

docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management
docker update rabbitmq --restart=always

谷粒商城笔记,学习,java,微服务
Exchange 类型
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

修改rabbitmq消息序列化方式

发送消息,如果发送的消息是个对象,会使用序列化机制,将对象写出去,对象必须实现Serializable接口
如果要修改为json,分析RabbitAutoConfiguration的RabbitTemplate的bean对象
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

RabbitMQ测试

参数可以写以下类型:
1、Message message:原生消息详情信息。头+体
2、T<发送的消息的类型> OrderReturnReasonEntity content;
3、Channel chanel:当前传输数据的通道
Queue:可以很多人都来监听。只要收到消息,队列删除消息,而且只能有一个收到此消息
场景:
1):订单服务启动多个(集群场景);同一个消息,只能有一个客户端收到
2):只有一个消息完全处理完,方法运行结束,我们就可以接收到下一个消息

监听消息:使用@RabbitListener; 主启动类必须有@EnableRabbit
@RabbitListener: 类+方法上(监听哪些队列即可)
@RabbitHandler: 标在方法上(重载区分不同的消息)

RabbitMQ消息确认机制-可靠抵达

谷粒商城笔记,学习,java,微服务
消息确认机制_发送端确认
谷粒商城笔记,学习,java,微服务

两个回调分别表示:
confirm回调:消息抵达Broker
return回调:只要消息没有投递给指定的队列,就触发这个失败回调(比如把routingkey写错)
谷粒商城笔记,学习,java,微服务

消费端确认(保证每个消息都被正确消费,此时才可以broker删除这个消息)

谷粒商城笔记,学习,java,微服务

订单服务

整合环境:
1、复制订单html进order模块,拷贝静态资源进nginx
2、配置网关

feign远程调用丢失请求头问题

谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务

feign异步调用丢失请求头问题

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

提交订单的幂等性处理

谷粒商城笔记,学习,java,微服务
幂等解决方案
1、token 机制
Token 获取、比较和删除必须是原子性
2、各种锁机制
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

本地事务&分布式事务

谷粒商城笔记,学习,java,微服务

本地事务

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

springboot中的事务的坑
a方法中直接调用b、c方法,使用的事务配置和a保持一致;
如果要使用b、c方法自己的事务配置,需要bService.b(),cService.c()
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
本地事务失效问题
同一个对象内事务方法互调默认失效,原因是绕过了代理对象,事务使用代理对象来控制的
解决:使用代理对象来调用事务方法
1)、引入aop-starter(因为此依赖引入了aspectj依赖)

<dependency>
     <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2)、@EnableAspectJAutoProxy(exposeProxy = true)
//开启aspectj动态代理功能。以后所有的动态代理都是aspectj创建的(即使没有接口也可以创建动态代理,对外暴露代理对象)。注:jdk动态代理必须有接口
3)、AopContext.currentProxy()
谷粒商城笔记,学习,java,微服务

分布式事务

谷粒商城笔记,学习,java,微服务

七、RabbitMQ延时队列(实现定时任务)

谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

RabbitMQ使用的是惰性检查机制,所以一般是给队列设置过期时间,不是给消息设置过期时间

谷粒商城笔记,学习,java,微服务
代码实现
谷粒商城笔记,学习,java,微服务
升级后
谷粒商城笔记,学习,java,微服务
消息队列流程
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

解决:在订单释放结束,再给库存服务发送消息,释放库存
最终一致性方案

谷粒商城笔记,学习,java,微服务

保证消息可靠性

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

支付业务

加密
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

内网穿透

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

秒杀

定时任务

解决定时任务阻塞问题
谷粒商城笔记,学习,java,微服务
使用redisson解决分布式系统的幂等性问题
谷粒商城笔记,学习,java,微服务

谷粒商城笔记,学习,java,微服务
使用redis的信号量模拟库存,减少并发场景下与数据库的交互

谷粒商城笔记,学习,java,微服务

高并发场景应对

谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务
谷粒商城笔记,学习,java,微服务

我们使用了:
1、我们将秒杀单独抽取出来了,秒杀服务
2、我们使用随机码,只有秒杀时间到了,才能收到随机码
3、我们使用定时任务,将秒杀的商品存进了redis,库存信息使用redisson分布式信号量控制,只有抢到了信号量才会去数据库
4、nginx动静分离
后续再加后四个
5、登陆拦截器(没有在网关层去做恶意请求拦截器)
6、我们使用队列削峰机制

秒杀

谷粒商城笔记,学习,java,微服务

使用rabbitmq实现流量的削峰,而不是每个请求都去调用订单服务

SpringCloud Alibaba-Sentinel

功能:熔断、降级、限流
谷粒商城笔记,学习,java,微服务
熔断:feign调用的远程服务出现问题,直接返回fallback指定的方法
降级:指定时间内指定请求数超过指定时长,一段时间内再调用该接口,就会触发熔断文章来源地址https://www.toymoban.com/news/detail-794251.html

到了这里,关于谷粒商城学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java笔记+踩坑汇总】Java基础+进阶+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud+黑马旅游+谷粒商城+学成在线+MySQL高级篇+设计模式+面试题汇总+源码

    本文是“Java学习路线”专栏的导航文章,目标是为Java工程师提供一套 完整的Java学习路线 。 目录 0.摘要/资料/代码整理 1.Java基础+进阶 2.MySQL,JavaWeb,Mybatis,前端 3.Git 4.SSM(Spring,SpringMVC,Mybatis)框架 5.Maven高级 6.Springboot,MybatisPlus,JPA框架 7.瑞吉外卖、Redis、Nginx、Linux、mysql主从复制

    2024年02月16日
    浏览(44)
  • 【Java笔记+踩坑汇总】Java基础+进阶+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud+黑马旅游+谷粒商城+学成在线+MySQL高级篇+设计模式+常见面试题+源码

    本文是“Java学习路线”专栏的导航文章,目标是为Java工程师提供一套 完整的Java学习路线 。 目录 0.摘要/资料/代码整理 1.Java基础+进阶 2.MySQL,JavaWeb,Mybatis,前端 3.Git 4.SSM(Spring,SpringMVC,Mybatis)框架 5.Maven高级 6.Springboot,MybatisPlus,JPA框架 7.瑞吉外卖、Redis、Nginx、Linux、mysql主从复制

    2024年02月06日
    浏览(45)
  • 谷粒商城-订单服务

    目录 商城业务-订单服务-RabbitMQ延时队列 商城业务-订单服务-延时队列定时关单模拟 商城业务-订单服务-创建业务交换机队列 商城业务-订单服务-监听库存解锁 商城业务-订单服务-库存解锁逻辑 商城业务-订单服务-库存自动解锁完成 商城业务-订单服务-测试库存自动解锁 商城

    2023年04月08日
    浏览(27)
  • 001-谷粒商城-微服务剖析

    还是很强的,该有的都有 SpringCloudAlibaba组件包括 Sentinel Nacos RocketMQ Seata 搭配SpringCloudAlibaba组件 OpenFeign GateWay Ribbn gateway使用了SpringWebFlux,前几天研究到,为什么springboot不直接使用SpringWebFlux, 还是依然使用tomcat的servelet,内部NIO进行处理请求。 Spring WebFlux 使用 Reactor库来实现

    2024年04月16日
    浏览(25)
  • 谷粒商城第三天-微服务中基本组件的使用 java.lang.AbstractMethodError: org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.cho

    目录 一、前言 二、学习的内容 一、Nacos的服务注册/发现 1. 导依赖,nacos-discovery java.lang.AbstractMethodError: org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.cho 2. 在application.yml中声明nacos服务器的ip地址和端口号,以及指定好服务的名称 3. 在启动类上面加上@EnableDiscoverClient 二、

    2024年02月09日
    浏览(36)
  • 【系统开发】尚硅谷 - 谷粒商城项目笔记(七):消息队列

    Docker中安装 下载镜像: docker pull rabbitmq:management 创建实例并启动: 4369 – erlang发现口 5672 --client端通信口 15672 – 管理界面ui端口 25672 – server间内部通信口 在web浏览器中输入地址:http://服务器ip:15672/ 输入默认账号: guest : guest overview :概览 connections :无论生产者还是消费者

    2024年02月12日
    浏览(36)
  • 谷粒商城笔记+踩坑(1)——架构、项目环境搭建、代码生成器

     导航: 谷粒商城笔记+踩坑汇总篇_谷粒商城笔记踩坑6_vincewm的博客-CSDN博客 目录 1、项目介绍 1.1 微服务架构图 1.2. 微服务划分图 2、项目环境搭建 2.1. 虚拟机搭建环境 2.2. Linux安装docker、配置镜像加速 2.3. docker配置mysql、设置自启动 2.3.1、安装mysql5.7 2.3.2、修改mysql配置文件

    2024年02月01日
    浏览(47)
  • 【系统开发】尚硅谷 - 谷粒商城项目笔记(五):分布式缓存

    引入redis依赖 配置redis 堆外内存溢出 缓存穿透 缓存雪崩 缓存击穿 导入依赖 redisson配置类 可重入锁 可重入锁解释 :无论是公平方式还是非公平方式,进门坐下来之后,你可以问医生问题一次,两次,无数次( 重入),只要你还坐着,你都可以问,但是一旦起身离开座位,

    2024年02月09日
    浏览(45)
  • 谷粒商城笔记+踩坑(9)——上架商品spu到ES索引库

    导航: 谷粒商城笔记+踩坑汇总篇 目录 1、ES回顾 2、ES整合商品上架  2.1、分析 2.2、创建sku的es索引库 2.2.1、两种索引库设计方案分析 2.2.2、最终选用的索引库方案,nested类型 2.3、SkuEsModel模型类 2.4、【库存模块】库存量查询 2.5、【查询模块】保存ES文档 2.5.1、常量类 2.5.2、

    2024年02月05日
    浏览(31)
  • 谷粒商城笔记(详细版) IDEA2021 高级篇1(2022/11/9)

    谷粒商城笔记(详细版) IDEA2021 基础篇(1/3). 谷粒商城笔记(详细版) IDEA2021 基础篇(2/3). ES6 VUE 基础篇前端笔记 谷粒商城笔记(详细版) IDEA2021 基础篇(3/3). [谷粒商城笔记(详细版) IDEA2021 高级篇(第1篇) 索引对应mysql中的库 类型对应Mysql中的数据表 文档对应mysql中的一条条数据 在我们

    2023年04月09日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包