草庐IT

day04-SpringCloud Eureka-服务注册与发现01

liyuelian 2023-04-11 原文

SpringCloud Eureka-服务注册与发现01

1.Eureka介绍

1.1学习Eureka前的说明

目前主流的服务注册&发现的组件是 Nacos,但是 Eureka 作为老牌经典的服务注册&发现技术还是有必要学习一下,原因:

(1)一些早期的分布式微服务项目使用的是 Eureka,在工作中完全有可能遇到这种情况。

(2)后期的服务注册&发现组件/技术,都参考了 Eureka 设计和理念,学习了 Eureka 后, 我们上手 Nacos 容易很多,而且可以理解得更深刻。

1.2当前架构问题分析

在企业级项目中,服务消费访问请求会存在高并发现象。如果只有一个会员中心-提供服务,可用性很差——如果该模块宕机,那么整个分布式应用就不能使用了。所以,会员中心提供服务往往是一个集群,有多个会员中心-提供服务模块。

这时又会出现两个问题:

  1. 因为是分布式架构(不同的服务模块在不同的主机上),服务消费方怎么去发现多个可以使用的提供服务(服务发现问题)?
  2. 还有,当服务消费方法发现可以使用的多个服务后,怎么从多个服务中选择其中的一个?(服务注册、负载均衡问题——选择策略)

使用Eureka就可以解决上述问题。

1.3引入Eureka项目架构分析

图示是分布式架构,每个模块都在不同的主机上

  1. 会员中心-提供服务模块,在项目中,会做成集群,提供高可用性(某个提供服务模块宕机,其他服务模块可以继续提供服务)
  2. Eureka Server 有必要的话,也可以做成集群(同理,防止宕机,提供高可用性)
  3. Eureka 包含两个组件∶Eureka Server 和 Eureka Client(EurekaClient 在服务消费&服务提供方都要引入)
  4. Eureka Server 提供注册服务,各个微服务节点(图例的服务消费&服务提供方)通过配置启动后,会在 Eureka Server 中进行注册,这样 EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在 Eureka 提供的界面中直观看到。
  5. Eureka Client 通过注册中心进行访问,是一个 Java 客户端,用于简化 Eureka Server 的交互,客户端同时也具备一个内置的、使用轮询(round-robin))负载算法的负载均衡器。在所有 Eurek Client 应用启动后,将会向 Eureka Server 发送心跳(默认周期为 30 秒),目的是告诉 Eureka Server 自己所在的微服务模块可以正常工作 。如果 Eureka Server 在多个心跳周期内(默认 90 秒)没有接收到某个节点的心跳,EurekaServer 将会从服务注册表中把这个服务节点移除。

1.4服务治理介绍

服务治理即服务管理:当项目中有多个服务的时候,怎么去管理这些服务。

Eureka 实现服务治理:

在传统的 rpc (remote procedure call)远程调用框架中,每个服务与服务之间的依赖关系比较复杂,管理也比较困难,所以需要管理服务之间的依赖关系。服务治理实现服务调用、负载均衡、容错等功能,实现服务发现与注册。

二说分布式开发

1.5服务注册和发现

  1. Eureka 采用 CS[Client-Server] 设计架构,Eureka Server 作为服务注册功能的服务器,成为服务注册中心。
  2. 系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server 并维持心跳连接,通过 Eureka Server 来监控系统中各个微服务是否正常运行。
  3. 当每个服务器启动的时候,会把当前自己服务器的信息,比如服务地址、通讯地址等,以别名方式注册到服务注册中心(Eureka Server)。
  4. 服务消费者或者服务提供者,以服务别名的方式去注册中心获取实际的服务提供者的通讯地址,然后通过 RPC 调用服务。

2.创建单机版Eureka Server-注册中心

2.1需求说明

演示创建单机版的Eureka Server,集群版的后面再使用。

2.2实现步骤

2.2.1创建Module&完成配置

(1)创建 e-commerce-eureka-server-9001 微服务模块 [作为注册中心]

选中父项目并右键--New--Module--Maven--直接点击next--根据下图配置--Finish

(2)修改本模块的pom.xml,加入依赖

<!--引入相关依赖,版本都使用父项目声明的版本-->
<dependencies>
    <!--引入Eureka Server场景启动器,使用版本仲裁-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

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

    <!--actuator-starter 是 springboot程序的监控系统,可以实现系统的健康监测
        可以通过http://localhost:9001/actuator看到相关的连接和信息-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

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

    <!--通用模块的jar包-e_commerce_center_common-api-->
    <dependency>
        <groupId>com.li.springcloud</groupId>
        <artifactId>e_commerce_center_common-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

</dependencies>

(3)创建application.yml,配置服务端口

server:
  port: 9001

