谷粒商城项目搭建思路
文章目录
- 基础篇
- 核心技术点
- 1. 搭建环境
- 1.1 安装Linux虚拟机
- 1.2 安装Docker
- 1.3 统一开发环境
- 1.4 搭建后台管理项目
- 1.5 逆向工程
- 1.6 测试商品服务功能
- 1.7 修改配置其他微服务代码
- 2. 添加分布式组件
- 2.1 添加注册中心-Nacos
- 2.2 添加API网关-Gateway
- 3. 前端基础知识
- 3.1 ES6
- 3.2 Vue
- 4. 商品服务API
- 4.1 三级分类(拖拽功能比较绕,需要多练习)
- 4.2 品牌管理(阿里云服务使用,JSR303校验)
- 4.3 商品服务
- 4.4 仓储服务
- 5. 分布式基础篇总结
- 高级篇
- 核心技术点
- 1. Elasticsearch检索
- 2. 性能压测
- 3. 性能监控(JVM)
- 4. 缓存的使用(分布式锁)
- 5. 商城业务-检索服务
- 6. 商城业务-线程&异步
- 7. 商城业务-商品详情页
- 8. 商城业务-认证服务(社交登录、单点登录)
- 9. 商城业务-购物车
- 10. 商城业务-RabbitMQ消息队列
- 11. 商城业务-订单服务
- 12. 商城服务-支付业务(支付宝、秘钥)
- 13. 商城业务-秒杀服务
- 14. Sentinel-高并发
- 15. Sleuth+Zipkin-服务链路追踪
- 3. 集群篇
基础篇
核心技术点
微服务基础开发:
- 逆向工程、微服务基础开发
- SpringBoot、Mybatis、MybatisPlus、JCR303、Restful
- Maven、Git、Vagrant、Linux、Docker
- Aliyun-Oss、MySQL、Redis
- ES6、Vue、element-ui
- 目标:从0开始做一个合格的小全栈程序员
1. 搭建环境
1.1 安装Linux虚拟机
使用VirtualBox搭建虚拟机环境,开源,需要cpu开启虚拟化,设置主板,下载vagrant,调整网络
1.2 安装Docker
在虚拟机中安装docker,方便安装使用各种软件,
安装MySQL、Redis,并对其进行配置
1.3 统一开发环境
- 本机安装JDK1.8,maven,IDEA插件lombok,MybatisX,
- 安装Visual Studio Code,以及相关插件
- 安装git,准备gitee仓库,配置git,使用git秘钥免密提交
- idea拉取gitee仓库代码得到本地项目,以后的代码就都在这里添加
- idea创建微服务项目,每个服务都是一个springboot,添加项目起始必要依赖,创建聚合项目整合整个微服务
- 修改gitignore,忽略不需要提交的文件
- 第一次提交并推送整个初始项目到git
- 安装powerdesigner,查看表结构,我们不使用表外键,而是使用逻辑外键,因为电商项目数据量大,物理外键非常不便
- 每个微服务都创建自己对应的数据库,创建各个数据库、数据表
1.4 搭建后台管理项目
- 使用开源项目-人人开源,作为我们后台管理项目,减轻开发压力
- 人人开源使用前后分离,包括前端项目、后端项目,同时我们也下载generator代码生成器
- 将人人开源后台项目放到我们谷粒聚合项目中,
- 创建人人开源后台管理的数据库(项目自带了sql)
- 修改人人后台项目配置能够连接后台管理数据库
- vscode打开人人前端项目,配置相关环境,安装node.js,确保支持vue,配置npm镜像地址,
- 初始化npm,下载前端所需依赖
- 运行人人前端项目、后端项目、联调地址、端口,联通整个人人管理项目
1.5 逆向工程
- 使用generator,添加至谷粒项目中,修改配置匹配当前项目,指定需要逆向的数据库,快速生成增删改查代码
- 将对应数据库生成的所有代码替换到各个谷粒微服务中,生成的代码会爆红,需要我们准备各个依赖以及公共类
- 逆向工程创建的代码有许多需要的工具类和依赖都可以到人人后台项目中找到,可以将其复制到其他微服务中
1.6 测试商品服务功能
- 整合mybatis-plus,依赖、配置,注意数据库的版本对应的驱动
- 配置springboot核心配置文件
- 测试增删改查
1.7 修改配置其他微服务代码
- 方法同商品服务类似
2. 添加分布式组件
- SpringCloud 部分组件已经停止维护,且配置比较麻烦
- 使用SpringCloud Alibaba 组件可以解决这些问题,可视化界面更加友好,
- 注意SpringCloud 与 SpringCloud Alibaba 版本的对应
- 引入alibaba依赖
2.1 添加注册中心-Nacos
官方文档有步骤演示
- 引入依赖,下载Nacos server 并运行,配置Nacos地址
- 配置微服务核心配置,注册到注册中心
- 查看Nacos控制台,检测服务之间远程调用,使用openfeign;将各个服务都注册到配置中心
- nacos还可添加配置文件,让服务启动时加载配置,便于我们动态获取一些参数,免去修改源码打包
- 如果nacos和微服务中properties都配置了相同项,则优先加载nacos的配置
nacos细节
- 命名空间:默认新增的配置命名空间为public,我们可以使用命名空间来区分dev/test/pro环境,yml加载不同的配置,区分环境;也可以基于微服务隔离,每个服务也可以建立自己的命名空间,进一步区分
- 配合集:所有的配置的集合
- 配置集ID:类似于文件名,
- 配置分组:一类配置集可以放在一个分组中,比如双十一使用一个配置集,
- 谷粒项目的配置情况:每个微服务区分命名空间,配置分组区分dev/test/prod
加载多配置集
- 我们将微服务的配置都交给nacos管理,按照分类区分放置在配置中,比如数据源、mybatis、springcloud等等
- 微服务项目中的配置文件只需要加载nacos中的各个配置即可
- 在微服务的启动日志中可以查看,微服务启动时都加载了哪些nacos配置
- 任何配置信息、配置文件都可以放在nacos中,只需要在properties中说明加载哪些配置文件即可
- 开发期间我们还是先放在微服务配置文件中,方便查看
2.2 添加API网关-Gateway
- 用户的任何请求都要经过网关,网关动态发给各个服务,并从注册中心中实时感知某个服务的上线下线,将用户请求路由到正确的位置
- 每个请求加上权限,在网关层面做权限控制
- gateway是springcloud的第二代网关,比zuul性能更强
- springcloud官方文档有gateway的介绍、实例代码
- 路由、断言、过滤器
核心流程
- 请求到达网关,网关通过断言判断该请求是否符合某个路由规则,如果符合规则就路由到指定的服务,还要经过一系列过滤器过滤
- 难点在于怎样指定路由规则,断言该如何配置,过滤器怎么过滤
- 官方稳定提供了各种过滤规则、断言规则的实例
在谷粒项目中创建网关服务
- 添加至注册中心,添加依赖,修改配置
- 开启网关的注册发现,访问网关测试
3. 前端基础知识
技术栈:
- vscode使用
- ES6:重点
- Node.js
- Vue:重点
- Babel
- Webpack
3.1 ES6
- ECMAScript是浏览器脚本语言的规范,我们熟知的js语言如,JavaScript则是规范的具体实现
- 使用vscode创建项目文件,测试ES6各个功能特性
3.2 Vue
4. 商品服务API
4.1 三级分类(拖拽功能比较绕,需要多练习)
- 商品服务数据库,导入商品分类表数据
- 修改商品服务接口,查询商品分类数据,已树形结构组装起来,使用现有方法listwithtree
- 将分类数据保存菜单中返回,使用sort对菜单信息排序
- 修改前端项目的分类代码,商品系统-菜单管理-添加菜单
- 添加组件,让点击每个菜单都会显示菜单分类页面,使用elementui属性控件
- 调整前端项目配置,转发请求,注册人人项目能够被网关发现,可以处理验证码信息
- 解决人人登录时的跨域访限制,跨域的流程详解
- 添加菜单的删除逻辑,前台逻辑、后台逻辑
- 编写前端,点击按钮删除菜单,发起请求,后台逻辑删除响应的菜单
- 优化删除动作,添加弹窗提示确认是否删除,如果删除成功,有提示消息,也要展开删除节点的父节点
- 添加菜单,需要添加对话框,在对话框显示表单项,可以输入子分类
- 区分修改对话框和添加对话框,修改时要回显数据
- 通过拖拽节点改变节点的父子关系,使用elementui的draggable属性,需要我们保证节点能够被放置在指定位置
- 拖拽成功之后,相应的数据的收集使用handle-drop工具
- 添加开关,控制是否开启拖拽功能,添加批量保存,避免每次拖拽都访问数据库,而是一次性提交拖拽结果
- 节点批量删除,
4.2 品牌管理(阿里云服务使用,JSR303校验)
- 添加前端菜单-品牌管理,路由、相关信息,添加逆向工程生成的品牌相关代码
- 监听状态,管理品牌的显示和隐藏,添加品牌logo的文件上传功能
- 单体架构和分布式的文件上传不同,分布式需要单独有个文件服务系统,推荐使用云服务存储
- 开启阿里云对象存储OSS,根据使用情况收费,此项目中消费很小;需要注意理解对象存储的几个重点名词
- 浏览器上传方式使用,携带签名方式,直接上传OSS服务器
- 查看阿里云文档,了解文件上传api使用方法,为了安全,使用阿里云子账户上传,给子账户分配对象存储的权限
- springcloud alibaba 提供了更方便的对象存储,比阿里云原生api更方便
- 创建一个新的微服务,整合所有的第三方服务,
- 浏览器点击上传文件,访问服务端获取签名,然后从浏览器直接上传阿里云存储
- 编写前端代码,使用elementui upload 组件,添加上传文件的代码
- 修改品牌表格logo列的代码,可以显示图片;表单提交数据之前,还需要依据校验规则进行表单校验
- 前端校验,后端也要校验,使用JSR303,添加统一的异常处理的类 ControllerAdvice
- 新增、修改等等可能提交的字段校验规则不同,基于这种场景,我们可以使用JSR303的分组校验规则
- 除了分组校验,还可以自定校验规则,满足各种业务功能;编写自定义校验器,使用自定义的校验注释
4.3 商品服务
- SPU与SKU的概念理解,SPU相当于类,有很多版本和特性;SKU对应一个具体的对象,具体的那个版本
- 规格参数:商品基本属性,大小尺寸,长宽高,厚度;销售属性:决定售价与库存量的,比如,容量、颜色、版本
- 区分这些概念的层级、分类关系,才能在后台理清业务逻辑
- 理解商品服务表设计:【属性分组-规则参数-销售属性】关联关系,【SPU-SKU-属性表】
- 前端添加商品属性菜单,由于三级分类组件经常使用,可以将其抽取出来做一个公共的组价
- 当点击三级分类的时候,表格可以动态显示相应的属性;后台返回查询的分类数据
- 分组新增,级联选择器
- 品牌管理,完善功能,添加后台分页插件;一个品牌可能对应多个分类,一个分类有多个品牌,多对多关系
- 修改平台属性-规格参数,属性信息的回显,需要携带属性的分类、分组
- 查询分组关联属性,删除关联,批量删除;
- 获取当前分组没有关联的所有属性,新增分组与属性关联关系
- 添加微服务-会员服务,
- 新增商品:添加基本信息、规格参数、销售属性、SKU信息、保存完成
- 发布商品的前端逻辑已经提前准备好了代码
- 发布商品-基本信息:获取会员等级,获取某一个分类所关联的品牌
- 发布商品-规则参数:获取某个分类下所有的属性分组,包括分组内的所有属性
- 发布商品-销售属性:
- 发布商品-SKU信息:需要录入会员价格
- 保存提交的商品数据,后端接收提交的商品发布信息,商品信息大保存
- 准备vo,校验保存数据,添加事务,保存信息分基本信息、保存spu描述,保存图片集,保存规格参数,保存当前spu信息
- spu对应的所有sku信息:sku基本信息、sku图片信息、sku销售属性信息、sku优惠满减信息
- 整体测试商品发布功能,debug调试,
- 商品管理:sku检索,参照接口文档,检索条件有个多种条件
- 商品管理:搜索,
- 商品sku规格,点击商品规格,显示sku规格;更新sku属性
4.4 仓储服务
- 启动库存服务,开启服务注册发现功能,配置网关,
- 仓库维护:查询功能,某个sku的库存情况;添加库存,
- 采购员采购商品,扫码通过,商品进入库存;这个功能我们暂时不做,而是使用采购单,
- 采购单可能是人工自行采购,并创建采购单,也可以是库存不足,系统自动预警,发起采购单,
- 新增采购单,包括多个采购需求;查询各个仓库的采购需求;将采购需求合并成一个采购单,分配个采购人员,采购完成商品入库
- 采购人员可以领取采购单的需求,分配采购单之后,其他人员不能再被分配,修改采购单状态
- 采购完成:改变采购单状态,改变采购项状态、将成功的采购入库,如果有库存则修改,没有则新增
5. 分布式基础篇总结
分布式基础概念
- 微服务、注册中心、配置中心、远程调用、Feign、网关
基础开发
- SpringBoot2.0、SpringCloud、Mybatis-Plus、Vue组件化、阿里云对象存储
环境
- Vagrant、Linux、Docker、MySQL、Redis、逆向工程&人人开源
开发规范
- 数据校验JSR303、全局异常处理、全局统一返回、全局跨域处理
- 枚举状态、业务状态码、VO与TO与PO划分、逻辑删除
- Lombok:@Data、@Slf4j
高级篇
核心技术点
高级篇:
- 基础的全部应用,关注集群/分布式,远程调用,负载均衡,服务注册/发现,配置中心,网关,熔断降级,关注高并发
- SpringCloudAlibaba系列
- Nacos、Seata、Sentinel
- SpringCloud系列
- Sleuth+Zipkin、Gateway、OpenFeign
- ElasticSearch7、RabbitMQ、Redisson
- Thymeleaf、Spring-Session、SpringCache、Nginx
- JMeter压力测试+JVisualVm监控,测出问题及瓶颈
- 目标:Java高级开发20k-35k
解决的问题
- Nginx域名访问、动静分离、网关转发
- 本地缓存、分布式缓存、数据一致性、分布式锁
- 分布式Session共享
- 单点登录&社交登录&SpringSession
- Feign远程调用丢失请求头&异步丢失请求头
- 内网穿透、支付宝沙箱联调
- 线程池隔离、异步编排、分布式信号量
- 高并发编码技巧:缓存、异步、队列好
- ElasticSearch复杂检索、聚合、桶
- RabbitMQ死信+延时队列,双确认机制可靠消息、业务队列回路
1. Elasticsearch检索
- Elasticsearch基本概念,
- Docker安装Elasticsearch、kibana可视化界面,配置es启动参数
- 访问浏览器可视化界面,检查启动
- postman模拟es各个请求,初步的功能实现增删改查,批量导入
- 参照官网文档,测试检索查询功能,注意请求方式,携带参数方式
- 分词器的练习使用,下载安装ik分词器,自定义扩展词库
- docker安装Nginx,将相关文件挂载到宿主机
- 通过Nginx访问es搜索,返回检索结果
- Java springboot 整合es搜索,创建检索服务,整合进微服务中,
- 使用检索服务,对es进行增删改查,测试复杂检索,使用search api
- sku在es中的模型存储分析,将商品的有用信息保存到es中,es可以对商品信息进行检索,
- 商品上架,构造基本数据;商品上架的同时将重要数据封装进es中;
- 还要查询库存是否足够;热度评分;查询品牌和分类的名字信息,再存入es模型中;设置检索属性
- 单独封装一个查询的sku库存的接口;
- 调试整体上架功能源码;查看feign远程调用源码;
- 编写商品客户端前端页面,商城系统前端项目本来也可以分离,这里为了教学展现更多细节,我们将前端页面写在各个微服务中,使用thymeleaf模板引擎渲染,商城前端页面已经在课件资料中准备好
- 动静分离:静态页面交给nginx服务返回,动态页面交给各个微服务返回,分担微服务压力;
- 引入thymeleaf依赖,配置参数,关闭缓存,配置路径;
- 配置首页的默认访问路径,首页显示默认显示以及分类,鼠标放在上面可以显示对应的二级分类三级分类
- 搭建域名访问环境,需要买一个公网ip,在我们开发环境局域网内,使用nginx的反向代理;使用switchhost方便修改系统host
- 反向代理详细配置;
- 前面是nginx直接代理到微服务,现在将nginx代理到网关,由网关进行负载均衡到各个上线的微服务;
- 配置网关的路由规则;nginx在代理给网关的时候会丢掉host信息,需要配置nginx,防止丢失信息,保证网关能正确路由到微服务
- 注意路由配置的顺序,顺序错误会导致后续访问路径被干扰
2. 性能压测
- 检测开发时难以发现的问题
- 性能指标:响应时间、HPS、TPS、QPS、最大/小响应时间、90%响应时间,吞吐量、响应时间、错误率
- 使用apache-jmeter工具,直接执行jmeter.bat启动,options可以设置语言,
- 添加请求、查看结果树、汇总报告、聚合报告、图标等详细信息
- jmeter容易出现的问题,address already in use,windows系统的问题
- cpu密集型、io密集型
- 查看性能监控指标,优化代码
3. 性能监控(JVM)
- 监控jvm工作情,jvm内存模型复习,重点讲解堆
- 避免经常发生full gc,非常耗时
- 做压力测试的时候,使用jconsole或jvisualvm监控jvm
- jvisualvm默认功能还不够,需要下载插件,工具-插件,如果无法下载,可能是地址配置的问题
- 结论:中间越多,性能损失越大,大多损失在网络交互上;
- 压测业务功能:db,模板渲染速度、静态资源
- 首页渲染开缓存,有小幅度提升;数据库影响吞吐量较大,需要优化sql
- 添加数据库索引,测试有无索引的的性能区别
4. 缓存的使用(分布式锁)
- 仅仅依靠优化业务代码逻辑也不够,还要添加缓存
- 哪些数据适合做缓存:即时性数据一致性要求不高的;访问量大且更新频率不高的数据(读多、写少)
- 分布式缓存问题:本地缓存有数据一致性问题,将所有缓存放在缓存中间件中
- docker安装redis,微服务引入依赖,添加配置,整合redis
- 改造三级分类业务逻辑,缓存存入redis
- netty与jedis区别,已经bug
- 缓存使用,缓存失效,穿透、击穿、雪崩
- 解决缓存失效问题:空结果缓存、设置过期时间+随机值、加锁
- 加锁是难点,本地锁只能锁当前进程,我们需要分布式锁
- 分布式锁的原理与使用;所有的客户端都向同一个位置占坑
- 现在不使用sync,而是使用redis的分布式锁;
- 分布式锁的坑:需要避免死锁,设置过期时间,绑定原子命令,占锁的时候添加uuid,避免删错锁
- 加锁、解锁都要保证原子性
- 分布式锁:redisson,作为所有分布式锁,分布式等功能的框架
- redisson基本实现了juc的所有功能,可以无缝衔接,但是比juc强大,支持分布式
- 自动解锁的时间一定要大于业务时间,redisson不会像lock一样自动续期
- 读+读,写+读,写+写,读+写;只要有写的存在就必须等待,
- 闭锁:计数,全部走完,可以锁大门
- 信号量:车库停车,看停车位够不够,类比分布式信号量,获取一个信号,释放一个信号;也可以用来做分布式限流,限制信号量
- 锁的名字,锁的粒度
- 缓存一致性解决:双写模式、失效模式,都会有数据不一致的问题
- 如果数据实时性高还不如直接查数据库;用户操作也不可能那么快,缓存不一致问题概率不高;业务本身允许短时间不一致;
- 解决方案:推荐使用失效模式,结合读写锁;缓存的所有数据都有过期时间
- 使用Canal中间件,可以更新缓存;
- SpringCache专门对缓存的抽象层,提供了丰富的注解,省去我们编写大量的代码
- cachemanager管理缓存,定义规则,缓存组件具体缓存
- 整合springcache,添加依赖,编写配置,自定义缓存配置
- springcache的不足,
5. 商城业务-检索服务
- 搜索页面点击搜索之后,跳转到检索页面,页面与首页相似,检索页面仍然提供的检索服务也和首页的一样
- 检索服务静态资源放在nginx中,搭建页面环境
- 梳理检索逻辑,调整页面跳转,首页有几处可以点击跳转到检索页面
- 处理检索页面请求,后台添加检索逻辑,完善各种条件检索的业务逻辑
- 返回页面数据的逻辑,封装数据、分页,品牌信息,分类信息,
- kibana调试复杂检索,后台代码构建检索请求;排序、分页、高亮
- 聚合分析:品牌聚合、分类聚合、属性聚合
- 封装数据,返回页面;断点测试,验证封装数据的正确性;渲染页面
- 页面效果:分页效果,排序效果,页面排序字段回显,仅显示有货,上架时间区间,面包屑导航,条件删除
- 条件筛选的细化
6. 商城业务-线程&异步
- 线程、线程池;线程生产一般不用,主要用线程池;
- 线程池的创建,工具类创建,原生创建,各个参数含义;工作顺序
- 线程池的优点总结;商品各个信息异步获取
- completablefuture的使用,创建异步任务,回调和异常感知
- 线程串行化,两个任务都要完成;两个任务一个完成;多任务组合
7. 商城业务-商品详情页
- 详情页资源导入商品微服务中,静态资源导入nginx,实现页面跳转
- 商品详情,编写后台代码,抽取模型;获取各个商品信息模型
- 规格参数、销售属性,点击切换sku
- 异步编排优化
8. 商城业务-认证服务(社交登录、单点登录)
- 新建认证服务,后续将要继承社交登录、单点登录
- 添加依赖,初始化配置,引入注册中心,网管
- 添加前端页面,静态存入nginx,动态导入后台服务中,
- 引入登录页、注册页
- 添加验证码功能, 绑点击事件,倒计时效果,
- 后台添加视图控制,用来跳转页面,免去写空方法跳页面
- 短信验证码功能:开通第三方阿里云短信服务,
- 验证码防刷校验:防止恶意刷调用接口,刷新页面不能重置倒计时,验证码有效期
- redis实现验证码有效期,记录系统时间,设置时间间隔,接口防刷后续解决
- 点击注册,实现注册功能
- 后续解决分布式 session 问题
- 异常机制的完善,验证码校验,注册校验,最终插入会员数据库,检查用户名手机号唯一性,密码加密
- 其余次要信息可以后续用户完善
- 密码加密存储:可逆、不可逆(推荐);md5&md5盐值加密,消息摘要算法,md5的特点;加盐,随机值
- 除了加密后的密文,数据库还需要保存添加的随机数是什么;校验的时候,先计算用户的明文密码,再加盐,最终与数据库查询
- spring提供了密码加密器,基于以上原理封装,简化加密过程;
- 进一步完善注册功能,
- 登录功能:页面表单提交账号、密码;登录成功后首页显示登录信息,登录失败跳回登录页
- 社交登录:登录社交账号,引导跳转到授权页,用户点授权,跳回原网站
- OAuth2.0:开放授权协议,登录授权流程讲解;以微博为例
- 登录微博,设置开放平台,进行授权设置。创建应用信息,使用微博的社交登录
- 用户点社交登录,跳转到授权页(微博提供),
- 登录成功后,首页显示登录用户信息;session原理
- 分布式中session问题:如果使用session,则不同域名返回的cookie不能共享;分布式环境,不同节点session不同步
- session同步问题解决:小集群可以节点之间使用tomcat同步,但是占用带宽资源,不适合大分布式
- session共享问题解决:hash一致性,只要是同一个用户访问,就落到一个固定的服务器上;但是重启也可能导致session丢失,重启加载数据
- session共享问题解决:统一存储,存到redis中,这样也不怕服务器重启;缺点,服务器到redis取数据,需要网络交互,效率有损失
- session共享问题以上两种都可以用户;
- springsession框架完美解决session统一存储问题,
- 父域名访问获取cookie之后,对应的子域应该也能得到
- 后台代码,将jsessionid保存到cookie中,设置作用域,
- 采用springsession整合解决session问题,查看官方文档
- 需要解决问题:指定session作用域,
- springsession核心原理;认证服务,页面效果实现
- 单点登录:一次登录,其他服务也可以登录;springsession不能实现,因为发卡域名不同
- gitee搜索xxl单点登录demo,演示效果
- 添加单点登录服务器,访问单点登录页,如果登录,
9. 商城业务-购物车
- 创建购物车服务,搭建环境,配置,联通微服务集群,
- 调试购物车页面正常展示,
- 京东中有两套购物车交替操作,登录购物车,游客购物车,
- 数据模型分析:购物车商品的增删改查,
- 登录购物车读写都比较多,推荐Redis保存,设置持久化,比MySQL性能好;游客购物车也使用Redis
- 分析Redis存储购物车数据结构,字段,添加VO
- ThreadLocal 同一个线程共享数据,用于用户身份鉴别
- 购物车的添加逻辑细化,防止刷新页面购物车商品数量增加;鼠标放在购车上显示购物车信息,区分登录和没登录
- 登录时要合并两个购物车数量,合并之后还要清除临时购物车数据;
- 购物车中选中商品和不选中商品的效果;改变购物车商品的数量,增减按钮绑定事件,修改购物项数量,删除购物项
10. 商城业务-RabbitMQ消息队列
- 异步处理,应用解耦,流量控制,
- 消息代理,目的地;消息队列模式,消息服务规范,spring支持,
- 概念:生产者、消费者、交换机、消息头体路由键、消息服务器、队列、绑定关系、建立长连接、信道、虚拟主机、
- Docker安装RabbitMQ,RabbitMQ管理界面;使用测试:交换机类型
- springboot整合rabbitmq场景启动器,amqpAdmin组件,rabbittemplate组件,@RabbitListener,
- 消息确认机制,可靠投递,回调,发送端确认,消费端确认机制,
11. 商城业务-订单服务
- 添加订单服务,页面环境搭建,订单模块页面,动静分离,订单确认页面、订单详情页面,支付页面
- 订单操作需要用户登录状态,整合springsession做session共享,
- 订单中心重难点:信息流、资金流、物流,需要获取多模块信息;订单状态,订单流程,幂等性处理
- 订单服务添加拦截器,订单服务所有请求必须登录才能访问;购物页面点击结算跳转订单确认页面;
- 后台封装VO,封装订单确认页需要的数据,收货地址,选中的购物项,发票记录,优惠券信息,订单总额,应付价格,优惠价
- 调用各个服务,获取订单确认所需各个信息;商品价格不能从购物车获取,因为价格会变,购物车价格是旧的;调用商品服务查价格
- Feign远程调用地市请求头问题,没有cookie,购物车认为没有登录,自己加上feign远程调用请求拦截器,给请求头加cookie
- 订单确认页面的数据渲染,查询库存信息,模拟运费效果,根据用户地址计算运费,
- 提交订单:接口幂等性,
- 运费计算:远程调用获取会员地址,计算运费;显示寄送至、收货人,
- 接口幂等性:订单防重复提交,同一订单点多少次都是一次;
- 幂等性解决方案:token机制,获取令牌、对比、删除,这三者必须原子性,使用各种锁机制;token设置过期时间
- 结算页提交数据,还要去购物车重新获取一遍,提交一个价格,后台算一个价格,作对比,验价;
- 下单:创建订单、验令牌、验价格、验库存;成功来到支付页面,失败重回确认页面;
- 改前端,提交按钮事件;准备隐藏的表单数据,给表单回填已选的地址,应付总额,
- 下单逻辑:后台处理下单逻辑,下单成功,下单失败,指定跳转页,
- 执行对比脚本,原子验证令牌;创建订单TO,生成订单号,需要的共享数据可以使用ThreadLocal获取;
- 构建订单项数据:订单信息订单号,商品spu信息、sku信息,优惠,积分
- 保存订单,锁库存,加事务,如果锁库存失败,则保存订单回滚;根据订单号,锁定指定的商品和锁的数量;返回每个商品的锁定结果
- 锁库存逻辑:库存表,有总数,锁定数,相减为正,则库存可以正常锁定;一个商品仓库可能有多个,暂时先不考虑;
- 锁库存采取就近策略,哪个仓库有库存,逐个锁定,出现库存-锁定>=购买数量即可;如果没有仓库满足条件,直接抛异常;提示哪个商品没有库存
- 如果没有问题,则表锁定量增加,最终商品全部锁完,通过状态码提示下单成功,进入确认支付页;调试提交订单代码
- 分布式事务:本地服务可以回滚,远程服务已经执行完的代码不会回滚;远程服务假失败效果;采用分布式事务,产生分布式事务最大的原因来源网络问题;
- 本地事务基本性质,隔离级别,spring注解直接实现本地事务;
- 分布式事务,CAP原则;如何实现分布式一致性,raft算法,paxos
- 分布式事务几种方案:2PC模式,柔性事务,
- Seata开源的分布式事务解决方案,事务协调者、事务管理器、资源管理器,只需要使用一个注解,开启全局事务@GlobalTransactional
- springcloud整合seata,导入依赖,每个微服务,必须创建undo_logs表,下载安装seata server,启动seata server
- 配置seata server配置文件,在业务方法上添加注解开启全局事务;所有需要用到分布式事务的微服务,都需要seata代理数据源,参考文档,导入配置文件
- 给分布式大事务的入口使用@GlobalTransactional,小事务用本地Transactional即可
- rabbitmq延时队列,死信队列,解决下订单不支付的问题;
- 延时队列解决库存解锁问题,补偿解锁问题;订单自动关单,库存自动解锁;
- 如何保证消息可靠性:防止消息丢失,防止消息重复,消息积压,
12. 商城服务-支付业务(支付宝、秘钥)
- 接入支付宝进行支付,支付开放平台-文档中心-产品文档-电脑网站支付-快速接入,有官方使用流程,需要创建应用;提交审核
- 对接功能,签约,上传营业执照,审核需要时间;开发者可以使用沙箱环境,模拟了所有完整功能,下载官方SDK和demo
- 支付核心概念:加密-对称加密(不安全),非对称加密(比较安全):对应了四把钥匙;公钥、私钥;签名,验签;
- 发送方使用私钥不让外界知道,并告诉接收方使用哪个秘钥接收,这就是公钥;
- 私钥加密,公钥解密,谁发送谁签名,谁接收谁验签;实际代码中,我们要配置四把钥匙对应这里;
- 复制过来官方演示demo,自己改代码;使用支付宝秘钥生成器;商户私钥自己留着配置,公钥上传支付宝;同时支付宝返回一个商户公钥,自己保存配置;全称只有支付宝的私钥是我们不知道的;
- 登录沙箱账号,模拟支付流程;支付成功,跳回页面;
- 内网穿透,将我们的项目并入第三方提供的域名下,方便外网放我们的项目;
- 支付功能整合到订单系统;首页点击付款,跳转支付页;调用支付的方法, 传参PayVo,支付宝返回页面,用来买家支付;
- 支付完毕后,会跳回我们设置的用户订单列表页;
- 会员系统添加订单列表页,显示所有订单,后台验证支付宝返回的验证签名,防止被篡改,确认是否成功支付,使用支付宝异步通知;
- 使用内网穿透的地址,保证支付宝能够访问;我们接收结果,返回success,支付宝不再通知;记录交易流水信息
- 收单,如果在支付页面不支付,订单已经过期了,不应该再支付成功;设置支付宝api,绝对超时时间,超过时间后不能再支付;
- 极端情况:在支付宝时限的最后一刻支付成功,但支付宝返回信息有延迟,我们的服务判定为超时,解锁订单;
- 解决方案:修改代码,在解锁订单前,手动调用支付宝api收单;
- 支付宝交易查询接口可以方面我们对账
13. 商城业务-秒杀服务
- 商家不定期发布低价商品,特点就是瞬时流量非常大,考验系统对峰值流量的控制,高并发,所以秒杀系统都是独立部署
- 秒杀逻辑:商品在秒杀系统中价格会变化,后台系统中,我们可以设置秒杀时间
- 后台设置,每个场次都有秒杀商品,
- 创建秒杀服务,
- 定时任务:Java原生timer也支持定时任务,cron表达式,定时计划,网上有在线生成器
- 秒杀服务开启定时任务,配置相关设置,将定时任务放在线程池中,防止线程阻塞,设置配置文件,支持定时任务线程池,有些版本有bug,设置不好使
- 我们可以直接让定时任务异步,开启异步任务,解决定时任务不阻塞的问题,
- 重复上架无需处理,添加接口,添加需要上架的商品,需要远程调用优惠服务,扫描需要参与秒杀的商品,活动时间筛选
- Redis保存活动信息,判断当前时间,哪些活动需要参加活动,再缓存活动关联的商品信息,每个商品需要随机码
- 引入随机码,只有秒杀开启的时候才开启,防止恶意攻击,
- 提前在Redis中设置信号量,数量不足后无需再访问数据库,防止数据库压力过大;每个商品都要设置Redis分布式信号量
- 幂等性处理,有多个任务要执行上架代码,上架代码需要加分布式锁,防止重复上架,
- 首页展示可以参与秒杀的商品,后台提供接口,查询当前时间参与秒杀的商品,到Redis查询,查询当前时间属于哪个秒杀场次
- 秒杀页面渲染,秒杀商品抢购,加入购物车,价格改为秒杀价格;重点在于后台的高并发系统的处理
- 高并发考虑问题:服务单一职责,专注秒杀;秒杀链接加密;库存预热,快速扣减;动静分离
- 秒杀完成创建订单,使用rabbitmq流量消峰,
14. Sentinel-高并发
- 服务单一职责+独立部署、秒杀链接加密、库存预热+快速扣减、动静分离、恶意请求拦截、恶意请求拦截、限流&熔断&降级、队列削峰、流量错峰、
- sentinel和hystrix对比,sentinel优势很大,且阿里一直在维护,推荐使用;
- 官方文档有详细使用方法
- springcloud整合sentinel,导入依赖,下载sentinel控制台,配置相关信息,全服务引入
- 流量控制,模式效果,熔断降级,
- 调用方的熔断保护,调用方手动指定远程服务降级策略,
- 服务提供方也可以降级,不过一般不设置,因为最终还是调用方调用最终导致降级
- 超大浏览量的时候,也会从全局考虑,在提供方降级
- 自定义受保护资源,通过注解放在任意想要保护的方法上,当出现流控后再指定降级方法;
- 网关流控,需要与springcloud gateway整合,在网关层面进行限制,请求无需进入到微服务,更加方便、精确
- 定制网关流控返回,
15. Sleuth+Zipkin-服务链路追踪
- 方便我们查询服务链路追踪系统,辨别哪些服务耗时长,哪些调用耗时长,服务耗时还是网络耗时,便于下一步优化
- 基本术语,整合参照文档,docker安装Zipkin服务器,添加依赖,配置所有的微服务整合链路追踪
- 哪里慢,优化哪里;指定docker数据源,挂载到本地;可以将数据保存es中,方便查找
- zipkin界面分析,
总结:高并发三宝,缓存、异步、队排好
3. 集群篇
- k8s简介,参考文档,
- 组件:master组件,node组件,
- k8s集群安装
谷粒商城项目搭建思路相关推荐
- M5(项目)-01-尚硅谷谷粒商城项目分布式基础篇开发文档
M5(项目)-01-尚硅谷谷粒商城项目分布式基础篇开发文档 分布式基础篇 一.环境搭建 各种开发软件的安装 虚拟机: docker,mysql,redis 主机: Maven, idea(后端),Vs ...
- 谷粒商城项目工具准备
谷粒商城项目新手 返回导航页 1.前置知识-安装虚拟机 虚拟机问题 虚拟机安装让必要软件 docker安装其余用到的软件 项目架构图 项目划分图 创建项目 创建数据库 人人开源项目 人人开源前端 代码 ...
- *谷粒商城项目笔记*
谷粒商城项目笔记 一 项目介绍(略) 二分布式的基础概念 1,微服务 拒绝大型单体应用,基于业务边界进行服务微化拆分,各个服务独立部署运行 2, 集群是个物理形态,分布式是个工作方式. 例如:京东是个 ...
- 尚硅谷——谷粒商城项目开发记录——2021.11.19
尚硅谷--谷粒商城项目开发记录--2021.11.19 出现错误 1.SpringBoot测试类出现Could not autowire. No beans of 'BrandService' typ ...
- 【系】微信小程序云开发实战坚果商城-商城项目搭建
第 2-1 课:商城项目搭建 目录 开篇 [系]微信小程序云开发实战坚果商城-开篇 基础篇 [系]微信小程序云开发实战坚果商城-弹性盒子 [系]微信小程序云开发实战坚果商城-ES6 简单入门 [系]微 ...
- leyou商城项目搭建(1)-电商行业及乐优商城介绍
leyou商城项目搭建(1)-电商行业介绍 1.了解电商行业 1.1.项目分类 1.1.1.传统项目 1.1.2.互联网项目 1.2.电商行业的发展 1.2.1.钱景 1.2.2.数据 1.2.3.技 ...
- 谷粒商城项目笔记之分布式基础(一)
谷粒商城项目之分布式基础 目录 谷粒商城项目之分布式基础 前言 1 项目简介 1.1 项目背景 1.1.1 电商模式 1.1.2 谷粒商城 1.2 项目架构图 1.2.1 项目微服务架构图 1.2.2 ...
- 尚硅谷——谷粒商城项目开发记录——2021.11.22
尚硅谷--谷粒商城项目开发记录--2021.11.22 概念: 1.对象优化: 新增的API: ES6 给 Object 拓展了许多新的方法,如: keys(obj): 获取对象的所有 key 形成的 ...
- 尚硅谷——谷粒商城项目开发记录——2021.11.21
尚硅谷--谷粒商城项目开发记录--2021.11.21 概念: 1.var和let的区别: 作用域: var 声明的变量往往会越域 let 声明的变量有严格局部作用域 声明次数: var 可以声明多次 ...
最新文章
- 大型网站技术架构(2):架构要素和高性能架构
- 截断骨干用于检测,YOLO-ReT开源:边缘GPU设备上的高性能检测器
- 万字字符长文带你了解遗传算法(有几个算例源码)
- java ubuntu 14.04,ubuntu14.04下安装JAVA
- C++——二维vector初始化大小方法
- javascript中原型模式创建对象特点分析
- js文件中使用jstl或者其他标签
- linux的/dev内容介绍
- Gitlab+Git实现版本控制系统
- WCF Ria Service“操作失败,指定的命名链接在配置中找不到”错误解决方法
- 工作中,什么情况下应该负责到底?
- 电工技师技能实训考核装置QY-W601C
- stm32实验报告心得体会_stm32实验报告心得体会
- 【解决方案】Collecting package metadata (current_repodata.json): failed
- 苹果中国首家直营店选址北京三里屯
- C++开发斗地主(QT)第三篇之动画发牌与位置计算
- 查找和排序方法归类----C和C++
- 不会聊天?不会撩妹?宅男如何走出自闭的循环圈
- 【嵌入式开发教程6】手把手教你做平板电脑-触摸屏驱动实验教程
- 机器学习系列(2)——CART算法
热门文章
- 嵌入式Linux驱动笔记(五)------学习platform设备驱动
- 条码打印软件中如何插入特殊字符
- mpv播放器 —— 一个免费的、开源的、跨平台的媒体播放器
- CentOS下安装dosBox
- 小米2s刷原生安卓_小米2S升级安卓5.0原生ROM下载刷机教程
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Xor
- 简易验收管理系统的设计(php)
- e5408fc4a618ed2a663d0306def2cec3 (学生实验,谢谢)
- deepin连接企业加密wifi
- 使用任务计划实现宽带pppoe断线自动连接 - Windows