Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2021升级版微服务教程3—Eureka完全使用指南

2021升级版微服务教程3—Eureka完全使用指南

原创
作者头像
鹿老师的Java笔记
修改于 2021-01-11 02:21:23
修改于 2021-01-11 02:21:23
1.6K0
举报

2021升级版SpringCloud教程从入门到实战精通「H版&alibaba&链路追踪&日志&事务&锁」

教程全目录「含视频」https://gitee.com/bingqilinpeishenme/Java-Wiki

Eureka服务注册和发现

本文要点: 什么是服务注册和发现 Eureka的使用 CAP Eureka集群搭建

什么是服务注册和发现

1593934895413
1593934895413
  • 治理中心
  • 服务注册
  • 服务发现
  • 心跳机制

以上都可以通过 Eureka 可以实现

Eureka基本使用

基本概念

Spring Cloud 封装了 Netflix 公司开发的 Eureka 组件来实现服务注册和发现。

image-20200420161934202
image-20200420161934202

在Eureka的架构中有两个角色:服务注册中心 Eureka Server服务客户端 Eureka Client

Eureka Server 作为服务注册功能的服务器,是服务注册中心。系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。

  • Eureka客户端 Eureka Client

EurekaClient是一个Java客户端,用于简化Eureka Server的交互

  • 在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)
  • Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势首先可以降低Eureka Server的压力,其次当所有的Eureka Server宕机,服务调用方依然可以完成调用

Eureka注册中心搭建

  1. 在Project中创建module
image-20210109160624673
image-20210109160624673
  1. 导入依赖
代码语言:txt
复制
代码语言:txt
AI代码解释
复制
 <!--        引入SpringCloud Eureka server的依赖-->
代码语言:txt
AI代码解释
复制
       <dependency>
代码语言:txt
AI代码解释
复制
           <groupId>org.springframework.cloud</groupId>
代码语言:txt
AI代码解释
复制
           <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
代码语言:txt
AI代码解释
复制
       </dependency>
代码语言:txt
AI代码解释
复制
   </dependencies>
代码语言:txt
复制
  1. 启动类上加注解
1593935968864
1593935968864
  1. 配置文件
代码语言:txt
复制

server:

代码语言:txt
AI代码解释
复制
 port: 8800

eureka:

代码语言:txt
AI代码解释
复制
 client:
代码语言:txt
AI代码解释
复制
   #    eureka.client. register-with-eureka:由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己
代码语言:txt
AI代码解释
复制
   registerWithEureka: false
代码语言:txt
AI代码解释
复制
   #      不主动发现别人
代码语言:txt
AI代码解释
复制
   fetchRegistry: false
代码语言:txt
AI代码解释
复制
   #    声明注册中心的地址
代码语言:txt
AI代码解释
复制
   serviceUrl:
代码语言:txt
AI代码解释
复制
     defaultZone: http://localhost:8800/eureka/

#给当前应用起个服务名称 不能通过路径访问的 这个服务名称 在微服务中使用代表当前服务

spring:

代码语言:txt
AI代码解释
复制
 application:
代码语言:txt
AI代码解释
复制
   name: eureka-server
代码语言:txt
复制
  1. 启动注册中心 访问注册中心的监控页面 http://localhost:8800
image-20210109160155304
image-20210109160155304

客户端搭建—用户服务

以用户服务为例

  1. 创建项目
  2. 导入相关依赖
代码语言:txt
复制
代码语言:txt
AI代码解释
复制
       <dependency>
代码语言:txt
AI代码解释
复制
           <groupId>org.springframework.cloud</groupId>
代码语言:txt
AI代码解释
复制
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
代码语言:txt
AI代码解释
复制
       </dependency>
代码语言:txt
复制
  1. 启动类上加注解
image-20200420165233554
image-20200420165233554
  1. 配置文件
代码语言:txt
复制

server:

代码语言:txt
AI代码解释
复制
 port: 8804

