Rubin's Blog

  • 首页
  • 关于作者
  • 隐私政策
享受恬静与美好~~~
分享生活的点点滴滴~~~
  1. 首页
  2. SpringCloud
  3. 正文

SpringCloud Netflix之Eureka Server

2021年10月20日 364点热度 1人点赞 0条评论

SpringCloud是什么

SpringCloud是一系列框架的有序集合。它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等等,都可以用SpringBoot的开发风格做到一键启动和部署。

SpringCloud并没有重复造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过SpringBoot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

这里,我们需要注意,SpringCloud其实是一套规范,是一套用于构建微服务架构的规范,而不是一个可以拿来即用的框架。在这个规范之下第三方公司的Netflix公司开发了一些组件(SCN)、spring官方开发了一些框架/组件,包括第三方的阿里巴巴开发了一套框架/组件集合SpringCloud Alibaba(SCA),这些才是SpringCloud规范的实现。

SpringCloud体系结构(组件协同工作机制)

SpringCloud中的各组件协同工作,才能够支持一个完整的微服务架构。比如:

  • 注册中心负责服务的注册与发现,很好将各服务连接起来
  • API网关负责转发所有外来的请求
  • 断路器负责监控服务之间的调用情况,连续多次失败进行熔断保护
  • 配置中心提供了统一的配置信息管理服务,可以实时的通知各个服务获取最新的配置信息

Eureka服务注册中心

关于服务注册中心

对于任何一个微服务,原则上都应存在或者支持多个提供者,这是由微服务的分布式属性决定的。更进一步,为了支持弹性扩缩容特性,一个微服务的提供者的数量和分布往往是动态变化的,也是无法预先确定的。因此,原本是在单体应用阶段常用的静态LB机制就不再适用了,需要引入额外的组件来管理微服务提供者的注册与发现,而这个组件就是服务注册中心。

注册中心的一般原理如下图所示:

分布式微服务架构中,服务注册中心用于存储服务提供者地址信息、服务发布相关的属性信息,消费者通过主动查询和被动通知的方式获取服务提供者的地址信息,而不再需要通过硬编码方式得到提供者的地址信息。消费者只需要知道当前系统发布了哪些服务,而不需要知道服务具体存在于什么位置,这就是透明化路由。

以下是几种主流注册中心的对比:

组件名语言CAP对外暴露接口
EurekaJavaAP(自我保护机制,保证可用)HTTP
ConsulGoCPHTTP/DNS
ZooKeeperJavaCP客户端
NacosJava支持AP/CP切换HTTP

搭建单例Eureka Server

由于我们要搭建一个SpringCloud体系框架,所以我们先创建一个spring-cloud-demo的父工程,其Maven的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>

    <!--spring boot 父启动器依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <groupId>com.rubin</groupId>
    <artifactId>spring-cloud-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>pom</packaging>

    <dependencies>
        <!--日志依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <!--测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok⼯具-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <!-- Actuator可以帮助你监控和管理Spring Boot应⽤-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <!--打包插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

创建子模块scn,其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">
    <parent>
        <artifactId>spring-cloud-demo</artifactId>
        <groupId>com.rubin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>

    <artifactId>scn</artifactId>

    <dependencies>
        <!--web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

在scn模块下创建我们的Eureka Server单例服务模块:scn-eureka-8761,其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">
    <parent>
        <artifactId>scn</artifactId>
        <groupId>com.rubin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>scn-eureka-8761</artifactId>

    <dependencies>
        <!--Eureka server依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

由于是SpringBoot项目,我们编写SpringBoot的启动类如下:

package com.rubin.scn.eureka;

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

@SpringBootApplication
@EnableEurekaServer
public class Eureka8761Bootstrap {

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

}

由上述代码可知,我们使用@EnableEurekaServer注解来标明我们该服务是一个Eureka Server服务器。接下来便写我们的配置文件:application.yml。内容如下:

server:
  port: 8761
spring:
  application:
    name: scn-eureka
