SpringCloud (一) 微服务入门
SpringCloud 是目前主流的 Java 开发框架,平时一直在用 SpringCloud 开发项目,所以花点时间把 SpringCloud 相关知识整理一下,没有其他目的就是喜欢。
不要求写的有多好,但是别留坑!
环境说明
以下所有的 SpringCloud 项目均基于以下环境:
- Jdk版本:1.8
- maven版本:3.6.0
- 开发工具:idea 2019.3.3 版本
SpringCloud 是什么?
SpringCloud 是一系列框架的有序集合。它利用 SpringBoot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 SpringBoot 的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 SpringBoot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
微服务是可以独立部署、水平扩展、独立访问(或者有独立的数据库)的服务单元,SpringCloud 就是这些微服务的大管家,采用了微服务这种架构之后,项目的数量会非常多,SpringCloud 做为大管家就需要提供各种方案来维护整个生态。
SpringCloud 就是一套分布式服务治理的框架,既然它是一套服务治理的框架,那么它本身不会提供具体功能性的操作,更专注于服务之间的通讯、熔断、监控等。
使用 SpringCloud 开发项目,必须认同它的开发理念和思想,SpringCloud 本身并不是一款框架,而是基于 SpringBoot 的一系列微服务框架的集合,SpringCloud 中最重要的就是整合一系列组件实现 服务调用、熔断降级、监控等功能
SpringCloud 搭建架构
这是一张比较完整的 SpringCloud 分布式服务架构图,从上到下分析一下:
1、首先客户端通过域名访问服务端,通过 DNS + Nginx 实现服务端负载均衡方式对外提供服务
2、然后到达服务网关集群,服务网关集群对请求进行一些 鉴权、限流、路由转发 等进一步处理,过滤掉一些无效请求,保证服务高可用
3、业务服务进行集群部署,处理业务请求
4、提供一些中间件处理数据和服务调用,例如 消息中间件、大数据中间件 等
5、在数据库层提供 Mysql集群、Redis集群、MQ集群等,保障数据存储和性能
6、SpingCloud 搭建的分布式微服务,扩展以后往往是庞大的,为了保证服务的高可用和性能,SpringCloud 提供注册中心进行服务治理,提供配置中心对配置进行统一管理和动态修改,提供链路追踪对调用链路进行分析发现耗时服务,提供熔断降级防止因为某些微服务不可用导致整个系统雪崩
SpringCloud 项目搭建
前面我们介绍了 SringCloud 是什么
、SpringCloud 项目架构
,下面带大家搭建使用 SpringCloud 作为项目架构的分布式系统,后面的一系列课程都是基于这个项目。
准备工作
开发工具
IDEA 2019.3.3 版本
SpringCloud 和 SpringBoot 版本依赖说明
在搭建SpringCloud项目时,由于其基于SpringBoot所以两者版本依赖关系必须要了解。
了解的途径:https://spring.io/projects/spring-cloud
打开上面的地址,然后往下翻,或者 Ctrl + F 然后搜索 Release Trains
,就能看到 SpringCloud 和 SpringBoot 版本依赖关系了
搭建父工程
1、创建项目
使用 idea 工具可以很方便的创建 Spring project,首先进入 New Project 界面,选择 Spring Initiallizr
点击 Next
完成后,继续 Next
然后选择代码的存放位置
使用 idea 工具创建 project,由于我们的项目使用 maven 进行依赖管理,所以这里选择 Maven
2、修改 pom
以下文件是修改后的,并对位置做了一些调整,其中包含:
1、统一管理jar包版本
2、统一依赖管理
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gorun</groupId>
<artifactId>cloud2020</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloud2020</name>
<packaging>pom</packaging>
<!-- 统一管理jar包版本 -->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.1.RELEASE</spring-boot.version>
<spring-cloud.version>Greenwich.SR6</spring-cloud.version>
</properties>
<!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud -->
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
搭建子module
接下来我们新建一个基于 Eureka 注册中心的服务端
1、创建 module
此时创建的项目是这样的,和我们的父工程没有关系
2、修改 pom
修改父工程pom,将刚才新建的子module 纳入管理
修改子module pom,修改点如下
1、将parent替换为父工程
2、删除无用的依赖管理,插件管理
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gorun</groupId>
<artifactId>cloud2020</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>cloud-eureka-server-8761</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
3、修改 application.properties
由于我们的子module是搭建 Eureka Server,为了项目可以正常启动,需要修改 application.propertes 文件,修改 Eureka 相关配置
server.port=8761
eureka.instance.hostname=localhost
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
spring.application.name=eureka-server
4、主启动类添加 @EnableEurekaServer 注解
5、测试
启动项目,访问 http://localhost:8761/
SpringCloud 组件及功能介绍
Spring Cloud 新旧组件一览
SpringCloud 整合了目前各家公司开发的比较成熟、经得起实际考验的服务框架,经过进一步的封装,纳入了 SpringCloud 社区形成各种组件。其中某些组件已经停止更新维护了,大家要对这些有一定的了解,在项目中谨慎使用,当然 SpringCloud 也提供了更好的替代者,如下图所示:
Spring Cloud Netflix
简单介绍
Spring Cloud Netflix通过自动配置并绑定到Spring Environment和其他Spring编程模型习惯用法,为Spring Boot应用程序提供Netflix OSS集成。使用一些简单的批注,您可以快速启用和配置应用程序内部的通用模式,并使用经过测试的Netflix组件构建大型分布式系统。提供的模式包括服务发现(Eureka),断路器(Hystrix),智能路由(Zuul)和客户端负载平衡(Ribbon)。
特性
Spring Cloud Netflix功能:
- 服务发现:可以注册Eureka实例,并且客户端可以使用Spring托管的Bean发现实例
- 服务发现:可以使用声明性Java配置创建嵌入式Eureka服务器
- 断路器:Hystrix客户端可以使用简单的注释驱动的方法装饰器构建
- 断路器:具有声明性Java配置的嵌入式Hystrix仪表板
- 声明式REST客户端:Feign创建一个用JAX-RS或Spring MVC注释修饰的接口的动态实现。
- 客户端负载均衡器:功能区
- 外部配置:从Spring Environment到Archaius的桥梁(使用Spring Boot约定启用Netflix组件的本机配置)
- 路由器和过滤器:Zuul过滤器的自动注册,以及用于反向代理创建的简单配置约定
Spring Cloud Alibaba
简单介绍
Spring Cloud Alibaba为分布式应用程序开发提供了一站式解决方案。它包含开发分布式应用程序所需的所有组件,使您可以轻松地使用Spring Cloud开发应用程序。
使用Spring Cloud Alibaba,您只需要添加一些注释和少量配置即可将Spring Cloud应用程序连接到Alibaba的分布式解决方案,并使用Alibaba中间件构建分布式应用程序系统。
特性
- 流量控制和服务降级:使用阿里巴巴Sentinel进行流量控制,断路和系统自适应保护
- 服务注册和发现:实例可以在Alibaba Nacos上注册,客户可以使用Spring管理的bean发现实例。通过Spring Cloud Netflix支持Ribbon,客户端负载均衡器
- 分布式配置:使用阿里巴巴Nacos作为数据存储
- 事件驱动:构建与Spring Cloud Stream RocketMQ Binder 连接的高度可扩展的事件驱动微服务
- 消息总线:使用Spring Cloud Bus RocketMQ链接分布式系统的节点
- 分布式事务:支持高性能且易于使用的Seata分布式事务解决方案
- Dubbo RPC:通过Apache Dubbo RPC扩展Spring Cloud服务间调用的通信协议
如何使用
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>{project-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Spring Cloud Security
简单介绍
Spring Cloud Security提供了一组原语,用于以最少的麻烦构建安全的应用程序和服务。可以在外部(或中央)进行大量配置的声明式模型通常可以通过中央身份管理服务来实现大型的,相互协作的远程组件系统。在Cloud Foundry等服务平台中使用它也非常容易。在Spring Boot和Spring Security OAuth2的基础上,我们可以快速创建实现常见模式(如单点登录,令牌中继和令牌交换)的系统。
如何使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
Spring Cloud Stream
简单介绍
Spring Cloud Stream是一个框架,用于构建与共享消息传递系统连接的高度可扩展的事件驱动型微服务。
该框架提供了一个灵活的编程模型,该模型建立在已经建立并熟悉的Spring习惯用法和最佳实践的基础上,包括对持久性pub / sub语义,使用者组和有状态分区的支持。
如何使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
Spring Cloud Gateway
简单介绍
Spring Cloud Gateway 提供了一个用于在Spring MVC之上构建API网关的库。Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域的关注,例如:安全性,监视/指标和弹性。
如何使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Spring Cloud OpenFeign
简单介绍
Spring Cloud OpenFeign以将OpenFeign集成到Spring Boot应用中的方式,为微服务架构下服务之间的调用提供了解决方案。首先,利用了OpenFeign的声明式方式定义Web服务客户端;其次还更进一步,通过集成Ribbon或Eureka实现负载均衡的HTTP客户端。
如何使用
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>