#指定当前服务的名称 这个名称会注册到注册中心

spring:

代码语言:txt
AI代码解释
复制
 application:
代码语言:txt
AI代码解释
复制
   name: cloud-user-8804

指定 服务注册中心的地址

eureka:

代码语言:txt
AI代码解释
复制
 client:
代码语言:txt
AI代码解释
复制
   serviceUrl:
代码语言:txt
AI代码解释
复制
     defaultZone: http://localhost:8800/eureka
代码语言:txt
复制

通过以上四步 就完成了一个 Eureka客户端的搭建 直接启动项目 通过Eureka的注册中心可以看到

image-20210109160221422
image-20210109160221422

按照上述步骤,将商品服务和订单服务改造为Eureka客户端。

Eureka进阶使用

CAP理论

目前,大型网站几乎都是分布式的,分布式系统的最大难点,就是各个节点的状态如何同步。CAP 定理是这方面的基本定理,也是理解分布式系统的起点。

1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标。

Consistency 一致性 Availability 可用性 Partition tolerance 分区容错性

它们的第一个字母分别是 C、A、P。

Eric Brewer 说,这三个指标不可能同时做到。这个结论就叫做 CAP 定理。

  • 分区容错性

大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信。

Node1 和 Node2 是两台跨区的服务器。Node1 向 Node2 发送一条消息,Node2可能无法收到。系统设计的时候,必须考虑到这种情况。

一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。CAP 定理告诉我们,剩下的 C 和 A 无法同时做到。

  • 数据一致性

由于系统问题,Node1 的数据不能即时同步给Node2,此时如果获取数据,会获取到不一致的数据,所有为了保证分布式系统对外的数据一致性,选择不返回任何数据【或者所有节点不响应任何请求】。

  • 可用性

要求系统内的节点在接受到请求的时候能够即时给出响应,具体来说就是:一方面需要在合理的时间内给出响应,另一方面即便是部分节点宕机,那么其他未宕机的节点也需要能够正常处理请求,即时返回的数据有问题。

一致性和可用性,为什么不可能同时成立?

答案很简单,因为可能通信失败(即出现分区容错),所以,对于分布式系统,我们只能能考虑当发生分区错误时,如何选择一致性和可用性。

需要强调的是:C 和 A 的抉择是发生在有分区问题的时候,正常情况下系统就应该有完美的数据一致性和可用性 例子: 比如,我们有个分布式系统,由三个节点 a、b、c 组成。其中节点 a 存放了 A 表的数据,b 存放了 B 表的数据,c 存放了 C 表的数据。 如果有一个业务,它的意图是想往 A 表插入一条新数据,在 B 表删除一条已有数据,在 C 表更新一条老数据,这个分布式系统该怎么处理这种业务? 技术上我们对这种一个意图想做多件事的情况往往会包装成一个事务。当我们包装成一个事务以后,我们可能会通过先在 a 节点执行,然后去 b 节点执行,最后去 c 节点执行,等到都成功了,才会返回成功。 但是,发生了分区以后怎么办?当在 a、b 节点都成功了,到 c 发现发生了通信故障? 此时,根据 CAP 定理,你有两个选择,要么就直接返回一个部分成功的结果给客户端,要么直接卡死等客户端超时或者返回失败给客户端。当返回部分成功的时候,这就是选择了可用性(A),当卡死或者返回失败给客户端的时候,就是选择了一致性(C)。

而根据一致性和可用性的选择不同,开源的分布式系统往往又被分为 CP 系统和 AP 系统。

  • 当一套系统在发生分区故障后,客户端的任何请求都被卡死或者超时,但是,系统的每个节点总是会返回一致的数据,则这套系统就是 CP 系统,经典的比如 Zookeeper。
  • 如果一套系统发生分区故障后,客户端依然可以访问系统,但是获取的数据有的是新的数据,有的还是老数据,那么这套系统就是 AP 系统,经典的比如 Eureka。

