1. 项目概述
宠物商城网站是近年来电商领域增长最快的垂直细分市场之一。随着宠物经济持续升温,越来越多的养宠人士倾向于通过线上渠道购买宠物用品、食品和相关服务。这个基于Spring Boot的宠物商城项目,正是瞄准了这一市场需求,为中小型宠物用品商家提供了一个完整的电商解决方案。
我在实际开发过程中发现,宠物电商与传统电商平台存在显著差异:用户更关注商品安全性、配送时效性和个性化推荐。因此,在设计架构时特别强化了商品溯源、同城配送和智能推荐模块。整个项目采用Spring Boot 2.7作为基础框架,配合MyBatis-Plus实现数据持久化,前端使用Thymeleaf模板引擎,形成了典型的前后端不分离架构——这种选择特别适合中小型电商项目快速迭代的需求。
2. 核心模块设计
2.1 分层架构设计
项目采用经典的三层架构,但在具体实现上针对电商场景做了优化:
code复制表现层(Web)
│
业务逻辑层(Service) → 消息队列(RabbitMQ)
│
数据访问层(Dao) → 缓存(Redis)
提示:在商品详情页这种高并发场景,我们采用Redis缓存+MySQL持久化的混合存储策略。实测显示,这种方案在1000QPS压力下,响应时间能稳定在200ms以内。
2.2 数据库设计关键点
宠物商城的数据库设计有几个特殊考量:
- 商品多维度分类:除了常规的食品/用品分类,还增加了适用宠物类型(猫/狗/异宠)、年龄段等标签
- 溯源信息字段:进口商品需要记录报关单号、检疫证明等合规信息
- 配送时效标识:区分普通快递、同城急送、到店自提等不同配送方式
核心表关系如下:
sql复制CREATE TABLE `product` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '商品名称',
`pet_type` tinyint NOT NULL COMMENT '适用宠物类型(1猫2狗3其他)',
`has_trace` bit(1) DEFAULT 0 COMMENT '是否可溯源',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.3 支付系统对接
考虑到宠物用品客单价差异大(从几元的零食到上万元的智能设备),我们同时接入了两种支付方案:
- 微信/支付宝官方SDK:适用于常规交易
- 信用卡分期接口:针对高单价商品(如进口宠物医疗设备)
支付状态机设计特别重要,我们采用状态模式实现:
java复制public interface PaymentState {
void handle(PaymentContext context);
}
@Component
public class UnpaidState implements PaymentState {
@Override
public void handle(PaymentContext context) {
if(context.verifySuccess()){
context.setState(new PaidState());
}
}
}
3. 特色功能实现
3.1 智能推荐系统
不同于普通电商的协同过滤算法,宠物商城推荐系统加入了宠物画像维度:
- 基础推荐:基于用户历史购买记录
- 跨品类推荐:如购买猫粮的用户可能对猫砂有需求
- 生命周期推荐:根据宠物年龄推荐相应阶段的商品
实现代码片段:
java复制public List<Product> recommend(Long userId) {
// 获取用户宠物信息
Pet pet = petService.getByOwner(userId);
// 多维度组合查询
return productMapper.selectList(new QueryWrapper<Product>()
.eq("pet_type", pet.getType())
.between("appropriate_age", pet.getAge()-1, pet.getAge()+1)
.orderByDesc("sales"));
}
3.2 同城即时配送
与第三方配送平台API对接时,需要特别注意:
- 时效性计算:根据商户地址和用户地址实时计算预计送达时间
- 温控要求:部分生鲜食品需要特殊配送条件
- 异常处理:配送超时、拒收等情况的补偿方案
我们在Service层实现了配送策略模式:
java复制public interface DeliveryStrategy {
DeliveryResult calculate(Order order);
}
@Service
@Slf4j
public class SameCityDelivery implements DeliveryStrategy {
@Override
public DeliveryResult calculate(Order order) {
// 调用地图API计算距离
DistanceResult distance = mapService.getDistance(
order.getStore().getAddress(),
order.getUser().getAddress());
// 预估时间 = 基础时间 + 距离时间
int minutes = 30 + distance.getMinutes();
return new DeliveryResult(minutes, "同城急送");
}
}
4. 性能优化实践
4.1 缓存策略设计
针对宠物商城的访问特点,我们设计了多级缓存:
- 热点商品:全量缓存到Redis,设置5分钟过期时间
- 商品列表:缓存第一页数据,采用LFU淘汰策略
- 购物车:使用本地缓存+Redis持久化方案
缓存击穿解决方案示例:
java复制public Product getProduct(Long id) {
// 1. 先查缓存
Product product = redisTemplate.opsForValue().get("product:" + id);
if (product != null) {
return product;
}
// 2. 获取分布式锁
RLock lock = redissonClient.getLock("lock:product:" + id);
try {
lock.lock();
// 3. 二次检查缓存
product = redisTemplate.opsForValue().get("product:" + id);
if (product != null) {
return product;
}
// 4. 查数据库
product = productMapper.selectById(id);
if (product != null) {
redisTemplate.opsForValue().set("product:"+id, product, 5, TimeUnit.MINUTES);
}
return product;
} finally {
lock.unlock();
}
}
4.2 高并发下单处理
秒杀场景采用预扣库存方案:
- Redis原子操作扣减预库存
- 异步队列处理实际订单创建
- 定时任务回收超时未支付库存
核心代码如下:
java复制public boolean seckill(Long productId, Integer num) {
String key = "stock:" + productId;
// Redis原子操作
Long remain = redisTemplate.opsForValue().decrement(key, num);
if (remain < 0) {
// 回滚
redisTemplate.opsForValue().increment(key, num);
return false;
}
// 发送MQ消息
rabbitTemplate.convertAndSend("order.create",
new OrderMessage(productId, num));
return true;
}
5. 安全防护措施
5.1 敏感数据保护
宠物商城涉及用户住址、宠物信息等敏感数据,我们采取以下措施:
- 数据库字段加密:使用AES算法加密地址、联系方式
- 日志脱敏:在Logback配置中过滤敏感信息
- 接口权限控制:Spring Security + 自定义注解
手机号加密示例:
java复制public String encryptPhone(String phone) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
return Base64.encodeToString(cipher.doFinal(phone.getBytes()));
} catch (Exception e) {
log.error("加密失败", e);
return null;
}
}
5.2 防刷单机制
针对宠物食品这种高频复购商品,我们建立了多维度风控系统:
- 行为分析:检测异常下单频率
- 设备指纹:识别同一设备多账号
- 购物车分析:识别批量下单行为
风控规则引擎部分实现:
java复制public RiskResult checkOrderRisk(Order order) {
// 规则1:同一IP短时间内多次下单
if(orderCounter.getIpCount(order.getIp()) > 5) {
return new RiskResult(true, "IP下单频率过高");
}
// 规则2:收货地址异常
if(addressService.isSuspicious(order.getAddress())) {
return new RiskResult(true, "地址存在风险");
}
return new RiskResult(false, "");
}
6. 部署与监控
6.1 容器化部署
采用Docker Compose编排方案:
yaml复制version: '3'
services:
app:
image: petmall:1.0
ports:
- "8080:8080"
depends_on:
- redis
- mysql
redis:
image: redis:6
ports:
- "6379:6379"
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: pet123
6.2 监控方案设计
使用Prometheus + Grafana监控关键指标:
- 业务指标:订单创建成功率、支付转化率
- 系统指标:API响应时间、数据库查询耗时
- 自定义指标:库存变更次数、优惠券使用率
Spring Boot集成Prometheus示例:
java复制@Bean
public MeterRegistryCustomizer<PrometheusMeterRegistry> configureMetrics() {
return registry -> {
registry.config().commonTags("application", "petmall");
// 自定义订单指标
Counter.builder("orders.created")
.description("已创建订单数")
.register(registry);
};
}
在项目上线后,我们发现商品详情页的CDN缓存命中率直接影响用户体验。通过调整Nginx配置,将静态资源缓存时间从1小时延长到24小时,页面加载速度提升了40%。这个优化点特别值得同类项目参考——宠物主人往往会反复查看同一商品的详情,高缓存命中率能显著改善使用体验。