先在这里
声明
一下:这一系列的文章都是自己查询网上资料学习而来,不可避免有些内容从其他地方copy过来,如有侵犯请联系我删除,谢谢!(引用部分都会添加注脚
)
本系列文章的写作环境为:
Spring Boot 2.0.7.RELEASE
、Spring Cloud Finchley.SR2
、JDK 1.8.0_131
、IntelliJ IDEA ULTIMATE 2018.1
。并没有使用最新版本的Spring Cloud进行学习,原因是新版本还不稳定,存在很多问题,不要把时间花费在无谓的BUG上。
1 Spring Cloud Eureka 介绍
在上篇文章简单介绍了Spring Cloud和微服务架构之后,下面回归本文的主旨内容,如何使用Spring Cloud来实现服务治理
。
由于Spring Cloud为服务治理做了一层抽象接口,所以在Spring Cloud应用中可以支持多种不同的服务治理框架,比如:Netflix Eureka、Consul、Zookeeper。在Spring Cloud服务治理抽象层的作用下,我们
可以无缝地切换服务治理实现
,并且不影响任何其他的服务注册、服务发现、服务调用等逻辑。1
Eureka是 Netflix 开源的一款基于REST(Representational State Transfer)风格的服务发现框架,目前已被 Spring Cloud 集成在其子项目 spring-cloud-netflix 中,用于 Spring Cloud 的服务注册发现功能。
下面,就来具体看看如何使用Spring Cloud Eureka实现服务治理。
2 Spring Cloud Eureka 工作过程
Eureka包含了服务器端
和客户端
组件。服务器端,也被称作是服务注册中心,用于提供服务的注册与发现。
客户端组件包含服务消费者
与服务生产者
。在应用程序运行时,Eureka客户端向Eureka服务端注册自身提供的服务并周期性的发送心跳来更新它的服务租约。同时也可以从服务端查询当前注册的服务信息并把他们缓存到本地并周期性的刷新服务状态。2
当一个Eureka客户端注册到Eureka服务端,它会提供关于它自己的端口、地址、健康监控URL和Home页面等等的元数据,服务端会从每个实例接受心跳信息。如果心跳在配置的时间内失败,实例通常会从注册表中移除。
Eureka支持高可用的配置(图中没有画出来,后边会有讲解),当集群中有分片出现故障时,Eureka就会转入自动保护模式,它允许分片故障期间继续提供服务的发现和注册,当故障分片恢复正常时,集群中其他分片会把他们的状态再次同步回来。
关系调用说明:
- 服务生产者启动时,向服务注册中心注册自己提供的服务;
- 服务消费者启动时,在服务注册中心订阅自己所需要的服务;
- 注册中心返回服务提供者的地址信息给消费者;
- 消费者从提供者中调用服务;
3 Spring Cloud Eureka Server 配置过程
3.1 pom.xml 添加依赖
Eureka 服务端我们只需要添加一个依赖就可以。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
3.2 配置启动类
通过@EnableEurekaServer
注解启动一个服务注册中心:
@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaServerApplication.class, args);
}
}
到此,我们 Eureka Server 就算是搭建完成了,是不是so easy。但是,如果直接启动的话会报错,原因请看 3.3 application.yml基础配置。
3.3 application.yml基础配置
下面是一个Eureka服务器最基本的配置:
spring:
application:
name: eureka-server
server:
port: 9000
eureka:
instance:
hostname: eureka-server.com
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
logging.level.root: info
配置解释:
eureka.instance
: 对eureka实例进行配置的部分;eureka.instance.hostname
:定义 eureka 实例所在的主机名称。在C:\Windows\System32\drivers\etc\hosts
文件中添加如下内容:127.0.0.1 eureka-server.com
,然后我们就可以使用http://eureka-server.com:9000/
来访问 eureka 的信息展示页面;eureka.client
:客户端进行 eureka 注册的配置;eureka.client.fetch-registry
:是否从 eureka 服务器上获取注册信息,默认为 true,此处建议修改成 false(单机设置的意义不大。如果设置成 true,启动时会去抓取一次注册表,获取不到更新缓存就会出错(该错误不影响 eureka 正常使用));eureka.client.register-with-eureka
:在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为;eureka.client.service-url.defaultZone
:指定服务注册中心的位置。默认注册地址this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");
,此处的 defaultZone 千万别写成 default-zone。另外,请注意,serviceUrl指向与本地实例相同的主机。
默认情况下,每个Eureka服务器也是一个Eureka客户端,所以需要(至少一个)服务URL来定位Eureka服务器。如果不提供,Eureka服务器也会运行和工作,但会产生大量无法注册到Eureka服务器的日志。
3.4 Controller、Service等
Eureka Server 不需要Controller、Service等,只需简单配置就可以。
3.5 配置/测试/展示结果
3.5.1 访问 eureka
此时,访问 eureka(页面上东西很多,我只截取了部分):对于页面上的各部分不理解没关系,后面会讲解
3.5.2 设置注册表的更新时间
在实际的项目运行过程之中需要通过 Eureka 作为所有微服务的监控处理程序,但是对于监控程序那么就必然要面临以下问题:
- 新服务追加的时候应该立刻可以进行注册;
- 当某一个服务下线之后应该可以进行清理;
在 application.yml 文件中添加如下配置项:
eureka:
server:
eviction-interval-timer-in-ms: 5000
配置解释:
eureka.server.eviction-interval-timer-in-ms
: 设置注册表的清理间隔(默认是60 * 1000 毫秒)。单位:毫秒
可以看到,注册表的清理间隔已经变成每5秒清理一次了。
一般情况下,该配置不建议进行修改,默认就是 60 秒,也就是说你的微服务如果 60 秒没有心跳了,那么就认为可以清理掉。
3.5.3 Eureka 自我保护模式3
自我保护模式是Eureka的重要特性。进入自我保护模式最直观的体现,是Eureka Server首页输出的警告:
默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。
Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。
在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false
禁用自我保护模式。
3.5.3 Eureka 安全配置
可以注册的服务是能够满足于认证要求的微服务,所以这样一来在之前所进行的 Eureka 里面配置缺少关键性的一步: 安全认证,所以应该为 Eureka 配置上安全认证处理。
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
一旦我们的项目之中导入了 Security 开发包,则每一次启动微服务的时候都会自动生成一个密码, 而这个密码由于会改变,所以一般都不使用。要修改 application.yml 配置文件,追加密码的配置项:
spring.security.user.name: lpf
spring.security.user.password: root
此时再访问Eureka就需要输入密码了:
这里需要注意
:如果只是简单进行上面的配置,Eureka Client是不能成功注册到Eureka Server上的。
原因是由于新版的Spring Security会默认开启防 csrf 攻击,所有的请求都必须携带 crsf 这个参数,但是Eureka Client去注册时是没有的。所以我们需要主动去关闭,在Eureka Server添加以下配置:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}
注意:添加安全配置后
eureka.client.service-url.defaultZone
需要进行修改,改成:http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/
未完,请看下文……