03-02、SpringCloud第二章,Eureka服务的注册与发现

SpringCloud从看不懂到放弃,第二章

一、Eureka服务的注册与发现

Eureka

xml 复制代码
Netflix在设计Eureka时遵守的就是AP原则

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

1、Eureka简介

xml 复制代码
	Eureka是Netflix的一个子模块,是一个基于Rest的服务,用于服务定位,已实现云端中间层服务发现和故障转移。
	
	服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。

	功能类似于dubbo的注册中心,比如zookeeper

Eureka基本架构

xml 复制代码
	Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。

	Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。
 
	而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。SpringCloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。

	Eureka包含两个组件:Eureka Server和Eureka Client
	Eureka Server提供服务注册服务
	各个节点启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到
 
	EurekaClient是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

三大结构

xml 复制代码
1、Eureka server提供服务注册与发现
2、service provide将自身服务注册到Eureka,从而使服务消费方能够找到
3、service consumer从Eureka获取注册服务列表,从而能够消费服务

2、构建项目

项目结构

xml 复制代码
总父工程
通用模块API
服务提供者Provider
服务消费者Consumer
eureka服务注册中心module
(1)、cloud-eureka-7001

POM

主要包含一个spring-cloud-starter-eureka-server

XML 复制代码
<?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>cloud</artifactId>
        <groupId>com.lee</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloud-eureka-7001</artifactId>

    <dependencies>
        <!--eureka-server服务端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <!-- 修改后立即生效,热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>


</project>

注意:

xml 复制代码
基本上我们要引入cloud的一个新的技术组件,会有两步

1、新增一个相关的maven坐标
	<dependency>
		<groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
	</dependency>

2、在主启动类上标注启动该新组件的相关注解标签
	@EnableEurekaServer 
	@EnableZuulProxy
	@EnableXXXXX
	...

APPLICATION.YML

主要暴露eureka端口和对外服务地址

XML 复制代码
server:
  port: 7001

eureka:
  instance:
    hostname: localhost #eureka服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己。
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。

主启动类

xml 复制代码
package com.lee.cloud;

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

