Eureka Server 应用

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

前言

  1. 所有内容基于 Spring Boot(2.0.0.RELEASE) 和 Gradle(4.5.1),建议使用 Intellij 编辑器 和 application.yml 配置文件
  2. 创建项目时 Web 为必选项
  3. 使用 Java 便可,不要使用 Groovy 。因为,如果 Java 中出现 Groovy ,Gradle 打包会报错。而且以 Groovy 写的 Controller,打包后不会被识别(所有地址都是404)

1、建立服务端 Eureka Server

添加Eureka服务端依赖(创建项目时选择 Eureka Server项便可)

compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-server')

启动类增加注解

@EnableEurekaServer

application.yml 配置文件中增加以下内容

server:
    port: 8761
eureka:
    client:
        # 禁止客户端添加自身
        register-with-eureka: false
        fetch-registry: false
        service-url:
            defaultZone: http://localhost:8761/eureka/

启动项目,访问 http://localhsot:8761 可以看到 Eureka 的首页
Eureka Server 应用_第1张图片

2、建立客户端并注册到 Eureka Server

增加Eureka客户端依赖(创建项目时选择 Eureka Discovery便可)。使用服务端依赖也可以,服务端可同时支持服务端和客户端

compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')

启动类增加注解

@EnableEurekaClient

以上的注解只能使用 Eureka ,为了支持多种发现组件 Zookeeper、Consul等,可改为

@EnabelDiscoveryClient

application.yml 配置文件中增加以下内容

spring:
    applicaion:
        # 项目名
        name: microservice-provider-user
server:
    port: 8000
eureka:
    client:
        # 注册到 Server
        service-url:
            defaultZone: http://localhost:8761/eureka/
        instance:
            prefer-ip-address: true

先启动服务端,然后再启动客户端。之后可在 Eureka 首页看到客服端的注册信息

3、部署 Eureka Server 集群,增加可用性

Eureka Server 集群是服务端相互注册来提高整个服务的可用性部署

首先要配置系统的 hosts 文件。Windows hosts文件路径是 C:\Windows\System32\drivers\etc\hosts;Linux、Mac Os 等的路径是 /etc/hosts 。文件中增加以下行,文件编辑权限问题请自行百度。

127.0.0.1 peer1 peer2

建立一个服务端,application.yml 如下

spring:
    application:
        # 这个是项目的名字
        name: eureka-group
---
spring:
    # 指定profiles
    profiles: peer1
server:
    port: 8761
eureka:
    instance:
        # 当指定profile=peer1时,主机名是peer1
        hostname: peer1
    client:
        service-url:
            # 注册到peer2这个Eureka
            defaultZone: http://peer2:8762/eureka/
---
spring:
    # 指定profiles
    profiles: peer2
server:
    port: 8762
eureka:
    instance:
        # 当指定profile=peer2时,主机名是peer2
        hostname: peer2
    client:
        service-url:
            # 注册到peer1这个Eureka
            defaultZone: http://peer1:8761/eureka/

将应用打成 Jar 包, 若使用的是 Gradle , 使用终端进入项目目录执行以下命令

gradle build

显示 SUCCESS 后会在项目目录 build/lib 下生成jar包(名字由 version 和 项目名决定,我生成的是 eureka-group-0.0.1-SHAPSHOT)。使用终端分别执行:

java -jar eureka-group-0.0.1-SHAPSHOT.jar --spring.profiles.active=peer1
java -jar eureka-group-0.0.1-SHAPSHOT.jar --spring.profiles.active=peer2
第一个执行的必定会报错,因为要互相注册,第一个执行的找不到对方。但不影响后续

执行过后分别访问 http://peer1:8761和 http://peer2:8762进入 Eureka 首页会发现两个服务已经相互注册

客户端注册到服务端方式类似:

eureka:
    client:
        service-url:
            # 因为集群数据会同步,注册到一个节点便可。为适应极端情景,可注册多个节点。
            defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/

4、为 Eureka Server 增加用户认证

也就是在进入 Eureka 首页时需要输入密码,且注册时需要账号密码属性

加入 security 依赖

compile( 'org.springframework.boot:spring-boot-starter-security')

appliction.yml 中配置

security:
    basic:
        enabled: true
    user:
        name: user
        password: password123

如果不写这一段,默认的账号就是 user(最新版Spring Cloud似乎已经禁用此配置) ,密码会在启动时打印出来。现在进入 Eureka 首页会收到登录验证。

而现在客户端要注册到服务端需要修改以下配置为:

eureka:
    client:
        serviceUrl:
            # 用户:密码@服务器
            defaultZone: http://user:password123@localhost:8761/eureka/

5、Eureka 的元数据

Eureka 元数据分为标准元数据和自定义元数据

修改客户端的 application.yml ,使用 eureka.instance.metadata-map 增加自定义属性

eureka:
    client:
        service-url:
        defaultZone: http://localhost:8761/eureka/
    instance:
        prefer-ip-address: true
            metadata-map:
            # 以下是自定义元数据, key/value 随便写
            my-metata: The Self-made meta-data

写 Controller

package ***.Controller

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cloud.client.ServiceInstance
import org.springframework.cloud.client.discovery.DiscoveryClient
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

//@RestController = @ResponseBody + @Controller
@RestController("/")
public class Controller {

