微服务之服务发现

概述

在微服务架构中,服务发现可以说是最为核心和基础的模块,这个模块主要用于实现各个微服务实例的自动化注册和发现。这篇文章介绍了微服务架构中的服务发现技术,介绍了服务发现的概念与用法。

什么是服务发现

服务发现组件可以看作为一个服务中介,让服务提供者(生产者)在此进行服务注册,并为微服务调用者(消费者)提供服务信息。

以生活中的例子来类比,在美团上有跑腿服务,小明闲置在家,于是去注册了一个账号,为人提供跑腿服务,此时小华需要人帮忙跑腿办点事,于是去美团上看,找到了小明,最终小明为小华提供了跑腿服务。在这个事件中,美团平台就扮演了服务发现角色,小明扮演服务提供方为人提供服务,小华作为服务调用者。如果有很多人注册提供跑腿服务,那消费者就可以拿到一个服务列表,可以从中选择一个服务。

常见的实现技术

Eureka

eureka 读音 [juˈriːkə] ,意为(因找到某物,尤指问题的答案而高兴)我发现了,我找到了。

Eureka 是 Netflix 公司开源的项目,spring cloud 对其做了二次封装,于是有了 spring cloud eureka 子项目。

官方项目信息:https://spring.io/projects/spring-cloud-netflix

在 spring cloud 中可以使用 eureka 来实现服务发现功能。在 Eureka 中,分为服务端(Eureka Server)和客户端(Eureka Client),服务端提供服务注册功能,客户端的发现组件用于处理服务的注册于发现。

当客户端启动时,会向注册中心注册自己提供的服务,并周期性的发送心跳来更新服务,如果连续三次心跳都不能发现服务,Eureka 将会把这个服务节点从服务列表中移除。

如果服务端出现问题,客户端可以通过自己缓存的服务信息进行服务调用。各个服务之间会通过注册中心的注册信息以 Rest 方式实现调用,并且可以直接通过服务名进行调用。

Zookeeper

官网: https://zookeeper.apache.org/

Zookeeper 是一个开源的、处理分布式系统协调工作的服务组件,程序可以基于 Zookeeper 实现数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、分布式锁、分布式队列等功能。常见的使用场景是将 Zookeeper 作为协调生产者和消费者的注册中心,在 dubbo 中,官方就推荐使用 Zookeeper 作为注册中心。

Consul

consul ,读音 [ˈkɑːnsl] ,意为领事。

Consul 官网: https://www.consul.io/

Consul 是 HashiCorp 公司开源的、用于分布式系统服务发现和配置的工具,其具有部署简单、轻量的特点。Consul 的使用场景包括服务发现、服务隔离、服务配置。

Nacos

官网: https://nacos.io/

Nacos 是阿里开源项目,致力于服务发现、配置和管理,能够实现服务发现和健康监测、动态服务配置、动态DMS服务、服务元数据及流量管理。

示例

Spring Cloud Eureka

Spring Cloud Eureka Server

创建一个 springboot 工程,引入 spring cloud 依赖和 eureka server 的依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<properties>
<java.version>1.8</java.version>
<!-- 所有微服务都要使用同一个版本 -->
<spring-cloud.version>2020.0.0-SNAPSHOT</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- eureka server 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>

<!-- spring cloud 依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

在启动类上加上 @EnableEurekaServer 注解。

1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}

修改配置

配置说明:

  • 配置端口号为 8761 ,其他服务实例都要向这个端口注册服务。

  • 配置实例名为 localhost

  • 因为这是一个 eureka server,不需要注册自己,将 eureka.client.register-with-eurekaeureka.client.fetch-registry 设置为 false

  • 将注册中心的地址改为当前项目地址,将 eureka.client.service-url.defaultZone 改为 http://${eureka.instance.hostname}:${server.port}/eureka/

1
2
3
4
5
6
7
8
9
10
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
instance:
hostname: localhost
server:
port: 8761

运行项目,访问 http://localhost:8761/ ,查看 Eureka 的信息面板。

Spring Cloud Eureka Client

创建 springboot 项目,添加 spring cloud 和 spring cloud eureka client 依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<properties>
<java.version>1.8</java.version>
<!-- spring cloud 版本 -->
<spring-cloud.version>2020.0.0-M5</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- eureka client 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>

<!-- spring cloud 依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

修改配置文件

配置说明:

  • eureka.client.service-url.defaultZone 注册中心地址
  • spring.application.name 应用名
  • server.port 项目运行端口
1
2
3
4
5
6
7
8
9
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
server:
port: 8787
spring:
application:
name: EureakClinet_1

运行项目,访问注册中心面板 http://localhost:8761/ ,能看到注册的实例。

注意在eureka注册信息页面上红色显示的

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

这是因为本地调试时触发了 Eureka Server 的自我保护机制。这个机制会使注册中心维护的实例不是很准确,所以在本地开发时可以修改配置 eureka.server.enable-self-preservation 为 false,以此关闭保护机制,确保注册中心将不可用的实例正确删除。

参考资料

总结

服务发现是微服务的第一站,要学习微服务,首先就要了解服务发现的原理机制,学会使用常见的服务注册中心。