从 Struts2 单体到 Spring Cloud 微服务:一个 P2P 系统的真实重构之路(2019 年实战复盘)

从 Struts2 单体到 Spring Cloud 微服务:一个 P2P 系统的真实重构之路(2019 年实战复盘)

开源地址https://gitee.com/lijinquanBlog/lijinquan-p2p
关键词:微服务重构、Spring Cloud、Eureka、Feign、Hystrix、P2P 系统、架构演进


🌟 写在前面:这不是 Demo,而是一次"生存式"重构

2019 年初,我手头有一个运行多年的 P2P 投资平台------基于 Struts2 + Spring + MyBatis + Oracle 的典型单体架构。随着用户增长,系统暴露出严重问题:

  • 每次发版需全量部署,上线风险高
  • 团队协作困难:前端改页面,后端动接口,测试全回归
  • 高峰期数据库连接池打满,投资下单经常超时
  • 权限、账户、债权逻辑耦合,改一处崩三处

于是,我决定:彻底重构为微服务架构

没有大厂资源,没有团队支持,只有一个人、一台 Dell 笔记本,和一个信念:"能跑起来,就能活下去。"


🔧 一、为什么选择 Eureka + Feign + Hystrix?(不是没得选,而是选得稳)

很多人问我:"2019 年都快 Nacos 了,为啥不用?"

答案很简单:时间点不对。

  • Nacos :2018 年 7 月才开源,2019 年初仍是 0.x 版本,无生产级案例,文档匮乏。
  • Sentinel :虽已开源,但 Spring Cloud 集成不成熟,连自动装配都靠手写
  • Eureka + Feign + Hystrix :Netflix 套件,经过 Netflix、国内电商多年验证,社区问题一搜就有解。

💡 在资金敏感的 P2P 系统里,稳定性 > 新潮。

我选择了"能让我睡着觉"的技术栈。


🏗️ 二、如何拆分服务?从业务出发,而非技术炫技

我没有盲目按"用户、订单、商品"拆,而是根据 P2P 核心业务域

微服务 职责 端口
microservicecloud-provider-user-8001 用户注册、登录、实名认证 8001
microservicecloud-provider-invest-8002 投资、债权匹配、收益计算 8002
microservicecloud-provider-account-8003 资金账户、充值提现(对接支付) 8003
microservicecloud-consumer-web-81 前台 Web(Angular)调用聚合层 81
microservicecloud-eureka-7001 服务注册中心 7001

关键原则

  • 每个服务独立数据库(避免跨库事务)
  • 异步解耦:投资成功后,通过 ActiveMQ 通知账户系统扣款
  • 统一入口:Web 层通过 Feign 调用多个 Provider,前端无感知

⚙️ 三、踩过的坑与解决方案(全是血泪经验)

❌ 坑 1:Feign 调用默认超时 1 秒,投资下单直接失败

复制代码

yaml

复制代码
# 解决方案:显式配置超时
feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 10000

❌ 坑 2:Redis Token 多服务共享,登出失效难

  • 方案:Token 存 Redis,Key = user:token:{userId}
  • 登出时删除该 Key,所有服务读取同一 Redis 实例

❌ 坑 3:Hystrix 熔断后,用户看到"系统繁忙",体验差

  • 优化:自定义 fallback 返回友好提示,并记录日志供运维分析

📊 四、效果如何?数据不会说谎

指标 重构前(单体) 重构后(微服务)
部署时间 15 分钟(全量) 3 分钟(单服务)
并发能力 ≈ 50 TPS ≈ 500 TPS(本地压测)
故障隔离 一处崩,全站挂 投资服务挂,用户仍可查账户
开发效率 全员阻塞 前端 + 后端并行开发

💡 虽然没上云、没做 CI/CD,但在资源有限的个人项目中,这已是质的飞跃


❤️ 五、给后来者的建议

  1. 不要为了微服务而微服务:先问"业务是否需要拆?"
  2. 技术选型看成熟度,不看热度:2019 年用 Eureka,是专业;硬上 Nacos,是冒险。
  3. 文档比代码更重要:我在 README 里写了架构图、启动顺序、依赖关系------这是项目能被理解的关键。
  4. 开源不是为了 Star,而是为了证明"我能搞定复杂系统"
相关推荐
名字还没想好☜1 分钟前
Go 的 select 实战:超时、非阻塞收发与优雅退出的三个套路
开发语言·数据库·golang·go·并发
geovindu2 分钟前
java: Backtracking Algorithm
java·开发语言·windows·后端·算法·回溯算法
NWU_LK6 分钟前
【WebFlux】第六篇 —— 全链路响应式与数据库交互
java·数据库
一只小菜鸡..7 分钟前
南京大学 操作系统 (JYY) 学习笔记:Hello, OS World! (程序的机器视角)
java·笔记·学习
叶总没有会13 分钟前
3.2 构建AI智能体项目扩展知识
java·数据库·人工智能·spring·ai
Lakers-2414 分钟前
1987年6月10日晚上23-24点出生性格、运势和命运
java
唐青枫17 分钟前
Java Jetty 实战详解:从嵌入式 HTTP 服务到 Spring Boot 容器替换
java
Scott9999HH8 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔9 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社10 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言