第一篇了解了Spring Cloud Eureka Server 之后,我们就可以搭建起单机或者简单集群的注册中心,此时已经可以允许客户端将服务注册到eureka server上,开始eureka client的实践!
声明:本次的SC实践采用的是
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
版本,SB采用的是
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
因SC版本迭代以及和SB的版本兼容性问题,故在实操中有些个别的差异性及坑要注意,及时查看官网最新描述,尤其是actuator模块,应注意~
--------------------------------------------------------------------------------------------------------
1、引入相关依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、配置相关属性
一般配置服务名称、端口号、注册地址等。
#application
spring.application.name=movie-service
server.port=8090
eureka.client.service-url.defaultZone=http://localhost:8000/eureka
3、在启动类上添加注解@EnableEurekaClient或者@EnableDiscoveryClient后便可以启动项目。
4、访问【http://localhost:8000/】后会发现我们的客户端服务已经注册到服务端,基本操作已经完成。
这只是简单的操作,即将我的客户端服务注册到服务端服务上。下面问题来了:
1、客户端服务是如何注册到服务端的呢?
2、我的服务端是如何做到服务注册发现的呢?
3、我的服务端是如何管理我的服务列表的呢?
4、熟悉过Dubbo的一定也了解过利用Zookeeper实现服务的注册与发现,那么这两者有何区别和相似点呢?针对这两个技术又如何选型呢?开始一一解答(仅个人意见和总结)。
1、 客户端服务是如何注册到服务端的呢?
在配置中我们不难发现有这个配置:
eureka.client.service-url.defaultZone=http://localhost:8000/eureka
这个配置指定了我的客户端所要注册的地址,在启动类中有@EnbaleDiscoveryClient注解,该注解激活了自动注册和发现功能,下面来看一下这个注解的概述:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({EnableDiscoveryClientImportSelector.class})
public @interface EnableDiscoveryClient {
boolean autoRegister() default true;
}
除了四个元注解外还有一个很熟悉的注解@Import注解,该注解指定了外层注解的要引入的辅助类。
服务提供者:
服务注册:服务提供者在自启动时会发送rest请求到注册中心并把自己注册到eureka server上,同时带上自身服务的一些元数据,eureka server接收到这个rest请求后将元数据信息存储在一个双层的Map中,第一层的Key为服务名称,第二层Key为具体的服务的实例名。在服务注册时,eureka.client.register-with-eureka=true(默认),若为false,则不会触发注册,这也是eureka server将改配置设为false的原因,即自己不向自身注册。
服务同步:
服务续约:服务提供者会维护一个心跳机制向eureka server通知自身还活着(此处可以延伸理解dubbo的心跳检测机制<利用ScheduleExecutorService实现定时发送心跳检测>)以防止被eureka serve剔除服务列表,重要配置如下:
eureka.instance.lease-renewal-intervel-in-second=30//服务续约时间间隔
eureka.instance.lease-expiration-duration-in-second=90//服务失效时间
服务消费者:
获取服务:服务消费者会从服务注册中心获取到当前所有服务的服务列表,eureka server为了性能考虑会维护一份只读的服务清单返给服务消费者。
服务消费:
服务下线:
注册中心:
服务失效剔除:
服务保护机制:为了防止出现健康的服务被误删除所以eureka server会先保留当前的服务,可以通过eureka.server-enable-self-preservation=false来关闭自我保护机制。
客户端和服务端的相关配置,可引入actuator,引入health、info等端点来对系统进行监控等
Zookeeper和Eureka的选型及技术比较:
Zookeeper是一个分布式协调服务组件,基于CP原则,保证数据一致性和容错。可以先了解一下Zookeeper的内部选举机制,当当前的leader宕机或者不可用时,此时会触发leader选举机制,在选举过程中存在服务对外不可用的空档时间,针对该空档时间的长短对整个系统的可用性的影响也是不太确定的这也是我们不太愿意看到的,虽然所我们可以在leader的选举上进行优化(主要是配置follower和observer,虽然两者都能同步数据信息,但是在选举时observer不参与投票,这就减少了多台机器的选举时间)
Spring Cloud Eureka是基于Netflix Eureka实现的服务注册,他是基于AP原则,放弃了数据的强一致性,保证了服务的可用性,同时为了避免因网络问题造成的网络不可用导致的服务剔除问题而采取的自我保护机制等等。
针对采用何种注册中心不能单纯的依靠哪一点或者哪一方面,开发过程及实现过程是眼前要考虑的,对其他组件的影响和兼容等、当然还要考虑他的运维层次等事情,包括部署环境、业务要求、团队的知识储备等。同样作为注册中心的还有consul,至于在实际的项目中作何选择,就只能仁者见仁、智者见智了。若要面试时被问及该问题,笔者猜想面试官故意给面试者挖坑,所以不要立马就回答这个问题,最好能够考虑全面再去回答这个问题。这两者不能说孰优孰劣,适合自己的才是最好的。