SpringCloud Eureka注册中心

简介: SpringCloud Eureka注册中心

1.Eureka 简介

Eureka 是 Netflix 开发的服务发现框架,本身是一个基于 REST 的服务,主要用于定位运行在 AWS 域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务发现功能。


1.1 Eureka 组件

Eureka 包含两个组件:Eureka Server 和 Eureka Client。


1.1.1 Eureka Server

Eureka Server 提供服务注册服务,各个节点启动后,会在 Eureka Server 中进行注册,这样 EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到 Eureka Server 本身也是一个服务,默认情况下会自动注册到 Eureka 注册中心。

如果搭建单机版的 Eureka Server 注册中心,则需要配置取消 Eureka Server 的自动注册逻辑。毕竟当前服务注册到当前服务代表的注册中心中是一个说不通的逻辑。

Eureka Server 通过 Register、Get、Renew 等接口提供服务的注册、发现和心跳检测等服务。

常见错误:no main manifest attribute

无法启动linux注册中心

解决:

1.1.2 Eureka Client

Eureka Client 是一个 java 客户端,用于简化与 Eureka Server 的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向 Eureka Server 发送心跳,默认周期为 30 秒,如果 Eureka Server 在多个心跳周期内没有接收到某个节点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除(默认 90 秒)。

Eureka Client 分 为 两 个 角 色 , 分 别 是 : Application Service(Service Provider) 和 Application Client(Service Consumer)

Application Service

服务提供方,是注册到 Eureka Server 中的服务

Application Client

服务消费方,通过 Eureka Server 发现服务,并消费


注意:在这里,Application Service 和 Application Client 不是绝对上的定义,因为 Provider 在提供服务的同时,也可以消费其他 Provider 提供的服务;Consumer 在消费服务的同时,也可以提供对外服务

2.Eureka 和 Zookeeper 对比

2.1 什么是 CAP 定理

CAP 原则又称 CAP 定理,指的是在一个分布式系统中,Consistency(数据一致性)、Availability(服务可用性)、Partition tolerance(分区容错性),三者不可兼得。

CAP 由 Eric Brewer 在 2000 年 PODC 会议上提出。该猜想在提出两年后被证明成立,成为我们熟知的 CAP 定理

image.png

2.2 基于 CAP 定理比对 Eureka 和 Zookeeper

image.png

3.搭建 Eureka 注册中心

Eureka Server 既是一个注册中心,同时也是一个服务。那么搭建 Eureka Server 的方式和以往搭建 Dubbo 注册中心 ZooKeeper 的方式必然不同,那么首先搭建一个单机版的 Eureka Server 注册中心。

3.1 POM 文件

<?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.2.2.RELEASE</version>
  </parent>
  <groupId>com.bjsxt</groupId>
  <artifactId>cloudeureka</artifactId>
  <version>1.0-SNAPSHOT</version>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Hoxton.SR1</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
  </dependencies>
</project>

3.2 配置文件 application.yml

Eureka Server 本身也是一个服务,同时又是一个注册中心。在 Spring Cloud 中,启动的微服务会自动的搜索注册中心并注册服务,那么在单机版 Eureka Server 环境中,当前服务注册到当前服务中,明显是不合适的。所以搭建 Eureka Server 单机版时,需要提供特殊的全局配置,避免回路注册逻辑。

同理,Eureka Server 服务在注册中心中发现服务列表逻辑也是不必要的。毕竟注册中心是一个中立的服务管理平台,如果是单机版 Eureka Server 环境中,Eureka Server 服务再去发现服务列表,明显也是不必要的。也需要通过全局配置,避免回路发现逻辑。

server:
  # 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册发现端口默认为 8761。
  port: 8761
spring:
  application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中。
    name: cloud-eureka
eureka:
  client:
    # 是否将自己注册到 Eureka-Server 中,默认的为 true
    register-with-eureka: false
    # 是否从 Eureka-Server 中获取服务注册信息,默认为 true
    fetch-registry: false
  • 如果需要修改 Eureka Server 服务注册发现端口,具体配置如下:
server:
  # 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册发现端口默认为 8761。
  port: 8080
spring:
  application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中
    name: cloud-eureka
eureka:
  client:
    # 是否将自己注册到 Eureka-Server 中,默认的为 true
    register-with-eureka: false
    # 是否从 Eureka-Server 中获取服务注册信息,默认为 true
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8080/eureka/

3.3 启动类

package com.csdn.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
//@EnableEurekaServer - 启动时初始化 Eureka Server 注册中心。
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
  public static void main(String[] args) {
    SpringApplication.run(EurekaApp.class, args);
  }
}