很多时候一致性和可用性并不是二选一的问题,大部分的时候,系统设计会尽可能的实现两点,在二者之间做出妥协,当强调一致性的时候,并不表示可用性是完全不可用的状态,比如,Zookeeper 只是在 master 出现问题的时候,才可能出现几十秒的不可用状态,而别的时候,都会以各种方式保证系统的可用性。而强调可用性的时候,也往往会采用一些技术手段,去保证数据最终是一致的。

自我保护机制

Eureka首页输出警告如图:

image-20210109160302395
image-20210109160302395

默认情况下,如果Eureka Server在一定时间内没有接受到服务实例的心跳,Eureka将会注销该实例(默认90秒).但是当网络分区发生故障时,微服务客户端和Eureka Server 无法正常通信。以上行为可能变得特别危险了,因为微服务本身是健康的,此时不能注销该服务实例。

Eureka通过自我保护机制来解决这个问题,当Eureka Server在短时间丢失过多的服务实例(可能发生了网络分区的故障),那么Eureka Server进入自我保护模式,一旦进入此模式,Eureka Server将会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不再注销任何的服务实例),当网络故障恢复后,Eureka Server会自动退出自我保护模式。

综上,自我保护模式是一种应对网络故障的安全保护措施,它的架构哲学是宁可同时保留所有的微服务,也不盲目注销任何健康的微服务,使用自我保护模式可以让Eureka,更加健壮,稳定。

一句话:大面积出现客户端失联的时候,Eureka 注册中心进入自我保护模式,不注销任何实例

自我保护机制的配置【了解】

在Eureka Server中配置关闭自我保护机制

代码语言:txt
AI代码解释
复制
#关闭自我保护机制  默认开启
eureka.server.enable-self-preservation=false

如果想及时剔除失效的eureka服务除了关闭自我保护机制外,可以调低eureka的心跳值

代码语言:txt
AI代码解释
复制
eureka-server服务端
配置文件中我们添加如下配置

#关闭保护机制,以确保注册中心将不可用的实例正确剔除
eureka.server.enable-self-preservation=false
#(代表是5秒,单位是毫秒,清理失效服务的间隔 )
eureka.server.eviction-interval-timer-in-ms=5000
代码语言:txt
AI代码解释
复制
客户端
配置文件中我们添加如下配置

# 心跳检测检测与续约时间
# 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
# 配置说明
#  lease-renewal-interval-in-seconds 每间隔10s,向服务端发送一次心跳,证明自己依然”存活“
#  lease-expiration-duration-in-seconds  告诉服务端,如果我20s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.instance.lease-expiration-duration-in-seconds=20

Eureka集群搭建

注册中心集群,防止注册中心单机故障。

  1. 创建一个新的注册中心 eureka-server-8801
  2. 创建项目
