SpringCloud(一)——微服务介绍及Eureka搭建
前言
微服务的相关概念请移步链接内查看。SpringCloud——实战。
在微服务中,存在这么几种身份:服务调用者、服务注册中心;而在分布式中身份分为三种:服务提供者、服务调用者、注册中心。首先,区别开微服务与分布式的一个概念:分布式不一定是微服务;微服务一定是分布式。
分布式
分布式的概念在MVC三层架构的诞生后发挥了强大的作用。在最开始的时候,大家都会将控制器(controller)、业务层(service)、持久层(dao)进行拆分,然后分别注册到对应的注册中心中,等待服务调用。所谓注册中心,其实可以理解为以前的电话局,大家在打电话的时候,会有接线员帮我们将电话线插入到对应的频段上,这样可以使两个电话进行通信。
其实注册中心也一样,它完成的工作是将所有的需要被注册中信息记录的服务中的url、port等相关信息放入在注册中心并生成一个列表,等待服务调用者连接到服务注册中心中,服务注册中心会根据服务调用者的相关需求将服务列表中对应的服务信息给予调用者,调用者会按照这个信息来调用对应的服务。
微服务
微服务虽然执行过程和分布式相同,但是在本质的逻辑上却完全不同。分布式中部署的对象一般是各层业务,而微服务的部署对象对应的是按照业务逻辑区分开的各种服务。即:一个电商项目中会包括用户服务、订单服务、商品服务等,我们将这些按照业务逻辑分开的各项服务进行分布式概念的拆分,然后部署成为各个微服务。需要注意的是,分布式中的角色信息有三个,除开注册中心外分别是:服务提供者以及服务调用者;而微服务中,每一个注册到注册中心的对象结尾服务调用者(也可以理解为服务提供者),因为按照业务逻辑拆分开的项目中,每一个服务之间都息息相关。
由此可以推出分布式与微服务的另一个区别是:分布式中的各个服务是项目中的一部分结构,并不是一个独立的项目,即脱离了项目整体的无法单独运行。而微服务中的各个服务是一个单独的SpringBoot项目,即脱离了项目整体是可以单独运行的。
文章目录
微服务项目的搭建
本系列笔记中会把现在微服务中的三种架构方式(分别为:netfix、spring、alibaba)都做说明,因为这三个架构中的插件各有各的优点,所以在现在的企业开发中,大多数使用微服务架构的企业都会使用这三种架构融合在一起使用。
微服务项目的搭建基于SpringBoot和SpringCloud,而这两种技术之间有严格的版本对应关系,具体关系如下:
netfix(erueka)
netfix是一个很出名的视频网站,很早的时候它的视频网站使用的就是基于微服务搭建的架构,所以在2014年出现微服务概念和架构的时候,netfix便将自己的网站的组件进行了封装并进行开源,所以最早SpringCloud的组件完全是将netfix开源的组件进行了二次封装为自己所用。
首先,我们需要搭建一个基于SpringBoot和SpringCloud的父项目,这个父项目不作任何操作,仅对整个项目的架构提供版本控制以及相关支持。
父项目搭建
新建一个maven项目,不选择任何骨架支持。然后再这个父项目的pom.xml
中引入相关依赖
<properties>
<spring.cloud-version>2021.0.0</spring.cloud-version>
</properties>
<dependencyManagement>
<dependencies>
<!--维护SpringCloud 版本-->
<!--SpringCloud插件的引入同样不会引入依赖,只是维护版本-->
<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>
我们通过<dependencyManagement>
来维护SpringCloud
的版本依赖。接下来需要引入对应的SpringBoot版本依赖。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
</parent>
子项目搭建
Eureka搭建注册中心的时候,我们需要自己搭建一个专门做注册中心的项目并启动,这样才能提供一个服务注册中心给其他的服务。
Eureka服务中心搭建
- 首先需要引入依赖
<dependencies>
<!--springmvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
- 书写配置文件
server:
# eureka server 默认端口号
port: 8761
eureka:
client:
service-url:
# 指定eureka配置文件的路径
defaultZone: http://localhost:8761/eureka
# 如果不设定以下两条配置,则会出现启动时报错,但是不会宕掉服务,因为fetch-registry为true时表示在服务启动的时候就将自己作为服务的一员注册到自己的注册中心中,而这个时候注册中心还没有启动完毕,所以会报错
fetch-registry: false # 在启动时不将自己作为客户端进行注册
# register-with-eureka: false # 仅将自己作为服务注册中心,不作为客户端服务进行注册
spring:
application:
name: EUREKA-SERVER8761
# 服务名不能出现下划线,可以使用横杠来间隔,如果出现下划线后续可能会出现无法找到该服务的情况
# 服务名不区分大小写,但默认为大写,故推荐大写服务名
# 服务名必须唯一
# 大写服务名不方便,我们可以使用IDEA的快捷键 ‘ctrl + shift + u’来快速切换选中数据的大小写
- 最后提供一个SpringBoot项目的启动入口:
// 如果将该项目设定为Eureka的注册中心,则需要在启动类中加入该接口
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
现在可以启动该项目,如果我们将该注册中心也作为一个服务注册到注册中心的话,那我们可以在浏览器中访问我们提供的路径http://localhost:8761
,但是不要加上最后的/eureka
最后的这个接口是为服务调用提供的。
接下来我们可以Eureka为我们提供的注册中心管理界面。
Eureka搭建服务
- 首先引入服务依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
注意关于Eureka的依赖,服务注册中心和普通的服务引入的依赖不一样。
- 书写配置文件
server:
port: 8989
spring:
application:
name: EUREKA-CLIENT8989
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka # 设定服务注册中心的url。表示当前服务注册地址指向
- 最后提供SpringBoot类启动入口
@SpringBootApplication
// 服务调用者的启动类和注册中心的注解不一样,注意区分
@EnableEurekaClient
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class,args);
}
}
细节补充
我们在注册中心和服务调用者都搭建好以后,启动并访问Eureka提供的注册中心管理界面,会发现出现一行红色的英文,这个英文的意思是该服务可能已经终止。这个其实就是微服务中,Eureka为我们提供的一个心跳检查服务。
所谓心跳检查,就是注册中心和服务之间每隔一个固定时间进行一次通信,如果通信成功,则表示该服务还存在;如果通信不成功,则表示该服务可能宕掉了。但是微服务通信是通过http
协议来进行网络通信,这就势必会出现因为网络延迟等原因造成的通信不成功。所以Eureka提供了一个默认的计算方式,即在十五分钟内心跳检查成功率低于85%的时候认定为服务宕机。而这十五分钟无疑是很漫长的,所以为了解决这个情况,我们可以通过修改配置文件来改变这个检查时间。
- 办法一:关闭心跳检查(解决不了问题,就解决出问题的部分)
这个方法是不推荐的,因为心跳检查是专门用来检查各项服务是否出现问题的功能,如果服务宕机而不被检查,那么将会在实际调用该服务的时候出现运行异常等问题。所以我们一般不建议关闭心跳检查,不过你要是非得关闭,那关闭配置如下:
eureka.server.enable-self-preservation=false
- 办法二:修改心跳检查的时间间隔和判定条件
心跳检查的红线是85%,这个是写死在源码中的,所以这个参数我们没办法更改,但是我们可以修改发送心跳检查的频率来缩短判定的时间。
eureka:
instance:
lease-expiration-duration-in-seconds: 10 # 设定心跳检查10s为一组
lease-renewal-interval-in-seconds: 5 # 设定每5s发送一次心跳检查
这种情况下,我们每5s发送一次心跳检查,设定每10s为一组检查,这样如果我们的某个服务宕机了,则可以最快在10s内完成检查。
服务集群搭建
服务集群就是将同一个项目部署在不同的端口、位置甚至不同的服务器之上,一般我们将多个同种服务搭建在同一个服务器中称之为伪集群,真正的集群是部署在不同的服务器中,所以我们在IDEA中可以搭建一个伪集群。
注册中心集群
注册中心的集群是部署多个注册中心,同时将哥哥注册中心互相注册在对方的服务注册中心当中,可以通过修改配置简单的搭建伪集群。
eureka:
client:
service-url:
defaultZone: http://localhost:8763/eureka,http://localhost:8762/eureka
这个时候我们发现8762
和8762
端口并没有启动服务,这时候我们可以通过IDEA启动配置中加入启动参数来修改启动的端口。
上图中先点击1号位置复制一个项目配置,然后在赋值出来的启动项中添加2号的参数,修改启动端口。
如法炮制8763
端口的注册中心,对应的我们应该每次启动不同端口的服务时,修改配置文件中对应的注册端口。为了方便区分各个服务名,其实也可以修改服务名用以区分各个注册中心中注册的服务。
当所有的注册中心启动完毕后,我们可以访问任意一个注册中心的管理页面,这个时候我们都会看到有对应的注册中心服务在当前注册中心的服务列表中。
接下来修改定义的服务调用者的配置文件。
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka,http://localhost:8763/eureka # 设定服务注册中心的url。表示当前服务注册地址指向
在服务调用者的配置文件中,书写任何一个注册中心的url都可以,因为注册中心已经互相注册所以会共享自己的服务注册列表,但是我们为了服务架构的健壮性选择将所有注册中心的url都写入配置,这样在启动的时候会按照默认规则选择一个注册中心进行注册。这涉及到微服务中通信的负载均衡算法,后续会有说明,大家可以暂时有个印象。
总结
本篇笔记记录了netfix
中的基础微服务搭建进行了简单说明,在SpringCloud架构中仅仅是学习的时候有些概念比较繁琐,但是在使用上的确是很方便,在上面的服务搭建中可以看出,其实SpringCloud架构的核心搭建过程仅有三步:引入依赖、书写配置、启动项目。在后续的使用中会有一些较为复杂的细节,总体来说,架构和工具集的作用是方便我们的开发,所以这些复杂的地方基本大同小异,记住核心部分即可。