【微服务】Ribbon的实现原理

1、场景:这里有两个服务,user-server和store-server

在这里插入图片描述

1.1、user服务

接口:

package com.lkx.user.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @Author: lkx* @Date: 2023/8/23/13:20* @Description:*/
@RestController
public class UserController {@GetMapping("/testUser")public Object testUser() {return "HelloWorld";}
}

1.2、store服务

配置类:

package com.lkx.store.config;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;/*** @Author: lkx* @Date: 2023/8/23/13:18* @Description:*/
@SpringBootConfiguration
@ComponentScan(basePackages = {"com.lkx.store"})
public class AppConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

接口:

package com.lkx.store.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;/*** @Author: lkx* @Date: 2023/8/23/13:20* @Description:*/
@RestController
public class StoreController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/testStore")public Object testStore() {/*** 原生调用方式实际上存在一种问题* 每多一次新地址的调用 都要维护一个全地址 这样维护起来相对就比较复杂了** Ribbon :这个组件实际上就是为了来做服务的发现的* Ribbon最终服务的调用还是使用的是  restTemplate*/// 原生调用return restTemplate.getForObject("http://192.168.230.1:8081/testUser",String.class);// Ribbon调用
//        return restTemplate.getForObject("http://user-server/testUser",String.class);}
}

代码中,store服务通过url(ip地址加端口/方法)去调用user服务的接口,这是原生的调用方式。可以成功调用。Ribbon调用通过服务名称也可成功.

2、Ribbon的实现原理。

在这里插入图片描述
  解释:两个服务启动时,会将自己的服务名称,以及IP地址和端口注册到注册中心,当有服务调用时,就会拉取注册中心的注册表,里面包含了所有的注册信息。当我们使用Ribbon方式去调用其他服务时,ribbon的拦截器会拦截请求,然后根据拉取到的注册信息,去找到服务名称对应的ip地址和端口,然后重组请求地址,最后以原生的RestTemplate方式去实现服务的调用。

3、源码跟踪

配置类中,我们在设置Bean RestTemplate时,加了一个注解@LoadBalanced。这个注解尤为重要,它就是Ribbon实现原理最为重要的一环。

@LoadBalanced 源码:

/** Copyright 2013-2015 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.cloud.client.loadbalancer;import org.springframework.beans.factory.annotation.Qualifier;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** Annotation to mark a RestTemplate bean to be configured to use a LoadBalancerClient.* @author Spencer Gibb*/
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}

这里的解释翻译是:标记一个RestTemplate bean来配置使用LoadBalancerClient。那么,这个LoadBalancerClient是什么呢?

/** Copyright 2013-2015 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.cloud.client.loadbalancer;import org.springframework.cloud.client.ServiceInstance;import java.io.IOException;
import java.net.URI;/*** Represents a client-side load balancer.* @author Spencer Gibb*/
public interface LoadBalancerClient extends ServiceInstanceChooser {/*** Executes request using a ServiceInstance from the LoadBalancer for the specified* service.* @param serviceId The service ID to look up the LoadBalancer.* @param request Allows implementations to execute pre and post actions, such as* incrementing metrics.* @return The result of the LoadBalancerRequest callback on the selected* ServiceInstance.*/<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;/*** Executes request using a ServiceInstance from the LoadBalancer for the specified* service.* @param serviceId The service ID to look up the LoadBalancer.* @param serviceInstance The service to execute the request to.* @param request Allows implementations to execute pre and post actions, such as* incrementing metrics.* @return The result of the LoadBalancerRequest callback on the selected* ServiceInstance.*/<T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException;/*** Creates a proper URI with a real host and port for systems to utilize.* Some systems use a URI with the logical service name as the host,* such as http://myservice/path/to/service.  This will replace the* service name with the host:port from the ServiceInstance.* @param instance* @param original A URI with the host as a logical service name.* @return A reconstructed URI.*/URI reconstructURI(ServiceInstance instance, URI original);
}

