Spring Cloud构建微服务架构(一)服务注册与发现、高可用(Eureka)

服务注册发现

1.1 服务发现

在微服务架构中,服务发现组件是很关键的一个组件,服务发现组件就是去管理各服务的网络地址等信息。

服务提供者、服务消费者、服务发现组件的关系:

服务启动时,会将自己的网络地址等信息注册到服务发现组件中,让服务发现组件去存储管理这些信息。

服务消费者从服务发现组件这里查询服务提供者的网路地址信息,并使用该地址去调用服务提供者的接口。

各服务和服务发现组件通过一定的机制通信(心跳)。

Spring Cloud 支持多种服务发现组件,如 Eureka、Consul 和 Zookeeper 等,这里主要介绍 Spring Cloud Eureka 的使用。

1.2 Eureka简介

Eureka 是 Netflix 开源的服务治理模块,本身是一个基于 Rest 的服务。Spring Cloud 中将 Eureka 集成在 Spring Cloud Netflix 项目中,另外 Spring Cloud Netflix 还提供了自配置的Netflix OSS整合。提供的模块包括:服务发现(Eureka),断路器(Hystrix),智能路由(Zuul),客户端负载均衡(Ribbon)等。

Eureka架构图

Eureka 是包含两个组件的:Eureka Server 和 Eureka Client

Eureka Server 提供服务发现的功能,服务启动后,向 Eureka Server 注册自己的地址信息(IP、端口、服务名)

Eureka Client 是一个客户端,用于与 Eureka 的交互0服务启动后,与 Eureka Server 通过 心跳 机制通信,默认周期为 30 秒

当 Eureka Server 在一定时间内接收不到某个服务实例的心跳,将会注销该实例,默认时间为 90 秒

默认情况下 Eureka Server 同时也是 Eureka Client。多个 Eureka Server 实例通过复制的方式来实现服务注册

Eureka Client 有 缓存机制,会缓存服务注册表中的信息。服务不需要每次请求都查询 Eureka Server,这样既降低了 Server 的压力,同时即便 Eureka Server 的节点都宕机了,也可以使用缓存查询到服务提供者的信息完成调用

服务注册中心 Eureka Server

创建一个 Spring Boot 项目,依赖项 dependencies 添加 Eureka Server , pom.xml 文件部分内容如下:

org.springframework.bootspring-boot-starter-parent2.1.4.RELEASEcom.cindyeureka-server0.0.1-SNAPSHOTeureka-server1.8Greenwich.SR1org.springframework.cloudspring-cloud-starter-netflix-eureka-serverorg.springframework.cloudspring-cloud-dependencies${spring-cloud.version}pomimport

要启动一个服务注册中心,我们要使用注解 @EnableEurekaServer

@SpringBootApplication@EnableEurekaServerpublicclassEurekaServerApplication{publicstaticvoidmain(String[] args){        SpringApplication.run(EurekaServerApplication.class, args);    }}

这个时候如果我们直接启动,会发现有个连接异常,那是因为默认设置下,服务注册中心也会把自己当做客户端来注册自己,也就是说 Eureka Server 同时也是一个 Eureka Client,需要指定一个 Server。而通常我们只需要它作为注册中心,可以使用 eureka.client.registerWithEureka=false 和 eureka.client.fetchRegistry:false 来禁用客户端注册行为

spring:application:name:eureka-serverserver:port:8761eureka:client:    # 是否将自己注册到 Eureka ServerregisterWithEureka:false    # 是否从 Eureka Server 获取注册信息fetchRegistry:falseeurekaserver 有一个UI的主页,并且 /eureka/* 下有正常 Eureka 功能的HTTP API端点。

启动工程,访问 http://localhost:8761可以看到以下页面,由于还没有注册服务,所以没有被发现的服务

3 注册服务

上面创建了服务注册中心,接下来我们来创建服务客户端,也就是我们要去注册的服务。

还是去创建一个 Spring Boot 工程,要添加的依赖为 Eureka Discovery。

org.springframework.bootspring-boot-starter-parent2.1.4.RELEASEcom.cindyproduct1.0.0-SNAPSHOTproduct1.8Greenwich.SR1org.springframework.cloudspring-cloud-starter-netflix-eureka-clientorg.springframework.bootspring-boot-starter-web    org.springframework.bootspring-boot-starter-testtestorg.springframework.cloudspring-cloud-dependencies${spring-cloud.version}pomimport

同样的,要使用服务注册需要主类上添加注解,注解为@EnableDiscoveryClient

@SpringBootApplication@EnableDiscoveryClientpublicclassProductApplication{publicstaticvoidmain(String[] args){        SpringApplication.run(ProductApplication.class, args);    }}

