一、简介

服务消费者需要一个强大的服务发现机制,服务消费者使用这种机制获取服务提供者的网络信息。即使服务提供者的信息发生变化,服务消费者也无须修改配置。


服务提供者、服务消费者、服务发现组件三者之间的关系大致如下:

 1.各个微服务在启动时,将自己的网络地址等信息注册到服务发现组件中,服务发现组件会存储这些信息。

 2.服务消费者可以从服务发现组件查询服务提供者的网络地址,并使用该地址调用服务提供者的接口。

 3.各个微服务与服务发现组件使用一定机制(如:心跳)通信,服务发现组件如长时间无法与某微服务实例通信,就会注销该实例。

 4.微服务网络地址发生变更时,会重新注册到服务发现组件。

1.1、服务发现组件

服务发现组件应具备以下功能:服务注册表、服务注册与服务发现、服务检查

1.1.1、服务注册表

是服务发现组件的核心,用来记录各个微服务的信息,如服务名称、IP、端口等。服务注册表提供查询API(用于查询可用的微服务实例)和管理API(用户服务的注册与注销)

1.1.2、服务注册与服务发现

服务注册是指微服务在启动时,将自己的信息注册到服务发现组件上的过程。服务发现是指查询可用微服务列表及其网络地址的机制。

1.1.3、服务检查

服务发现组件使用一定机制定时检测已注册的服务,如发现某实例长时间无法访问,就会从服务注册表中移除实例


Spring Cloud提供了多种服务发现组件的支持,如:Eureka、Zookeeper等。

二、Eureka

Eureka是Netflix开源的服务发现组件,本身是基于REST的服务。它包含Server和Client两部分。Spring Cloud将其集成在子项目Spring Cloud Netflix中,从而实现微服务的注册与发现。

Eureka的两个组件

Eureka包含两个组件:Eureka Server与Eureka Client,作用如下:

1、Eureka Server提供服务发现的能力,各个微服务启动时,会向Eureka Server注册自己的信息(IP、端口、微服务名称等),Eureka Server会存储这些信息。 

2、Eureka Client是一个java客户端,用于简化与Eureka Server的交互。

3、微服务启动后,会周期性(默认30秒)地向Eureka Server发送心跳以续约自己的“租期”。

4、如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)

5、默认情况下,Eureka Server同时也是Eureka Client。多个Eureka Server实例,互相之间通过复制的方式,来实现服务注册表中数据的同步。

6、Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势---首先,微服务无须每次请求都查询Eureka Server,从而降低了Eureka Server的压力;其次,即使Eureka Server所有的节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者并完成调用。


综上:Eureka通过心跳检查、客户端缓存等机制,提高了系统的灵活性、可伸缩性和可用性


2.1、编写Eureka Server

2.1.1 新建springboot工程

新建一个springboot(1.5.4.RELEASE)工程,再添加如下依赖:

<dependencyManagement>
    <dependencies>
        <dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-dependencies</artifactId>
	    <version>Dalston.SR1</version>
	    <type>pom</type>
	    <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
</dependencies>

2.1.2、编写启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

2.1.3、配置文件application.properties

server.port=9090
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://localhost:9090/eureka/,http://localhost:9090/eureka1/

说明:

 eureka.client.register-with-eureka:表示是否将自己注册到Eureka Server,默认为true.(由于此工程本身就是Eureka Server,所有这里写false)

 eureka.client.fetch-registry:表示是否从Eureka Server获取信息,默认为true(由于此工程现在是单节点的,所有这里写false)

 eureka.client.service-url.defaultZone:设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址,多个用逗号分隔


2.1.4、测试

访问:http://localhost:9090/ 

springCloud(3):微服务的注册与发现(Eureka)_spring

2.2、将微服务注册到Eureka Server上

2.2.1 新建springboot工程

新建一个springboot(1.5.4.RELEASE)工程,再添加如下依赖:

<dependencyManagement>
    <dependencies>
        <dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-dependencies</artifactId>
	    <version>Dalston.SR1</version>
	    <type>pom</type>
	    <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
</dependencies>

2.2.2、编写启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {

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

2.2.3、配置文件application.properties

server.port=9091
spring.application.name=demo1
eureka.client.service-url.defaultZone=http://localhost:9090/eureka/
eureka.instance.prefer-ip-address=true

2.2.4、测试

访问:http://localhost:9090/ 

springCloud(3):微服务的注册与发现(Eureka)_Cloud_02


如果在Eureka Server的首页看到以下这段提示,则说明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.

解决:显示指定ip

server.port=9091
spring.application.name=demo1
eureka.client.service-url.defaultZone=http://localhost:9090/eureka/
eureka.instance.prefer-ip-address=true
#显示指定IP
eureka.instance.instance-id: ${spring.cloud.client.ipAddress}:${server.port}

 springCloud(3):微服务的注册与发现(Eureka)_spring_03