本篇是微服务综合实战项目「锋迷铺子」的总览笔记,包括项目背景、技术选型、工程搭建、敏捷开发工具以及首页、站内搜索等核心模块的开发要点。
1. 项目背景(锋迷铺子)
锋迷铺子是一个垂直电商项目,属于典型的 B2C 模式,整体拆分为两个系统:
| 系统 | 架构 | 说明 |
|---|---|---|
| 运营平台 | 单体架构 | 面向内部运营人员,做商品、内容等数据管理 |
| 门户系统 | 分布式架构(微服务) | 面向消费者,通过互联网项目应用微服务组件 |
本篇是微服务综合实战项目「锋迷铺子」的总览笔记,包括项目背景、技术选型、工程搭建、敏捷开发工具以及首页、站内搜索等核心模块的开发要点。
锋迷铺子是一个垂直电商项目,属于典型的 B2C 模式,整体拆分为两个系统:
| 系统 | 架构 | 说明 |
|---|---|---|
| 运营平台 | 单体架构 | 面向内部运营人员,做商品、内容等数据管理 |
| 门户系统 | 分布式架构(微服务) | 面向消费者,通过互联网项目应用微服务组件 |
本篇先介绍 JWT 令牌的组成与使用(含 HMAC 对称签名与 RSA 非对称签名两种方案),再落地完整的单点登录链路:单点登录服务颁发令牌 → 网关全局过滤器统一校验 → 资源服务通过拦截器获取用户信息。
JWT(JSON Web Token,官网 https://jwt.io)是一款出色的分布式身份校验方案,可以生成 token,也可以解析校验 token。
本篇记录商品站内搜索的落地过程:设计 ES 索引域、初始化索引库数据、拆解并开发关键字搜索功能(含分页与高亮),最后与前端联调。
站内搜索的原型效果如下,用户输入关键字即可搜索商品,并支持过滤面板、分页等能力:
设计索引的域(Field)时,从四个维度考虑:
据此设计出的商品索引实体:
package com.portal.entity;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.Date;
@Data
@Document(indexName = "es-goods", shards = 1, replicas = 0)
public class ESGoods {
@Id
private Long spuId; // spuId
@Field(type = FieldType.Text, analyzer = "ik_max_word", store = true)
private String goodsName; // 商品名称,Text 类型,需要分词参与检索
@Field(type = FieldType.Long, index = true, store = true)
private Long brandId; // 品牌 id
@Field(type = FieldType.Keyword, index = true, store = true)
private String brandName; // 品牌名称,不分词,用于过滤与分桶
@Field(type = FieldType.Long, index = true, store = true)
private Long cid1id; // 1 级分类 id
@Field(type = FieldType.Keyword, index = true, store = true)
private String cat1name; // 1 级分类名称
@Field(type = FieldType.Long, index = true, store = true)
private Long cid2id; // 2 级分类 id
@Field(type = FieldType.Keyword, index = true, store = true)
private String cat2name; // 2 级分类名称
@Field(type = FieldType.Long, index = true, store = true)
private Long cid3id; // 3 级分类 id
@Field(type = FieldType.Keyword, index = true, store = true)
private String cat3name; // 3 级分类名称
@Field(type = FieldType.Date, index = true, store = true, format = DateFormat.date_time)
private Date createTime; // 创建时间
@Field(type = FieldType.Double, index = true, store = true)
private Double price; // 价格,spu 默认取 sku 的 price
@Field(type = FieldType.Keyword, index = false, store = true)
private String imageUrl; // 图片地址,只存储不参与检索
}
本篇介绍分布式系统中订单 id 的生成策略,以及基于雪花算法的分布式 id 生成器 IdWorker 在项目中的使用。
分布式系统订单 id 生成策略的要求:
常见的候选方案对比:
| 方案 | 问题 |
|---|---|
| UUID | 极端高并发情况下会存在 id 冲突,且不是纯数字、不定长 |
| 分布式 id 生成器 IdWorker | 雪花算法实现,分布式 id 的完美解决方案 |
本篇记录项目中接入微信扫码支付(NATIVE)的全过程:从公众号与商户平台的申请流程,到统一下单、二维码展示、订单状态查询、关闭订单,以及订单超时自动关闭的落地实现。
注册地址:https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN&token=
本篇从商品详情页的实现方案引出网页静态化技术,介绍 Freemarker 模板引擎的基本用法、Spring Boot 整合方式,以及商品详情页静态化在项目中的完整落地。
商品详情页怎么实现?常见的三种方案:
| 方案 | 做法 | 弊端 |
|---|---|---|
| 方案一 | 从数据库中获取数据,然后渲染到前端 | 数据库访问压力大;数据库效率低(磁盘 IO),导致商品详情服务不稳定 |
| 方案二 | 使用 Redis 缓存 | 商品数据量太大,存在 Redis 的内存瓶颈 |
| 方案三 | 网页静态化 | 页面生成后基本不变,改动时重新生成即可,综合表现最好 |
本篇记录购物车模块的开发思路与购物车实体设计:购物车数据存入 Redis,用 Hash 结构按用户维度隔离存储。
购物车是典型的"高频读写、随登录态变化"的数据,项目选择用 Redis 的 Hash 结构存储购物车数据:
Redis 存储购物车数据结构:Hash
K => menhu:cart
field => ${userid}
value => ${cart}