上面的注解也可使用 @EnableEurekaClient,而 @EnableDiscoveryClient 是 spring-cloud-commons 项目的注解,是一个高度的抽象,对各种服务发现组件都提供了支持,如 Zookeeper 和 Consul 也支持

这时需要在客户端这边配置服务注册中心的一些信息,defaultZone 是与 Eureka Server 交互地址,用于查询服务和注册服务 (默认端口是 8761),如果要向多个服务中心注册用逗号隔开

spring:application:name:productserver:port:8081eureka:client:serviceUrl:      # 这里默认是 http://localhost:8761/eureka/defaultZone:http://localhost:8761/eureka/如果想要IP 地址注册,而不是主机名。可以设置 eureka.instance.preferIpAddress=true

先启动 Eureka Server,再启动该工程,我们打开 Eureka Server 的 UI 界面,可以看到我们的 product 服务已经注册成功了

Eureka 的高可用

尽管 Eureka 的客户端具有缓存机制,即使 Eureka Server 宕机,服务之间也可以通过缓存调用,但是在 Eureka Server 宕机的时候,一些微服务也可能出现不可用的问题,而这些情况会没有被更新到缓存中,就可能会影响到某些微服务的调用。

生产中通常会部署一个高可用的 Eureka Server 集群,由上面的 Eureka 架构图也可以看出可以通过运行多个 Eureka Server 实例并让他们相互注册来实现高可用部署。

我们来改一下上面的 eureka-server ,同时启动两个实例,来构建双节点的服务注册中心。这里我们要让 Eureka Server 相互注册,所以 registerWithEureka 和 fetchRegistry 就不设置 false 了,而 serviceUrl.defaultZone 则需要填入其他 Eureka Server 的服务地址

spring:application:name:eureka-server---server:port:8761eureka:client:serviceUrl:defaultZone:http://127.0.0.1:8762/eureka/      ---server:port:8762eureka:client:serviceUrl:defaultZone:http://127.0.0.1:8761/eureka/

这里我们起两台服务器,端口号分别为 8761 和 8762

启动之后我们再启动注册服务

端口号为 8762 的 server也能获取端口号为 8761 server 的服务注册信息,尽管我们的注册服务只写了 http://127.0.0.1:8761/eureka/, 这里我们要注册的服务最好把所有的 Eureka Server 地址都添加上,避免在某些情况下服务重启会注册不到

eureka:client:service-url:defaultZone:http://localhost:8761/eureka/,http://localhost:8761/eureka/

如果要构建多个节点的集群,其实也是很简单的,只要它们至少一个边缘彼此连接,也就是两两相互注册就可以了,同时服务同时向他们进行注册

上面直接通过不同 IP 地址和端口号来配置多个服务器会有些麻烦,可以使用 eureka.instance.hostname 定义不同的主机名配合 spring.profiles.active 激活不同的 application-{profile}.yml 配置文件来构建集群

server:  port: 8761eureka:instance:hostname:peer1client:service-url:defaulZone:http://peer2:8762/eureka/,http://peer3:8763/eureka/

server: port: 8762eureka:instance:hostname:peer2client:service-url:defaulZone:http://peer1:8761/eureka/,http://peer3:8763/eureka/

server:  port: 8763eureka:instance:hostname:peer3client:service-url:defaulZone:http://peer1:8761/eureka/,http://peer2:8762/eureka/

如上,我们定义了三个不同的 profile,同时命名了三个 Eureka Server 主机名,分别为 peer1、peer2 和 peer3,这样当我们以 peer1 这个 profile 启动项目,它会去注册到 http://peer2:8762/eureka/ 和 http://peer3:8763/eureka/; 同样当 spring.profiles.active 为 peer2 或者 peer3 时,他们会向其他两个地址注册服务,这样便做到了两两相互注册。

当我们打包好项目,可以通过以下命令来分别启动这三个 Eureka Server 节点。

java-jar eureka-server.jar --spring.profiles.active=peer1java-jar eureka-server.jar --spring.profiles.active=peer2java-jar eureka-server.jar --spring.profiles.active=peer3

当我们把服务再注册到这个 Eureka Server 集群的时候,配置多个 Eureka Server 地址就可以了

eureka:client:service-url:defaultZone:http://peer1:8761/eureka/,http://peer2:8762/eureka/,http://peer3:8763/eureka/

如果这里的主机名直接可以设置成域名,就可以直接配置像 http://peer1/eureka/ 这样的地址了。如果不是,就需要通过操作注册服务的服务器系统 /etc/hosts 来解析主机名,如127.0.0.1 peer1 peer2 peer3。

参考:http://blog.didispace.com/springcloud1/

https://mp.weixin.qq.com/s/4c0PQO-u9qfP-sTFHUdVkA

你可能感兴趣的:(Spring Cloud构建微服务架构(一)服务注册与发现、高可用(Eureka))