1. 项目概述与背景
房屋租赁市场在城市化进程中扮演着重要角色,但传统租赁方式存在信息不对称、流程繁琐等问题。作为一名经历过多次租房"踩坑"的开发者,我决定用技术手段解决这些痛点。这个基于SpringBoot+Vue的房屋租赁平台,正是我在帮助学弟完成毕业设计时沉淀下来的实战项目。
系统采用主流的前后端分离架构,后端使用SpringBoot 2.7提供RESTful API,前端采用Vue 3组合式API开发,数据库选用MySQL 8.0。特别在安全性方面,我们实现了JWT令牌认证、阿里云OSS图片存储加密、合同电子签名等多重保障。整个项目从需求分析到上线部署耗时约3个月,期间解决了高并发预约、在线支付对账等典型业务场景问题。
2. 技术架构设计解析
2.1 后端技术选型
SpringBoot的选择基于三个核心考量:
- 快速启动:通过spring-boot-starter-web、spring-boot-starter-data-jpa等starter包,5分钟即可搭建基础框架
- 生产就绪:集成Actuator监控端点,配合Prometheus+Grafana实现性能监控
- 扩展性:预留了Spring Cloud Alibaba微服务扩展接口
关键配置示例(application.yml):
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/rental_db?useSSL=false&serverTimezone=UTC
username: root
password: 加密密码
jpa:
show-sql: true
hibernate:
ddl-auto: update
jwt:
secret: 自定义加密密钥
expiration: 86400000 # 24小时
2.2 前端架构设计
Vue 3的组合式API相比Options API更适合复杂业务场景:
- 使用Pinia替代Vuex进行状态管理
- 基于axios的请求拦截器实现JWT自动刷新
- 采用Element Plus组件库加速开发
典型请求封装:
javascript复制const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000
})
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['Authorization'] = 'Bearer ' + getToken()
}
return config
},
error => {
return Promise.reject(error)
}
)
3. 核心功能实现细节
3.1 用户认证模块
采用JWT+Redis的双重认证方案:
- 登录成功生成access_token和refresh_token
- Redis存储token白名单(有效期短于JWT过期时间)
- 接口访问时通过Spring Security的OncePerRequestFilter校验
安全增强措施:
- 密码使用BCryptPasswordEncoder加密存储
- 关键操作需二次短信验证
- 接口限流防止暴力破解
3.2 房源管理模块
核心难点在于房源信息的富文本存储和高效检索:
- 使用MySQL的JSON类型存储配套设施数据
- 基于Elasticsearch构建全文检索
- 地理坐标采用MySQL的空间索引(POINT类型)
房源发布接口示例:
java复制@PostMapping("/houses")
@PreAuthorize("hasRole('LANDLORD')")
public Result publishHouse(@Valid @RequestBody HouseDTO dto) {
// 地址解析为经纬度
Location location = geoService.resolveAddress(dto.getAddress());
House house = new House()
.setLocation(location)
.setFacilities(JSON.toJSONString(dto.getFacilities()));
return Result.success(houseService.save(house));
}
4. 租赁业务流程实现
4.1 在线签约流程
电子合同签署的合法合规实现:
- 使用CA证书进行数字签名
- 合同哈希值上链存证(采用Hyperledger Fabric私有链)
- 签约过程录屏存证
状态机设计:
mermaid复制stateDiagram
[*] --> DRAFT
DRAFT --> REVIEW : 提交审核
REVIEW --> REJECTED : 审核不通过
REVIEW --> PENDING_SIGN : 审核通过
PENDING_SIGN --> SIGNED : 双方签署
SIGNED --> TERMINATED : 租期结束
4.2 支付对账系统
支付模块的防重入设计:
- 使用数据库乐观锁控制并发
- 支付宝/微信支付回调的幂等处理
- 每日定时对账任务补偿异常订单
支付核心逻辑:
java复制@Transactional
public PaymentResult processPayment(PaymentRequest request) {
// 防重检查
if (paymentDao.existsByOrderNo(request.getOrderNo())) {
throw new BusinessException("重复支付");
}
// 扣款逻辑
boolean success = paymentGateway.charge(request);
if (success) {
paymentDao.save(buildPaymentRecord(request));
orderService.updateOrderStatus(request.getOrderId(), PAID);
}
return new PaymentResult(success);
}
5. 性能优化实践
5.1 缓存策略
采用多级缓存架构:
- 本地Caffeine缓存高频访问的房源详情
- Redis集群缓存用户会话和热点数据
- MySQL查询结果缓存
缓存注解示例:
java复制@Cacheable(value = "house", key = "#id", unless = "#result == null")
public House getById(Long id) {
return houseRepository.findById(id).orElse(null);
}
5.2 数据库优化
针对租赁系统特点进行的优化:
- 用户表按注册时间范围分区
- 合同表建立(house_id, is_active)复合索引
- 慢查询日志分析优化
执行计划优化案例:
sql复制-- 优化前(全表扫描)
EXPLAIN SELECT * FROM houses WHERE address LIKE '%中关村%';
-- 优化后(使用全文索引)
CREATE FULLTEXT INDEX idx_address ON houses(address);
EXPLAIN SELECT * FROM houses WHERE MATCH(address) AGAINST('中关村');
6. 安全防护体系
6.1 常见攻击防护
实战中遇到的攻击类型及应对:
- XSS:前端DOMPurify过滤 + 后端Jackson转义
- CSRF:SameSite Cookie + 关键操作验证码
- SQL注入:MyBatis参数绑定 + 正则过滤
安全过滤器配置:
java复制@Bean
public FilterRegistrationBean<XssFilter> xssFilter() {
FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new XssFilter());
registration.addUrlPatterns("/*");
registration.setOrder(1);
return registration;
}
6.2 数据隐私保护
符合GDPR要求的实践:
- 敏感字段加密存储(如手机号、身份证号)
- 日志脱敏处理
- 数据导出自动加水印
加密工具类示例:
java复制public class CryptoUtil {
private static final String AES_KEY = "配置密钥";
public static String encrypt(String plainText) {
// AES-GCM加密实现
}
public static String decrypt(String cipherText) {
// 解密逻辑
}
}
7. 部署与运维方案
7.1 容器化部署
Docker Compose编排方案:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
frontend:
build: ./frontend
ports:
- "80:80"
7.2 监控告警体系
Prometheus监控指标配置:
yaml复制scrape_configs:
- job_name: 'springboot'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['backend:8080']
Grafana看板包含:
- JVM内存/线程监控
- 接口响应时间P99
- 数据库连接池使用率
8. 典型问题排查实录
8.1 并发签约问题
现象:同一房源被多人同时签约
解决:采用分布式锁(Redisson)控制
java复制RLock lock = redissonClient.getLock("house:" + houseId);
try {
if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
// 执行业务逻辑
}
} finally {
lock.unlock();
}
8.2 支付回调丢失
现象:第三方支付回调偶尔丢失
解决:增加主动查询补偿机制
java复制@Scheduled(cron = "0 0/5 * * * ?")
public void checkPendingPayments() {
List<Payment> pendings = paymentDao.findByStatus(PENDING);
pendings.forEach(payment -> {
boolean success = paymentGateway.query(payment.getTradeNo());
if (success) {
payment.setStatus(SUCCESS);
paymentDao.save(payment);
}
});
}
9. 项目扩展方向
9.1 微服务改造
可拆分的服务边界:
- 用户中心服务
- 房源搜索服务
- 支付结算服务
- 合同存证服务
Spring Cloud集成要点:
xml复制<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
9.2 大数据分析
基于Flink的实时数据分析:
- 房源点击热度统计
- 区域租金价格波动监测
- 用户行为路径分析
数据处理管道示例:
java复制DataStream<UserBehavior> stream = env
.addSource(new KafkaSource())
.keyBy(Behavior::getUserId)
.window(TumblingEventTimeWindows.of(Time.hours(1)))
.aggregate(new BehaviorAnalyzer());
10. 开发经验总结
在项目开发过程中,有几个关键点值得特别注意:
-
合同法律效力问题:需要与法务团队密切配合,确保电子签约流程符合《电子签名法》要求。我们最终采用了第三方认证服务提供的时间戳服务。
-
支付系统对账:实际运营中会发现约0.1%的订单会出现支付渠道与系统状态不一致的情况。建议每天固定时间运行对账任务,我们设置的是凌晨2点。
-
图片存储优化:初期直接使用数据库存储base64编码图片,导致查询性能急剧下降。后来迁移到OSS后,配合CDN加速,页面加载时间从3s降至800ms。
-
缓存一致性问题:房源信息更新后,出现过缓存未及时失效导致用户看到旧数据的情况。最终通过Redis的Pub/Sub机制实现缓存更新通知。
这个项目让我深刻体会到,一个完整的商业系统不仅需要技术实现,更要考虑业务合规性、系统稳定性和用户体验的平衡。特别是在处理金钱交易和法律文书时,必须建立完善的日志审计和异常处理机制。