翻译一下注释:Represents a client-side load balancer.这是一个客户端负载平衡器。而@LoadBalanced注解标记的RestTemplate就是来配置这个平衡器的,这里我们就需要找到这个配置类,同文件夹下有一个LoadBalancerAutoConfiguration,给它的解释是功能区的自动配置(客户端负载平衡)

@Configuration@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")static class LoadBalancerInterceptorConfig {@Beanpublic LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient,LoadBalancerRequestFactory requestFactory) {return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);}@Bean@ConditionalOnMissingBeanpublic RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {return restTemplate -> {List<ClientHttpRequestInterceptor> list = new ArrayList<>(restTemplate.getInterceptors());list.add(loadBalancerInterceptor);restTemplate.setInterceptors(list);};}}

而在这个配置类里就有我们的ribbon的拦截器设置了。然后进入LoadBalancerInterceptor拦截器,通过拦截器的执行代码,然后到RibbonLoadBalancerClient的execute方法,这个方法就是通过我们的key来找到对应的服务器去执行请求,后面方法太多,就不一 一叙述,最后发现,最底层调用的还是原生的请求去实现调用的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/107570.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HashTable, HashMap, ConcurrentHashMap 之间的区别

前言 哈希表的组织形式是这样的&#xff1a; 对于哈希表这种重要而又频繁被使用的数据结构&#xff0c;是否线程安全往往是人们经常考虑的方向之一。 一、HashTable HashTable是线程安全的。但是它的线程安全在于它的关键方法都使用了synchronized&#xff0c;比如get方法、pu…

Python | assert关键字

Python断言assert是帮助代码流畅的调试工具。断言主要是假设程序员知道或总是希望是真的&#xff0c;因此将它们放在代码中&#xff0c;这样这些失败不会允许代码进一步执行。 简单地说&#xff0c;断言是一个布尔表达式&#xff0c;用来检查语句是True还是False。如果语句为T…

R包开发-2.2:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)

目录 4-添加C函数 5-编辑元数据 6-启用Roxygen&#xff0c;执行文档化。 7-单元测试 8-在自己的计算机上安装R包&#xff1a; 9-程序发布 参考&#xff1a; 为什么要写这篇文章的更新日期&#xff1f;因为R语言发展很快&#xff0c;很多函数或者方式&#xff0c;现在可以使…

js中作用域的理解?

1.作用域 作用域&#xff0c;即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变量和其他资源的可见性 举个例子 function myFunction() {let inVariable "函数内部变量"; } myFunction();//要先执行这…

NPM 管理组织包

目录 1、关于组织范围和包 1.1 管理无作用域的包 2、使用组织设置配置npm客户端 2.1 配置您的npm客户端以使用您组织的范围 为所有新包设置组织范围 为单个包设置组织范围 2.2 将默认包可见性更改为public 将单个包的包可见性设置为public 将所有包的包可见性设置为pu…

人脸识别平台批量导入绑定设备的一种方法

因为原先平台绑定设备是通过一个界面进行人工选择绑定或一个人一个人绑定设备。如下&#xff1a; 但有时候需要在几千个里选择出几百个&#xff0c;那这种方式就不大现实了&#xff0c;需要另外一种方法。 目前相到可以通过导入批量数据进行绑定的方式。 一、前端 主要是显示…

opencv进阶18-基于opencv 决策树导论

1. 什么是决策树&#xff1f; 决策树是最早的机器学习算法之一&#xff0c;起源于对人类某些决策过程 的模仿&#xff0c;属于监督学习算法。 决策树的优点是易于理解&#xff0c;有些决策树既可以做分类&#xff0c;也可以做回归。在排名前十的数据挖掘算法中有两种是决策树[1…

软件设计师学习笔记6-存储系统

1.层次化存储体系 1.1层次化存储结构 局部性原理是层次化存储结构的支持 时空局部性&#xff1a;刚被访问的内容&#xff0c;立即又被访问(eg: 循环体 ) 空间局部性&#xff1a;刚被访问的内容&#xff0c;临近的空间很快被访问(eg:数组) 1.2层次化存储结构的分类 DRAM&…