//EurekaServer服务器端启动类,接受其它微服务注册进来
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer7001_App {

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

测试

xml 复制代码
http://localhost:7001
(2)、将已有的部门微服务注册进Eureka服务中心

修改cloud-provider-dept-8001

POM - 新增 eureka客户端 config配置中心

xml 复制代码
<!-- 将微服务provider侧注册进eureka -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

<!--注意:-->
<!--
	如果eureka下载不下来的话
	改成这个
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.6.RELEASE</version>
        </dependency>

-->

YML - 新增 eureka服务地址

xml 复制代码
 eureka:
  client: #客户端注册进eureka服务列表内
    service-url: 
      defaultZone: http://localhost:7001/eureka

主启动类 - 新增 将本服务启动后自动注册进eureka服务中

xml 复制代码
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中

测试:

xml 复制代码
1、启动 cloud-eureka-7001
2、启动 cloud-provider-dept-8001
3、http://localhost:7001

注意:暴露在eureka中的微服务名称,即provider的yml中spring:application:name的名称

如果找不到服务的话,大概率是应为spring-cloud-starter-eureka和
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>

版本不一致导致的
(3)、actuator与注册微服务信息完善---主机映射名称修改

Eureka服务中的显示

Application AMIs Availability Zones Status
CLOUD-DEPT n/a (1) (1) UP (1) - windows10.microdone.cn:cloud-dept:8001

目标:修改 windows10.microdone.cn:cloud-dept:8001的显示

cloud-provider-dept-8001修改:

YML

xml 复制代码
eureka:
	instance:
    	instance-id: cloud-dept8001

结果:

Application AMIs Availability Zones Status
CLOUD-DEPT n/a (1) (1) UP (1) - cloud-dept8001
(4)、actuator与注册微服务信息完善---主机IP信息提示

鼠标移动到上侧超链接时,浏览器左下角的链接显示

cloud-provider-dept-8001修改:

YML

XML 复制代码
eureka:
	instance:
		prefer-ip-address: true  #访问路径可以显示IP地址
(5)、actuator与注册微服务信息完善---Info内容构建

cloud-dept8001超了解点击后内容的构建

cloud-provider-dept-8001修改:

POM

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

YML

XML 复制代码
info:									#内容以info开头下边随便写
  app.name: cloud
  author.name: lee
  app.function: 部门服务提供者
  build.artifactId: $project.artifactId$
  build.version: $project.version$

CLOUD父工程POM

xml 复制代码
<build><!--构建-->
   <finalName>microservicecloud</finalName>
   <resources>	<!--可以访问src/main/resources下的文件-->
     <resource>
       <directory>src/main/resources</directory>
       <filtering>true</filtering>
     </resource>
   </resources>
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-resources-plugin</artifactId>
       <configuration>
         <delimiters>
          <delimit>$</delimit>
         </delimiters>
       </configuration>
     </plugin>
   </plugins>
  </build>

结果:

xml 复制代码
访问:http://192.168.101.39:8001/info
显示:
{"app":
	{
		"name":"cloud",
		"function":"部门服务提供者"
	},
 "author":{"name":"lee"},
 "build":{
			"artifactId":"$project.artifactId$",
			"version":"$project.version$"
		  }
}

3、Eureka集群配置

(1)、仿照cloud-eureka-7001创建cloud-eureka-7002和cloud-eureka-7003

(2)、修改 映射

xml 复制代码
c:\Windows\System32\drivers\etc下的host文件
添加如下:
	127.0.0.1   eureka7001.com
	127.0.0.1   eureka7002.com
	127.0.0.1   eureka7003.com

(3)、三台eureka服务的yml配置

xml 复制代码
eureka:
   instance:
		hostname: eureka7001.com  ##eureka服务端的实例名称,知识localhost换了个名而已

eureka:
	client:
		defaultZone: http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
		##也可以是http://localhost:7002/eureka,http://localhost:7003/eureka

(4)、cloud-provider-dept-8001 YML服务地址修改

XML 复制代码
eureka:
	client:
		service-url:
			defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

测试:

xml 复制代码
http://eureka7001.com:7001
http://eureka7002.com:7002
http://eureka7003.com:7003

4、Eureka自我保护机制

xml 复制代码
	某时刻某一个微服务不可用了,或者长时间没有被调用,eureka不会立刻清理,依旧会对该微服务的信息进行保存。(网络拥堵或者调用超时)

	什么是自我保护模式?
  
	默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了------因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过"自我保护模式"来解决这个问题------当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
 
	在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着
 
	综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

5、Eureka和Zookeeper对比

xml 复制代码
RDBS(mysql/oracle/sqlserver)---->ACID
NOSQL(redis/mongodb)----->CAP
---------------------------------------------------------
---------------------------------------------------------
ACID:   atomicity原子性、
		consistency一致性、
		isolation独立性、
		durability持久性

CAP:	consistency强一致性、
		 availability高可用、
		 partition tolerance 分区容错性
---------------------------------------------------------
---------------------------------------------------------
Eureka遵守AP  Zookeeper遵守CP

 
 	作为服务注册中心,Eureka比Zookeeper好在哪里
著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性P在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。
因此
	Zookeeper保证的是CP,
	Eureka则是AP。
 
1. Zookeeper保证CP
	当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。
 
2. Eureka保证AP
	Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况: 

2.1、Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务 
2.2、Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用) 
2.3、当网络稳定时,当前实例新的注册信息会被同步到其它节点中
 
	因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。
	

拓展知识

xml 复制代码
#服务发现

@AutoWire
private DiscoveryClient client;

List<String> serviceList = client.getServices();//列出Eureka中所有的服务
List<ServiceInstance> instanceList = client.getInstances("CLOUD-DEPT");//查找服务实例
 
instance.getServiceId();//实例ID
instance.getHost();//实例主机
instance.getPort();//实例端口
instance.getUri();//实例Uri
    
@EnableDiscoveryClient //主启动类上+服务发现注解
相关推荐
韩立学长1 小时前
【开题答辩实录分享】以《植物园信息管理系统》为例进行选题答辩实录分享
java·数据库·spring
Knight_AL1 小时前
Spring Boot 的主要特性与传统 Spring 项目的区别
spring boot·后端·spring
无名无姓某罗2 小时前
jQuery 请求 SpringMVC 接口返回404错误排查
前端·spring·jquery
黄俊懿2 小时前
【深入理解SpringCloud微服务】Gateway简介与模拟Gateway手写一个微服务网关
spring boot·后端·spring·spring cloud·微服务·gateway·架构师
我是小妖怪,潇洒又自在2 小时前
springcloud alibaba(十)分布式事务
分布式·spring cloud·wpf
眠りたいです3 小时前
Docker:Docker image常用命令使用及实操
运维·docker·容器·eureka·镜像
RemainderTime3 小时前
(十)Spring Cloud Alibaba 2023.x:生产级 CI/CD 全链路实战(从 Dockerfile 到 Jenkins)
运维·spring cloud·ci/cd·docker·jenkins
ALex_zry4 小时前
现代C++如何解决传统内存分配器的核心痛点
java·c++·spring
别惹CC4 小时前
Spring AI 进阶之路05:集成 MCP 协议实现工具调用
java·人工智能·spring
韩立学长13 小时前
【开题答辩实录分享】以《自助游网站的设计与实现》为例进行选题答辩实录分享
java·mysql·spring