注册中心-Eureka 基础篇
文章目录
前言
注册中心的内容分为上下两章进行发布
- 上篇,基础部分,介绍注册中心的基本概念和含义,以及 Eureka 的基本使用和部署。
- 下篇,源码分析,讨论 Eureka 如何实现服务注册和服务发现,以及 Eureka 中的重要设计实现和相关细节。
项目环境
- Java 8
- Spring Cloud Finchley
- 项目地址:https://github.com/huajiexiewenfeng/deep-in-spring-cloud-netflix
1.什么是注册中心?
注册中心是统一管理所有服务注册信息的平台
在学习相关的概念之前,我们先来看看为什么需要注册中心,或者说它是怎么来的?
假设下图的服务调用场景:
在传统的单体应用场景中,假设一个用户下单,此时后台的订单服务调用库存服务,因为都是单体应用,所以只需要记录一个服务地址,就可以通过 RPC 或者其他远程调用的方式来进行服务调用。
但是随着业务的体量越来越大,当库存服务达到一定的瓶颈,我们就需要库存服务做集群,然后采用负载均衡的策略来应对服务调用的压力,而客户端负载均衡的首要条件就是拿到所有的库存服务器列表,然后再通过随机、轮询、加权等等方式来进行负载均衡,已达到对应的目的。
我们就需要一个平台来记录和管理各个服务的元信息,比如 IP 地址,端口,运行状态等等,这就是注册中心。
1.1 服务注册
服务注册指的就是服务启动的时候将自身的相关信息注册到 注册中心 上,方便信息的统一管理。
1.2 服务发现
服务发现指的是从 注册中心 获取对应服务的信息,服务发现是客户端向注册中心获取信息的动作。
在 Spring Cloud 中,对应的服务发现客户端的接口源码如下:
public interface DiscoveryClient {
/**
* A human readable description of the implementation, used in HealthIndicator
* @return the description
*/
String description();
/**
* Get all ServiceInstances associated with a particular serviceId
* @param serviceId the serviceId to query
* @return a List of ServiceInstance
*/
List<ServiceInstance> getInstances(String serviceId);
/**
* @return all known service ids
*/
List<String> getServices();
}
可以看到服务发现接口方法返回的一般是一个 List 列表。
服务的元信息 ServiceInstance 接口代码如下:
public interface ServiceInstance {
String getServiceId();
String getHost();
int getPort();
boolean isSecure();
URI getUri();
Map<String, String> getMetadata();
default String getScheme() {
return null;
}
}
1.3 整体流程图
- 订单服务和库存服务启动,将服务信息注册到注册中心(服务注册);
- 订单服务调用库存服务,先从注册中心获取库存服务信息列表(服务发现);
- 客服端(订单服务)负载均衡器从信息列表中(随机/轮询/加权等等)选择一个库存服务进行访问;
- 心跳指的是健康汇报,定时跟注册中心汇报服务健康状态;当一定时间内无心跳产生,则证明服务可能出现故障,无法汇报健康状态,注册中心就会剔除无效的服务信息。
2.什么是 Eureka?
Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud for locating services for the purpose of load balancing and failover of middle-tier servers. We call this service, the Eureka Server. Eureka also comes with a Java-based client component,the Eureka Client, which makes interactions with the service much easier. The client also has a built-in load balancer that does basic round-robin load balancing. At Netflix, a much more sophisticated load balancer wraps Eureka to provide weighted load balancing based on several factors like traffic, resource usage, error conditions etc to provide superior resiliency.
Eureka 是一个基于 REST(表述性状态转移)的服务,主要用于AWS云中定位服务,以实现中间层服务器的负载平衡和故障转移。
Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 进行了二次封装,主要负责完成微服务架构中的服务治理功能。
3.部署 Eureka Server 服务端
示例具体代码参考 github 仓库
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
引导类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
application.yaml 配置文件
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server:
waitTimeInMsWhenSyncEmpty: 0
配置信息说明
-
端口默认配置 8761;
-
eureka.client.registerWithEureka:表示是否将自己的实例注册到 Eureka Server 中,这里配置成 false,本身是 Eureka Server 节点,不需要将自己进行注册;
-
eureka.client.fetchRegistry:表示是否应从 Eureka Server 中获取 Eureka 的注册表信息,这里也设置成 false,因为不需要消费其他服务信息,所以也不需要拉取注册表信息;
-
eureka.server.waitTimeInMsWhenSyncEmpty:表示从其他节点同步实例信息为空时等待的时间。
相关的配置 Bean 源码位置:org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean
4.部署 Eureka Client 客户端
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
引导类
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientProviderServer {
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaClientProviderServer.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
application.yaml 配置文件
server:
port: 8081
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/
spring:
application:
name: eureka-client-provider
eureka.client.serviceUrl.defaultZone : 注册中心的地址
启动效果
浏览器输入127.0.0.1:8761
5.集群部署
Eureka Server 之间会将注册信息复制到集群中的 Eureka Server 的所有节点中,也就是说可以在任意一个 Eureka Server 的节点上进行注册,也可以在任意一个节点上进行读取,因为集群之间会相互复制注册信息。
假设我们需要搭建一个由两个节点组成的集群,核心思想就是 A 节点会将自己的信息复制到 B 节点,B 节点会将自己的信息复制到 A 节点。
我们将 Eureka Server 示例代码进行改造;
修改配置文件 application.yaml
spring:
profiles:
active: master
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server:
waitTimeInMsWhenSyncEmpty: 0
新增配置文件 application-master.yaml
server:
port: 8761
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8762/eureka/
新增配置文件 application-slave.yaml
server:
port: 8762
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/
启动步骤
-
修改
spring.profiles.active=master
,启动 Eureka Server 主服务; -
修改
spring.profiles.active=slave
,再次启动 Eureka Server 从服务; -
启动 Eureka Client 服务,将服务注册到主服务中。
浏览器输入 http://127.0.0.1:8761/,可以看到服务正确注册。
浏览器输入 http://127.0.0.1:8762/,可以看到服务已经被复制到了 Eureka Server 从服务中。
6.总结
本章我们主要介绍了注册中心的来源,讨论了什么是服务注册和服务发现
- 服务注册,主要是服务将自身信息注册到注册中心
- 服务发现,则是从注册中心获取服务相关的信息
然后,简单的演示了如何部署 Eureka 的服务端和客户端,以及 Eureka Server 集群如何部署。