eureka:
  instance:
    hostname: 127.0.0.1
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
    # 租约续约间隔时间,默认30秒
    lease-renewal-interval-in-seconds: 30
    # 租约到期,服务时效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除
    lease-expiration-duration-in-seconds: 90
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka/
    register-with-eureka: false
    fetch-registry: false
  server:
    # EurekaServer每隔多少秒检查服务列表是否全部有效
    eviction-interval-timer-in-ms: 6000
    # 打开自动进入自我保护模式
    enable-self-preservation: true
    # Eureka缓存更新时间间隔
    response-cache-update-interval-ms: 3000
    # 关闭只读缓存来提高服务上下线的响应速度
    use-read-only-response-cache: false

启动我们的服务,我们访问:http://127.0.0.1:8761,会看到如下页面:

至此,我们的单实例Eureka Server注册中心就搭建完成。

搭建Eureka Server集群

单实例在我们开发测试阶段比较常见,在生产环境下,我们还是要搭建一个Eureka Server集群来保证注册中心的可用性。下面我们就来在单例的基础上改造成集群方式。

首先,我们要在scn模块下再新建一个名称为scn-eureka-8762的子模块,其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">
    <parent>
        <artifactId>scn</artifactId>
        <groupId>com.rubin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>scn-eureka-8762</artifactId>

    <dependencies>
        <!--Eureka server依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

编写其启动类:

package com.rubin.scn.eureka;

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

@SpringBootApplication
@EnableEurekaServer
public class Eureka8762Bootstrap {

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

}

编写其配置文件如下:

server:
  port: 8762
spring:
  application:
    name: scn-eureka
eureka:
  instance:
    hostname: 127.0.0.1
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
    # 租约续约间隔时间,默认30秒
    lease-renewal-interval-in-seconds: 30
    # 租约到期,服务时效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除
    lease-expiration-duration-in-seconds: 90
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka/
    register-with-eureka: true
    fetch-registry: true
    # 配制了该项 回阻止将该实例注册为一个eureka client 默认是true 默认自动加入一个Maker类标记  所以引入eureka-client依赖之后 加不加@EnableEurekaClient都会默认注册进EurekaServer
    # enabled: false
    # 每隔多久拉取一次服务列表
    registry-fetch-interval-seconds: 30
  server:
    # EurekaServer每隔多少秒检查服务列表是否全部有效
    eviction-interval-timer-in-ms: 6000
    # 打开自动进入自我保护模式
    enable-self-preservation: true
    # Eureka缓存更新时间间隔
    response-cache-update-interval-ms: 3000
    # 关闭只读缓存来提高服务上下线的响应速度
    use-read-only-response-cache: false

修改我们原来单例的scn-eureka-8761服务的配置文件如下:

server:
  port: 8761
spring:
  application:
    name: scn-eureka
eureka:
  instance:
    hostname: 127.0.0.1
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
    # 租约续约间隔时间,默认30秒
    lease-renewal-interval-in-seconds: 30
    # 租约到期,服务时效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除
    lease-expiration-duration-in-seconds: 90
  client:
    service-url:
      defaultZone: http://127.0.0.1:8762/eureka/
    register-with-eureka: true
    # 每隔多久拉取一次服务列表
    registry-fetch-interval-seconds: 30
    fetch-registry: true
    # 配制了该项 回阻止将该实例注册为一个eureka client 默认是true 默认自动加入一个Maker类标记  所以引入eureka-client依赖之后 加不加@EnableEurekaClient都会默认注册进EurekaServer
    # enabled: false
  server:
    # EurekaServer每隔多少秒检查服务列表是否全部有效
    eviction-interval-timer-in-ms: 6000
    # 打开自动进入自我保护模式
    enable-self-preservation: true
    # Eureka缓存更新时间间隔
    response-cache-update-interval-ms: 3000
    # 关闭只读缓存来提高服务上下线的响应速度
    use-read-only-response-cache: false

依次启动两个项目,打开http://127.0.0.1:8761和http://127.0.0.1:8762会看到我们的两个Eureka Server实例已经启动成功并且成功注册进了彼此的注册表中:

至此,我们的Eureka Server集群就搭建完成了。欢迎小伙伴积极留言交流~~~

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: SpringCloud
最后更新:2022年6月9日

RubinChu

一个快乐的小逗比~~~

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复
  • SpringCloud是什么
  • SpringCloud体系结构(组件协同工作机制)
  • Eureka服务注册中心
    • 关于服务注册中心
    • 搭建单例Eureka Server
    • 搭建Eureka Server集群

COPYRIGHT © 2021 rubinchu.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

京ICP备19039146号-1