Spring Cloud概述
从本篇开始,我们将正式踏上探索Spring Cloud秘密的旅程。学完本文后,读者将学会搭建一个完整的分布式架构,从而向架构师的目标靠近。
简介
Spring Cloud基于Spring Boot,是微服务架构思想的一个具体实现,它为开发人员提供了一些快速构建分布式系统中常见模式的工具,如配置管理、服务发现、熔断器、智能路由、微代理、控制总线等。Spring Cloud 的底层基于Spring Boot框架,它不重复“造轮子”,而是将一些第三方实现的微服务应用模块集成。
Spring Cloud是一系列有序框架的集合,下面列举了一些我们在实际项目中可能会用到的子项目。
- Spring Cloud Config:通过SVN、Git等仓库使配置集中化存储,配置资源可以直接映射到Spring Environment 中。
- Spring Cloud Netflix:与 Netflix开发的各种组件集成,包括服务注册与发现、熔断器、服务网关、Rest客户端及负载均衡器等。
- Spring Cloud Bus:将服务、服务实例与分布式消息链接在一起的事件总线;用于在集群中传播状态变化;和 Spring Cloud Config配合,可以实现配置的动态刷新。
- Spring Cloud Consul:进行Spring Cloud中的服务注册与发现配置管理。
- Spring Cloud Security:为Zuul代理中的负载平衡OAuth2REST客户端和身份验证中继提供支持。
- Spring Cloud Sleuth:用于Spring Cloud应用程序的分布式跟踪,兼容Zipkin、HTrace和基于日志(例如ELK)的跟踪。
- Spring Cloud Data Flow:一种能够用于现代运行时并可以组合微服务应用程序的云本地编排服务。易于使用的DSL、拖放式GUI和REST-API共同简化了基于微服务的数据管道的整体编排。
- Spring Cloud Stream:轻量级事件驱动的微服务框架,能够快速构建可连接到外部系统的应用程序,用于在Spring Boot应用程序之间使用Apache Kafka或RabbitMQ发送和接收消息。
- Spring Cloud Task:一种短暂的微服务框架,用于快速构建执行有限数据处理的应用程序,它用于向Spring Boot应用程序中添加功能性和非功能性的简单声明。
- Spring Cloud Gateway:一款基于Project Reactor的智能可编程路由器。由于Zuul 2.0版本的开发经常跳票,所以Spring官方开发了路由网关以支持Spring Boot 2.0及新版Spring Cloud。
- Spring Cloud OpenFeign:基于Netflix Feign,是一个声明式的HTTP客户端,可以轻松实现服务间接口调用。
- Spring Cloud Function:通过函数促进业务逻辑的实现,它支持无服务器提供商之间的统一编程模型以及独立运行(本地或PaaS )。
这些项目不会全部集中在一个应用上,将它们列举出来的目的是方便读者在构建基于SpringCloud的微服架构时,可根据实际应用情况选择一些适合的组件集成到应用中。
优缺点
在技术更新如此频繁的时代中,存活下来的框架必然有它的优点。那么,Spring Cloud 有什么优点呢?下面我们就来探讨一下。
- 集大成者:包含了微服务架构的方方面面。约定优于配置:基于注解,没有配置文件。
- 轻量级组件:整合的组件大多比较轻量,且都是各自领域的佼佼者。
- 开发简便:对组件进行了大量封装,从而简化了开发。
- 开发灵活:组件都是解耦的,开发人员可以灵活按需选择组件。
事物都有双面性,Spring Cloud也不例外,它主要有以下缺点。
- 项目结构复杂:每一个组件或者每一个服务都需要创建一个项目。
- 部署门槛高:需要配合Docker等容器技术进行集群部署。而要想深入了解Docker,学习成本比较高。
Spring Cloud 的优势是显而易见的,因此对于想研究微服务架构的读者来说,学习Spring Cloud是一个不错的选择。
现状
目前,国内使用Spring Cloud作为主要技术栈的公司并不多见,这并不是因为Spring Cloud不好,主要原因有以下几点。
- Spring Cloud中文文档较少,出现问题找不到太多的解决方案。
- 国内创业型公司的技术老大很多曾就职于阿里巴巴,他们多采用Dubbo来构建微服务架构。
- 大型公司基本都有自己的分布式解决方案,而中小型公司的架构很多用不上微服务,所以没有采用Spring Cloud 的必要性。
但是微服务架构是一个趋势,而Spring Cloud是微服务解决方案中的佼佼者,这也是我编写本书的意义所在。
开始Spring Cloud 实战
学习任何一门语言或者一种框架,都是由Hello World 开始的,本书也不例外。在正式进入实战之前,我们先来搭建一个最简单的Spring Cloud框架,以便大家能够领略其强大之处。
技术储备
在开始 Spring Cloud学习之前,读者应该拥有以下技术储备。
Java基础:如果你的Java基础还不够扎实,建议先学习相关内容,再来阅读本文。
Spring MVC: Spring Cloud基于Spring Boot,而 Spring Boot又基于Spring MVC,因此读者需要具备Spring MVC框架的基础。
准备工作
本文采用IntelliJIDEA开发Spring Cloud项目,若读者尚未安装该工具,可以从其官网 https://www.jetbrains.com/idea/下载最新版。图4-1是我所用的IDEA的详细版本信息。
本文所用的Spring Boot版本为2.0.3.RELEASE,Spring Cloud版本为Finchley.RELEASE,因此JDK的版本至少在1.8以上。此外,书中也包含了大量lambda表达式,读者也需要了解lambda表达式,否则有些代码可能无法读懂。
从Hello World开始你的实战之旅
下面开始搭建一个最简单的Spring Cloud框架,主要包括服务的注册与发现、客户端以及服务网关。Spring Cloud 属于微服务架构,会包含多个工程,因此,我们应该先创建一个父工程,并设置<packaging>为pom,每个子工程都创建在父工程之下。
打开IntelliJ IDEA,创建一个Maven工程,将其命名为springclouddemo,然后修改pom.xml的内容:
代码语言:javascript复制<packaging>pom</packaging><parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</ artifactId><version>2.0.3.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java. version>
</ properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId></ dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId><version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import< / scope></dependency>
</ dependencies>
</dependencyManagement>
其中,pom.xml里面需要添加Hystrix熔断器的依赖,这是因为Spring Cloud默认加人了该熔断器,如果不添加此依赖,启动子工程时会报错。
父工程创建好后,就可以创建子工程,并实现一个最简单的Spring Cloud项目。
1.服务的注册与发现
Spring Cloud默认的服务注册与发现组件是Netflix的Eureka组件(该组件会在第6章中详细介绍),本节也是使用它的默认组件来创建服务注册与发现的。
Spring Cloud将 Eureka集成到微服务家族中,并对它进行了二次封装,Eureka负责微服务架构中的服务治理功能。服务治理是微服务架构中的核心思想,它可以实现服务的注册、发现、销毁和续约等。
(1)右击springclouddemo工程,在弹出的快捷菜单中选择New→Module(如图4-2所示),在打开的New Module窗口中将ArtifactIld命名为eurekaserver,如图4-3所示,然后一直点击Next 按钮即可。
(2)在pom.xml文件中添加如下依赖:
代码语言:javascript复制<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>
</dependencies>
Eureka组件分为服务端和客户端,服务端负责管理客户端,比如注册、销毁和续约等。加入上述依赖后,我们就可以将该工程设置为Eureka 服务端来管理Eureka客户端。
(3)创建启动类Application:
代码语言:javascript复制@EnableEurekaServer
@SpringCloudApplicationpublic class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
Application是该工程的启动类。我们知道,一个Java程序的入口函数是main方法。在上述代码中,我们在Application类中添加了main方法,并通过SpringApplication调用run方法,启动一个Spring Cloud工程。
此外,我们还在Application类中添加了@EnableEurekaServer和@SpringCloudApplication注解。其中,第一个注解表示将当前工程设置为注册中心,只有加入该注解,当前工程才能作为注册与发现的服务端,后者表明该工程是一个 Spring Cloud工程。
@SpringcloudApplication注解的源码如下:
代码语言:javascript复制@Target({ElementType. TYPE})
@Retention(RetentionPolicy.RUNTIME)@Documented
@Inherited
@SpringBootApplication@EnableDiscoveryclient@EnableCircuitBreaker
public @interface SpringCloudApplication {
}
可以发现,它也包含3个核心注解:@SpringBootApplication、@EnableDiscoveryClient和@EnableCircuitBreaker。@SpringBootApplication注解在第2章中已经讲过,一个Spring Boot工程的启动类必须添加该注解,否则无法正确启动工程;@EnableDiscoveryClient表示该工程可以作为客户端注册到注册中心;@EnableCircuitBreaker表示开启熔断器,熔断器的相关内容详见第10篇(此文为第四篇)。
(4)在resources下创建配置文件application.yml,并添加如下内容:
代码语言:javascript复制server:
port: 8761spring:
application :
name: eurekaserver
eureka:
client:
register-with-eureka: truefetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka/
上述配置是注册中心最基本的配置。其中, spring. application.name定义了当前工程的应用名,Eureka服务端将以该名称注册,默认全部替换成大写字母; eureka.client. register-with-eureka用于说明当前工程是否注册到Eureka服务端,默认为true; eureka.client.fetch-registry可以指示该工程是否应从 Eureka服务端中获取Eureka注册表信息,默认为true,主要在高可用注册中心或进行负载均衡等场景下使用,而上述示例是单节点Eureka服务端,不需要同步其他Eureka 服务端的信息,因此设置为false;eureka.client.service-url指示该工程注册到哪个注册中心下, eureka为固定值,8761为注册中心端口。
这样服务的注册与发现就创建完成了,下面我们来测试一下。(1)启动Application类的main方法。
(2)在浏览器中访问localhost:8761,就能看到如图4-4所示的界面。Eureka服务端将自己也注册了,而eurekaserver就是在spring.application.name 定义的应用名,Eureka服务端统一将其转换为大写字母EUREKASERVER了。
2.客户端
Eureka服务端搭建完成后,我们继续来搭建客户端。
(1)创建Module,将其命名为eurekaclient,在pom.xml文件里添加依赖:
代码语言:javascript复制<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></ dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId></ dependency>
</ dependencies>
其中, spring-cloud-starter-netflix-eureka-client为Eureka 客户端依赖,只有添加该依赖,我们才能将客户端注册到Eureka服务端; spring-boot-starter-web集成了Spring MVC框架,在Eureka客户端必须添加该依赖,否则无法启动工程。工程启动日志如图4-5所示。
通过图4-5可以清晰地看到,工程启动后会自动停止.而加上spring-boot-starter-web依赖后,我们就能正确启动工程,如图4-6所示。
(2)创建启动类Application,其代码与本节前面的“服务的注册与发现”相同。注意,本启动类只需要添加@SpringCloudApplication即可,无须添加 @EnableEurekaServer注解。
(3)创建配置文件 application.yml,其代码与本节前面的“服务的注册与发现”相同,只需要将server.port 设置为8762,将spring.application.name 设置为eurekaclient即可。
下面来测试一下。
(1)分别启动eurekaserver和 eurekaclient。
(2)通过浏览器访问localhost:8761,我们发现 Eureka客户端(EUREKACLIENT)也被注册上去了,如图4-7所示。
3.服务网关
在Spring Boot 1.x时代, Spring Cloud的默认网关是Netflix的Zuul 1.0,Zuul 2.0也在持续开发中,但是开发过程一波三折,经常跳票°。于是Spring Cloud官方也没有耐心等下去,自己开发了一套路由网关框架,在Spring Boot 2.0以后,服务网关有了新的框架,那就是Spring Cloud Gateway。
Zuul 1.0是阻塞式网关,也不支持WebSocket; Zuul 2.0是非阻塞式网关,并且支持了WebSocket。由于Spring Cloud官方自己开发了一套网关,它采用非阻塞API,支持WebSocket、熔断、限流、路由过滤等功能,所以没有必要再集成Zuul 2.0。当前如果继续依赖Zuul 的话,依然是Zuul 1.0。Zuul 1.0在处理并发性能方面明显不如 Spring Cloud Gateway,因此,本书使用Spring Cloud Gateway作为服务网关。
下面我们就来搭建服务网关。
(1)在springclouddemo下创建一个Module,将其命名为gateway,然后添加如下依赖:
代码语言:javascript复制<dependencies>
<dependency>
<groupId>org-springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId></dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</ artifactId></dependency>
<dependency>
<groupId>org.springframework.cloud</ groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
</ dependencies>
在上面的代码中,我们加人了 spring-cloud-starter-gateway依赖,这样就可以将该工程设置为服务网关。而服务网关也需要注册到Eureka服务端,否则它无法代理其他Eureka 客户端,也失去了网关的作用,因此也需要添加spring-cloud-starter-netflix-eureka-client依赖。
因为Spring Cloud Gateway采用 WebFlux,所以我们需要添加 WebFlux 的依赖。注意不能添加spring-boot-starter-web 依赖,否则启动会报错,如图4-8所示。
如果我们要实现动态路由,需要将Spring Cloud Gateway注册到注册中心,此时需要添加Eureka客户端的依赖。
(2)创建配置文件application.yml:
代码语言:javascript复制server:
port:8080spring:
application:
name: gatewaycloud:
gateway:
discovery:
locator:
enabled: true
eureka:
client:
register-with-eureka: truefetch-registry: true
service-url :
defaultzone: http:// localhost:8761/eureka/
在上述配置中, eureka.client.fetch-registry 设置为true,这是因为外部访问通过本服务网关访问具体的 Eureka客户端,服务网关需要拉取Eureka注册表信息,否则无法发现具体的客户端;而spring.cloud.gateway.discovery.locator.enabled用于设置是否开启动态路由配置,如果将其设置为 true,表示Gateway 会通过注册中心注册的 serviceId 去请求指定客户端接口,地址如http:/localhost:gateway port/serviceId/**。这里需要注意的是,通过Eureka服务端注册的serviceId是大写的,如图4-9所示。
因此,请求地址的 serviceId也应写成大写的,因为它是区分大小写的,而 serviceId就是我们在application.yml中设置的 spring.application.name。
(3)创建启动类Application。由于服务网关也作为Eureka客户端注册到Eureka服务端,因此所有客户端代码都几乎同上述“客户端”一样,此处也不例外,所以代码不再给出。
(4)在eurekaclient工程中创建HelloController类,该类是Spring MVC中的控制器:
代码语言:javascript复制@RestController
public class Hellocontroller {
@RequestMapping( "index")public string index(){
return"这是一个eurekaclient" ;
}
}
在上述代码中,我们定义了一个HTTP请求方法 index,外部环境(如浏览器)可以通过index地址访问该方法。
然后测试一下。
(1)分别启动eurekaserver、eurekaclient和l gateway三个工程。
(2)按照前面讲到的规则,通过浏览器访问 localhost:8080/EUREKACLIENT/index,可以看到如图4-10所示的界面。
以上就是基于Spring Cloud架构创建的最简单的工程,通过这个工程,我们可以了解如何创建注册中心、如何将客户端注册到注册中心,如何通过Gateway请求客户端定义的接口。
在本书后面的实战中,我们将进一步研究Spring Cloud 的各个组件,并且将这些组件合理运用到实际应用中。
小结
本篇中,我们正式进入Spring Cloud的学习。任何一门技术入门书,都是从Hello World开始的,本文也不例外。
本篇先介绍了Spring Cloud 的基本概念、Spring Cloud 的优缺点及发展现状,随后以一个最简单的Spring Cloud示例演示了其部分核心思想,即服务的注册与发现、服务网关,使读者对Spring Cloud有了初步的了解,为后面的项目开发奠定基础。
本文给大家讲解的内容是springcloud实战:探索springcloud的秘密
- 下篇文章给大家讲解的是springcloud实战:项目准备,构建大型实战项目-博客网站;
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。