统计学补充概念-17-线性决策边界

概念 线性决策边界是一个用于分类问题的线性超平面&#xff0c;可以将不同类别的样本分开。在二维空间中&#xff0c;线性决策边界是一条直线&#xff0c;将两个不同类别的样本分隔开来。对于更高维的数据&#xff0c;决策边界可能是一个超平面。 线性决策边界的一般形式可以表…

使用信号处理算法过滤加速度数据并将其转换为速度和位移研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

postgresql常用函数-数学函数

postgresql常用函数 简介数学函数算术运算符绝对值取整函数乘方与开方指数与对数整数商和余数弧度与角度常量 π符号函数生成随机数 简介 函数&#xff08;function&#xff09;是一些预定义好的代码模块&#xff0c;可以将输入进行计算和处理&#xff0c;最终输出一个 结果值…

【Git】学习总结

【Git】学习总结 【一】安装【二】Git克隆项目代码【1】idea下载git项目【2】创建新的分支【3】新建的分支推送到远程【4】合并最新代码到主分支【5】切换分支 【三】提交本地项目到远程&#x1f680;1. 配置 Git&#x1f680;2. 创建项目远程仓库&#x1f680;3. 初始化本地仓…

详细手机代理IP配置

嗨&#xff0c;亲爱的朋友们&#xff01;作为一家代理产品供应商&#xff0c;我知道有很多小伙伴在使用手机进行网络爬虫和数据采集时&#xff0c;常常会遇到一些IP限制的问题。别担心&#xff01;今天我要给大家分享一下手机IP代理的设置方法&#xff0c;让你们轻松应对这些限…

C语言暑假刷题冲刺篇——day5

目录 一、选择题 二、编程题 &#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C语言每日一练✨相关专栏&#xff1a;代码小游戏、C语言初阶、C语言进阶&#x1f91d;希望作者…

飞天使-k8s基础组件分析-控制器

文章目录 控制器含义解释pod的标签与注释ReplicaControllerReplicaSetDeploymentsDaemonSetJobCronjob参考文档 控制器含义解释 空调遥控器知道吧ReplicationController: ReplicationController确保在任何时候都运行指定数量的pod副本。换句话说&#xff0c;一个ReplicationCo…

实战项目 在线学院springcloud调用篇3(nacos,feging,hystrix,gateway)

一 springcloud与springboot的关系 1.1 关系 1.2 版本关系 1.3 list转json串 public class Test {public static void main(String[] args) {List<String> dataListnew ArrayList<String>();dataList.add("12");dataList.add("45");dataLi…

guassian filter and bilateral filter

在用CRF 后处理segmentation的时候有一项 d.addPairwiseGaussian(sxy(5, 5), compat3, kerneldcrf.DIAG_KERNEL,normalizationdcrf.NORMALIZE_SYMMETRIC)# This adds the color-dependent term, i.e. features are (x,y,r,g,b).d.addPairwiseBilateral(sxy(5, 5), srgb(13, 13…

代码随想录算法训练营之JAVA|第三十九天|474. 一和零

今天是第39天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 474. 一和零https://leetcode.cn/problems/ones-and-zeroes/ 第一想法 题目理解&#xff1a;找到符合条件的子集&#xff0c;这又是一个组合的问题。 看到这个题目的时候&#xff0c;我好像…

量化QAT QLoRA GPTQ

模型量化的思路可以分为PTQ&#xff08;Post-Training Quantization&#xff0c;训练后量化&#xff09;和QAT&#xff08;Quantization Aware Training&#xff0c;在量化过程中进行梯度反传更新权重&#xff0c;例如QLoRA&#xff09;&#xff0c;GPTQ是一种PTQ的思路。 QAT…

Java将PDF文件转为Word文档

Java将PDF文件转为Word文档 一、创建Springboot Maven项目 二、导入依赖信息 <repositories><repository><id>com.e-iceblue</id><url>https://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories&g…