1 Eureka 注册中心
1.1 需求分析
在前后端分离架构中,服务层被拆分成了很多的微服务,微服务的信息如何管理?Spring Cloud中提供服务注册中心来管理微服务信息。
1.2 为什么要用注册中心?
1、微服务数量众多,要进行远程调用就需要知道服务端的ip地址和端口,注册中心帮助我们管理这些服务的ip和端口。
2、微服务会实时上报自己的状态,注册中心统一管理这些微服务的状态,将存在问题的服务踢出服务列表,客户端获取到可用的服务进行调用。
1.3 Eureka注册中心
1.3.1 Eureka介绍
Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka采用的是C/S架构,提供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和客户端均采用Java语言编写。下图显示了Eureka Server与Eureka Client的关系:
- Eureka Server是服务端,负责管理各各微服务结点的信息和状态。
- 在微服务上部署Eureka Client程序,远程访问Eureka Server将自己注册在Eureka Server。
- 微服务需要调用另一个微服务时从Eureka Server中获取服务调用地址,进行远程调用。
1.3.2 Eureka Server搭建
1.3.2.1 单机环境搭建
- 创建注册中心工程springcloud-eureka-server工程:
- 添加依赖
父工程添加:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
在Eureka Server工程添加:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐eureka‐server</artifactId>
</dependency>
- 启动类
需要在启动类上用@EnableEurekaServer标识此服务为Eureka服务
@EnableEurekaServer //标识此工程是一个EurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
- 配置 application.yml
server:
port: 8761 #服务端口
spring:
application:
name: springcloud-eureka-server #指定服务名
eureka:
client:
registerWithEureka: false #服务注册,是否将自己注册到Eureka服务中
fetchRegistry: false #服务发现,是否从Eureka中获取注册信息
serviceUrl: #Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口)
defaultZone: http://localhost:8761/eureka/
server:
enable‐self‐preservation: false #是否开启自我保护模式
eviction‐interval‐timer‐in‐ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)
- registerWithEureka:被其它服务调用时需向Eureka注册
- fetchRegistry:需要从Eureka中查找要调用的目标服务时需要设置为true
- serviceUrl.defaultZone 配置上报Eureka服务地址高可用状态配置对方的地址,单机状态配置自己
- enable-self-preservation:自保护设置,下边有介绍。
- eviction-interval-timer-in-ms:清理失效结点的间隔,在这个时间段内如果没有收到该结点的上报则将结点从服务列表中剔除。
- 启动项目
访问服务:http://localhost:8761/
Eureka Server有一种自我保护模式,当微服务不再向Eureka Server上报状态,Eureka Server会从服务列表将此服务删除,如果出现网络异常情况(微服务正常),此时Eureka server进入自保护模式,不再将微服务从服务列表删除。在开发阶段建议关闭自保护模式。
1.3.2.2 高可用环境搭建
Eureka Server 高可用环境需要部署至少两个Eureka server,它们互相向对方注册。如果在本机启动两个Eureka需要注意两个Eureka Server的端口要设置不一样,这里我们部署一个Eureka Server工程,将端口可配置,制作两个Eureka Server启动脚本,启动不同的端口,如下图:
1)在实际使用时Eureka Server至少部署两台服务器,实现高可用。
2)两台Eureka Server互相注册。
3)微服务需要连接两台Eureka Server注册,当其中一台Eureka死掉也不会影响服务的注册与发现。
4)微服务会定时向Eureka server发送心跳,报告自己的状态。
5)微服务从注册中心获取服务地址以RESTful方式发起远程调用。
- 修改application配置文件
server:
port: ${PORT:8761} #服务端口
spring:
application:
name: springcloud-eureka-server #指定服务名
eureka:
client:
registerWithEureka: true #服务注册,是否将自己注册到Eureka服务中
fetchRegistry: true #服务发现,是否从Eureka中获取注册信息
serviceUrl: #Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口)
defaultZone: ${EUREKA_SERVER:http://localhost:8762/eureka/}
server:
enable-self-preservation: false #是否开启自我保护模式
eviction-interval-timer-in-ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)
- 配置两个启动应用
分别设置启动参数(IDEA 或者Eclipse均可).
-DPORT=8762 -DEUREKA_SERVER=http://localhost:8761/eureka/
-DPORT=8761 -DEUREKA_SERVER=http://localhost:8762/eureka/ - 启动两个服务,访问其中任意一个即可
1.3.3 服务注册
官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.2.1.RELEASE/reference/html/#service-discovery-eureka-clients
1.3.3.1 将teacher服务注册到Eureka Server
- teacher工程添加依赖
<!‐‐ 导入Eureka客户端的依赖 ‐‐>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐eureka‐client</artifactId>
</dependency>
- 在application.yml配置注册中心及服务名
server:
port: ${PORT:8082}
spring:
application:
name: service-provider-teacher
eureka:
client:
registerWithEureka: true #服务注册开关
fetchRegistry: true #服务发现开关
serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔
defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka/,http://localhost:8762/eureka/}
instance:
prefer-ip-address: true #将自己的ip地址注册到Eureka服务中
ip-address: ${IP_ADDRESS:127.0.0.1}
instance-id: ${spring.application.name}:${server.port} #指定实例id
- 添加客户端注解
@EnableDiscoveryClient
在启动类上添加该注解,表示它是一个Eureka的客户端。
- 启动教师微服务,刷新服务注册中心。
即可看见新注册的教师微服务了。同理可将其他微服务注册到注册心。
1.3.4 特殊说明
官网地址:https://spring.io/projects/spring-cloud
版本问题
- Spring Cloud是一个集合包含很多子项目,为了避免子项目冲突,发行版本只有名称没有版本号;名称带有伦敦地铁名称按照字母顺序发型(Angel是第一个版本,Brixton是第二个,现在最新版本是Hoxton)
- Spring Cloud和Spring Boot 版本兼容问题,不兼容启动会报错:
java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V
配置说明
服务端配置
server:
port: 8090
eureka:
server:
enable-self-preservation: false #关闭自我保护机制
eviction-interval-timer-in-ms: 4000 #设置清理间隔(单位:毫秒 默认是60*1000)
instance:
hostname: localhost
client:
registerWithEureka: false #不把自己作为一个客户端注册到自己身上,集群需要true
fetchRegistry: false #不需要从服务端获取注册信息(因为在这里自己就是服务端,而且已经禁用自己注册了),集群需要true
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka #集群的时候配置多个,因为注册信息会同步所以在集群的时候不需要配置自己的地址
客户端配置
server:
port: 8080
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8090/eureka/ #eureka服务端提供的注册地址 参考服务端配置的这个路径,多个用逗号隔开
instance:
instance-id: power-1 #此实例注册到eureka服务端的唯一的实例ID,每个实例ID需要不同
prefer-ip-address: true #是否显示IP地址
leaseRenewalIntervalInSeconds: 10 #eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒 (与下面配置的单位都是秒)
leaseExpirationDurationInSeconds: 30 #Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
spring:
application:
name: server-power #此实例注册到eureka服务端的name,同一个服务多个实例配置同一个名称
1.3.5 Eureka对比Zookeeper:
- Zookeeper在设计的时候遵循的是CP原则,即一致性,Zookeeper会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时剩余节点会重新进行leader选举,问题在于,选举leader的时间太长:30~120s,且选举期间整个Zookeeper集群是不可用的,这就导致在选举期间注册服务处于瘫痪状态,在云部署的环境下,因网络环境使Zookeeper集群失去master节点是较大概率发生的事情,虽然服务能够最终恢复,但是漫长的选举时间导致长期的服务注册不可用是不能容忍的。
- Eureka在设计的时候遵循的是AP原则,即可用性。Eureka各个节点(服务)是平等的, 没有主从之分,几个节点down掉不会影响正常工作,剩余的节点(服务) 依然可以提供注册与查询服务,而Eureka的客户端在向某个Eureka注册或发现连接失败,则会自动切换到其他节点,也就是说,只要有一台Eureka还在,就能注册可用(保证可用性), 只不过查询到的信息不是最新的(不保证强一致),除此之外,Eureka还有自我保护机制,如果在15分钟内超过85%节点都没有正常心跳,那么eureka就认为客户端与注册中心出现了网络故障,此时会出现一下情况:
1: Eureka 不再从注册列表中移除因为长时间没有收到心跳而过期的服务。
2:Eureka 仍然能够接收新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点可用)。
3: 当网络稳定后,当前实例新的注册信息会被同步到其它节点中。 - CAP:C即Consistency 中文叫做"一致性";A即Availability 中文叫做"可用性";P即Partition tolerance中文叫做"分区容错"。
源码地址:https://github.com/qqxhb/springcloud-demo
下篇:Spring Cloud——负载均衡Ribbon和远程调用Feign原理和示例