【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon
文章目录
- 一、Eureka
- 1、服务提供者与消费者
- 2、Eureka原理分析
- 3、搭建Eureka
- 4、服务注册
- 5、模拟多服务实例启动
- 6、服务的发现
- 二、Ribbon
- 1、负载均衡的原理
- 2、源码分析
- 3、负载均衡策略
- 4、饥饿加载
一、Eureka
1、服务提供者与消费者
服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
很明显,这是一个相对的概念。
2、Eureka原理分析
上一篇中,远程调用时,url参数是写死在代码中的,而不同的测试、生产、开发环境IP不同,有集群时,端口也不能固定。
很明显,硬编码肯定行不通。Eureka就是来解决这个问题的。
- 每个服务启动的时候,将自己的信息注册到eureka中
- 某个服务需要调用其他服务时,向eureka拉取对应的服务信息
- 负载均衡到其中一台(如图中的localhost:8081)
- 进行远程调用
- 服务实例向eureka心跳续约,每30秒一次,eureka监控到某个服务实例不再心跳时,就从其注册信息中剔除这条信息。服务消费者拉取时当然也就拉取不到这个宕掉的服务实例
- 新启动一个服务,服务信息注册到了eureka中…以此类推
接下来开始搭建Eureka,并进行服务注册和服务发现
3、搭建Eureka
- 在父工程下新建eureka模块,选择Maven,点击Finish
- 给该模块引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--版本在父工程中统一管理,这里不用写-->
- 编写启动类,添加@EnableEurekaServer注解(自动装配的开关)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class, args);}
}
- 添加application.yaml文件
server:port: 10086 # 服务端口
spring:application:name: eurekaserver # eureka的服务名称,eureka自身也是个微服务,也要注册自己的信息到eureka注册中心
eureka:client:service-url: # eureka的地址信息defaultZone: http://127.0.0.1:10086/eureka# eureka自身也是个微服务,也要注册自己的信息到eureka注册中心
# 王思聪住万达酒店也得身份证登记一下,虽然那就是他家的产业
- 启动eureka模块
- 注册成功
4、服务注册
接下来将user和order服务注册到eureka中:
- 在user模块的pom文件中引入eureka客户端依赖
<!--eureka客户端依赖-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 在application.yaml文件中增加注册中心地址的配置
server:port: 8081
spring:application: name: userservice
eyreka:client:service-url: # eureka的地址信息defaultZone: http://127.0.0.1:10086/eureka
- 重启user模块(order模块操作步骤相同),注册成功
5、模拟多服务实例启动
上面完成的注册都是单服务实例的,接下来在IDEA中模拟启动多个服务实例:
- 右键选择拷贝
- -Dserver.port覆盖yaml文件中的端口,从而换个新端口
- 启动这个新服务实例,注册成功
6、服务的发现
接下来实现:在order服务中完成服务信息的拉取,然后通过负载均衡挑选一个user服务,实现远程调用
服务拉取是基于服务名称获取服务列表,然后在对服务列表做负载均衡
- 修改order代码,将服务IP和端口改为服务名
String url ="http://userservice/user/" + order.getUserId();
- 在order启动类OrderApplication中的RestTemplate添加负载均衡注解
@Bean
@LoadBalanced
public RestTemplate restTemplate() {return new RestTemplate();
}
- 分别调用order接口两次,传参101和102,看它远程调用了哪个user服务实例
- 可以看到两个服务实例均有对应的日志,成功!
二、Ribbon
1、负载均衡的原理
分析:
我在浏览器中直接访问http://userservice/user/,访问失败,这是因为userservice既不是可用域名,也不是IP。那order调用到user服务的过程中经历了什么呢?
- order发起请求
- Ribbon拦截请求,拿到服务名,向eureka拉取信息
- eureka返回服务列表信息给Ribbon
- Ribbon将请求轮询到相应的服务地址上去
具体信息,在源码中打断点来调试看看。
2、源码分析
@LoadBalanced注解,就标识了调用方当前这个restTemplate这个对象发起的请求,要被Ribbon拦截
LoadBalancerInterceptor实现了ClientHttpRequestInterceptor接口:
在LoadBalancerInterceptor接口重写的intercent方法上打断点,调用order接口(中途会对user服务发起远程调用),断点进入到了这里:
继续往下,看到了Ribbon对象
继续往下:成功从eureka拿到服务列表信息
继续往下调试,看到了IRule这个接口,决定了负载均衡的策略
以上,调用接口http://localhost:8080/order/102后发生的事情如图:
- 接口中途通过restTemple远程调用http://userservice/user/1
- 被负载均衡拦截器拦截
- 获取url中的服务id,即userservice
- 动态服务列表均衡器向eureka拉取userservice的信息
- eureka返回服务列表给DynamicServiceListLoadBalancer
- 通过IRule挑选出某个服务,返回给RibbonLoadBalancerClient
- 请求被转发到了某个一具体的实例上
3、负载均衡策略
Ribbon的负载均衡策略是由IRule接口来定义的,它的每一个子接口就是一种策略。
具体的含义为:
以上策略中,Ribbon默认的是ZoneAvoidanceRule。想修改负载均衡策略有这两种方法:
代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:
@Bean
public IRule randomRule(){return new RandomRule(); //改为随机
}
配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则
userservice: ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #负载均衡规则
此时,多次调用order接口(代码中途远程调用user):
http://localhost:8080/order/102
可以看到转发到user实例上的请求不再有明显规律。
4、饥饿加载
重启order服务,然后两次访问order接口,发现耗时相差巨大:
Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,因此请求时间会很长。
饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下配置开启饥饿加载:
ribbon:eager-load: enabled: true #开启饥饿加载clients: userservice # 指定对userservice这个服务饥饿加载# clients为list,可添加多个
相关文章:

【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon
文章目录 一、Eureka1、服务提供者与消费者2、Eureka原理分析3、搭建Eureka4、服务注册5、模拟多服务实例启动6、服务的发现 二、Ribbon1、负载均衡的原理2、源码分析3、负载均衡策略4、饥饿加载 一、Eureka 1、服务提供者与消费者 服务提供者:一次业务中…...

图形学实验(完整文件见上传)
CRect rect; this->GetClientRect(rect); pDC->Ellipse(rect); // DDALineView.cpp : implementation of the CDDALineView class // #include “stdafx.h” #include “DDALine.h” #include “DDALineDoc.h” #include “DDALineView.h” #ifdef _DEBUG #define new…...

Spark大数据处理学习笔记(3.2.1)掌握RDD算子
该文章主要为完成实训任务,详细实现过程及结果见【http://t.csdn.cn/FArNP】 文章目录 一、准备工作1.1 准备文件1. 准备本地系统文件2. 把文件上传到 1.2 启动Spark Shell1. 启动HDFS服务2. 启动Spark服务3. 启动Spark Shell 二、掌握转换算子2.1 映射算子 - map()…...
lammps初级:石墨烯、金属材料、纳米流体、热传导、多成分体系、金属、半导体材料的辐照、自建分子力场、MOFS、H2/CO2混合气体等模拟
1 LAMMPS的基础入门——初识LAMMPS是什么?能干什么?怎么用? 1.1 LAMMPS在win10和ubuntu系统的安装及使用 1.2 in文件结构格式 1.3 in文件基本语法:结合实例,讲解in文件常用命令 1.4 data文件格式 1.5 LAMMPS常见错误解…...
【MarkerDown】CSDN Markdown之时序图sequenceDiagram详解
CSDN Markdown之时序图sequenceDiagram详解 序列图 sequenceDiagram参与者与组参与者 participant拟人符号 actor别名 as组 box 消息(连线)激活/失活 activate/deactivate备注 Note循环 loop备选 Alt并行 par临界区 critical中断 break背景高亮 rect注释 %%转义字符的实体代码序…...

ReentrantLock实现原理-公平锁
在ReentrantLock实现原理(1)一节中,我们了解了ReentrantLock非公平锁的获取流程,在本节中我们来看下ReentrantLock公平锁的创建以及锁管理流程 创建ReentrantLock公平锁 创建公平锁代码如下: ReentrantLock reentrantLock new ReentrantL…...