#配置Eureka-server
eureka:
  instance:
    hostname: localhost #服务实例名
  client: #如果Eureka是一个集群,那么相互两个Eureka之间也可以当做对方为客户端
    #配置是否向注册中心注册自己
    register-with-eureka: false
    #表示自己就是注册中心,作用是维护注册的服务实例,不需要去检索服务
    fetch-registry: false
    service-url: #设置于 Eureka server 的交互模块,查询服务和注册服务都需要依赖这个地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

(4)创建主启动类 EurekaApplication.java

package com.li.springcloud;

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

/**
 * @author 李
 * @version 1.0
 */
@EnableEurekaServer //表示该程序作为EurekaServer
@SpringBootApplication
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class,args);
    }
}

2.2.2完成测试

启动主程序,在浏览器访问设置的ip+端口,已经能够看到Eureka的监控页面:

2.3将其他微服务模块注册到Eureka

2.3.1注册member-service-provider-10000

将member-service-provider-10000作为EurekaClient,注册到注册中心(e-commerce-eureka-server-9001),成为服务提供者

(1)在本模块的pom.xml中引入EurekaClient依赖

<!--引入EurekaClient场景启动器starter-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

(2)修改本模块的application.yml,添加如下配置:

#配置Eureka-Client
eureka:
  client:
    register-with-eureka: true #将自己注册到EurekaServer
    #表示从EurekaServer抓取注册信息
    fetch-registry: true
    service-url:
      #表示将自己注册到哪个EurekaServer
      defaultZone: http://localhost:9001/eureka
  instance:
    # 消费端地址
    ip-address: localhost
    #以IP地址的方式向eureka进行注册,域名变ip
    prefer-ip-address: true

(3)在本模块的主启动类添加注解@EnableEurekaClient,将该程序标识为EurekaClient

(4)完成测试:

先启动EurekaServer(e-commerce-eureka-server-9001),再启动EurekaServer(member-service-provider-10000),然后在浏览器中访问EurekaServer的监控页面,可以看到注册中心已经检测到一个Eureka实例:

2.3.2注册member-service-consumer-80

将member-service-consumer-80也作为EurekaClient注册到注册中心(e-commerce-eureka-server-9001),并且可以拉取注册中心提供的服务信息。

步骤、代码和2.3.1一致:

(1)修改本模块的pom.xml,添加EurekaClient的依赖

(2)在本模块的application.yml中进行EurekaClient的配置

(3)在本模块的主启动类添加注解@EnableEurekaClient,将该程序标识为EurekaClient

(4)先启动EurekaServer,再启动本模块,然后在浏览器中访问EurekaServer的监控页面,可以看到注册中心已经检测到本模块的EurekaClient实例:

如果上面的Status显示的是电脑名、localhost而不是ip地址,解决方案:

配置Eureka时Status显示的是电脑名而不是localhost及ipAddr显示为本机ip的问题

2.4Eureka注册中心的维护机制

2.5Eureka自我保护模式

在默认情况下,Eureka会启动自我保护模式(如图红字)

2.5.1自我保护模式是什么

Eureka自我保护机制

默认情况下,Eureka Client定时向Eureka Server端发送心跳包。如果Eureka Server在一定时间内没有收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90s)

但是当网络分区故障发生(延时、卡顿、拥挤)时,微服务与Eureka Server之间无法正常通信,以上的注销行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务的。

Eureka 通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时,Eureka Server 就会进入自我保护模式。开启自我保护模式之后,不会剔除微服务。因为客户端还能发送心跳,可能只是网络延迟问题。

综上,自我保护是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的、不健康的微服务都会保留),也不盲目注销任何健康的微服务。

一句话:开启自我保护模式后,如果某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该服务的信息进行保存。

  • 自我保护属于CAP里面的AP分支,即:保证可用性、分区容错性。

CAP原则:分布式系统中,C:一致性;A:可用性;P:分区容错性。CAP理论详解

验证下 Eureka 的自我保护机制:

  1. 启动 member-service-provider-10000 和 e-commerce-eureka-server-9001

  2. 让 member-service-provider-10000 正确的注册

  3. 然后关闭 member-service-provider-10000,观察注册的 member-service-provider-10000 服务是否还在

注意不能通过idea直接关闭,详见:自我保护机制开启了但是服务还是"被删掉了"

2.5.2如何禁用自我保护模式(不推荐)

在生产环境中一般不禁用自我保护模式

在Eureka Server端的配置文件中:

#配置Eureka-server
eureka:
  server:
    enable-self-preservation: false #禁用自我保护模式

有关day04-SpringCloud Eureka-服务注册与发现01的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  4. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  5. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  6. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  7. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  8. 阿里云国际版免费试用:如何注册以及注意事项 - 2

    作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

  9. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  10. ruby-on-rails - 设计注册确认 - 2

    我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:

随机推荐