要深入学习Spring Cloud框架,你需要系统地掌握其核心组件和概念,并了解如何在实际项目中应用这些知识。以下是一些关键的学习点和相应的学习内容:
一共分为10个模块包括:
1、微服务架构基础:
- 理解微服务架构的概念和优势。
- 学习单体架构向微服务架构演进的过程。
- 掌握微服务架构的特点,如服务拆分、自治性、去中心化等。
微服务架构是一种软件开发风格,它鼓励将大型复杂软件应用分解为一组小型、松耦合的服务。这些服务围绕特定的业务功能构建,并通过轻量级的通信机制(通常是HTTP RESTful API)进行交互。微服务架构的主要优势包括:
1. 模块化:微服务架构通过将应用程序分解为独立的模块,提高了代码的可读性和可维护性。每个服务负责一个特定的业务功能,使得开发和调试变得更加容易。
2. 可扩展性:由于每个服务都是独立的,可以针对特定服务的需求进行扩展,而不影响整个系统。这使得系统能够更灵活地应对不同的负载需求。
3. 敏捷性:微服务架构支持快速迭代和部署。小型、专注的服务可以独立开发和部署,使得新功能和更新可以快速推向生产环境。
4. 技术多样性:在微服务架构中,每个服务可以选择最适合其需求的技术栈,包括编程语言、数据库和工具。这种多样性鼓励技术创新和团队的专业化。
5. 容错性:微服务架构通过隔离失败来提高系统的可靠性。如果一个服务失败,它不会导致整个应用程序崩溃,而是可以被限制在局部范围内。
从单体架构向微服务架构演进的过程通常包括以下步骤:
1. 服务识别:识别和定义应用程序中可以作为独立服务的业务功能。
2. 服务拆分:将这些功能从单体应用中拆分出来,并为每个功能创建独立的服务。
3. 定义接口:为每个服务定义清晰的API,确保服务之间的通信高效且可靠。
4. 独立部署:确保每个服务可以独立部署和运行,不依赖于其他服务。
5. 持续集成和持续部署(CI/CD):建立自动化的构建、测试和部署流程,以支持快速迭代和高质量的软件交付。
微服务架构的特点还包括服务自治性,即每个服务都拥有自己的生命周期,可以独立于其他服务进行开发、部署和扩展。此外,去中心化意味着没有中央控制点,服务之间的交互基于分布式的决策和协调机制。这些特点共同促进了系统的灵活性、可维护性和可扩展性。
2、Spring Cloud核心组件:
- 学习服务发现与注册中心,如Eureka、Nacos。
- 掌握配置中心的使用,如Spring Cloud Config。
- 理解服务网关的作用,学习Zuul和Spring Cloud Gateway。
- 学习负载均衡和断路器模式,掌握Ribbon和Hystrix的使用。
- 了解消息驱动的微服务,学习Spring Cloud Stream。
2.1、服务发现与注册中心:
- Eureka:Netflix开源的服务发现组件,主要用于服务注册和服务发现。在微服务架构中,各个服务实例会向Eureka Server注册自己的地址,并可以从中查询其他服务的地址来进行远程调用。
- Nacos:一个更全面的服务发现和配置管理平台,它集成了服务发现、配置管理和服务健康检查等功能,适用于构建云原生应用。
下面是V哥使用Spring Cloud Netflix Eureka的服务发现与注册中心的代码示例和具体解释。
Eureka Server
首先,我们需要创建一个Eureka Server服务注册中心。
1. 添加依赖:
在pom.xml文件中添加Eureka Server的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<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>
2. 配置Eureka Server:
在application.yml文件中配置Eureka Server:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${
eureka.instance.hostname}:${
server.port}/eureka/
3. 启用Eureka Server:
在主类上添加@EnableEurekaServer注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Eureka Client
接下来,我们需要创建一个Eureka Client服务,该服务将注册到Eureka Server。
1. 添加依赖:
在pom.xml文件中添加Eureka Client的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2. 配置Eureka Client:
在application.yml文件中配置Eureka Client:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
3. 启用Eureka Client:
在主类上添加@EnableDiscoveryClient注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
解释
在Eureka Server中,@EnableEurekaServer注解启用了Eureka的服务端功能。配置文件中指定了服务端口和Eureka Server的相关配置,例如不注册自己到Eureka。
在Eureka Client中,@EnableDiscoveryClient注解启用了服务发现客户端功能。配置文件中指定了Eureka Server的地址,这样客户端就可以注册到Eureka Server并提供服务发现功能。
当Eureka Client启动时,它会向Eureka Server注册自己的服务实例,并可以从Eureka Server获取其他服务的实例信息。这样,服务之间的调用就可以通过Eureka进行服务发现和负载均衡。
这个简单的例子展示了如何使用Spring Cloud Netflix Eureka来实现服务发现与注册中心。在实际应用中,可能还需要配置更多的Eureka Server实例来实现高可用,以及配置服务的健康检查等高级功能。
下面是V哥用Nacos作为服务发现与注册中心的代码示例和具体解释。
Nacos Server
首先,您需要安装和运行Nacos Server。Nacos提供了开箱即用的服务器,您可以从Nacos的官方网站下载最新的release版本,然后按照官方文档启动服务器。
Nacos Client
接下来,我们需要创建一个Nacos Client服务,该服务将注册到Nacos Server。
- 添加依赖:
在pom.xml文件中添加Nacos Discovery Client的依赖:
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 配置Nacos Client:
在application.yml文件中配置Nacos Client:
spring:
application:
name: my-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
- 启用Nacos Client:
在主类上添加@EnableDiscoveryClient注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosClientApplication {
public static void main(String[] args) {
SpringApplication.run(NacosClientApplication.class, args);
}
}
解释
在Nacos Client中,@EnableDiscoveryClient注解启用了服务发现客户端功能。配置文件中指定了Nacos Server的地址,这样客户端就可以注册到Nacos Server并提供服务发现功能。
当Nacos Client启动时,它会向Nacos Server注册自己的服务实例,并可以从Nacos Server获取其他服务的实例信息。这样,服务之间的调用就可以通过Nacos进行服务发现和负载均衡。
Nacos不仅支持服务发现和注册,还提供了动态配置服务,可以在不需要重启微服务的情况下动态刷新配置。
这个简单的例子展示了如何使用Nacos作为服务发现与注册中心。在实际应用中,您可能需要配置更多的Nacos Server实例来实现高可用,以及配置服务的健康检查等高级功能。
2.2、配置中心:
- Spring Cloud Config:提供服务器和客户端支持,用于集中管理应用程序各个环境下的配置。支持使用Git或文件系统作为配置存储,可以实现配置的热更新。
Spring Cloud Config 提供了服务端和客户端的支持,允许您集中管理应用程序在多个环境中的配置。下面我将提供一个使用Spring Cloud Config的代码示例和具体解释。
Spring Cloud Config Server
首先,我们需要创建一个Spring Cloud Config Server来提供配置服务。
- 添加依赖:
在pom.xml文件中添加Spring Cloud Config Server的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<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>
- 配置Config Server:
在application.yml文件中配置Config Server:
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/yourusername/config-repo.git
search-paths: config-repo
- 启用Config Server:
在主类上添加@EnableConfigServer注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
Spring Cloud Config Client
接下来,我们需要创建一个Spring Cloud Config Client来使用配置服务。
- 添加依赖:
在pom.xml文件中添加Spring Cloud Config Client的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
- 配置Config Client:
在bootstrap.yml文件中配置Config Client:
spring:
cloud:
config:
uri: http://localhost:8888
name: my-service
profile: development
label: main
- 使用配置:
在应用程序中,您可以通过@Value注解或Environment对象来使用配置属性:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigClientController {
@Value("${my.config.property}")
private String configProperty;
@GetMapping("/config")
public String getConfigProperty() {
return configProperty;
}
}
解释
在Config Server中,@EnableConfigServer注解启用了配置服务器的功能。配置文件中指定了配置文件存储在Git仓库中,并设置了搜索路径。
在Config Client中,bootstrap.yml文件中指定了Config Server的地址,以及客户端的名称、配置文件的环境和分支。客户端在启动时会从配置服务器获取配置信息。
当Git仓库中的配置发生变化时,您可以通过向Config Client发送POST请求到/actuator/refresh端点来刷新配置。
这个简单的例子展示了如何使用Spring Cloud Config来集中管理配置。实际应用中,配置可能会更复杂,包括多个环境、多个配置文件和加密解密等功能。
2.3、服务网关:
- Zuul:Netflix开源的微服务网关,提供动态路由、监控、弹性、安全等边缘服务功能。Zuul的主要作用是路由用户的请求到不同的微服务上,并提供过滤功能。
- Spring Cloud Gateway:Spring Cloud的官方网关,用于构建基于Spring Framework的API网关服务。它支持路由匹配、断言和过滤等。
服务网关是微服务架构中的一个关键组件,它负责处理外部请求并将其路由到相应的微服务上。下面我将提供使用Zuul和Spring Cloud Gateway的代码示例和具体解释。
Zuul网关
- 添加依赖:
在pom.xml文件中添加Zuul的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
<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>
- 配置Zuul:
在application.yml文件中配置Zuul:
server:
port: 8080
zuul:
routes:
my-service:
path: /my-service/**
serviceId: my-service
- 启用Zuul:
在主类上添加@EnableZuulProxy注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class ZuulGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
}
Spring Cloud Gateway
- 添加依赖:
在pom.xml文件中添加Spring Cloud Gateway的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
- 配置Spring Cloud Gateway:
在application.yml文件中配置Spring Cloud Gateway:
server:
port: 8080
spring:
cloud:
gateway:
routes:
- id: my-service
uri: lb://my-service
predicates:
- Path=/my-service/**
- 启用Spring Cloud Gateway:
在主类上添加@EnableGateway注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.config.GatewayAutoConfiguration;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
解释
在Zuul网关中,@EnableZuulProxy注解启用了Zuul的代理功能。配置文件中定义了路由规则,将匹配特定路径的请求转发到对应的服务ID。
在Spring Cloud Gateway中,配置文件中定义了路由规则,包括路由ID、目标URI和谓词。Spring Cloud Gateway使用Reactor Netty作为底层的网络引擎,并且支持异步非阻塞的API。
这两个网关都支持动态路由、监控、弹性和安全等边缘服务功能。它们可以处理跨域问题、负载均衡、请求转发、路由过滤等。
这个简单的例子展示了如何使用Zuul和Spring Cloud Gateway来构建服务网关。在实际应用中,您可能需要配置更多的路由规则和过滤器,以及集成安全认证等高级功能。
2.4、负载均衡和断路器:
- Ribbon:Netflix开源的客户端负载均衡器,它可以在客户端配置ribbonServerList(服务端列表),然后轮询请求以实现负载均衡。
- Hystrix:Netflix开源的断路器组件,用于处理分布式系统的延迟和容错。Hystrix通过隔离服务之间的依赖关系,阻止级联失败,并提供回退机制,以提高系统的整体弹性。
负载均衡和断路器是微服务架构中确保系统高可用和容错的重要组件。下面我将提供使用Ribbon和Hystrix的代码示例和具体解释。
Ribbon负载均衡
Ribbon通常与Eureka或Consul等服务发现组件一起使用,以实现客户端负载均衡。
- 添加依赖:
在pom.xml文件中添加Ribbon的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!-- 添加Eureka Client依赖以实现服务发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<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>
- 配置Ribbon:
在application.yml文件中配置Ribbon和Eureka:
server:
port: 8080
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
ribbon:
eureka:
enabled: true
- 使用Ribbon:
在Java配置类中,使用@LoadBalanced注解创建一个RestTemplate bean:
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RibbonConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
在服务类中,使用RestTemplate来调用其他服务:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class MyService {
private final RestTemplate restTemplate;
@Autowired
public MyService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public String callOtherService() {
// 使用服务ID调用其他服务
return restTemplate.getForObject("http://my-service/endpoint", String.class);
}
}
Hystrix断路器
- 添加依赖:
在pom.xml文件中添加Hystrix的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
- 启用Hystrix:
在主类上添加@EnableCircuitBreaker注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@SpringBootApplication
@EnableHystrix
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
- 使用Hystrix:
在服务类中,使用@HystrixCommand注解定义断路器的行为:
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class MyService {
private final RestTemplate restTemplate;
@Autowired
public MyService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@HystrixCommand(fallbackMethod = "defaultCall")
public String callOtherService() {
// 使用服务ID调用其他服务
return restTemplate.getForObject("http://my-service/endpoint", String.class);
}
public String defaultCall() {
// 断路器开启时的回退逻辑
return "Fallback response";
}
}
解释
在Ribbon中,@LoadBalanced注解启用了客户端负载均衡功能。Ribbon会自动从Eureka获取服务实例列表,并实现轮询负载均衡。
在Hystrix中,@HystrixCommand注解用于定义断路器的行为,包括回退方法。当调用失败次数超过阈值时,Hystrix会开启断路器,阻止进一步的调用,并直接调用回退逻辑。
这两个组件共同确保了微服务之间的调用更加健壮和可靠。Ribbon处理负载均衡,而Hystrix处理服务调用的容错,以提高系统的整体弹性。
在实际应用中,Ribbon和Hystrix通常与Spring Cloud的其他组件结合使用,如Eureka用于服务发现,Spring Cloud Gateway或Zuul用于服务网关,以及Spring Cloud Config用于配置管理。这些组件共同构成了一个完整的微服务架构解决方案。
Ribbon和Hystrix的配置可以通过属性文件进行详细配置,例如设置超时时间、重试次数、线程池大小等。这些配置可以根据实际业务需求进行调整,以达到最佳的性能和可靠性。
此外,Spring Cloud还提供了Hystrix Dashboard和Turbine,用于监控Hystrix断路器的状态和性能。Hystrix Dashboard提供了一个可视化的界面,用于展示每个Hystrix命令的请求次数、失败次数、延迟等信息。Turbine则用于聚合多个微服务的Hystrix数据,以便在Hystrix Dashboard中统一查看。
以下是一个简单的Hystrix Dashboard和Turbine的配置示例:
Hystrix Dashboard
- 添加依赖:
在pom.xml文件中添加Hystrix Dashboard的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
</dependencies>
- 启用Hystrix Dashboard:
在主类上添加@EnableHystrixDashboard注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardApplication.class, args);
}
}
- 访问Hystrix Dashboard:
启动应用后,访问http://localhost:8080/hystrix即可看到Hystrix Dashboard。
Turbine
- 添加依赖:
在pom.xml文件中添加Turbine的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
</dependencies>
- 配置Turbine:
在application.yml文件中配置Turbine:
turbine:
aggregator:
clusterConfig: DEFAULT
appConfig: my-service
- 启用Turbine:
在主类上添加@EnableTurbine注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@SpringBootApplication
@EnableTurbine
public class TurbineApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineApplication.class, args);
}
}
- 访问Turbine Stream:
启动应用后,访问http://localhost:8080/turbine.stream即可获取Turbine聚合的Hystrix数据流。
通过这些工具,开发者和运维人员可以实时监控微服务的健康状态和性能,及时发现问题并进行调整。
2.5、消息驱动的微服务:
- Spring Cloud Stream:一个构建消息驱动微服务的框架。它为消息中间件产品提供了可配置的绑定,如RabbitMQ、Kafka等,使得开发者无需关心消息中间件的细节,可以专注于业务逻辑。
Spring Cloud Stream 是一个用于构建消息驱动微服务的框架,它提供了对消息中间件产品如 RabbitMQ、Kafka 的可配置绑定。这使得开发者可以专注于业务逻辑,而无需关心消息中间件的具体细节。下面我将提供一个使用 Spring Cloud Stream 的代码示例和具体解释。
Spring Cloud Stream 示例
- 添加依赖:
在 pom.xml 文件中添加 Spring Cloud Stream 的依赖,以及选择一个消息中间件实现,比如 RabbitMQ:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
</dependencies>
<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>
- 配置 Spring Cloud Stream:
在 application.yml 文件中配置 Spring Cloud Stream,定义输入和输出通道:
spring:
cloud:
stream:
bindings:
output:
destination: my-messages
content-type: text/plain
input:
destination: my-messages
content-type: text/plain
rabbitmq:
host: localhost
port: 5672
- 使用 Spring Cloud Stream:
在 Java 代码中,使用 @EnableBinding 注解来指定要使用的通道,并使用 @StreamListener 来处理消息:
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.core.MessageSource;
import org.springframework.messaging.support.GenericMessage;
@EnableBinding({
Source.class, Sink.class})
public class StreamApplication {
@StreamListener(Sink.INPUT)
public void handle(String message) {
System.out.println("Received message: " + message);
}
@InboundChannelAdapter(value = Source.OUTPUT, poller = @Poller(fixedDelay = "1000"))
public MessageSource<String> produceMessage() {
return () -> new GenericMessage<>("Hello, World!");
}
public static void main(String[] args) {
SpringApplication.run(StreamApplication.class, args);
}
}
解释
在 Spring Cloud Stream 中,@EnableBinding 注解用于指定要使用的消息通道。在本例中,我们使用了 Source 和 Sink 接口,它们分别代表输出和输入通道。
@StreamListener 注解用于处理输入通道接收到的消息。在本例中,我们定义了一个方法来打印接收到的消息。
@InboundChannelAdapter 注解用于定义一个消息源,它定期生成消息并将其发送到输出通道。在本例中,我们创建了一个简单的消息源,每隔一秒发送一条 “Hello, World!” 消息。
通过这种方式,Spring Cloud Stream 允许开发者以统一的方式处理不同消息中间件的消息,而无需关注底层的实现细节。这使得微服务可以轻松地与各种消息系统集成,并且可以轻松地切换消息中间件,而不会影响到业务逻辑。
3、服务间通信:
- 掌握Feign的使用,了解其声明式Web服务客户端的原理。
- 学习Dubbo和其他RPC框架在Spring Cloud中的应用。
服务间通信是微服务架构中的关键组成部分,它涉及到服务之间的调用和数据传输。下面我将介绍Feign和Dubbo这两种在Spring Cloud中常用的服务间通信方式。
Feign
Feign是一个声明式的Web服务客户端,它使得编写Web服务客户端变得更加简单。Feign客户端允许你通过编写简单的接口和注解来定义远程调用。
示例
- 添加依赖:
在pom.xml文件中添加Feign的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
- 配置Feign:
在application.yml文件中配置Feign:
feign:
client:
config:
default:
loggerLevel: full
- 定义Feign客户端接口:
创建一个Feign客户端接口,使用@FeignClient注解来指定服务名称:
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("my-service")
public interface MyServiceClient {
@GetMapping("/hello/{name}")
String hello(@PathVariable String name);
}
- 使用Feign客户端:
在服务类中,注入Feign客户端接口并调用远程服务:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Autowired
private MyServiceClient myServiceClient;
public String callOtherService() {
return myServiceClient.hello("World");
}
}
- 原理
Feign客户端的原理是基于Spring MVC的,它通过代理的方式将HTTP请求转换为客户端的调用。当调用Feign客户端接口时,Feign会自动生成一个代理类,这个代理类实现了Feign客户端接口。在代理类中,Feign会处理HTTP请求,包括构建请求、发送请求和解析响应。
Dubbo
Dubbo是一个高性能的Java RPC框架,它提供了服务发现、负载均衡、容错和高可用等功能。Dubbo可以与Spring Cloud无缝集成,使得在Spring Cloud中使用Dubbo变得简单。
示例
- 添加依赖:
在pom.xml文件中添加Dubbo的依赖:
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.spring.boot.starter.version}</version>
</dependency>
</dependencies>
- 配置Dubbo:
在application.yml文件中配置Dubbo:
dubbo:
application:
name: my-service
registry:
address: N/A # 本地注册,无需注册中心
scan:
base-packages: com.example.myservice
- 使用Dubbo服务:
在服务类中,注入Dubbo服务并调用远程服务:
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@DubboReference
private OtherService otherService;
public String callOtherService() {
return otherService.sayHello("World");
}
}
- 原理
Dubbo的原理是基于Java反射和动态代理。当调用Dubbo服务时,Dubbo会根据服务接口生成一个代理类,这个代理类实现了服务接口。在代理类中,Dubbo会处理远程调用,包括构建请求、发送请求和解析响应。
总结
Feign和Dubbo都是Spring Cloud中常用的服务间通信方式。Feign基于Spring MVC,提供了一种声明式的Web服务客户端方式,而Dubbo则是一个高性能的Java RPC框架,提供了服务发现、负载均衡、容错和高可用等功能。
在实际应用中,可以根据具体需求选择使用Feign或Dubbo。如果服务之间的调用相对简单,可以使用Feign来简化开发。如果需要更强大的功能,如服务治理、分布式事务等,可以使用Dubbo来构建更健壮的微服务架构。
4、分布式系统模式:
- 学习分布式系统中常见的模式,如API网关、断路器、配置管理等。
- 掌握Spring Cloud如何实现这些模式。
分布式系统模式是构建微服务架构时需要遵循的一些最佳实践和设计模式。下面我将介绍几种常见的分布式系统模式,以及Spring Cloud如何实现这些模式。
- API网关
API网关是微服务架构中的一个关键组件,它负责处理外部请求并将其路由到相应的微服务上。API网关还可以提供安全、监控、限流、日志聚合等功能。
Spring Cloud实现:
- Spring Cloud Gateway:Spring Cloud的官方网关,用于构建基于Spring Framework的API网关服务。它支持路由匹配、断言和过滤等。
- Zuul:Netflix开源的微服务网关,提供动态路由、监控、弹性、安全等边缘服务功能。
- 断路器
断路器模式用于处理分布式系统的延迟和容错。Hystrix是Netflix开源的一个断路器组件,用于隔离服务之间的依赖关系,阻止级联失败,并提供回退机制。
Spring Cloud实现:
- Hystrix:通过@HystrixCommand注解来定义断路器的行为,包括回退方法。当调用失败次数超过阈值时,Hystrix会开启断路器,阻止进一步的调用,并直接调用回退逻辑。
- 配置管理
配置管理是分布式系统中非常重要的一部分,它允许在运行时动态地更新应用程序的配置。
Spring Cloud实现:
- Spring Cloud Config:提供服务器和客户端支持,用于集中管理应用程序各个环境下的配置。支持使用Git或文件系统作为配置存储,可以实现配置的热更新。
- 服务发现与注册
服务发现与注册是微服务架构中的一个核心概念,它允许服务实例自动注册到注册中心,并允许其他服务实例发现和调用这些服务。
Spring Cloud实现:
- Eureka:Netflix开源的服务发现组件,主要用于服务注册和服务发现。
- Consul:一个开源的分布式系统协调服务,支持服务发现、配置管理和键值存储。
- Nacos:一个更全面的服务发现和配置管理平台,它集成了服务发现、配置管理和服务健康检查等功能。
- 分布式跟踪
分布式跟踪可以帮助我们追踪分布式系统中各个组件之间的交互,以便于诊断和解决问题。
Spring Cloud实现:
- Spring Cloud Sleuth:提供了一种简单的分布式跟踪解决方案,可以与Zipkin、Jaeger等分布式跟踪系统集成。
- 分布式锁
分布式锁用于确保在分布式系统中,多个服务实例不会同时修改共享资源。
Spring Cloud实现:
- Redisson:一个基于Redis的Java客户端,提供了分布式锁、队列、计数器等功能。
- 分布式缓存
分布式缓存用于提高系统性能,减少对数据库的访问。
Spring Cloud实现:
- Ehcache:一个流行的开源Java分布式缓存框架。
- Redis:一个开源的、高性能的键值对存储系统,常用于缓存和消息队列。
- 分布式事务
分布式事务用于确保分布式系统中多个服务之间的操作要么全部成功,要么全部失败。
Spring Cloud实现:
- Seata:一个开源的分布式事务解决方案,可以与Spring Cloud无缝集成。
这些分布式系统模式是构建微服务架构时需要考虑的关键方面。通过使用Spring Cloud提供的各种组件,可以简化实现这些模式的过程,并提高微服务架构的健壮性和可维护性。
5、Spring Boot基础:
- 由于Spring Cloud基于Spring Boot,因此需要扎实的Spring Boot基础。
- 学习Spring Boot的自动配置、起步依赖和嵌入式服务器的使用。
Spring Boot是基于Spring框架的一个开源的Java平台,它旨在简化新Spring应用的初始搭建以及开发过程。由于Spring Cloud是基于Spring Boot构建的,因此对Spring Boot的深入理解是使用Spring Cloud的基础。下面我将介绍Spring Boot的一些基本概念和特性。
- 自动配置
Spring Boot的一个主要特点是它的自动配置能力。Spring Boot能够根据添加的依赖自动配置Spring应用程序。例如,如果你添加了Spring Web的依赖,它会自动配置嵌入式Tomcat服务器,并添加Spring MVC相关的Bean。
- 起步依赖
Spring Boot使用起步依赖(Spring Starter)来简化依赖管理。每个起步依赖都是一个Maven或Gradle项目,它包含了所有必需的依赖和版本。通过添加起步依赖,你可以快速地构建一个包含Spring应用程序所需所有依赖的构建文件。
- 嵌入式服务器
Spring Boot使用嵌入式服务器来简化Web应用的部署。这意味着你不需要将应用程序打包成WAR文件,也不需要部署到外部Web服务器。Spring Boot支持多种嵌入式服务器,如Tomcat、Jetty和Undertow。
- 示例
下面是一个简单的Spring Boot应用程序的示例,它使用了Spring Web起步依赖,并且使用嵌入式Tomcat服务器:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class SpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication.class, args);
}
@RestController
public class MyController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
}
在这个示例中,我们定义了一个简单的@RestController,它处理/hello路径的GET请求。当我们运行这个应用程序时,它会自动配置嵌入式Tomcat服务器,并且提供http://localhost:8080/hello的访问点。
通过学习Spring Boot的自动配置、起步依赖和嵌入式服务器的使用,你可以更轻松地构建和管理Spring应用程序。这些特性是Spring Boot的核心优势,也是使用Spring Cloud的基础。
6、安全性和认证:
- 学习如何在微服务架构中实现安全控制,掌握Spring Security的应用。
在微服务架构中,安全性是一个关键的考虑因素,因为每个服务都可能暴露其API以供外部访问。Spring Cloud提供了多种方式来实现安全性,其中最常用的是Spring Security。
- Spring Security简介
Spring Security是一个强大且灵活的框架,用于保护基于Spring的应用程序。它提供了认证(Authentication)、授权(Authorization)、会话管理、密码编码器等功能。
- 在微服务中使用Spring Security
在微服务架构中,通常会有一个单独的安全服务,它负责处理所有的认证和授权逻辑。其他服务可以通过REST API调用这个安全服务来获取认证信息。
示例
添加依赖:
在pom.xml文件中添加Spring Security的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
- 配置Spring Security:
在application.yml文件中配置Spring Security:
spring:
security:
user:
name: user
password: password
- 使用Spring Security:
在Java代码中,使用@EnableWebSecurity注解来启用Spring Security,并定义认证逻辑:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
在这个示例中,我们配置了Spring Security来保护所有路径,除了/public/**
,这些路径对所有人开放。其他路径需要认证。我们还配置了表单登录页面为/login。
- 微服务中的认证逻辑
在微服务架构中,认证逻辑通常由一个专门的安全服务来处理。这个服务可能会使用OAuth 2.0、JWT(JSON Web Tokens)或其他认证机制。
示例(使用JWT)
添加依赖:
在pom.xml文件中添加JWT依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
生成和验证JWT:
在Java代码中,使用JJWT库来生成和验证JWT:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
public class JwtUtil {
private static final String SECRET_KEY = "mySecretKey";
public static String generateJwt(UserDetails userDetails) {
return Jwts.builder()
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 3600000))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
public static String getUsernameFromJwt(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
在这个示例中,我们定义了一个JwtUtil
类,它包含了生成和验证JWT的方法。在认证逻辑中,我们使用这个类来生成JWT,并在用户登录时将JWT作为认证令牌存储。
- 微服务中的授权逻辑
授权逻辑通常与认证逻辑结合在一起处理。在微服务架构中,授权可能涉及检查用户的角色或权限,以确定他们是否有权访问特定的资源。
- 总结
在微服务架构中实现安全性是一个复杂的过程,需要考虑多种因素,如身份验证、授权、会话管理、安全通信等。Spring Security是一个强大的工具,可以帮助你实现这些安全性需求。通过使用JWT或OAuth 2.0等现代认证机制,你可以创建一个安全的微服务架构,同时保持服务的解耦和独立性。
7、监控和观察性:
- 学习如何使用Spring Boot Actuator进行应用监控。
- 掌握分布式追踪系统,如Spring Cloud Sleuth和Zipkin的集成和使用。
在微服务架构中,监控和观察性是确保系统稳定性和性能的关键。Spring Cloud提供了多种工具来帮助开发者实现这一目标。下面我将介绍如何使用Spring Boot Actuator进行应用监控,以及如何集成Spring Cloud Sleuth和Zipkin进行分布式追踪。
- Spring Boot Actuator
Spring Boot Actuator提供了一系列的端点,允许你访问有关应用程序、环境和运行状况的信息。它可以帮助你监控应用程序的健康状态、环境变量、日志和指标等。
示例
添加依赖:
在pom.xml文件中添加Spring Boot Actuator的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
配置Actuator:
在application.yml文件中配置Actuator的端点:
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
访问Actuator端点:
启动应用程序后,你可以通过以下URL访问Actuator端点:
- 应用信息:http://localhost:8080/actuator/info
- 运行状况:http://localhost:8080/actuator/health
- 环境变量:http://localhost:8080/actuator/env
- 指标:http://localhost:8080/actuator/metrics
- Spring Cloud Sleuth和Zipkin
Spring Cloud Sleuth是一个分布式跟踪的框架,它可以与Zipkin一起使用来追踪分布式系统中各个组件之间的交互。
示例
添加依赖:
在pom.xml文件中添加Spring Cloud Sleuth和Zipkin的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
配置Zipkin:
在application.yml文件中配置Zipkin:
spring:
sleuth:
sampler:
probability: 1.0 # 设置采样率为100%,以便于追踪所有请求
zipkin:
base-url: http://localhost:9411 # Zipkin服务的URL
访问Zipkin UI:
启动应用程序后,Zipkin会收集追踪数据。你可以通过以下URL访问Zipkin UI:
http://localhost:9411/
- 总结
通过使用Spring Boot Actuator,你可以监控应用程序的运行状况和性能。而通过集成Spring Cloud Sleuth和Zipkin,你可以追踪分布式系统中各个组件之间的交互,以便于诊断和解决问题。这些工具是构建可观察性和可维护性的微服务架构的重要组成部分。
8、部署和运维:
- 学习如何将Spring Cloud应用打包、部署和运维。
- 掌握使用Docker和Kubernetes等容器化技术部署微服务。
在微服务架构中,部署和运维是确保应用程序持续运行和性能的关键环节。Spring Cloud应用的打包、部署和运维涉及多个方面,包括构建工具、容器化技术、自动化部署和监控等。下面我将介绍如何使用Docker和Kubernetes等容器化技术部署微服务。
- 构建和打包
Spring Cloud应用通常使用Maven或Gradle作为构建工具。应用打包后,可以创建Docker镜像或Jar/War文件,以便于部署。
Maven示例
在pom.xml文件中添加构建和打包的配置:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>my-service</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
在这个示例中,我们使用了Spring Boot Maven插件来构建应用,并使用了Docker Maven插件来创建Docker镜像。
- 容器化
容器化技术,如Docker,允许你将应用程序及其依赖打包到一个轻量级的容器中,以便于在不同的环境中运行。
Dockerfile示例
创建一个Dockerfile文件来定义Docker镜像的构建过程:
FROM java:8-jdk-slim
VOLUME /tmp
ADD ./target/my-service-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
在这个示例中,我们使用Java 8 JDK Slim镜像作为基础镜像,将构建好的Jar文件添加到容器中,并定义了入口点。
- 部署
将构建好的Docker镜像推送到Docker Hub或Registry,然后使用Kubernetes等容器编排工具来部署和管理容器。
Kubernetes YAML示例
创建一个Kubernetes YAML文件来定义部署:
apiVersion: v1
kind: Pod
metadata:
name: my-service-pod
spec:
containers:
- name: my-service-container
image: my-service:latest
ports:
- containerPort: 8080
在这个示例中,我们定义了一个Pod,其中包含一个容器,使用我们的Docker镜像。
- 运维
运维涉及监控、日志收集、自动扩展和故障转移等方面。Spring Cloud应用可以集成Kubernetes的Horizontal Pod Autoscaler(HPA)来自动扩展Pods,并使用Prometheus和Grafana来监控应用程序的性能和健康状况。
Prometheus和Grafana示例
在Kubernetes集群中部署Prometheus和Grafana,然后配置Grafana Dashboard来显示应用程序的监控数据。
- 总结
通过使用Docker和Kubernetes等容器化技术,你可以更轻松地部署和管理Spring Cloud应用。容器化允许你打包应用程序及其依赖,并确保在不同的环境中一致运行。同时,通过监控和自动扩展等运维工具,你可以确保应用程序的稳定性和性能。
9、实战项目:
- 通过构建实际的微服务项目来综合运用所学知识。
- 学习如何处理分布式系统中的问题,如服务发现、配置管理、负载均衡等。
实战项目是学习微服务架构的最佳方式,因为它可以帮助你将理论知识应用于实际场景中。通过构建实际的微服务项目,你可以学习如何处理分布式系统中的各种问题,如服务发现、配置管理、负载均衡等。
由于项目涵盖源码,资料,文内是放不下的,有需要的兄弟可以文末联系V哥,提出你需求,有合适的项目可以分享给你。
10、源码和原理分析:
- 阅读Spring Cloud组件的源码,理解其工作原理。
- 学习Spring Cloud的架构设计和最佳实践。
为了深入学习Spring Cloud,你可以参考上述文档中的资源链接,包括官方文档、在线教程、课程和书籍。此外,加入社区论坛和微信群,参与讨论和交流,也是提高技能的有效途径。通过不断实践和学习,你将能够掌握Spring Cloud框架,并在微服务架构中发挥其优势。
阅读和理解Spring Cloud组件的源码,以及其工作原理,是深入掌握Spring Cloud的关键步骤。通过源码分析,你可以更好地理解Spring Cloud的设计哲学和实现细节,从而在实际项目中做出更合理的技术决策。下面我将介绍如何进行Spring Cloud组件的源码分析,以及学习Spring Cloud的架构设计和最佳实践。
- 源码分析
选择组件
首先,选择一个你感兴趣的Spring Cloud组件,比如Spring Cloud Gateway、Eureka、Hystrix等。
构建项目
使用Maven或Gradle构建该组件的源码项目。
阅读文档
阅读组件的官方文档,了解其基本概念、使用方式和配置选项。
代码阅读
从入口类开始,逐步阅读代码,理解各个组件的启动流程、核心逻辑和对外提供的API。
调试分析
在关键点设置断点,运行项目,观察变量值和控制台输出,以帮助理解代码的工作原理。
实践验证
在本地项目中尝试使用该组件,并在运行时查看日志输出,以验证你对源码的理解。
- 架构设计和最佳实践
设计模式
学习Spring Cloud组件中使用的设计模式,如观察者模式、责任链模式、装饰者模式等。
架构风格
了解Spring Cloud组件的架构风格,如微服务、事件驱动、响应式编程等。
最佳实践
学习Spring Cloud组件的最佳实践,如使用Feign时如何配置、使用Hystrix时如何设置超时时间和重试策略等。
性能优化
了解Spring Cloud组件的性能优化技巧,如使用Ribbon时如何配置客户端负载均衡等。
示例
以Spring Cloud Gateway为例,你可以从入口类GatewayAutoConfiguration开始阅读,了解其自动配置的流程。然后阅读GatewayFilter和GatewayFilterChain类,理解过滤器的实现和链式调用。最后,你可以阅读RouteDefinition和RouteDefinitionLocator类,了解路由定义和发现机制。
通过这种方式,你可以逐步深入理解Spring Cloud组件的源码和原理,并将其应用于实际项目中。同时,不断实践和学习最佳实践,可以帮助你在微服务架构中做出更明智的技术决策。
最后
V 哥建议:如果你正在学习SpringCloud,你可以把这篇文章作为学习指南,如果你已经学过了,可以查漏补缺,因为 V 哥这篇文章全面介绍了SpringCloud的方方面面,当然你还需要结合官方文档的细节和源码部分去学习,成功拿下SpringCloud不是问题。加油兄弟!