基于Spring Cloud的Java毕设实战:从单体到微服务的完整落地指南
2026/9/17 13:50:50 网站建设 项目流程


背景痛点:Demo 能跑,上线就崩?

做毕设时,很多同学把“微服务”当成关键词,却只是把原来的三层架构拆成三个 Maven 模块:

  • 端口写死、IP 硬编码,一换电脑就失联;
  • 调用链直接RestTemplate,对方超时整个线程就卡死;
  • 配置散落在application.properties,数据库密码明文躺平 GitHub;
  • 没有熔断,一个慢 SQL 把整站拖拖垮;
  • 日志各写各的,排查 Bug 全靠System.out

结果演示那天,老师一句“换个机器部署”就当场社死。

技术选型:Nacos + Sentinel 真香在哪?

维度Eureka 1.xHystrixNacos 2.xSentinel
社区状态停更停更阿里持续维护阿里持续维护
控制台简陋独立 Dash一体化注册+配置一体化流控+熔断
规则推送手动手动长轮询秒级长轮询秒级
扩展语言Java OnlyJava Only多语言 SDK多语言 SDK

结论:毕设周期只有 3 4 个月,选“能跑、能改、有界面”的组件最划算,Nacos + Sentinel 开箱即用,省出来的时间还能把 PPT 做漂亮点。

核心实现:一条调用链跑通

下面以“学生选课”场景为例,拆成 3 个服务:

  • course-service:课程中心
  • student-service:学生中心
  • gateway:统一入口

1. 启动 Nacos Server(单例模式即可)

docker run -d -p 8848:8848 -e MODE=standalone nacos/nacos-server:v2.3.0

浏览器打开http://localhost:8848/nacos,账号密码都是nacos,先新建命名空间dev,把毕设跟教学环境隔开。

2. 各服务引入依赖(以 course-service 为例)

<!-- 父 pom 统一版本 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>

3. bootstrap.yml(优先级高于 application)

spring: application: name: course-service cloud: nacos: discovery: server-addr: 127.0.0.1:8848 namespace: dev config: server-addr: 127.0.0.1:8848 namespace: dev file-extension: yaml group: DEFAULT_GROUP refresh-enabled: true sentinel: transport: dashboard: localhost:8080 port: 8719 eager: true # 提前初始化,防止冷启动无数据 server: port: 8082 management: endpoints: web: exposure: '*' # 健康检查接口给网关用

4. 业务代码:Feign + 熔断

@FeignClient(name = "student-service", fallbackFactory = StudentClientFallbackFactory.class) public interface StudentClient { @GetMapping("/students/{id}") Result<StudentDTO> getStudent(@PathVariable("id") Long id); } @Component class StudentClientFallbackFactory implements FallbackFactory<StudentClient> { @Override public StudentClient create(Throwable cause) { return id -> Result.fail("student-service 繁忙,降级返回空对象"); } }

Controller 层加流控注解:

@RestController @RequestMapping("/courses") public class CourseController { @GetMapping("/{id}") @SentinelResource(value = "course-detail", blockHandler = "blockHandler", fallback = "fallback") public Result<CourseDTO> detail(@PathVariable Long id) { return Result.ok(courseService.get(id)); } public Result<CourseDTO> blockHandler(Long id, BlockException e) { return Result.fail("接口被流控,稍后再试"); } public Result<CourseDTO> fallback(Long id, Throwable e) { return Result.fail("服务异常,降级返回"); } }

Sentinel 控制台http://localhost:8080里新增“簇点链路” → 给course-detail设置 QPS=1 的规则,浏览器狂刷F5立即触发流控,直观感受“雪崩”被按住。

5. 配置热更新演示

在 Nacos 控制台新建DataId=course-service.yaml,内容:

course: max-allow: 50

代码里直接@ConfigurationProperties("course")绑定,改完点“发布”,服务日志打印Refresh keys: [course.max-allow],无需重启。

性能 & 安全:别让老师抓包抓到密码

  1. 接口幂等
    选课接口用“学生 ID + 课程 ID”做唯一索引,POST 前先查 Redis 分布式锁set key NX EX 5,重复提交返回“已选”。

  2. 敏感配置加密
    在 Nacos 里把数据库密码写成cipher-{cipher}AQBxxx,引入jasypt-spring-boot-starter,启动参数加--jasypt.encryptor.password=你的毕业年份,运维人员即使拿到配置也解不开。

  3. 服务间认证
    所有内部 Feign 调用统一加RequestInterceptor,把网关颁发的 JWT 原样转发;course-service 收到后先验签名,防止学生用 Postman 直接刷内部接口。

生产环境避坑清单

  • 本地跑 Docker 内存限制 2 G,上了云 1 C 1 G,Sentinel 一启动就 OOM;启动脚本加-Xms256m -Xmx512m并关闭不必要的 Actuator。
  • 冷启动超时:Spring Cloud 2021 默认开启懒加载,第一次调用才初始化 Feign Client,把spring.cloud.nacos.discovery.metadata.preserved.register.ip=127.0.0.1写死,或者加spring.main.lazy-initialization=false
  • 日志聚合:别再用System.out,直接logback-spring.xmlCONSOLE改为LOKIELASTIC的 TCP Appender,老师验收时打开 Grafana 一搜关键词,比翻 10 个窗口高效。
  • 端口冲突:云主机常把 8080 留给管理台,本地 yml 写server.port=${PORT:0}让 K8s 自动分配,本地 IDE 启动也能随机端口。
  • GitHub 泄露:.gitignore一定加**/target,**/*.log,application-secret.yml;用 GitHub Actions 做 CI 时,把jasypt.encryptor.password写进仓库 Secrets,别写明文。

一键部署脚本(CentOS 单例)

#!/bin/bash # install.sh yum -y install java-11-openjdk docker run -d --name nacos -e MODE=standalone -p 8848:8848 nacos/nacos-server:v2.3.0 docker run -d --name sentinel -p 8080:8080 bladex/sentinel-dashboard:1.8.6 nohup java -jar course-service.jar --jasypt.encryptor.password=2024 > course.log 2>&1 & nohup java -jar student-service.jar --jasypt.encryptor.password=2024 > student.log 2>&1 & nohup java -jar gateway.jar > gateway.log 2>&1 &

把脚本丢到云主机,5 分钟就能给老师发演示链接。

结语:毕设不是终点,是服务治理的起点

把单体拆成微服务只是第一步,真正的坑在“拆完以后怎么管”。
建议你趁热打铁:

  1. 把选课接口换成 RocketMQ 异步流,测一下最终一致性;
  2. 给 gateway 加 Spring Cloud LoadBalancer + Nacos 权重,模拟灰度发布;
  3. 用 SkyWalking 替换 Sentinel 自带链路,看看一次选课到底经过几次网络跃点。

当你能对着监控图讲清楚“为什么 QPS 翻倍但 RT 没涨”,毕业答辩那张 PPT 就稳了。
动手重构你的老项目吧,先让“Demo 能跑”进化成“能扛 100 并发”,再思考服务治理的边界到底在哪——毕竟,老板以后不会只看你“能跑”,而是看你“不崩”。


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询