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 什么是 NacosNacos 是阿里巴巴开源的项目集成了服务注册中心所有微服务启动时注册到这里配置中心所有配置文件可以写在 Nacos 里服务运行时动态拉取官网https://nacos.io下载https://github.com/alibaba/nacos/releases下载 zip 解压运行startup.cmd3.2 服务注册子模块 pom.xmldependenciesdependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactIdversion2021.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# 服务名称启动类加注解SpringBootApplicationEnableDiscoveryClientpublicclassDishServiceApplication{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?useUnicodetrue...username:rootpassword:123456项目中的bootstrap.ymlspring: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 快速使用依赖dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-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路径匹配规则五、服务间通信Feign5.1 什么是 Feign一个微服务经常需要调用另一个微服务的接口比如下单服务需要调用菜品服务查询菜品信息。Feign 就是一个声明式的 HTTP 客户端让你像调用本地方法一样调用远程接口。5.2 使用示例依赖dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency定义调用接口FeignClient(namescan-order-dish-service,path/dish)publicinterfaceDishFeignClient{GetMapping(/{id})DishgetById(PathVariable(id)Longid);GetMapping(/list)ListDishlist();}调用方使用RestControllerRequestMapping(/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 实现代码提交自动构建部署。