SpringCloud系列第02節之註冊中心Eureka

簡介

Eureka 是 Netflix 開發的,一個基於 REST 服務的,服務註冊與發現的組件java

它主要包括兩個組件:Eureka Server 和 Eureka Clientgit

  • Eureka Client:一個Java客戶端,用於簡化與 Eureka Server 的交互(一般就是微服務中的客戶端和服務端)
  • Eureka Server:提供服務註冊和發現的能力(一般就是微服務中的註冊中心)

各個微服務啓動時,會經過 Eureka Client 向 Eureka Server 註冊本身,Eureka Server 會存儲該服務的信息github

也就是說,每一個微服務的客戶端和服務端,都會註冊到 Eureka Server,這就衍生出了微服務相互識別的話題web

  • 同步:每一個 Eureka Server 同時也是 Eureka Client(邏輯上的)
       多個 Eureka Server 之間經過複製的方式完成服務註冊表的同步,造成 Eureka 的高可用
  • 識別:Eureka Client 會緩存 Eureka Server 中的信息
       即便全部 Eureka Server 節點都宕掉,服務消費者仍可以使用緩存中的信息找到服務提供者(筆者已親測)
  • 續約:微服務會週期性(默認30s)地向 Eureka Server 發送心跳以Renew(續約)本身的信息(相似於heartbeat)
  • 續期:Eureka Server 會按期(默認60s)執行一次失效服務檢測功能
       它會檢查超過必定時間(默認90s)沒有Renew的微服務,發現則會註銷該微服務節點

Spring Cloud 已經把 Eureka 集成在其子項目 Spring Cloud Netflix 裏面spring

關於 Eureka 配置的最佳實踐,可參考:https://github.com/spring-cloud/spring-cloud-netflix/issues/203apache

更多介紹,可參考:http://cloud.spring.io/spring-cloud-static/Camden.SR4/#spring-cloud-eureka-server瀏覽器

示例代碼

本文的例子只能用來嚐嚐鮮,更豐富的配置詳見 Eureka 進階篇:https://jadyer.cn/2017/01/17/springcloud-eureka-advance/緩存

這是演示的是一個由三個模塊組成的 Maven 工程,其中包含一個註冊中心和兩個服務提供者app

以下圖所示maven

這是公共的 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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.jadyer.demo</groupId>
    <artifactId>demo-cloud-02</artifactId>
    <version>1.1</version>
    <packaging>pom</packaging>
    <modules>
        <module>service-discovery</module>
        <module>service-server-01</module>
        <module>service-server-02</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

註冊中心

整體思路以下

  1. SpringBoot啓動類標註 @EnableEurekaServer 註解
  2. 設置本身自己不註冊到註冊中心

ok,let`s drink code …

這是註冊中心的 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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.jadyer.demo</groupId>
        <artifactId>demo-cloud-02</artifactId>
        <version>1.1</version>
    </parent>
    <artifactId>service-discovery</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>

這是註冊中心的 SpringBoot 啓動類 ServiceDiscoveryBootStrap.java

package com.jadyer.demo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

//建立服務註冊中心
@EnableEurekaServer
@SpringBootApplication
public class ServiceDiscoveryBootStrap {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ServiceDiscoveryBootStrap.class).run(args);
    }
}

這是註冊中心的配置文件 /src/main/resources/application.yml

server:
  port: 1100

eureka:
  client:
    # 設置是否從註冊中心獲取註冊信息(缺省true)
    # 由於這是一個單點的EurekaServer,不須要同步其它EurekaServer節點的數據,故設爲false
    fetch-registry: false
    # 設置是否將本身做爲客戶端註冊到註冊中心(缺省true)
    # 這裏爲不須要(查看@EnableEurekaServer註解的源碼,會發現它間接用到了@EnableDiscoveryClient)
    register-with-eureka: false
    # 在未設置defaultZone的狀況下,註冊中心在本例中的默認地址就是http://127.0.0.1:1100/eureka/
    # 但奇怪的是,啓動註冊中心時,控制檯仍是會打印這個地址的節點:http://localhost:8761/eureka/
    # 而實際服務端註冊時,要使用1100端口的才能註冊成功,8761端口的會註冊失敗並報告異常
    serviceUrl:
      # 實際測試:若修改尾部的eureka爲其它的,好比/myeureka,註冊中心啓動沒問題,但服務端在註冊時會失敗
      # 報告異常:com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
      defaultZone: http://127.0.0.1:${server.port}/eureka/

服務提供方01

整體思路以下

  1. SpringBoot啓動類標註 @EnableEurekaClient 或者 @EnableDiscoveryClient 註解
  2. 配置註冊中心地址

ok,let`s drink code …