    //!!应导入的是:org.springframework.cloud.client.discovery.DiscoveryClient
    @Autowired
    private DiscoveryClient discoveryClient

    @GetMapping("/user-instance")
    public List<InstanceInfo> showInfo(){
        return this.discoveryClient.getInstances("microservice-provider-user")
    }
}

启动服务端,然后启动客户端。访问 http://localhost:8000/user-instance 可以看到所有的元数据,包括自定义的
Eureka Server 应用_第2张图片

6、使用 Eureka 的 REST 端点注册和注销服务

非 JVM 的微服务可以使用 REST 端点操作 Eureka ,从而实现注册和发现

注册

首先,你需要 Curl 命令。Windows 系统到这里下载对应系统的 Curl ,把 curl.exe 放到 C:/Windows/System32 就能直接在 cmd 中使用了。Linux 或 Mac 可以使用。

然后,启动服务端

编写一个 XML ,命名为 rest-api-test.xml

<instance>
	<instanceId>itmuch:rest-api-test:9000instanceId>
	<hostName>intmuchhostName>
	<app>REST-API-TESTapp>
	<ipAddr>127.0.01ipAddr>
	<vipAddress>rest-api-testvipAddress>
	<secureVipAddress>rest-api-testsecureVipAddress>
	<status>UPstatus>
	<port enable="true">9000port>
	<securePort enable="false">443securePort>
	<homePageUrl>http://127.0.0.1:9000homePageUrl>
	<statusPageUrl>http://127.0.0.1:9000/infostatusPageUrl>
	<healthCheckUrl>http://127.0.0.1:9000/healthhealthCheckUrl>
	<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
		<name>MyOwnname>
	dataCenterInfo>
instance>

Linux 或 Mac 中执行

cat rest-api-test.xml | curl -v -X POST -H "Content-type: application/xml" -d @- http://localhost:8761/eureka/apps/rest-api-test

Windows 下执行(Windows 对应的 cat 命令是 type )

type rest-api-test.xml | curl -v -X POST -H "Content-type: application/xml" -d @- http://localhost:8761/eureka/apps/rest-api-test

会输出类似以下信息:

* upload completely sent off: 664 out of 664 bytes
< HTTP/1.1 204
< Content-Type: application/xml
< Date: Wed, 14 Mar 2018 03:21:48 GMT

到 Eureka 首页发现服务已经注册。 访问 http://loaclhost:8761/eureka/apps/rest-api-test 能看到此服务的所有实例,以及实例想详细信息

注销

执行以下命令

curl -v -X DELETE http://localhost:8761/eureka/apps/rest-api-test/itmuch:rest-api-test:9000

输出类似以下的信息,服务就已经注销

< HTTP/1.1 200
< Content-Type: application/xml
< Content-Length: 0
< Date: Wed, 14 Mar 2018 04:16:49 GMT

因为服务 rest-api-test 并不存在,所以 Eureka Server 过一段时间后便会自动注销此服务

7、多网卡环境下 IP 选择

对于多网卡的服务器,Spring Cloud 提供了按需选择 IP 的能力

配置如下 请看注释:

spring
    cloud:
        inetutils:
            # 1、忽略指定名称的网卡,以下忽略了 docker0 和 所有以 veth 开头的网卡
            ignored-interfaces:
                - docker0
                - veth.*
            # 2、使用正则表达式,指定使用的网络地址
            preferred-networks:
                - 192.168
                - 10.0
            # 3、只使用站点本地地址
            use-only-site-local-interfaces: true
eureka:
  instance:
    prefer-ip-address: true
    # 4、在某些极端场景下,可以手动指定注册到 Eureka Server 的微服务 IP
    id-address: 127.0.0,1

以上的方法按需选择

8、Eureka 的自我保护和自我检查

自我保护
  • Eureka 进入自我保护最直观的体现是 Eureka Server 首页输出的警告
    Eureka 自我保护
  • 如果 Eureka Server 在一定时间内没有收到某个微服务的心跳(默认是90s)。但是如果网络分区故障发生时,微服务与 Eureka Server 之间无法正常通信,以上行为会变得非常危险——因为微服务本事是健康的,此时本不应该注销这个服务
  • Eureka 通过“自我保护模式”来解决这个问题——当 Eureka Server 节点在短时间内丢失过多客服端时,那么这个节点就会进入自我保护模式。一旦进入自我保护模式, Eureka Server 就会保护服务注册表中的信息,不在删除服务注册表中的数据(不在注销任何微服务)。网络故障恢复后,该 Eureka Server 接待会自动退出自我保护模式。

可以使用以下配置来禁用自我保护模式:

eureka:
    server:
        enable-self-preservation: false
健康检查

在 Eureka Server 的首页,如果一个客户端和服务端的心跳保持正常,客户端 Status 的一栏会显示 “UP”。但仅仅代表心跳正常,不代表客户端一定可以连上数据源

Spring Boot Actuator 的 /health 端点可以展示应用程序的健康状况。引入 actuator 依赖:

compile('org.springframework.boot:spring-boot-starter-actuator')

然后开启以下配置,客户端就会将自己的健康状况发送给 Eureka Server

eureka:
    client:
        healthcheck:
            enabled:true

后记

以上的代码大多数经过我的测试

引用内容源自 《Spring Cloud与Docker微服务架构实战》/周立 著

你可能感兴趣的:(Spring)