SpringCloud项目开发入门教程
本文将详细介绍SpringCloud项目开发入门,涵盖SpringCloud的基本概念、优势及应用场景,快速搭建第一个SpringCloud项目,并深入讲解服务注册与发现、服务间调用与负载均衡、服务容错与熔断、配置中心及服务网关等关键组件的使用。
引入SpringCloud SpringCloud简介Spring Cloud是由Pivotal团队提供的开源框架,它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发。Spring Cloud基于Spring Boot的自动化配置,利用Spring Boot的约定优于配置的理念,为分布式系统提供了一套微服务解决方案。Spring Cloud涵盖了分布式系统的多个方面,包括服务注册与发现、配置中心、服务网关、负载均衡、服务容错与熔断等。
Spring Cloud依赖于Netflix OSS等开源组件来实现各种分布式功能。Netflix OSS是Netflix公司发布的一系列开源组件,其中包括Eureka、Ribbon、Feign、Hystrix等,这些组件为Spring Cloud提供了强大的支撑。
SpringCloud的优势及应用场景优势
- 分布式服务化:Spring Cloud可以快速构建分布式服务,简化服务间的通信。
- 服务治理:支持服务注册与发现,实现服务的动态治理。
- 负载均衡:通过Ribbon实现客户端的负载均衡。
- 服务容错:利用Hystrix实现服务的容错处理和熔断机制。
- 配置管理:通过Config组件实现配置的集中管理和动态刷新。
- API网关:通过Zuul实现API网关,提供统一的接口管理。
- 非功能服务:提供了断路器、日志监控、安全等非功能服务的支持。
应用场景
- 微服务架构:构建微服务架构,实现服务的细粒度划分。
- 云原生应用:支持云原生应用,实现服务的快速部署和弹性伸缩。
- 多环境部署:支持多环境部署(开发、测试、生产等),实现配置的动态刷新。
- 高可用性:支持服务的容错处理和负载均衡,提高系统的高可用性。
- 统一入口:通过API网关实现服务的统一入口,提供统一接口管理和权限控制。
准备工作
- 安装Java:确保已安装Java环境,并设置好JAVA_HOME环境变量。
- 安装Maven:确保已安装Maven,并设置好MAVEN_HOME环境变量。
- IDE配置:使用IDE(如IntelliJ IDEA或Eclipse)配置Maven。
- 新建Spring Boot项目:使用Spring Initializr或Maven创建一个新的Spring Boot项目。
搭建步骤
-
创建父工程(例如
spring-cloud-parent
):<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>spring-cloud-parent</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <properties> <java.version>1.8</java.version> <spring-cloud.version>2021.0.0</spring-cloud.version> </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> </project>
-
创建子工程(服务提供者)(例如
spring-cloud-provider
):<parent> <groupId>com.example</groupId> <artifactId>spring-cloud-parent</artifactId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-cloud-provider</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
- 创建子工程(服务消费者)(例如
spring-cloud-consumer
):<parent> <groupId>com.example</groupId> <artifactId>spring-cloud-parent</artifactId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-cloud-consumer</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
配置服务提供者
在服务提供者项目中,创建主类Application.java
:
package com.example.springcloudprovider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8081
spring:
application:
name: service-provider
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
实现服务提供者:
package com.example.springcloudprovider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@GetMapping("/hello")
public String hello() {
return "Hello from Service Provider";
}
}
配置服务消费者
在服务消费者项目中,创建主类Application.java
:
package com.example.springcloudconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8082
spring:
application:
name: service-consumer
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
ribbon:
eureka:
enabled: true
实现服务消费者:
package com.example.springcloudconsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired
private ServiceProviderClient serviceProviderClient;
@GetMapping("/consumer")
public String consumer() {
return serviceProviderClient.hello();
}
}
定义Feign接口
package com.example.springcloudconsumer;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
@GetMapping("/hello")
String hello();
}
启动Eureka服务注册中心
创建一个新的Spring Boot项目spring-cloud-eureka
,在主类Application.java
中启用Eureka服务:
package com.example.springcloudeureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
server:
enable-self-preservation: false
启动服务提供者和消费者
启动Eureka服务注册中心,访问http://localhost:8761
,可以看到Eureka服务注册中心已启动。
启动服务提供者,访问http://localhost:8081
,可以看到服务已注册到Eureka服务注册中心。
启动服务消费者,访问http://localhost:8082
,可以看到服务消费者已注册到Eureka服务注册中心,并能成功调用服务提供者。
原理概述
Eureka是Netflix开源的一个基于REST的分布式服务治理组件,主要提供服务注册与发现的功能。Eureka Server作为服务注册中心,接收客户端的注册信息与心跳,保存服务实例的信息,并提供查询服务列表和健康状态的功能。Eureka Client作为服务消费者,向服务注册中心注册自身信息,并通过服务注册中心获取其他服务的实例信息,实现服务间的调用。
组件介绍
-
Eureka Server:
- 服务注册中心,提供服务注册与发现的功能。
- 收集客户端注册信息,保存服务实例的信息。
- 提供查询服务列表和健康状态的功能。
- 提供服务实例的心跳机制,监控服务实例的状态。
- Eureka Client:
- 服务提供者,向服务注册中心注册自身信息。
- 服务消费者,从服务注册中心获取其他服务的实例信息,实现服务间的调用。
操作流程
- 服务提供者启动时向Eureka Server进行注册,每个实例定期通过心跳进行续约。
- 服务消费者启动时会向Eureka Server进行注册,同时会向Eureka Server获取服务实例列表。
- 服务注册中心接收服务提供者的注册信息,并保存服务实例的信息。
- 服务消费者通过服务注册中心获取服务实例列表,实现服务间的调用。
服务实例状态
- UP:服务实例正常运行。
- DOWN:服务实例停止运行。
- STARTING:服务实例正在启动。
- UNKNOWN:服务实例未知状态。
- CANCELED:服务实例被取消注册。
集群模式
Eureka Server可以配置为集群模式,支持多Eureka Server实例,通过集群模式保证服务注册中心的高可用性。
客户端配置
客户端可以通过配置文件application.yml
进行配置,例如:
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
快速搭建Eureka服务注册与发现
创建Eureka Server
创建一个新的Spring Boot项目spring-cloud-eureka
,在主类Application.java
中启用Eureka服务:
package com.example.springcloudeureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
server:
enable-self-preservation: false
启动Eureka Server
启动Eureka Server,访问http://localhost:8761
,可以看到Eureka服务注册中心已启动。
实战Eureka服务注册与发现
创建服务提供者
创建一个新的Spring Boot项目spring-cloud-provider
,在主类Application.java
中启用Eureka服务:
package com.example.springcloudprovider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8081
spring:
application:
name: service-provider
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
实现服务提供者:
package com.example.springcloudprovider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@GetMapping("/hello")
public String hello() {
return "Hello from Service Provider";
}
}
创建服务消费者
创建一个新的Spring Boot项目spring-cloud-consumer
,在主类Application.java
中启用Eureka服务:
package com.example.springcloudconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8082
spring:
application:
name: service-consumer
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
ribbon:
eureka:
enabled: true
实现服务消费者:
package com.example.springcloudconsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired
private ServiceProviderClient serviceProviderClient;
@GetMapping("/consumer")
public String consumer() {
return serviceProviderClient.hello();
}
}
定义Feign接口
package com.example.springcloudconsumer;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
@GetMapping("/hello")
String hello();
}
测试服务注册与发现
启动Eureka Server,启动服务提供者和服务消费者,访问http://localhost:8761
,可以看到服务提供者和服务消费者已注册到Eureka服务注册中心。
访问服务消费者的地址,可以看到服务消费者已成功调用服务提供者。
服务间调用与负载均衡 Ribbon与Feign的使用Ribbon简介
Ribbon是Netflix开源的一个客户端负载均衡器,它基于HTTP和TCP协议提供客户端的负载均衡。Ribbon内置了多种负载均衡策略,例如随机、轮询、最少活跃请求等,可以根据实际需求选择合适的策略。
Feign简介
Feign是Netflix开源的一个声明式Web服务客户端,它简化了HTTP请求的编写,提供了更优雅的接口定义方式。Feign内置了Ribbon的负载均衡能力,可以实现服务的负载均衡。
Ribbon与Feign的区别
-
代码编写风格:
- Ribbon需要手动编写HTTP请求代码,并通过负载均衡策略实现服务的调用。
- Feign提供了更优雅的接口定义方式,通过注解实现服务的调用。
- 使用场景:
- Ribbon适用于需要自定义HTTP请求和负载均衡策略的场景。
- Feign适用于需要声明式接口定义和内置负载均衡能力的场景。
Ribbon配置
基本配置
在服务提供者的application.yml
中配置服务提供者:
server:
port: 8081
spring:
application:
name: service-provider
在服务消费者的application.yml
中配置服务消费者:
server:
port: 8082
spring:
application:
name: service-consumer
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
ribbon:
eureka:
enabled: true
服务调用
在服务消费者中通过RestTemplate
实现服务调用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer")
public String consumer() {
return restTemplate.getForObject("http://service-provider/hello", String.class);
}
}
Feign配置
基本配置
添加Feign依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在服务消费者的主类中启用Feign:
package com.example.springcloudconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在服务消费者中定义Feign接口:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
@GetMapping("/hello")
String hello();
}
在服务消费者中实现服务调用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired
private ServiceProviderClient serviceProviderClient;
@GetMapping("/consumer")
public String consumer() {
return serviceProviderClient.hello();
}
}
实战服务调用与负载均衡
创建服务提供者
创建一个新的Spring Boot项目spring-cloud-provider
,在主类Application.java
中启用Eureka服务:
package com.example.springcloudprovider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8081
spring:
application:
name: service-provider
实现服务提供者:
package com.example.springcloudprovider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@GetMapping("/hello")
public String hello() {
return "Hello from Service Provider";
}
}
创建服务消费者
创建一个新的Spring Boot项目spring-cloud-consumer
,在主类Application.java
中启用Eureka服务和Feign:
package com.example.springcloudconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8082
spring:
application:
name: service-consumer
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
ribbon:
eureka:
enabled: true
在服务消费者中定义Feign接口:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
@GetMapping("/hello")
String hello();
}
在服务消费者中实现服务调用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired
private ServiceProviderClient serviceProviderClient;
@GetMapping("/consumer")
public String consumer() {
return serviceProviderClient.hello();
}
}
测试服务调用与负载均衡
启动Eureka Server,启动服务提供者和服务消费者,访问http://localhost:8082/consumer
,可以看到服务消费者成功调用了服务提供者。
什么是Hystrix
Hystrix是Netflix开源的一个分布式系统的服务容错框架,它提供了断路器、隔离服务请求、缓存响应等机制,用于提高系统的容错性。
工作原理
Hystrix通过断路器机制实现服务的容错处理。断路器是一种状态机,有三种状态:
- 关闭:服务请求正常,断路器处于关闭状态。
- 打开:服务请求失败,断路器处于打开状态,拒绝服务请求。
- 半开:服务请求恢复,断路器处于半开状态,尝试服务请求。
当断路器处于打开状态时,服务请求会被拒绝,从而避免服务请求的失败雪崩效应。Hystrix还提供了隔离机制,将服务请求隔离到单独的线程池中执行,避免服务请求的阻塞。
断路器状态切换
断路器状态切换的逻辑如下:
- 关闭状态:服务请求正常,断路器处于关闭状态。
- 打开状态:当服务请求失败的比例超过阈值时,断路器会切换到打开状态,拒绝服务请求。
- 半开状态:当服务请求恢复正常时,断路器会切换到半开状态,尝试服务请求。
- 关闭状态:当服务请求成功时,断路器会切换到关闭状态。
配置参数
Hystrix提供了多种配置参数,例如:
- 命令超时:设置命令超时时间。
- 失败阈值:设置失败阈值,超过阈值时断路器切换到打开状态。
- 恢复阈值:设置恢复阈值,超过阈值时断路器切换到半开状态。
- 隔离策略:设置隔离策略,例如隔离到单独的线程池中。
实战服务容错与熔断机制
创建服务提供者
创建一个新的Spring Boot项目spring-cloud-provider
,在主类Application.java
中启用Eureka服务:
package com.example.springcloudprovider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8081
spring:
application:
name: service-provider
实现服务提供者:
package com.example.springcloudprovider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@GetMapping("/hello")
public String hello() {
return "Hello from Service Provider";
}
}
创建服务消费者
创建一个新的Spring Boot项目spring-cloud-consumer
,在主类Application.java
中启用Eureka服务和Feign:
package com.example.springcloudconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8082
spring:
application:
name: service-consumer
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
ribbon:
eureka:
enabled: true
定义Feign接口:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
@GetMapping("/hello")
String hello();
}
在服务消费者中实现服务调用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController {
@Autowired
private ServiceProviderClient serviceProviderClient;
@GetMapping("/consumer")
public String consumer() {
return serviceProviderClient.hello();
}
}
添加Hystrix熔断机制
在服务消费者中添加Hystrix熔断机制:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@FeignClient(name = "service-provider", fallback = ServiceProviderFallback.class)
public interface ServiceProviderClient {
@GetMapping("/hello")
String hello();
}
定义熔断类:
import org.springframework.stereotype.Component;
@Component
public class ServiceProviderFallback implements ServiceProviderClient {
@Override
public String hello() {
return "Fallback: Service Provider is unavailable";
}
}
测试服务容错与熔断机制
启动Eureka Server,启动服务提供者和服务消费者,访问http://localhost:8082/consumer
,可以看到服务消费者成功调用了服务提供者。
停止服务提供者,访问http://localhost:8082/consumer
,可以看到服务消费者返回熔断类的错误信息。
Config简介
Spring Cloud Config是Spring Cloud提供的一套配置管理工具,支持对配置文件进行集中管理和动态刷新。Spring Cloud Config主要包括Config Server和Config Client两部分,Config Server作为配置中心,提供配置文件的访问接口;Config Client作为客户端,从Config Server获取配置文件。
配置中心架构
-
Config Server:
- 配置中心,提供配置文件的访问接口。
- 支持多种存储方式,例如本地文件、Git、SVN等。
- 支持配置文件的版本控制和动态刷新。
- Config Client:
- 客户端,从Config Server获取配置文件。
- 支持配置文件的多环境部署,例如开发、测试、生产等。
- 支持配置文件的动态刷新。
配置中心使用步骤
- 创建Config Server:
- 通过Spring Boot创建一个新的项目
spring-cloud-config-server
。 - 添加依赖
spring-cloud-starter-config
。 - 配置文件
bootstrap.yml
中指定配置文件的存储方式,例如本地文件、Git等。 - 启动Config Server,提供配置文件的访问接口。
- 通过Spring Boot创建一个新的项目
- 创建Config Client:
- 通过Spring Boot创建一个新的项目
spring-cloud-config-client
。 - 添加依赖
spring-cloud-starter-config
。 - 配置文件
bootstrap.yml
中指定Config Server的地址。 - 启动Config Client,从Config Server获取配置文件。
- 通过Spring Boot创建一个新的项目
实战动态刷新配置功能
创建Config Server
创建一个新的Spring Boot项目spring-cloud-config-server
,在主类Application.java
中启用Config Server:
package com.example.springcloudconfigserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件bootstrap.yml
:
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/example/config-repo
username: your-username
password: your-password
创建Config Client
创建一个新的Spring Boot项目spring-cloud-config-client
,在主类Application.java
中启用Config Client:
package com.example.springcloudconfigclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件bootstrap.yml
:
spring:
application:
name: service-client
cloud:
config:
server:
uri: http://localhost:8888
实现动态刷新配置功能
在Config Client中实现动态刷新配置功能:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class ConfigController {
@Value("${spring.application.name}")
private String appName;
@GetMapping("/config")
public String getConfig() {
return "Current App Name: " + appName;
}
}
测试动态刷新配置功能
启动Config Server,启动Config Client,访问http://localhost:8080/config
,可以看到Config Client获取到Config Server的配置文件。
修改Config Server的配置文件,刷新Config Client的配置,访问http://localhost:8080/config
,可以看到Config Client获取到最新的配置文件。
Zuul简介
Zuul是Netflix开源的一个API网关,主要用于提供动态路由、服务代理、数据过滤等功能。Zuul提供了多种过滤器,可以实现请求路由、请求过滤、请求转发等功能。
网关架构
-
路由过滤器:
- 路由过滤器用于实现路由功能,将请求路由到对应的服务实例。
- 路由过滤器可以通过路径匹配、请求头匹配等方式实现路由规则。
-
预处理过滤器:
- 预处理过滤器用于实现请求的预处理功能,例如身份验证、请求日志等。
- 预处理过滤器可以在请求到达服务实例之前执行。
- 后处理过滤器:
- 后处理过滤器用于实现请求的后处理功能,例如响应日志、响应缓存等。
- 后处理过滤器可以在请求到达服务实例之后执行。
网关使用步骤
- 创建Zuul网关:
- 通过Spring Boot创建一个新的项目
spring-cloud-zuul-gateway
。 - 添加依赖
spring-cloud-starter-zuul
。 - 配置文件
application.yml
中指定路由规则。 - 启动Zuul网关,实现服务的统一入口。
- 通过Spring Boot创建一个新的项目
- 创建服务提供者和消费者:
- 创建服务提供者和消费者,实现服务的提供和消费。
- 通过Zuul网关调用服务提供者和服务消费者。
Zuul过滤器
路由过滤器
路由过滤器可以通过路径匹配、请求头匹配等方式实现路由规则。例如:
zuul:
routes:
service-provider:
path: /service-provider/**
serviceId: service-provider
service-consumer:
path: /service-consumer/**
serviceId: service-consumer
前置过滤器
前置过滤器可以在请求到达服务实例之前执行。例如:
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;
@Component
public class PreFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulResponseHeader("X-Filter-Pre", "PreFilter");
return null;
}
}
后置过滤器
后置过滤器可以在请求到达服务实例之后执行。例如:
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;
@Component
public class PostFilter extends ZuulFilter {
@Override
public String filterType() {
return "post";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulResponseHeader("X-Filter-Post", "PostFilter");
return null;
}
}
实战API网关的创建与使用
创建Zuul网关
创建一个新的Spring Boot项目spring-cloud-zuul-gateway
,在主类Application.java
中启用Zuul网关:
package com.example.springcloudzuulgateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
添加配置文件application.yml
:
server:
port: 8080
spring:
application:
name: zuul-gateway
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
zuul:
routes:
service-provider:
path: /service-provider/**
serviceId: service-provider
service-consumer:
path: /service-consumer/**
serviceId: service-consumer
创建服务提供者和消费者
创建服务提供者和消费者,实现服务的提供和消费。配置文件application.yml
中指定服务名:
spring:
application:
name: service-provider
实现服务提供者:
package com.example.springcloudprovider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
@GetMapping("/hello")
public String hello() {
return "Hello from Service Provider";
}
}
实现服务消费者:
package com.example.springcloudconsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@FeignClient(name = "service-provider")
public interface ServiceProviderClient {
@GetMapping("/hello")
String hello();
}
@RestController
public class ConsumerController {
@Autowired
private ServiceProviderClient serviceProviderClient;
@GetMapping("/consumer")
public String consumer() {
return serviceProviderClient.hello();
}
}
测试API网关的创建与使用
启动Eureka Server,启动服务提供者和服务消费者,启动Zuul网关,访问http://localhost:8080/service-provider/hello
,可以看到服务提供者成功提供服务。
访问http://localhost:8080/service-consumer/consumer
,可以看到服务消费者成功调用服务提供者。
共同学习,写下你的评论
评论加载中...
作者其他优质文章