当前位置: 首页 > news >正文

Spring Cloud(3) - 服务治理: Spring Cloud Eureka

什么是Spring Cloud Eureka

Spring Cloud Eureka 是 Spring Cloud 中的一个组件,它是基于 Netflix Eureka 做了二次封装,主要是负责完成微服务框架中服务治理的功能。Spring Cloud通过为 Eureka 增加了 Spring Boot 风格的自动化配置,我们只需要通过简单的引用依赖和注解就能让 Spring Boot 够将的微服务应用轻松的与 Eureka 服务治理体系进行整合。

服务治理

服务治理是微服务框架中最为核心和基础的模块,它主要是用来实现各个微服务实例的自动化注册与发现。
最初开始,可能构建的微服务系统服务并不是很多,我们可以通过一些静态配置来完成服务的调用。比如有两个服务 A 和 B,其中 A 服务需要调用 B 服务来完成一个业务操作时,为了实现 B 服务的高可用,无论我们采用服务端的复杂均衡,还是客户端的负载均衡,我们都需要手工的来维护一份 B 的实例列表。但是随着业务的发展,系统功能越来越复杂,相应的微服务也是越来越多,这种静态手工维护的难度会越来越高。
为了解决这种问题,产生了大量的服务治理的框架和产品。这些框架其实都是围绕着服务注册和服务发现机制来完成对微服务应用实例的自动化管理。

  • 服务注册

在服务治理框架中,通常都会构建一个服务注册中心,每个服务实例单元向注册中心登记自己的服务,将实例主机位置、端口号、版本号、通信协议等一系列附加信息告诉注册中心,注册中心按服务名分类组织服务清单。

  • 服务发现

由于在服务治理框架下操作,服务间的通信与调用不再是通过指定具体的实例地址来实现,而是通过向服务名发起请求调用实现。所以,服务调用方在调用服务提供方的接口时,并不知道具体的服务实例位置。因此,需要先向注册中心发起查询请求,获取实例清单,以实现对具体服务实例的访问。

搭建 Eureka 注册中心服务

搭建单中心 Eureka

  • Spring Cloud 版本:Finchley.BUILD-SNAPSHOT
  • Spring Boot 版本:2.0.2.RELEASE

我们之后的所有开发都会基于以上版本进行操作,需要注意的是:Sring Cloud 使用的是 SNAPSHOT 版,所以需要在 pom 文件中指定仓库的地址。
首先,我们新建一个 Spring Boot 工程,命名为:spring-cloud-eureka,并在 pom 中添加必要的依赖,具体 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>

    <groupId>com.sagesource</groupId>
    <artifactId>spring-cloud-eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>spring-cloud-eureka</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.BUILD-SNAPSHOT</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.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>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

通过 @EnableEurekaServer 注解启动一个服务注册中心提供给其他应用进行对话。这一步非常简单,只需在一个普通的 Spring Boot 应用中添加这个注解就能开启此功能:

@SpringBootApplication
@EnableEurekaServer
public class ApplicationEurekaServer {

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

}

在默认的配置下,注册中心服务端也会将自己作为一个客户端来注册自身,一般情况下,我们需要禁用这个功能,修改后的 application.yml 如下:

# spring config
spring:
  application:
    name: spring-boot-eureka

# server config
server:
  port: 9871

# eureka config
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false #不向注册中心注册自己
    fetch-registry: false #不检索服务
    service-url:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

由于我们都是在本地运行,为了后续的服务区分,我们将服务注册中心的端口通过 server.port 设置运行端口为:9871
在完成上述配置后,启动应用并访问 http://localhost:9871。可以看到如下页面,其中 Instance currently registered with Eureka 的列表是空的,说明还没有服务注册到该注册中心。

clipboard.png
我想大家都注意到上面那两行醒目的红字:

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

原因:自我保护机制。Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。
由于在单机情况下很容易出现该问题,按照网上的配置关闭掉自我保护后,Eureka 仍会报警,提示安全模式关闭,无法保证实例正确性。所以,我们暂时忽略该问题,后期集群部署时即可解决。

注册服务提供者

在完成了注册中心服务的搭建后,接下来我们可以尝试将一个既有的 Spring Boot 应用加入到Eureka 的服务治理体系中去。
我们仍然以之前的 spring-cloud-server 为例,我们只需要修改 application.yml以下配置:

# 应用名称
spring:
  application:
    name: spring-cloud-server

# eureka 注册中心位置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9871/eureka/

修改完成后,即可启动服务,这时我们在刷新 eureka 的管理页面,看到Instance currently registered with Eureka的列表信息如下:

clipboard.png
这表明,我们的服务已经成功注册在注册中心。

相关实例代码:https://github.com/sagesource...

相关文章:

  • android Debuger 出现:Waiting for Debugger - Application XXX is waiting for the debugger to Attach...
  • [Redis源码阅读]当你输入get/set命令的时候,Redis做了什么
  • 黑马程序员--WPF学习笔记二-----WPF常用页面布局
  • 如何快速成长为不可或缺的技术人才?
  • MySQL主主复制
  • Nginx实现简单的负载均衡
  • 使用 Newtonsoft.Json 序列化 WPF 的 DependencyObject
  • QQ聊天实录:本年度最动人的爱情故事
  • 手机文件误删除,要怎样恢复?
  • HtmlAttribute HTML属性处理类
  • 当无人编辑坐镇新闻编辑部?未来人机社会共存指南
  • 两个listbox实现选项的添加删除和搜索
  • $jQuery 重写Alert样式方法
  • unbunt的svn重启动命令
  • JQ实现购物车价格计算
  • 【Leetcode】104. 二叉树的最大深度
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • docker容器内的网络抓包
  • Fastjson的基本使用方法大全
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • LeetCode29.两数相除 JavaScript
  • MySQL-事务管理(基础)
  • node.js
  • 搭建gitbook 和 访问权限认证
  • 聚簇索引和非聚簇索引
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 首页查询功能的一次实现过程
  • 数组大概知多少
  • 我是如何设计 Upload 上传组件的
  • 一起参Ember.js讨论、问答社区。
  • ​ubuntu下安装kvm虚拟机
  • !!Dom4j 学习笔记
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #includecmath
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (超详细)语音信号处理之特征提取
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (三)c52学习之旅-点亮LED灯
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • ./和../以及/和~之间的区别
  • .NET delegate 委托 、 Event 事件
  • .NET Standard 的管理策略
  • .NET 反射 Reflect
  • .NET框架设计—常被忽视的C#设计技巧
  • .NET与 java通用的3DES加密解密方法
  • .net中应用SQL缓存(实例使用)
  • @RequestMapping处理请求异常
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ C++ ] STL_list 使用及其模拟实现
  • []C/C++读取串口接收到的数据程序
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——
  • [codeforces]Recover the String
  • [Deepin 15] 编译安装 MySQL-5.6.35
  • [Golang]K-V存储引擎的学习 从零实现 (RoseDB mini版本)