掌握Scala数据结构(2)MAP、TUPLE、SET
一、映射 (Map) (一)不可变映射 1、创建不可变映射 创建不可变映射mp,用键->值的形式 创建不可变映射mp,用(键, 值)的形式 注意:Map是特质(Scala里的trait,相当于Java里的interface&#…...

flutter:文件系统目录、文件读写
参考 参考:老孟 文件存储和网络请求 数据存储 Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的。但…...

计算机提示“找不到vcruntime140.dll,无法继续执行代码可”以这样子修复
首先,对于那些不熟悉的人来说,vcruntime140.dll是一个关键文件,用于在Windows操作系统上运行使用C语言编写的大型应用程序。如果你正在运行或安装这样的应用程序,但找不到vcruntime140.dll文件,那么你的应用程序可能无…...

深度学习pytorch实战五:基于ResNet34迁移学习的方法图像分类篇自建花数据集图像分类(5类)超详细代码
1.数据集简介 2.模型相关知识 3.split_data.py——训练集与测试集划分 4.model.py——定义ResNet34网络模型 5.train.py——加载数据集并训练,训练集计算损失值loss,测试集计算accuracy,保存训练好的网络参数 6.predict.py——利用训练好的网…...

Rust in Action笔记 第五章 深入理解数据
如果希望看到f32类型的数转换成整型数字u32类型,需要在unsafe包裹下调用std::mem::transmute(data),因为在安全的Rust语法中没有把整型数据按照bit转换成浮点数据的实现,如果想要看到浮点数的二进制输出(通过{:b})&…...

Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码 最近在学习Cocos Creator,作为新手,刚刚开始学习Cocos Creator,刚刚入门,这里记录一下飞机大战小游戏实现。 https://wxaurl.cn/VEgRy2eTMyi 一 安装CocosDashBo…...

2.4 逻辑代数的基本定理
学习目标: 如果我要学习逻辑代数的基本定理,我会采取以下步骤: 1. 学习基本概念:首先,我会花时间了解逻辑代数的基本概念,如逻辑运算符(合取、析取、否定等)、真值表、逻辑等价性等…...

适用于 Linux 的 Windows 子系统wsl文档
参考链接:https://learn.microsoft.com/zh-cn/windows/wsl/ 鸟哥的Linux私房菜:http://cn.linux.vbird.org/ http://cn.linux.vbird.org/linux_basic/linux_basic.php http://cn.linux.vbird.org/linux_server/ 目录 安装列出可用的 Linux 发行版列出已…...

C++特殊类的设计与类型转换
特殊类的设计与类型转换 特殊类的设计请设计一个类,只能在堆上创建对象请设计一个类,只能在栈上创建对象请设计一个类,只能创建一个对象(单例模式) C的类型转换 特殊类的设计 请设计一个类,只能在堆上创建对象 通过new创建的类就…...
如何通过关键词搜索API接口
如果你是一位电商运营者或者是想要进行1688平台产品调研的人员,你可能需要借助API接口来获取你所需要的信息。在这篇文章中,我们将会讨论如何通过关键词搜索API接口获取1688的商品详情。 第一步:获取API接口的授权信息 在使用API接口前&…...
智驾域控新战争打响,谁在抢跑?
智能驾驶域控制器赛道,已经成为了时下最为火热的市场焦点之一。 最近,头部Tier1均胜电子公布了全球首批基于高通Snapdragon Ride第二代芯片平台的智能驾驶域控制器产品nDriveH,在这一赛道中显得格外引人注意。 就在不久之前,均胜…...
Android 13无源码应用去掉无资源ID的按钮
Android Wifionly项目,客户要求去掉谷歌联系人里的 手机联系人按钮 需求分析 无应用源码,只能通过系统侧去修改 首先通过 Android Studio 工具 uiautomatorviewer 获取父控件资源ID chip_group ,然后通过遍历获取子控件去掉目标按钮 --- a/frameworks/base/core/java/andr…...
【SCI征稿】中科院2区(TOP),正刊,SCIEEI双检,进化计算、模糊集和人工神经网络在数据不平衡中应用
【期刊简介】IF:8.0-9.0,JCR1区,中科院2区(TOP) 【检索情况】SCIE&EI 双检,正刊 【数据库收录年份】2004年 【国人占比】22.78%(期刊国际化程度高) 【征稿领域】进化计算、模…...
Android Audio开发——AAudio基础(十五)
AAudio 是一个自 Android O 引入的新的 Android C API。它主要是为需要低延迟的高性能音频应用设计的。应用程序通过直接从流中读取或向流中写入数据来与 AAudio 通信,但它只包含基本的音频输入输出能力。 一、AAudio概述 AAudio 在应用程序和 Android 设备上的音频输入输出之…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...