3.4 访问 Eureka Server WEB 服务管理平台

访问服务管理平台地址为: http://ip:port/

4.Eureka 服务管理平台介绍

4.1 Eureka Server 服务管理平台访问预览

4.2 System Status

  • 系统状态展示

4.3 DS Replicas

注册中心集群列表

4.4 Instances currently registered with Eureka

已在注册中心中注册的服务列表

4.5 General Info

当前注册中心相关信息展示

4.6 Instance Info

当前注册中心实例信息展示

5.搭建高可用集群

5.1 在 Eureka 应用中定义多环境配置

5.1.1 application-eureka1.yml

server:
  # 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册发现端口默认为 8761。
  port: 8761
spring:
  application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中。
    name: cloud-eureka
eureka:
  client:
    service-url:
      defaultZone:
        - http://eureka2:8761/eureka/
  instance:
    hostname: eureka1

5.1.2 application-eureka2.yml

server:
  # 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册发现端口默认为 8761。
  port: 8761
spring:
  application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中。
    name: cloud-eureka
eureka:
  client:
    service-url:
      defaultZone:
        - http://eureka1:8761/eureka/
  instance:
    hostname: eureka2

5.2 打包工程

5.2.1 POM 依赖

  • 增加 Spring Boot 打包插件
<?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.2.2.RELEASE</version>
  </parent>
  <groupId>com.csdn</groupId>
  <artifactId>cloudeureka</artifactId>
  <version>1.0-SNAPSHOT</version>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Hoxton.SR1</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

5.2.2 打包

5.2.3 打包结果

5.3 上传打包后的 jar 文件到 Linux 系统

每个人上传的方法不一样,就不演示了。手动滑稽。我用的是xftp6

5.4 设置 Linux 主机域名

修改/etc/hosts 文件,设置主机域名。将主机域名和 IP 进行绑定。

vi /etc/hosts

  • 新增内容如下:两个 Linux 系统修改内容相同。(IP 根据具体环境配置)
  • 192.168.17.10 eureka1
    192.168.17.20 eureka2

5.5 启动 Eureka

5.5.1 使用 java 命令启动

  • java -jar -Dspring.profiles.active=eureka1 cloudeureka-1.0-SNAPSHOT.jar

5.5.2 脚本启动

当然,每次通过命令来启动 Eureka Server 过于麻烦,可以定义一个 shell 文件来简化操作。(Java 程序员不必要掌握 shell 脚本的编写。建议对 shell 脚本有一定的了解,至少能够修改内部的必要参数值。Shell 脚本一般由运维或部署人员开发。也可能有系统工程师开发。)具体 shell 内容如下:

#!/bin/bash
cd `dirname $0`
CUR_SHELL_DIR=`pwd`
CUR_SHELL_NAME=`basename ${BASH_SOURCE}`
JAR_NAME="项目 jar 包名称"
JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME
#JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:PermSize=128m"
JAVA_MEM_OPTS=""
SPRING_PROFILES_ACTIV="-Dspring.profiles.active=配置文件变量名称"
#SPRING_PROFILES_ACTIV=""
LOG_DIR=$CUR_SHELL_DIR/logs
LOG_PATH=$LOG_DIR/eureka-server.log
echo_help()
{
  echo -e "syntax: sh $CUR_SHELL_NAME start|stop"
}
if [ -z $1 ];then
  echo_help
  exit 1
fi
if [ ! -d "$LOG_DIR" ];then
  mkdir "$LOG_DIR"
fi
if [ ! -f "$LOG_PATH" ];then
  touch "$LOG_DIR"
fi
if [ "$1" == "start" ];then
  # check server
  PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
  if [ -n "$PIDS" ]; then
    echo -e "ERROR: The $JAR_NAME already started and the PID is ${PIDS}."
    exit 1
  fi
  echo "Starting the $JAR_NAME..."
  # start
  nohup java $JAVA_MEM_OPTS -jar $SPRING_PROFILES_ACTIV $JAR_PATH >> $LOG_PATH 2>&1 &
  COUNT=0
  while [ $COUNT -lt 1 ]; do
    sleep 1
    COUNT=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}' | wc -l`
    if [ $COUNT -gt 0 ]; then
      break
    fi
  done
  PIDS=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print$2}
  echo "${JAR_NAME} Started and the PID is ${PIDS}."
  echo "You can check the log file in ${LOG_PATH} for details."
