10年老兵带你学Java(第19课):微服务架构入门 - Spring Cloud 核心组件
本课目标
- 理解什么是微服务架构,为什么要用微服务
- 掌握 Spring Cloud 核心组件及作用
- 学会使用 Nacos 作为注册中心和配置中心
- 了解 Gateway 网关的用法
- 理解微服务的拆分思想
一、从单体架构到微服务
1.1 单体架构的问题
我们之前做的扫码点餐系统,是一个单体应用:
- 所有代码打成一个 jar 包运行
- 一个MySQL数据库,一个Redis缓存
单体应用在项目小、团队少的时候很香:
- 简单,不需要懂分布式
- 部署方便,一台服务器就够
- 开发、测试、部署都简单
但当系统越来越复杂,用户越来越多,单体架构就扛不住了:
| 问题 | 描述 |
|---|---|
| 部署效率低 | 修改一行代码,要重新打包部署整个系统 |
| 扩展性差 | 只能整体扩展,无法针对瓶颈模块(如图文)单独扩展 |
| 可用性低 | 一个模块挂掉,整个系统不可用 |
| 技术栈绑定 | 选了一种语言/框架,所有模块都得用它 |
1.2 什么是微服务?
微服务(Microservice)是将一个大型应用拆分为多个独立的小服务,每个服务可以:
- 独立开发、独立部署
- 使用不同的技术栈(Java/Go/Python都可以)
- 独立扩展(访问量大的模块多部署几台)
- 独立容错(一个服务挂了不影响其他服务)
微服务拆分示例(点餐系统):
用户服务(用户注册登录) ↓ 菜品服务(菜品管理) ↓ 订单服务(下单、支付) ↓ 支付服务(对接微信/支付宝) ↓ 通知服务(短信、模板消息)1.3 微服务架构的挑战
微服务虽好,但也带来了新的复杂度:
- 服务之间如何通信?(HTTP / RPC)
- 如何统一管理所有服务?(服务注册与发现)
- 如何统一入口?(网关)
- 配置分散如何管理?(配置中心)
- 一个服务挂了怎么办?(熔断、限流)
这些问题,Spring Cloud 给你一套完整解决方案。
二、Spring Cloud 生态概述
Spring Cloud 不是"一个框架",而是一套微服务解决方案的规范,包含很多子项目:
| 组件 | 作用 | 常见实现 |
|---|---|---|
| 服务注册与发现 | 统一管理所有服务地址 | Nacos、Eureka |
| 配置中心 | 集中管理所有配置文件 | Nacos、Apollo |
| 网关 | 统一入口,路由+过滤 | Gateway、Zuul |
| 负载均衡 | 多个实例间均衡分发请求 | Ribbon、LoadBalancer |
| 服务通信 | 服务间调用 | Feign、WebClient |
| 熔断器 | 防止雪崩,保护系统 | Sentinel、Hystrix |
| 分布式事务 | 保证跨服务数据一致性 | Seata |
| 消息队列 | 异步解耦 | RabbitMQ、RocketMQ |
三、Nacos:注册中心 + 配置中心
3.1 什么是 Nacos?
Nacos 是阿里巴巴开源的项目,集成了:
- 服务注册中心:所有微服务启动时注册到这里
- 配置中心:所有配置文件可以写在 Nacos 里,服务运行时动态拉取
官网:https://nacos.io
下载:https://github.com/alibaba/nacos/releases(下载 zip 解压,运行startup.cmd)
3.2 服务注册
子模块 pom.xml:
<dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2021.1</version></dependency></dependencies>配置文件:
spring:cloud:nacos:discovery:server-addr:127.0.0.1:8848# Nacos地址namespace:publicconfig:server-addr:127.0.0.1:8848application:name:scan-order-dish-service# 服务名称启动类加注解:
@SpringBootApplication@EnableDiscoveryClientpublicclassDishServiceApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DishServiceApplication.class,args);}}启动后,打开http://127.0.0.1:8848/nacos,用nacos/nacos登录,就能看到服务已经注册上去了。
3.3 配置中心
在 Nacos 控制台添加配置:
// Data ID: scan-order-dish-service.yamlspring:datasource:url:jdbc:mysql://localhost:3306/scan_order?useUnicode=true...username:rootpassword:123456项目中的bootstrap.yml:
spring:cloud:nacos:config:server-addr:127.0.0.1:8848file-extension:yamlnamespace:publicapplication:name:scan-order-dish-service这样就不用在每个项目的 application.yml 里写数据库配置了,集中在 Nacos 里管理,改配置也不需要重启服务。
四、Gateway:统一网关
4.1 为什么需要网关?
微服务拆分后,客户端(小程序、APP)不能直接访问每个后台服务,需要一个统一入口:
- 路由转发:根据路径,把请求转发到对应的微服务
- 统一认证:所有请求先过网关,验证Token
- 限流熔断:保护后台服务
- 日志记录:统一记录所有请求日志
4.2 Gateway 快速使用
依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>配置:
server:port:8080spring:cloud:nacos:discovery:server-addr:127.0.0.1:8848gateway:routes:-id:dish-serviceuri:lb://scan-order-dish-servicepredicates:-Path=/dish/**-id:order-serviceuri:lb://scan-order-order-servicepredicates:-Path=/order/**-id:user-serviceuri:lb://scan-order-user-servicepredicates:-Path=/user/**lb://xxx:从 Nacos 获取服务地址,做负载均衡predicates:路径匹配规则
五、服务间通信:Feign
5.1 什么是 Feign?
一个微服务经常需要调用另一个微服务的接口,比如"下单服务"需要调用"菜品服务"查询菜品信息。
Feign 就是一个声明式的 HTTP 客户端,让你像调用本地方法一样调用远程接口。
5.2 使用示例
依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>定义调用接口:
@FeignClient(name="scan-order-dish-service",path="/dish")publicinterfaceDishFeignClient{@GetMapping("/{id}")DishgetById(@PathVariable("id")Longid);@GetMapping("/list")List<Dish>list();}调用方使用:
@RestController@RequestMapping("/order")publicclassOrderController{@AutowiredprivateDishFeignClientdishFeignClient;@GetMapping("/test")publicDishtest(){returndishFeignClient.getById(1L);}}启动类加@EnableFeignClients。
六、微服务拆分实战思路
6.1 什么时候该拆?
| 项目规模 | 建议 |
|---|---|
| 小型(团队<5人,用户<1万) | 单体架构足够,不要过度设计 |
| 中型(5-15人,1-10万用户) | 可拆分核心服务(用户、订单、菜品) |
| 大型(15人以上,10万+用户) | 全面微服务化 |
6.2 扫码点餐系统的微服务拆分
如果将来这个系统要扩展,可以这样拆:
scan-order-gateway(网关层,统一入口) 用户服务 user-service - 用户注册、登录 - 收获地址管理 菜品服务 dish-service - 菜品分类管理 - 菜品CRUD 订单服务 order-service - 下单、支付 - 订单状态管理 消息服务 notice-service - 短信通知 - 小程序模板消息七、本课作业
- 在本地安装 Nacos(单节点模式),启动并访问控制台
- 创建一个新的 Spring Boot 模块,引入 Nacos Discovery,实现服务注册
- (选做)尝试配置 Gateway,将请求转发到不同服务
八、下一课预告
下一课我们将学习Docker 容器化 + CI/CD 持续交付,学会用 Docker 部署 Spring Boot 项目,并用 GitHub Actions 实现代码提交自动构建部署。
