作为电商平台的核心功能模块之一,购物车系统承载着用户选购商品、价格计算、促销活动参与等重要功能。在小兔鲜这个生鲜电商项目中,购物车模块需要特别考虑生鲜商品的特殊性,比如库存时效性、称重计价、限购策略等业务场景。
我在实际开发中发现,一个健壮的购物车系统需要解决三个核心问题:
购物车数据采用Redis Hash结构存储,键设计为cart:{userId},字段为SKU ID,值为商品数量和其他扩展属性。这种结构相比关系型数据库有以下优势:
python复制# 示例数据结构
{
"cart:10086": {
"sku_12345": {
"count": 2,
"selected": 1,
"add_time": 1630000000,
"price": 39.9,
"spec": "500g/盒"
}
}
}
针对"超卖"问题,我们采用Redis+Lua脚本实现原子操作:
lua复制-- 库存检查Lua脚本
local stockKey = KEYS[1]
local cartKey = KEYS[2]
local sku = ARGV[1]
local num = tonumber(ARGV[2])
local stock = redis.call('GET', stockKey)
if not stock or tonumber(stock) < num then
return 0
end
redis.call('HINCRBY', cartKey, sku, num)
redis.call('DECRBY', stockKey, num)
return 1
促销系统采用规则引擎+优惠券池的设计:
java复制// 伪代码示例
public CartPriceVO calculatePrice(CartVO cart) {
// 1. 计算商品总价
BigDecimal itemTotal = cart.getItems().stream()
.map(i -> i.getPrice().multiply(i.getCount()))
.reduce(BigDecimal.ZERO, BigDecimal::add);
// 2. 应用促销规则
List<PromotionRule> matchedRules = ruleEngine.match(cart);
for (PromotionRule rule : matchedRules) {
itemTotal = rule.apply(itemTotal);
}
// 3. 应用优惠券
if (cart.getCouponId() != null) {
Coupon coupon = couponPool.get(cart.getCouponId());
itemTotal = coupon.apply(itemTotal);
}
return new CartPriceVO(itemTotal, ...);
}
针对生鲜商品的特点,我们在购物车中增加了以下逻辑:
用户在不同终端添加商品时,采用"最后一次修改优先"的合并策略:
采用多级缓存架构:
购物车查询接口做了以下优化:
初期直接使用Redis DECR命令扣减库存,在秒杀场景下仍会出现超卖。最终解决方案:
当多个促销活动叠加时,曾出现规则冲突导致价格计算异常。我们最终制定了优先级规则:
生鲜商品购物车需要特殊处理:
基于购物车商品实时推荐:
支持不同店铺商品分开结算:
在项目上线后,购物车模块的日均调用量达到200万次,平均响应时间控制在50ms以内。通过持续优化,购物车转化率从35%提升到58%,成为项目中最稳定的模块之一。