elif [ "$1" == "stop" ];then
  PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'`
  if [ -z "$PIDS" ]; then
    echo "ERROR:The $JAR_NAME does not started!"
    exit 1
  fi
  echo -e "Stopping the $JAR_NAME..."
  for PID in $PIDS; do
    kill $PID > /dev/null 2>&1
  done
  COUNT=0
  while [ $COUNT -lt 1 ]; do
    sleep 1
    COUNT=1
    for PID in $PIDS ; do
      PID_EXIST=`ps --no-heading -p $PID`
      if [ -n "$PID_EXIST" ]; then
        COUNT=0
        break
      fi
    done
  done
  echo -e "${JAR_NAME} Stopped and the PID is ${PIDS}."
else
  echo_help
  exit 1
fi

设置好 shell 启动脚本后,需要提供可执行权限:shell 脚本文件名自己修改。

chmod 755 xxx.sh

脚本使用方式为:

启动 Eureka Server 命令: ./xxx.sh start

关闭 Eureka Server 命令: ./xxx.sh stop

6.集群原理

  • Eureka 集群架构原理图

7.Eureka 优雅停服

7.1 自我保护模式

一般情况下,微服务在 Eureka 上注册后,会每 30 秒发送心跳包,Eureka 通过心跳来判断服务时候健康,同时会定期删除超过 90 秒没有发送心跳服务。

有两种情况会导致 Eureka Server 收不到微服务的心跳:一是微服务自身的原因;二是微服务与 Eureka 之间的网络故障。

通常微服务自身的故障关闭只会导致个别服务出现故障,一般不会出现大面积故障,而网络故障通常会导致 Eureka Server 在短时间内无法收到大批心跳。考虑到这个区别,Eureka 设置了一个阀值,当判断离线服务的数量超过阀值时,Eureka Server 认为很大程度上出现了网络故障,将不再删除心跳过期的服务。

那么这个阀值是多少呢?15 分钟之内是否低于 85%;Eureka Server 在运行期间,会统计心跳失败的比例在 15 分钟内是否低于 85%,这种算法叫做 Eureka Server 的自我保护模式。

7.2 为什么要自我保护

因为同时保留"好数据"与"坏数据"总比丢掉任何数据要更好,当网络故障恢复后,这个 Eureka 节点会退出"自我保护模式"。Eureka 还有客户端缓存功能(也就是微服务的缓存功能)。即便 Eureka 集群中所有节点都宕机失效,微服务的 Provider 和 Consumer 都能依托服务缓存正常通信。微服务的负载均衡策略会自动剔除离线的微服务节点。

7.3 关闭自我保护

修改 Eureka Server 中的核心配置文件 application.yml

server:
  # 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册发现端口默认为 8761。
  port: 8761
spring:
  application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中。
    name: cloud-eureka
eureka:
  client:
    service-url:
      defaultZone:
        - http://eureka2:8761/eureka/
  instance:
    hostname: eureka1
  server:
    # 是否开启自我保护, 默认为 true
    enable-self-preservation: false
    # 清理间隔,单位是毫秒。默认值为 1 分钟
    eviction-interval-timer-in-ms: 60000


目录
相关文章
|
1月前
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(二)Rest微服务工程搭建
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(二)Rest微服务工程搭建
54 0
|
1月前
|
SpringCloudAlibaba 负载均衡 Java
【一】SpringCloud Alibaba之Nacos整合篇(作为注册中心)
【一】SpringCloud Alibaba之Nacos整合篇(作为注册中心)
251 1
【一】SpringCloud Alibaba之Nacos整合篇(作为注册中心)
|
1月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
159 0
|
1月前
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
105 0
|
1月前
|
消息中间件 JSON Java
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
Spring Boot、Spring Cloud与Spring Cloud Alibaba版本对应关系
670 0
|
4天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
20天前
|
SpringCloudAlibaba Java Nacos
SpringCloud Alibaba微服务 -- Nacos使用以及注册中心和配置中心的应用(保姆级)
SpringCloud Alibaba微服务 -- Nacos使用以及注册中心和配置中心的应用(保姆级)
|
26天前
|
开发框架 负载均衡 Java
Spring boot与Spring cloud之间的关系
总之,Spring Boot和Spring Cloud之间的关系是一种构建和扩展的关系,Spring Boot提供了基础,而Spring Cloud在此基础上提供了分布式系统和微服务架构所需的扩展和工具。
19 4
Spring boot与Spring cloud之间的关系
|
1月前
|
SpringCloudAlibaba 负载均衡 Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(目录大纲)
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(目录大纲)
67 1
|
1月前
|
Java Nacos Sentinel
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(九)Nacos+Sentinel+Seata
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(九)Nacos+Sentinel+Seata
208 0