代码语言:txt
AI代码解释
复制
  ![image-20210109160323741](https://gitee.com/bingqilinpeishenme/blogimg/raw/master/img/image-20210109160323741.png)
  1. 导入依赖
  2. 启动类加注解
  3. 写配置文件
代码语言:txt
AI代码解释
复制
  ![image-20210109160336831](https://gitee.com/bingqilinpeishenme/blogimg/raw/master/img/image-20210109160336831.png)
  1. 修改注册中心 Eureka-server-8800的配置文件
image-20210109160350052
image-20210109160350052
  1. 修改所有的客户端的配置,让客户端能够同时向两个注册中心注册
image-20210109160405439
image-20210109160405439
  1. 启动所有的客户端和注册中心 看看能不能正常注册

如果你觉得这篇内容对你挺有有帮助的话:

  1. 点赞支持下吧,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)
  2. 欢迎在留言区与我分享你的想法,也欢迎你在留言区记录你的思考过程。
  3. 觉得不错的话,也可以关注 编程鹿 的个人公众号看更多文章和讲解视频(感谢大家的鼓励与支持🌹🌹🌹)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【掌印日记-点赞功能实现】使用Redis实现分布式锁
在项目开发中,点赞事件频率较高,我们不可能直接将对点赞功能的操作放到MySQL里面,所以我们引入Redis中间件。
Karos
2023/01/16
1.2K0
重新说说Redis实现分布式公平可重入锁的实现,这次具体说说异步唤醒机制,这次带上QPS检测
但是这样做会有一点问题,我们每次休眠的时间都是固定的,仍然会有一大部分空窗期,我设置30s的锁过期,那么好,20个线程足足跑了两三分钟,这个效率绝对不行,对吧。
Karos
2023/09/13
8971
重新说说Redis实现分布式公平可重入锁的实现,这次具体说说异步唤醒机制,这次带上QPS检测
RedisTemplate分布式锁演变、Redission分布式锁实现!
来源 | https://blog.csdn.net/zhangkaixuan456/article/details/110679617
程序猿DD
2021/09/03
1.4K0
Java基于redis实现分布式锁(SpringBoot)
分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉。
Happyjava
2024/02/02
7130
Java基于redis实现分布式锁(SpringBoot)
【Redis项目实战】使用Springcloud整合Redis分布式锁+RabbitMQ技术实现高并发预约管理处理系统
开发一个高并发预约管理处理系统,其中用户可以预约倾听者。由于并发预约可能导致冲突和混乱,需要实现分布式锁来确保同一时间段只有一个用户可以进行预约。为了实现这一目的,使用Redis作为分布式锁的存储介质,并设计一组表来存储倾听者的预约情况。
苏泽
2024/03/01
6650
分布式锁+AOP实现缓存
  随着业务中缓存及分布式锁的加入,业务代码变的复杂起来,除了需要考虑业务逻辑本身,还要考虑缓存及分布式锁的问题,增加了程序员的工作量及开发难度。而缓存的玩法套路特别类似于事务,而声明式事务就是用了aop的思想实现的。
别团等shy哥发育
2023/04/23
3030
分布式锁+AOP实现缓存
基于Redis实现分布式锁
基于Redis实现分布式锁 一. 基本原理 基于Redis的setnx命令,如果设置成功,则表示当前进程(线程)获取锁成功,否则说明有其他进程已经获取了锁,需进行等待 setnx 的key为需要加锁的资源名称(实例中为方法名),value为业务唯一的id 加锁时需制定锁的过期时间,避免锁未正常释放而导致的死锁问题 加锁时需设置等待超时时间,避免等待时间过长导致系统性能下降 释放锁时,与Redis中的value与当前的业务id进行对比,符合才执行释放操作 二. 代码实现 加锁的核心操作 /** * @Au
张申傲
2020/09/03
3540
redis命令和lua实现分布式锁
因为这个命令的性质,多个线程竞争时只有一个线程能修改key的值。利用这一点可以实现锁的互斥功能。
HUC思梦
2020/09/03
1.6K0
【110期】面试官:Redis分布式锁如何解决锁超时问题?
关于redis分布式锁, 查了很多资料, 发现很多只是实现了最基础的功能, 但是, 并没有解决当锁已超时而业务逻辑还未执行完的问题, 这样会导致: A线程超时时间设为10s(为了解决死锁问题), 但代码执行时间可能需要30s, 然后redis服务端10s后将锁删除, 此时, B线程恰好申请锁, redis服务端不存在该锁, 可以申请, 也执行了代码, 那么问题来了, A、B线程都同时获取到锁并执行业务逻辑, 这与分布式锁最基本的性质相违背: 在任意一个时刻, 只有一个客户端持有锁, 即独享。
良月柒
2021/01/07
9170
【110期】面试官:Redis分布式锁如何解决锁超时问题?
「分布式」实现分布式锁的正确姿势
最近看到好多博主都在推分布式锁,实现方式很多,基于db、redis、zookeeper。zookeeper方式实现起来比较繁琐,这里我们就谈谈基于redis实现分布式锁的正确实现方式。
一个程序员的成长
2020/11/25
8700
「分布式」实现分布式锁的正确姿势
Redis实现分布式锁
一看就会的超详细教程:SpringBoot整合MybatisPlus!>>> 1.自己实现 private static String REDIS_LOCK = "redis_lock";
用户5927264
2021/06/08
3840
Redis实现分布式锁
redis实现分布式锁工具类 灰常好用
public interface RedisDistributionLock { /** * 加锁成功,返回加锁时间 * @param lockKey * @param threadName * @return */ public long lock(String lockKey, String threadName); /** * 解锁, 需要更新加锁时间,判断
陈灬大灬海
2023/05/12
5640
Java基于redis实现分布式锁(SpringBoot)
分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉。
Happyjava
2019/07/17
5940
Java基于redis实现分布式锁(SpringBoot)
基于redis的分布式锁二种应用场景
“分布式锁”是用来解决分布式应用中“并发冲突”的一种常用手段,实现方式一般有基于zookeeper及基于redis二种。具体到业务场景中,我们要考虑二种情况:
菩提树下的杨过
2019/06/17
1.1K0
基于redis的分布式锁二种应用场景
纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式
在单机部署的时候,我们可以使用 Java 中提供的 JUC 锁机制避免多线程同时操作一个共享变量产生的安全问题。JUC 锁机制只能保证同一个 JVM 进程中的同一时刻只有一个线程操作共享资源。
码哥字节
2024/01/29
1.4K0
纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式
ZooKeeper 分布式锁实现
#1 场景描述# 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程共享了一些资源, 可能就需要分布式锁来锁定对这些资源的访问。 #2 思路# 进程需要访问共享数据时, 就在"/locks"节点下创建一个sequence类型的子节点, 称为thisPath. 当thisPath在所有子节点中最小时, 说明该进程获得了锁. 进程获得锁之后, 就可以访问共享资源了. 访问完成后, 需要将thisPath删除. 锁由新的最小的子节点获得.
用户1263954
2018/06/22
6750
SpringBoot实现Redis分布式锁
分布式锁一般有三种实现方式:1. 数据库乐观锁;2. 基于Redis的分布式锁;3. 基于ZooKeeper的分布式锁。本文介绍基于Redis实现分布式锁。
Ant丶
2022/03/01
5290
浅谈缓存与分布式锁
对于一个大型网站而言,每天的访问量是巨大的,尤其遇到某些特定的时间点,比如电商平台的购物节、教育平台开学季。当在某个时间点遇到过量的并发时,往往会压垮服务器导致网站崩溃,因此,网站对于高并发的处理是至关重要的,其中缓存起着举足轻重的作用。对于一些不经常变化,或者热度很高的数据,可以将其存入缓存,此时当用户访问时将直接读取缓存而不查询数据库,从而大大提高了网站的吞吐量。
wangweijun
2022/01/10
2100
SpringBoot-Redis 实现分布式锁
大多数互联网系统都是分布式部署的,分布式部署确实能带来性能和效率上的提升,但为此,我们就需要多解决一个分布式环境下,数据一致性的问题。
周三不加班
2019/09/03
5.8K0
SpringBoot系列之基于Jedis实现分布式锁
在单机环境,我们使用最多的是juc包里的单机锁,但是随着微服务分布式项目的普及,juc里的锁是不能控制分布锁环境的线程安全的,因为单机锁只能控制同个进程里的线程安全,不能控制多节点的线程安全,所以就需要使用分布式锁
SmileNicky
2023/12/13
1.5K0
SpringBoot系列之基于Jedis实现分布式锁
推荐阅读
相关推荐
【掌印日记-点赞功能实现】使用Redis实现分布式锁
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档