目录
SpringCloud学习笔记
背景
Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式 会话,群集状态)。 分布式系统的协调导致了样板式样,并且使用Spring Cloud开发人员可以快速站起来实现这些样板的服务和应用程序。 它们可以在任何分布式环境中很好地工作,包括开发人员自己的笔记本电脑,裸机数据中心以及Cloud Foundry等托管平台。
特征
Spring Cloud专注于为典型的用例和可扩展性机制(包括其他用例)提供良好的开箱即用体验。
- 分布式/版本化配置
- 服务注册和发现
- 路由
- 服务到服务的呼叫
- 负载均衡
- 断路器
- 全局锁
- 领导选举和集群状态
- 分布式消息传递
主要项目组成
-
基于git存储库支持的集中式外部配置管理。 配置资源直接映射到Spring Environment,但是如果需要,可以由非Spring应用程序使用。
-
与各种Netflix OSS组件(Eureka,Hystrix,Zuul,Archaius等)集成。
-
在分布式消息传递中,将服务实例之间连接起来的事件总线;在集群环境中发布状态变更(例如配置更改事件)非常有用。
-
Spring Cloud Cloudfoundry
(服务的注册、发现、权限验证)
负责将您的应用程序与Pivotal Cloud Foundry集成。 提供服务发现实现,还可以轻松实现SSO和OAuth2保护的资源。
-
Spring Cloud Open Service Broker
为一个正在运行的节点提供基于开源服务熔断API实现的服务熔断期
-
领导选举、常见状态模式的抽象、Zookeeper、Redis、Consul的实现
-
基于Hashicorp Consul的服务发现、配置管理。
-
Spring Cloud Security
基于OAuth2的负载均衡rest客户端的提供呢、Zuul代理中的认证信息头的传递
-
SpringCloud应用的分布式跟踪,已兼容ZipKin、Htrace和基于日志(ELK);
-
A cloud-native orchestration service for composable microservice applications on modern runtimes. Easy-to-use DSL, drag-and-drop GUI, and REST-APIs together simplifies the overall orchestration of microservice based data pipelines.
针对现代运行时可组合微服务应用程序的云原生编排服务。 易于使用的DSL,拖放式GUI和REST-API共同简化了基于微服务的数据管道的总体编排。
-
一个轻量级的事件驱动的微服务框架,用于快速构建可以连接到外部系统的应用程序。 在Spring Boot应用程序之间使用Apache Kafka或RabbitMQ发送和接收消息的简单声明性模型。
-
Spring Cloud Task App Starters
Spring Cloud Task App Starters are Spring Boot applications that may be any process including Spring Batch jobs that do not run forever, and they end/stop after a finite period of data processing.
Spring Cloud Task App Starters是Spring Boot应用程序,可以是任何进程,包括不会永远运行的Spring Batch作业,它们在有限的数据处理周期后结束/停止。
-
A short-lived microservices framework to quickly build applications that perform finite amounts of data processing. Simple declarative for adding both functional and non-functional features to Spring Boot apps.
一个短暂的微服务框架,可快速构建执行有限数量数据处理的应用程序。 用于向Spring Boot应用程序添加功能和非功能功能的简单声明。
-
基于Apache Zokkeeper的服务发现与管理配置
-
使各种平台上的PaaS应用程序轻松连接到后端服务,例如数据库和消息代理(该项目以前称为“ Spring Cloud”)。
-
Spring Boot CLI插件,用于在Groovy中快速创建Spring Cloud组件应用程序
-
Spring Cloud Contract is an umbrella project holding solutions that help users in successfully implementing the Consumer Driven Contracts approach.
Spring Cloud Contract是一个涵盖项目的总体解决方案,可帮助用户成功实施“消费者驱动契约”方法。
-
Spring Cloud Gateway is an intelligent and programmable router based on Project Reactor.
Spring Cloud Gateway是基于Project Reactor的智能可编程路由器。
-
Spring Cloud OpenFeign provides integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms.
-
Spring Cloud Pipelines provides an opinionated deployment pipeline with steps to ensure that your application can be deployed in zero downtime fashion and easily rolled back of something goes wrong.
Spring Cloud Pipelines提供了一个可靠的部署管道,其中包含一些步骤,以确保您的应用程序可以零停机时间进行部署,并且可以轻松回滚出错误的地方。
-
Spring Cloud Function promotes the implementation of business logic via functions. It supports a uniform programming model across serverless providers, as well as the ability to run standalone (locally or in a PaaS).
Spring Cloud Function通过功能业务逻辑的实现。 它支持跨无服务器提供程序的统一编程模型,以及独立运行(本地或在PaaS中)的功能。
Spring Cloud Function是一个具有以下高级目标的项目:
通过功能促进业务逻辑的实现。
将业务逻辑的开发生命周期与任何特定的运行时目标脱钩,以便可以将相同的代码作为Web终结点,流处理器或任务来运行。
支持跨无服务器提供程序的统一编程模型,以及独立运行(本地或在PaaS中)的能力。
在无服务器提供程序上启用Spring Boot功能(自动配置,依赖项注入,指标)。
它抽象出了所有传输细节和基础结构,使开发人员可以保留所有熟悉的工具和流程,并专注于业务逻辑。
Spring CLoud Netflix
Spring Cloud Netflix通过自动配置并绑定到Spring Environment和其他Spring编程模型习惯用法,为Spring Boot应用程序提供Netflix OSS【云存储服务】集成。 通过一些简单的注释,您可以快速启用和配置应用程序内部的通用模式,并使用经过实战检验的Netflix组件构建大型分布式系统。 提供的模式包括服务发现、注册(Eureka),断路器(Hystrix),智能路由(Zuul)和客户端负载平衡(Ribbon)。
功能介绍
服务发现:可以注册Eureka实例,并且客户端可以使用Spring托管的Bean发现实例
服务发现:可以使用声明性Java配置创建嵌入式Eureka服务器
断路器:Hystrix客户端可以使用简单的注释驱动的方法装饰器构建
声明式REST客户端:Feign创建一个用JAX-RS或Spring MVC注释修饰的接口的动态实现。
客户端负载均衡器:Ribbon
外部配置:从Spring Environment到Archaius的桥梁(使用Spring Boot约定启用Netflix组件的本机配置)
路由器和过滤器:Zuul过滤器的自动注册,以及用于反向代理创建的简单配置约定
项目实战
Eureka Server端
-
pom.xml文件的引入
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.3.RELEASE</version> </parent>
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> <version>2.2.4.RELEASE</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
-
application.yaml文件内容的修改
server.active1.port: 8761 server.active2.port: 8762 --- eureka: instance: hostname: wangxintao5-8761.com prefer-ip-address: true instance-id: student-server-eureka client: fetch-registry: false register-with-eureka: false service-url: #监控页面 defaultZone: http://wangxintao5-8762.com:${server.active2.port}/eureka/ spring: profiles: active1 application: name: eureka-8761 server: port: ${server.active1.port} --- eureka: instance: hostname: wangxintao5-8762.com prefer-ip-address: true instance-id: student-server-eureka client: fetch-registry: false register-with-eureka: false service-url: #监控页面 defaultZone: http://wangxintao5-8761.com:${server.active1.port}/eureka/ spring: profiles: active2 application: name: eureka-8762 server: port: ${server.active2.port}
-
EurekaServer的注解引入
package com.SpringCloud.Studay; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * Hello world! * */ @SpringBootApplication @EnableEurekaServer //服务端的启动类,可以让那个服务注册进来 public class EurekaServerActive1 { public static void main( String[] args ) { new SpringApplicationBuilder(EurekaServerActive1.class).run(args); } }
Eureka Client端+Hysrix熔断器
-
pom的引入
<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-client</artifactId> <version>2.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> </dependencies>
-
application.yaml的内容引入
eureka: client: service-url: #Eureka客户端服务注册地址 defaultZone: http://wangxintao5-8761.com:8761/eureka/,http://wangxintao5-8762.com:8762/eureka/ instance: #Eureka客户端服务示例标识 instance-id: student-provider-8602 management: endpoint: health: show-details: endpoints: web: exposure: include: "*" server: #服务开放端口,当运行多个服务时,需修改此服务的端口 port: 8602 spring: application: # Eureka 默认服务名称 大写 name: studentSystem datasource: driver-class-name: com.mysql.jdbc.Driver hikari: connection-test-query: select 1 connection-timeout: 20000 idle-timeout: 180000 maximum-pool-size: 50 minimum-idle: 10 pool-name: student-datasource-pool password: 123456 url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false username: root jpa: database: mysql database-platform: org.hibernate.dialect.MySQL5InnoDBDialect hibernate: ddl-auto: update redis: database: 10 host: 49.234.92.71 jedis: pool: max-wait: 30s min-idle: 4 lettuce: pool: max-active: 8 max-idle: 12 password: Niqusi8. port: 6379 timeout: 6s #SPringCloud actuator服务信息,方便别人理解 info: application.name: wangxintao5-student company.name: wangzha hystrix: dashboard: proxy-stream-allow-list: "localhost"
-
Eureka Client注解、Hystrix熔断器注解的引入(在引入SpringCloud Eureka Client后,无需加注解@EnableEurekaClient,即可作为服务注册者)
package com.SpringCloud.Studay; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * Hello world! * */ @SpringBootApplication @EnableCircuitBreaker //Hystrix熔断器注解 @EnableEurekaClient //Eureka客户端注解 public class App { public static void main( String[] args ) { SpringApplication.run(App.class); } }
-
Hystrix简单示例
package com.SpringCloud.Studay.controlller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/student") public class StudentController { @Value("${server.port}") private String port; @RequestMapping("/list") public Object list(){ return port; } @RequestMapping("/error") @HystrixCommand(fallbackMethod = "failback") public Object error(){ throw new RuntimeException("system inner error"); } private Object failback(){ return "system failback"; } }
-
服务信息发现示例
package com.SpringCloud.Studay.controlller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class IndexController { //获取服务信息 @Autowired private DiscoveryClient client; @RequestMapping("/login") public Object index(){ List<String> services = client.getServices(); System.out.println("discovery=>services:"+services); List<ServiceInstance> serviceInstances = client.getInstances("STUDENTSYSTEM"); return serviceInstances; } }
Rabbon、Feign负载均衡客户端
-
pom.xml内容引入
<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-client</artifactId> <version>2.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.4.RELEASE</version> </dependency> </dependencies>
-
application.yaml内容
server: port: 8701 spring: application: name: student-consumer eureka: client: service-url: defaultZone: http://wangxintao5-8761.com:8761/eureka/,http://wangxintao5-8762.com:8762/eureka/ register-with-eureka: false
-
Eureka客户端与Rabbon的引入
package com.SpringCloud.Studay; import com.SpringCloud.RabbonConfig.StudentRibbonConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @RibbonClient(name="STUDENTSYSTEM",configuration = StudentRibbonConfig.class) @EnableFeignClients public class StudentConsumer { public static void main( String[] args ) { SpringApplication.run(StudentConsumer.class); } @Bean @LoadBalanced //启用Rabbon负责均衡 public RestTemplate restTemplate(){ return new RestTemplate(); } }
-
其他备注
-
Feign自定义配置(具体配置信息需官网查看)以及客户端接口实现
package com.SpringCloud.RabbonConfig; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FooConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
package com.SpringCloud.Studay.FeignInterface; import com.SpringCloud.RabbonConfig.FooConfiguration; import com.netflix.hystrix.Hystrix; import com.netflix.hystrix.HystrixCommand; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @FeignClient(name = "STUDENTSYSTEM", path = "/student", fallback = HystrixClientFallback.class, primary = false, configuration = FooConfiguration.class) public interface StudentClient { @RequestMapping(method = RequestMethod.POST,value = "/list") String list(); } class HystrixClientFallback implements StudentClient { @Override public String list() { return "exception"; } }
-
Rabbon自定义服务负责均衡
package com.SpringCloud.RabbonConfig; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.ZoneAvoidanceRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class StudentRibbonConfig { @Bean public IRule ribbonRule(){ return new ZoneAvoidanceRule(); } }
-
Zuul的路由网关
-
pom.xml
<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-client</artifactId> <version>2.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> <version>2.2.4.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies>
-
application.yaml
server: port: 8702 spring: application: name: student-zuul eureka: client: service-url: defaultZone: http://wangxintao5-8761.com:8761/eureka/,http://wangxintao5-8762.com:8762/eureka/ instance: instance-id: student-zuul info: application.name: student-zuul company.name: wangzha zuul: ignored-services: '*' routes: users: path: /stu/** serviceId: studentsystem
-
启动类的编写
package com.SpringCloud.Studay; 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 StudentZuulConsumer { public static void main(String[] args) { SpringApplication.run(StudentZuulConsumer.class); } }