這是服務提供方的 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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.jadyer.demo</groupId>
        <artifactId>demo-cloud-02</artifactId>
        <version>1.1</version>
    </parent>
    <artifactId>service-server-01</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
    </dependencies>
</project>

這是服務提供方的 SpringBoot 啓動類 ServiceServer01BootStarp.java

package com.jadyer.demo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * 經過 @EnableEurekaClient 註解,爲服務提供方賦予註冊和發現服務的能力
 * ------------------------------------------------------------------------------------------------------------------
 * 也可使用org.springframework.cloud.client.discovery.@EnableDiscoveryClient註解
 * 詳見如下兩篇文章的介紹
 * http://cloud.spring.io/spring-cloud-static/Camden.SR3/#_registering_with_eureka
 * https://spring.io/blog/2015/01/20/microservice-registration-and-discovery-with-spring-cloud-and-netflix-s-eureka
 * ------------------------------------------------------------------------------------------------------------------
 * Created by 玄玉<https://jadyer.cn/> on 2017/1/9 16:00.
 */
@EnableEurekaClient
@SpringBootApplication
public class ServiceServer01BootStarp {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ServiceServer01BootStarp.class).run(args);
    }
}

這是服務提供方的配置文件 /src/main/resources/application.yml

server:
  port: 2100

spring:
  application:
    name: CalculatorServer                        # 指定發佈的微服務名(之後調用時,只需該名稱便可訪問該服務)

eureka:
  client:
    serviceUrl:
      defaultZone: http://127.0.0.1:1100/eureka/  # 指定服務註冊中心的地址

這是服務提供方暴露的數學運算服務 CalculatorController.java

package com.jadyer.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

/**
 * 服務提供方暴露的數學運算服務
 * Created by 玄玉<https://jadyer.cn/> on 2017/1/9 16:00.
 */
@RestController
public class CalculatorController {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Resource
    private DiscoveryClient client;

    @RequestMapping("/add")
    public int add(int a, int b){
        //加運算
        int result = a + b;
        //輸出服務信息
        ServiceInstance instance = client.getLocalServiceInstance();
        logger.info("uri={},serviceId={},result={}", instance.getUri(), instance.getServiceId(), result);
        //返回結果
        return result;
    }
}

服務提供方02

除了啓動端口爲2200外,其代碼與服務提供方01的徹底相同

驗證

先看一下注冊中心的 Eureka 首頁效果圖

能夠看到:兩個服務相同,啓動端口不一樣的 CalculatorServer 已經註冊進來了

因爲發佈的微服務所暴露出去的都是 HTTP 的接口,因此驗證的話,咱們能夠瀏覽器直接訪問下面的兩個地址

http://127.0.0.1:2100/add?a=3&b=13

http://127.0.0.1:2200/add?a=3&b=13

目前爲止,咱們完成了 Spring Cloud Netflix Eureka 搭建註冊中心的基本示例,不過也只是嚐嚐鮮

由於它還存在着不少問題,好比

  • 什麼是自我保護模式
  • 服務提供方關閉以後,在註冊中心看到的狀態仍是 UP
  • 註冊中心的服務提供方顯示的名字,是否是能夠自定義

等等吧,這些問題,請參見 Eureka 進階篇:https://jadyer.cn/2017/01/17/springcloud-eureka-advance/

相關文章
相關標籤/搜索