Spring Cloud微服务的注册和发现Eureka

avatar 2019年11月13日21:31:58 评论 986 次浏览

Eureka是Netflix开源的服务发现组件,本身是基于Rest的服务,它包含服务端和客户端两部分;在SpringCloud中将它集成在其中,从而实现了微服务的发现与注册;

Eureka Server

- 服务端-没有存储,内存保持,每服务实例需要发送心跳去续约
- 客户端-在内存中缓存着eureka的注册信息,因此不必每请求到eureka查找服务
- eureka之间会做注册服务同步,从而保证状态一致,客户端只需访问一个eureka

Service Provider

- 会向Eureka Server做Register(服务注册)、Renew(服务续约)、Cancel(服务下线)等操作

Service Consumer

- 会向Eureka Server获取注册服务列表,并消费服务

简单实战

创建服务端

创建Spring Boot服务端,给项目命一个名字为springcloud.helloworld.eureka.server,下面是创建流程:

因为部分流程和前面的入门都一样,所以这里就把不同之处单独写出来,其他的都一样,

我们需要安装eureka所以搜索一下:

Eureka服务端创建完成,pom.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>springcloud.helloworld.eureka</groupId>
    <artifactId>server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2、创建一个服务类EurekaServerApplication

package springcloud.helloworld.eureka.server;


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);
    }
}

3、配置application.yml,如果没有安装web结构里就不会有static和templates目录,可以把application.properties文件复制了一份修改文件名,如果已经安装web可以在resoources目录下创建config目录,并在config目录下创建application.yml文件,并配置:

server:
  port: 8761
  #表示是否将自己注册在EurekaServer上,默认为true。由于当前应用就是EurekaServer,所以置为false
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    #表示表示是否从EurekaServer获取注册信息,默认为true。单节点不需要同步其他的EurekaServer节点的数据
    fetch-registry: false
    #设置Eureka的地址
    service-url:
      defaultZone : http://${eureka.instance.hostname}:${server.port}/eureka/

4、eureka server工程结构如下:

5、启动eureka server,右键ServerApplication--run,然后访问http://localhost:8761/,页面如下,“No instances available”表示无client注册

创建客户端

和创建服务端类似,创建的时候增加的客户端插件如下:

1、创建Maven工程springcloud.helloword.eureka.client,pom.yml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>springcloud.helloworld.eureka</groupId>
    <artifactId>client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>client</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2、创建主类EurekaClientApplication,内容如下:

package springcloud.helloworld.eureka.client;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaClientApplication {


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


    @Value("${server.port}")
    String port;
    @RequestMapping("/")
    public String home() {
        return "hello world from port" + port;
    }
}

3、eureka client的配置文件application.yml内容如下:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8762
  #对该应用另起别名
spring:
  application:
    name: service-helloword

eureka client创建完成,下面看一下工程结构:

4、启动client服务,并访问http://localhost:8762/

5、再次访问服务端,可以看到Client中的application.yml中记录的name

扩展部分,资料补充:

这是因为Eureka进入了自我保护机制,默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳时,EurekaServer将会注销该实例(默认90s)。但是当网络发生故障时,微服务与EurekaServer之间无法通信,这样就会很危险了,因为微服务本身是很健康的,此时就不应该注销这个微服务,而Eureka通过自我保护机制来预防这种情况,当网络健康后,该EurekaServer节点就会自动退出自我保护模式;

这时再次将客户端微服务启动,刷新服务注册中心会发现,自我保护状态已取消。

综上所述,我们可以看出来Eureka的两个组件EurekaServer和EurekaClient的作用:

1、EurekaServer 提供服务发现的能力,各个微服务启动时,会向EurekaServer注册自己的信息(例如:ip、端口、微服务名称等),EurekaServer会存储这些信息;

2、EurekaClient是一个Java客户端,用于简化与EurekaServer的交互;

3、微服务启东后,会定期性(默认30s)的向EurekaServer发送心跳以续约自己的“租期”;

4、如果EurekaServer在一定时间内未接收某个微服务实例的心跳,EurekaServer将会注销该实例(默认90s);

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

6、EurekaClient也会缓存服务注册表中的信息;

综上,Eureka通过心跳检查、客户端缓存等机制,提高了系统的灵活性、可伸缩性和可用性,所以作为一个微服务架构,需要一个服务注册中心来统筹管理服务;

Eureka高可用

复制上面server项目,分别命名为: eureka-keepalived-server1,eureka-keepalived-server2;

复制上面的client项目,命名为: eureka-keepalived-client;

修改本地hosts文件:

127.0.0.1    localhost server1 server2

eureka-keepalived-server1

修改项目eureka-keepalived-server1的配置文件application.yml(application.yml文件是把application.properties文件复制过去并修改的文件名)

server:
  port: 8761
spring:
  application:
    name: eureka-server-1
  profiles:
    active: server1
eureka:
  instance:
    hostname: server1
  client:
    service-url:
      defaultZone: http://server2:8762/eureka

eureka-keepalived-server2

修改项目eureka-keepalived-server2的配置文件application.yml(application.yml文件是把application.properties文件复制过去并修改的文件名)

server:
  port: 8762
spring:
  application:
    name: eureka-server-2
  profiles:
    active: server2
eureka:
  client:
    service-url:
      defaultZone: http://server1:8761/eureka

eureka-keepalived-client;

修改项目eureka-keepalived-client的配置文件application.yml(application.yml文件是把application.properties文件复制过去并修改的文件名)

server:
  port: 8763
spring:
  application:
    name: client-8783
eureka:
  client:
    service-url:
      defaultZone: http://server1:8761/eureka

分别启动两个服务server1,server2,并访问http://localhost:8761,http://localhost:8762,如下:

启动客户端,发现客户端分别在两个服务端都有相应的注册,而我们的客户端实际只指定了一个Server;

Spring Cloud微服务的注册和发现Eureka

至此,Eureka高可用已经完成。

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: