1. 项目背景与核心目标
"苍穹外卖"是一个典型的外卖配送系统开发项目,作为现代O2O领域的核心业务系统,需要处理从用户下单到骑手配送的全流程。第二天的开发工作通常处于项目初期阶段,这个阶段需要完成基础架构搭建和核心模块的接口定义。
我参与过多个类似系统的从零搭建,深知这个阶段的技术决策直接影响后续开发效率。在项目第二天,我们需要重点关注以下几个核心问题:
- 数据库表结构设计与优化
- 基础微服务模块划分
- API接口规范制定
- 开发环境统一配置
- 基础工具类封装
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数据库设计与实现
2.1 核心表结构设计
外卖系统的数据库设计需要考虑高并发写入和复杂查询场景。根据我的经验,第二天应该先完成以下核心表的设计:
sql复制-- 用户表
CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`openid` varchar(45) DEFAULT NULL COMMENT '微信openid',
`name` varchar(32) DEFAULT NULL COMMENT '姓名',
`phone` varchar(11) DEFAULT NULL COMMENT '手机号',
`status` tinyint DEFAULT '1' COMMENT '状态 0:禁用 1:正常',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_openid` (`openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 地址表
CREATE TABLE `address` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint DEFAULT NULL COMMENT '用户id',
`consignee` varchar(50) DEFAULT NULL COMMENT '收货人',
`detail` varchar(200) DEFAULT NULL COMMENT '详细地址',
`label` varchar(10) DEFAULT NULL COMMENT '标签',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
注意:外卖系统的地址表需要特别注意索引设计,因为用户频繁查询自己的地址列表,但不需要跨用户查询。
2.2 分库分表策略考量
虽然项目初期数据量不大,但作为有经验的开发者,我们应该提前考虑分库分表方案:
- 用户相关数据按user_id哈希分片
- 订单数据按时间范围分表(每月一张表)
- 商品数据使用主从复制
3. 微服务架构搭建
3.1 服务划分方案
经过多个项目验证,外卖系统通常拆分为以下微服务:
- 用户服务(user-service):处理用户注册、登录、个人信息
- 订单服务(order-service):处理下单、支付、状态流转
- 店铺服务(shop-service):管理商家和商品信息
- 配送服务(delivery-service):调度骑手和路线规划
- 支付服务(payment-service):对接第三方支付渠道
3.2 Spring Cloud技术选型
我推荐使用以下技术栈组合:
- 注册中心:Nacos(比Eureka功能更丰富)
- 服务网关:Spring Cloud Gateway(性能优于Zuul)
- 配置中心:Nacos Config(统一管理配置)
- 熔断降级:Sentinel(比Hystrix更强大)
- 链路追踪:SkyWalking(国产优秀方案)
4. API接口规范制定
4.1 统一响应格式
所有API接口应该遵循统一的响应格式:
java复制public class Result<T> {
private Integer code; // 状态码
private String msg; // 提示信息
private T data; // 响应数据
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMsg("success");
result.setData(data);
return result;
}
}
4.2 接口版本控制
建议在URL路径中加入版本号:
code复制/api/v1/user/login
/api/v2/user/login
5. 开发环境配置
5.1 本地开发环境
推荐使用Docker Compose快速搭建依赖服务:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
redis:
image: redis:6.2
ports:
- "6379:6379"
5.2 代码规范检查
在pom.xml中加入以下插件:
xml复制<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<configLocation>google_checks.xml</configLocation>
</configuration>
</plugin>
6. 基础工具类封装
6.1 分布式ID生成器
推荐使用美团的Leaf方案:
java复制public class IdGenerator {
private static final Logger logger = LoggerFactory.getLogger(IdGenerator.class);
public static long nextId() {
// 实际项目中使用Leaf客户端获取ID
return SnowflakeIdWorker.nextId();
}
}
6.2 通用返回对象封装
java复制public class R<T> {
private Boolean success;
private String errorMsg;
private T data;
private Long timestamp = System.currentTimeMillis();
public static <T> R<T> ok(T data) {
R<T> r = new R<>();
r.setSuccess(true);
r.setData(data);
return r;
}
}
7. 常见问题与解决方案
7.1 跨服务事务问题
外卖系统中的订单创建涉及多个服务调用,推荐解决方案:
- 最终一致性+SAGA模式
- 本地消息表+定时任务
- 使用Seata分布式事务框架
7.2 缓存一致性问题
商品库存等关键数据需要特别注意缓存一致性:
java复制// 更新商品库存的推荐写法
@Transactional
public void reduceStock(Long productId, int quantity) {
// 1. 数据库扣减
productMapper.reduceStock(productId, quantity);
// 2. 删除缓存
redisTemplate.delete("product:" + productId);
}
8. 性能优化实践
8.1 数据库连接池配置
根据我的压测经验,推荐以下配置:
properties复制spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.connection-timeout=3000
8.2 Redis缓存优化
外卖系统的热点数据缓存策略:
- 使用多级缓存:本地缓存+Redis
- 热点数据预加载
- 使用Redis Pipeline批量操作
9. 安全防护措施
9.1 接口防刷策略
针对外卖系统常见的刷单问题:
java复制@RateLimiter(value = 10, key = "#userId")
public Result createOrder(OrderDTO orderDTO) {
// 下单逻辑
}
9.2 SQL注入防护
必须使用预编译语句:
java复制// 正确写法
@Select("SELECT * FROM user WHERE id = #{id}")
User getById(@Param("id") Long id);
// 错误写法(有SQL注入风险)
@Select("SELECT * FROM user WHERE id = " + "${id}")
User getById(@Param("id") String id);
10. 监控与日志方案
10.1 应用监控配置
推荐使用Prometheus+Grafana监控体系:
yaml复制management:
endpoints:
web:
exposure:
include: "*"
metrics:
tags:
application: ${spring.application.name}
10.2 日志收集方案
使用ELK栈收集日志:
xml复制<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.6</version>
</dependency>
在实际开发中,项目第二天的这些基础工作往往决定了后续的开发效率。根据我的经验,前期花时间做好架构设计和规范制定,能减少后期至少30%的返工工作量。特别是在团队协作项目中,统一的接口规范和开发环境能极大降低沟通成本。
