SpringCloud入门教程合集(1)-SpringCloud简介与Eureka+Feign实现服务注册中心、服务提供与服务消费
场景
SpringCloud 总体架构与核心子项目
SpringCloud 总体架构
1. 基础设施层
服务注册与发现:Eureka/Nacos
配置中心:Spring Cloud Config/Nacos
消息总线:Spring Cloud Bus
2. 服务通信层
负载均衡:Ribbon/LoadBalancer
服务调用:Feign/OpenFeign
API网关:Gateway/Zuul
3. 服务治理层
熔断降级:Hystrix/Sentinel
服务监控:Turbine/Hystrix Dashboard
分布式追踪:Sleuth/Zipkin
4. 数据层
分布式缓存:Spring Cache + Redis
分布式事务:Seata
数据库中间件:ShardingSphere
5. 安全控制层
认证授权:Spring Security OAuth2
服务鉴权:JWT
安全网关:Spring Cloud Gateway Security
SpringCloud Netflix 家族项目
SpringCloud Netflix 是 SpringCloud 早期版本的核心组件集合,为微服务架构提供了一系列成熟的解决方案。
尽管部分组件已进入维护模式,但理解其设计理念对掌握微服务架构仍有重要意义。
主要组件
Eureka - 服务注册与发现
Ribbon - 客户端负载均衡
Hystrix - 熔断降级
Zuul - API网关
Feign - 声明式REST客户端
SpringCloud Alibaba 家族项目
SpringCloud Alibaba 是阿里巴巴开源的一套微服务解决方案,为 SpringCloud 生态提供了丰富的企业级组件支持。
主要组件
Nacos - 服务注册与配置中心
Sentinel - 流量控制与熔断降级
Seata - 分布式事务解决方案
RocketMQ - 消息中间件集成
消息轨迹:完整追踪消息生命周期
事务消息:支持分布式事务场景
延迟消息:支持定时消息投递
顺序消息:保证局部顺序消费
Dubbo - RPC通信框架
高性能:基于Netty的NIO通信
多协议:支持Dubbo/REST/gRPC等
负载均衡:随机/轮询/最少活跃调用等策略
服务治理:条件路由/黑白名单/权重调节
Eureka 服务注册与发现框架介绍
1. 两大组件
Eureka Server:注册中心服务器,提供服务注册和发现功能
Eureka Client:服务提供者和消费者,会注册到 Eureka Server
2. 重要术语
服务注册(Register):服务启动时向 Eureka 注册自己的信息
服务续约(Renew):客户端定期发送心跳维持注册
服务下线(Cancel):客户端关闭时主动通知 Eureka
服务剔除(Eviction):Eureka 清理长时间无心跳的服务
服务获取(Fetch Registry):客户端从服务器获取服务注册表
3. 服务注册流程
服务提供者启动后向 Eureka Server 注册
Eureka Server 将注册信息存储到注册表
服务消费者从 Eureka Server 获取服务列表
消费者通过负载均衡调用服务提供者
2. 自我保护机制
当超过85%的客户端没有心跳时,Eureka 进入自我保护模式
在此模式下不会剔除任何服务实例
通过 eureka.server.enable-self-preservation 配置
Feign与OpenFeign
Feign
Feign 是 Netflix 开发的声明式 HTTP 客户端。
主要特点
通过注解方式定义和实现 HTTP API 调用
整合了 Ribbon 实现客户端负载均衡
支持可插拔的编码器和解码器
OpenFeign
OpenFeign 是 Spring Cloud 对 Feign 的增强和整合
主要特点
作为 Feign 的升级版本被纳入 Spring Cloud 生态
深度整合 Spring MVC 注解
支持 Spring Cloud 的服务发现(如 Eureka)
提供更完善的 Spring Boot 支持
OpenFeign 核心功能
声明式服务调用
负载均衡
自动集成 Ribbon
支持多种负载均衡策略(轮询、随机等)
服务熔断
可与 Hystrix 或 Sentinel 集成实现熔断降级
请求/响应处理
支持自定义编码器/解码器
支持请求拦截器和响应处理器
常用注解
@FeignClient 声明Feign客户端,主要参数:name/value(服务名), url(直接指定URL)
@RequestMapping 与Spring MVC用法一致
@GetMapping 映射GET请求
@PostMapping 映射POST请求
@RequestParam 请求参数
@PathVariable URL路径变量
@RequestBody 请求体
核心特性对比
最佳实践
最佳实践
接口设计原则
保持Feign接口与服务提供方API一致
使用继承或组合避免重复定义
为复杂对象定义DTO而非直接使用领域模型
性能优化建议
启用HTTP连接池(OKHttp或HttpClient)
合理设置超时时间
对频繁调用的接口考虑缓存结果
异常处理
实现ErrorDecoder处理特定状态码
统一异常转换机制
安全考虑
使用拦截器添加认证信息
敏感信息不应出现在URL或日志中
目录
场景
SpringCloud 总体架构与核心子项目
SpringCloud 总体架构
SpringCloud Netflix 家族项目
SpringCloud Alibaba 家族项目
Eureka 服务注册与发现框架介绍
Feign与OpenFeign
Feign
OpenFeign
核心特性对比
编辑
最佳实践
实现
学前准备(小白必看)
项目创建步骤详解
创建父工程(管理所有模块)
Eureka服务注册中心
服务提供者开发
服务消费者开发
全流程测试
注:
博客:
霸道流氓气质-CSDN博客
实现
学前准备(小白必看)
1. 你需要先掌握的基础
Java基础(类、接口、注解的概念)
SpringBoot简单项目搭建(会写@RestController)
HTTP协议基本了解(GET/POST请求)
项目创建步骤详解
创建父工程(管理所有模块)
IDEA-File → New → Project
选择 Maven → 勾选 Create from archetype → 选择 maven-archetype-site-simple
填写GroupId:ArtifactId:完成创建
修改pom
<packaging>pom</packaging> <!-- 注意这里是pom类型 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.18</version></parent><properties><java.version>1.8</java.version><spring-cloud.version>2021.0.8</spring-cloud.version><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
Eureka服务注册中心
在父工程上右键 → New → Module
选择Maven → 不选archetype
ArtifactId填写:eureka-server
修改pom.xml 添加依赖
<dependencies><!-- Eureka服务端依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!-- 健康检查(可选) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies>
配置文件application.yml
server:port: 8761 # Eureka默认端口eureka:instance:hostname: localhost # 主机名client:register-with-eureka: false # 不注册自己fetch-registry: false # 不获取注册表service-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ spring:application:name: eureka-server # 应用名称
启动类编写
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer // 关键注解:启用Eureka服务端功能
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}
}
启动并访问
运行启动类后,浏览器访问:http://localhost:8761
你会看到Eureka的管理界面(此时还没有服务注册)
服务提供者开发
创建service-provider模块
添加依赖
<dependencies><!-- Eureka客户端依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- Web支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
配置文件application.yml
server:port: 8081 # 服务端口spring:application:name: service-provider # 重要!这是服务名称eureka:client:service-url:defaultZone: http://localhost:8761/eureka/ # 注册到Eurekainstance:instance-id: ${spring.application.name}:${server.port} # 实例IDprefer-ip-address: true # 显示IP地址
编写业务接口
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/provider")
public class ProviderController {// 简单测试接口@GetMapping("/hello")public String hello() {return "Hello, I'm Provider Service!";}// 模拟获取用户信息@GetMapping("/user/{id}")public String getUser(@PathVariable Integer id) {return "User Info - ID: " + id + ", Name: User" + id;}
}
启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient // 启用服务发现客户端
public class ServiceProviderApplication {public static void main(String[] args) {SpringApplication.run(ServiceProviderApplication.class, args);}
}
验证注册
先启动Eureka Server
再启动Service Provider
刷新Eureka页面(http://localhost:8761),应该能看到SERVICE-PROVIDER服务
服务消费者开发
创建service-consumer模块
添加依赖
<dependencies><!-- Eureka客户端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- OpenFeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- Web支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
配置文件application.yml
server:port: 8082spring:application:name: service-consumereureka:client:service-url:defaultZone: http://localhost:8761/eureka/# Feign配置(可选)
feign:client:config:default: # 全局配置connectTimeout: 5000 # 连接超时5秒readTimeout: 5000 # 读取超时5秒
创建Feign客户端接口
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;@FeignClient(name = "service-provider") // 指定服务名称
public interface ProviderClient {// 对应provider的/hello接口@GetMapping("/provider/hello")String callHello();// 对应provider的/user/{id}接口@GetMapping("/provider/user/{id}")String getUser(@PathVariable Integer id);
}
编写消费者Controller
import com.badao.feign.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/consumer")
public class ConsumerController {@Autowiredprivate ProviderClient providerClient; // 注入Feign客户端@GetMapping("/test")public String testFeign() {return "Feign调用结果:" + providerClient.callHello();}@GetMapping("/user/{id}")public String getUser(@PathVariable Integer id) {return "通过Feign获取:" + providerClient.getUser(id);}
}
启动类(关键注解)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients // 关键!启用Feign客户端扫描
public class ServiceConsumerApplication {public static void main(String[] args) {SpringApplication.run(ServiceConsumerApplication.class, args);}
}
全流程测试
启动顺序很重要!
启动 eureka-server(端口8761)
启动 service-provider(端口8081)
启动 service-consumer(端口8082)
验证服务注册
访问 http://localhost:8761
测试接口调用
直接调用Provider:
http://localhost:8081/provider/hello
返回:Hello, I'm Provider Service!
通过Feign调用:
http://localhost:8082/consumer/test
返回:Feign调用结果:Hello, I'm Provider Service!
带参数的调用:
http://localhost:8082/consumer/user/123