目录
一.什么是 Spring Cloud?
二.Spring Cloud包含哪些东西?
三.Spring Cloud怎么用?
1.创建服务管理中心(eureka-server).
1.1 修改eureka-server下的启动类
1.2 配置eureka服务器
1.3 启动服务管理中心
2.创建服务的客服端
2.1 在项目中添加goods 模块,user 模块
2.2 配置客服端的配置文件
2.3 发现服务
四.高可用性
1.打开配置选项
2. 设置服务运行的端口号
3. 修改服务的配置文件
五.Spring Cloud 应该注意哪些地方?
1.错误一: Consider defining a bean of type 'com.netflix.discovery.AbstractDiscoveryClientOptionalArgs' in your configuration.
2.错误二:Connection refused: no further information
3.错误三:Cannot execute request on any known server
六.结束语:
网络上有的就不说了,谈谈自己的理解.
之前每个软件公司需要实现分布式的时候都需要开发一套分布式框架,而Spring Cloud相当于把这套方案做成了产品,一些公司可以直接使用这套方案实现分布式系统.所以Spring Cloud就相当于是一套通用的分布式系统解决方案.
再来谈谈什么是分布式,为什么要分布式?
与分布式对立的是单存储服务器或者集中存储服务器,顾名思义,就是将项目运行的所有程序都放置在一台服务器上,这样一旦某个模块产生问题,或者某个模块造成网络/进程拥堵,那么整个程序就都不能正常运行.例如淘宝的聚划算流量很大,造成网络拥堵,造成所有淘宝,天猫的功能都不可用,这显然不能被允许的.
将项目中按照不同的业务功能,将不同的模块放置在不同的服务器上,并且还可以将同一个功能模块放置在多个服务器上,这样一旦一个功能模块出现问题,还有其他的服务器可以执行这个功能模块(听上去有点想备胎).这样就增加了程序的健壮性和稳定性.这就是分布式的概念.
那么要实现分布式,显然不是简单的把文件拷贝到多个服务器那么简单.所以就由了Spring Cloud.
还有我们经常听到的微服务又是什么?
微服务:是将应用程序分解成多个小的服务,每个服务之间相互协调,调用,完成一个完整的功能,这个就是微服务.微服务是分布式系统架构中的一种.
所以不要理解错了,Spring Cloud不等同于微服务,Spring Cloud是实现微服务的一种解决方案.而微服务又是分布式系统架构中的一种.
Spring Cloud是代码相互相互之间组合和配合调用的一种解决方案(方式).
Spring Cloud包含:架构和组件(服务)
1.架构: Spring Cloud组件相互之间的关系,也是Spring Cloud的设计思路,架构将组件有序的结合在一起,协调组件共同完成项目/产品的功能.
所以学习Spring Cloud架构就是了解各个组件之间他们如何协同工作的.
关于Spring Cloud的架构我们需要了解以下几个概念:熔断器(Resilience4j)和服务调用(OpenFeign)
熔断器(Resilience4j),是Spring Cloud推荐的主流熔断器,它里面又包含了断路器,舱壁隔离,限速器的概念.
→断路器():当被调用的服务(服务提供方)出现状况时,断路器提供替代方案,通常的替代方式就是降级处理(例如我们在页面中看到的404页面就是一种降级处理,总比让用户卡在某个地方要好).
→舱壁隔离:也叫做隔板隔离,将不同的服务分配到不同的线程池,这样当一个服务出现线程阻塞时,不会造成另外的服务也发生阻塞.
→限速器:类似公路限速一样,限制每秒钟可以通过多少次的服务调用,避免在高并发时服务无法承受压力.
→仪表盘: 监控断路器运行.
服务调用(OpenFeign), 服务之间存在相互调用,OpenFeign提供Spring MVC 的注解来支持声明式服务调用.
2.组件(也称为服务,在项目中以模块的形式展现)包括以下几个内容:
1) 服务管理中心:(Eureka)
主要作用:服务实例通过发送请求在服务管理中心进行注册,续约,下线,服务管理中心管理服务实例的调用.btw:Eureka这个单词就是"我发现了"的意思
注册:服务实例通过配置application.yml文件,告诉服务管理中心,存在这样服务.相当于做一个等级.
续约:服务实例每间隔一段时间就需要向服务管理中心发送请求,告诉管理中心,这个服务是可以使用的,如果在规定时间(90s)不能完成续约,那么服务中心会将该服务从可用的服务实例中剔除.
下线:当一个服务实例不再运行时,需要给服务管理中心发送一个信息,告诉管理中心,当前这个服务实例下线了,服务管理中心就不再往该服务实例分配"工作".
2) 服务实例:
一个服务可以存在多个实例(相当于副本),服务实例根据功能又可以分为:服务提供方,服务调用方,还有网关.其中一个实例既可以是服务提供方又可以是服务调用方(相当于一个人既可以是销售者也同时是消费者).
服务提供方(服务提供者):
服务调用方(服务消费者):
网关:有多种网关可以调用,但是一般使用的是Gateway网关.网关是一种请求规则,可以简单的理解为路由.各个服务实例之间的请求调用是通过网关设置的规则进行.
网关通过设置的规则转发给对应的服务实例,通过网关实现对请求的过滤和转发,在微服务中,网关被称为服务器端负载均衡.
我们在了解了上面的这些概念之后,就需要了解如何将上面介绍的这些知识点变为实操,然后将每个知识点再组装起来.
第一天我们先创建一个小demo,使用idea的spring initializr生成器创建项目,这和创建普通的spring boot项目类似.
可以先加入以下几个常用的包:
Spring web,lombok,MyBatis Framework,MySql Driver,Spring Data Redis.
项目创建好之后,我们需要在项目里面添加几个模块,这里的模块其实就对应上面提到的组件.不过先不要着急,先创建服务管理中心(eureka-server).
在创建服务管理中心(erueka-server)时,可以添加Eureka Server依赖项.这样idea会自动在这个模块的pom.xml文件中添加以下配置:
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
如果手动添加也是一样的,
模块创建好之后,观察下模块下的java文件是否有被标注为代码,resource文件夹是否有被标注为资源,如果没有,可以点击pom.xml文件重新构建一次,或者,点击项目结构手动设置.
@SpringBootApplication
@EnableEurekaServer//驱动Eureka服务治理中心
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
上面这个代码只是加了@EnableEurekaServer注解,这个注解表示启动模块时将启动Eureka服务器.
修改模块下的application.yml文件,内容如下,解释在代码里面
#定义spring引用的的名称,也是这个服务的名称
spring:
application:
name: eureka-server
#这个服务启动的端口号
server:
port: 1001
eureka:
client:
#不需要进行注册,因为这个服务就是服务管理中心
register-with-eureka: false
#不进行服务获取
fetch-registry: false
instance:
#服务管理中心的IP地址.
hostname: 192.168.3.21
注意这里的hostname是配置服务器的IP地址,如果是本机作为服务器不能写localhost或者127.0.0.1,可以写本机IP(运行cmd,在执行ipconfig可以查看本机IP地址).
这段代码不用记,写好注释,理解上面的含义,下次用的时候拷贝过去就OK.
启动EurekaServerApplication类,并在地址栏中输入http://localhost:1001/
看到上面这个图,表示你的服务管理中心现在可以正常运行.目前我们有了一个好的开始(等于成功过了一半).
你可以按照项目的业务功能,创建不同的服务(模块),
在我们做项目时,一般根据数据库表创建对应的实体,dao,service,controller,在spring cloud中你可以对应每一个业务功能创建一个服务.在这个demo中,我们创建goods(商品)和user(用户)两个服务(模块)
在创建服务模块时需要添加Eureka客服端依赖包,你可以选择添加Spring Cloud Discovery -> Eureka Discovery Client 这个依赖.模块创建好之后,在pom.xml文件中会自动添加
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
或者你也可以手动输入.
修改goods模块和user模块下面的pom.xml文件,其中usr模块下的配置代码内容如下:
#设置服务的名称为:user
spring:
application:
name: user
eureka:
client:
service-url:
#通过defaultZone配置的地址向Eureka服务管理中心发送请求,完成注册,续约和下线的操作
defaultZone: http://localhost:1001/eureka/
instance:
#服务实例主机名称
hostname: 192.168.3.21
#user服务的端口号
server:
port: 2001
上面代码中的: defaultZone: http://localhost:1001/eureka/ 这个配置会主动向服务中心发送请求,完成服务的注册,续约和下线操作,其中1001是服务中心的端口号,和前面的配置文件端口号需保持一致.
设置有多个服务时请注意使用不同的端口号.
goods模块下的配置与上面文件类似,注意修改服务名称和端口号.
上面几步的工作做好之后,先启动eureka-server,再分别启动user,goods服务,最后打开浏览器,在http://localhost:1001/ 下你可以看到下面这个截图:
看到上面的内容表示上面的操作都是正确的.
前面提到了使用分布式部署的作用是做负载均衡,所以对一个服务往往我们需要多个实例,多个实例的好处是:
1. 当请求量比较大时多个实例可以分担压力;
2. 当某个实例存在故障时,服务管理中心可以将其下线,这样可以提高程序的健壮性.
下面介绍如何给一个服务配置多个实例以提高可用性.
在idea编译器的菜单中选择:运行-->编辑配置,如下图所示
1) 如果打开窗口没有覆盖配置属性这个区域,可以点击: 修改选项(画红框的位置)-->覆盖配置属性.
2) 选中EurekaServerApplication在覆盖配置属性填写server.port ,1001.
3) 保持EurekaServerApplication选中状态,点击右上角的第三个按钮(复制配置),会自动生成EurekaServerApplication 2,将这个配置的端口号改为1002.如下图所示:
接下来分别给UserApplication和GoodsApplication执行相同的操作,并配置不同的端口号,在本例中,端口号配置如下:
实例 | 端口号 |
EurekaServerApplication | 1001 |
EurekaServerApplication 2 | 1002 |
GoodsApplication | 3001 |
GoodsApplication 2 | 3002 |
UserApplication | 2001 |
UserApplication 2 | 2002 |
各模块配置完之后,将覆盖之前在application.yml文件中配置的端口设置.
1) 修改服务管理中心的配置文件:application.yml,代码如下:
#定义spring引用的的名称,也是这个服务的名称
spring:
application:
name: eureka-server
#这个服务启动的端口号,在idea的运行配置中设置了端口号之后,这段代码就可以去掉了.
#server:
# port: 1001
eureka:
client:
#不需要进行注册,因为这个服务就是服务管理中心
register-with-eureka: false
#不进行服务获取
fetch-registry: false
service-url:
defaultZone: http://localhost:1001/eurake/,http://localhost:1002/eurake/
instance:
#服务管理中心的IP地址.
hostname: 192.168.3.21
这里新增了eureka.client.service-url.defaultZone的配置,并且将服务管理中心的两端口号都进行了注册,在这里实际上是两个服务相互注册.
service-url:
defaultZone: http://localhost:1001/eurake/,http://localhost:1002/eurake/
2) 修改服务提供者(goods,user)的配置文件(application.yml),以user服务模块为例:
#设置服务的名称为:user
spring:
application:
name: user
eureka:
client:
service-url:
#通过defaultZone配置的地址向Eureka服务管理中心发送请求,完成注册,续约和下线的操作
defaultZone: http://localhost:1001/eureka/,http://localhost:1002/eureka/
instance:
#服务实例主机名称
hostname: 192.168.3.21
#user服务的端口号,使用了命令行参数后,这个配置不再需要了
#server:
# port: 2001
上面的代码在原来的基础上修改了两个地方,1)将原来设置的端口号去掉,2) 在eureka.client.service-url.defaultZone增加了一个服务管理中心的节点.
goods模块的配置同上.
3) 逐一运行配置,并且在浏览器访问http://localhost:1001/
效果如下所示:
可以看到goods和user服务模块启动了两端口.
检查你的服务模块的pom.xml中是否引入了:spring-boot-starter-web
检查你的application.yml中的defaultZone的路径配置是否正确,特别是拼写是否正确.
需要先启动服务管理中心再启动服务.
今天的内容先介绍到这里,后面章节还将向大家介绍spring cloud基础架构,服务调用,断路器,网关,限速器,舱壁隔离,限时器等内容.
spring cloud的学习并不难,在使用的时候我们可以先做好一个例子,使用的时候直接执行程序员的复制粘贴大法,但是一定要懂得如何修改,产生错误如何调整.