文章目录

  • 负载均衡分类
  • 分析
  • 工程
  • 调用
  • 测试
  • 源码


负载均衡分类

  • 服务端负载均衡 ,比如我们常见的ng
  • 客户端负载均衡 ,比如微服务体系中的ribbon

spring cloud ribbon是 基于NetFilix ribbon 实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。

通过Load Balancer(LB)获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。

Ribbon也支持自定义负载均衡算法


分析

我们前面的工程都是通过DiscoveryClient组件来去Nacos服务端拉取指定名称的微服务列表,然后通过RestTemplate执行远程调用

如果服务存在多个的话,加上我们使用的地址都是使用注册中心的地址 http://artisan-product-center/selectProductInfoById/ , RestTemplate 就处理不了这种问题了。所以我们才有第二步。

那如何让RestTemplate 自身也具备这种功能呢?

思路: 分析RestTemplate的源码,不管是post,get请求最终是会调用doExecute()方法,所以写一个CustomRestTemplate类继承RestTemplate,重写doExucute()方法即可


工程

artisan-cloud-custom-lb-order

artisan-cloud-custom-lb-product

package com.artisan.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;
import org.springframework.web.client.*;import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Random;/*** @author 小工匠* @version 1.0* @description: 根据RestTemplate特性自己改造* @date 2022/2/2 13:32* @mark: show me the code , change the world*/@Slf4j
public class CustomRestTemplate extends RestTemplate {@Autowiredprivate DiscoveryClient discoveryClient;public CustomRestTemplate(DiscoveryClient discoveryClient) {this.discoveryClient = discoveryClient;}@Overrideprotected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor) throws RestClientException {Assert.notNull(url, "URI is required");Assert.notNull(method, "HttpMethod is required");ClientHttpResponse response = null;try {/*** 在这里拦截一下子 偷梁换柱*///把服务名 替换成我们的IPurl = replaceUrl(url);log.info("替换后的请求路径:{}", url);ClientHttpRequest request = createRequest(url, method);if (requestCallback != null) {requestCallback.doWithRequest(request);}response = request.execute();handleResponse(url, method, response);return (responseExtractor != null ? responseExtractor.extractData(response) : null);} catch (IOException ex) {String resource = url.toString();String query = url.getRawQuery();resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);throw new ResourceAccessException("I/O error on " + method.name() +" request for \"" + resource + "\": " + ex.getMessage(), ex);} finally {if (response != null) {response.close();}}}/*** 方法实现说明:把微服务名称  去注册中心拉取对应IP进行调用* http://artisan-product-center/selectProductInfoById/1** @param url:请求的url* @return:* @exception:*/private URI replaceUrl(URI url) {log.info("原始请求路径为:{}", url);//1:从URI中解析调用的调用的serviceName=artisan-product-centerString serviceName = url.getHost();log.info("调用微服务的名称:{}", serviceName);//2:解析我们的请求路径 reqPath= /selectProductInfoById/1String reqPath = url.getPath();log.info("请求path:{}", reqPath);//通过微服务的名称去nacos服务端获取 对应的实例列表List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances(serviceName);if (serviceInstanceList.isEmpty()) {throw new RuntimeException("没有可用的微服务实例列表:" + serviceName);}String serviceIp = chooseTargetIp(serviceInstanceList);String source = serviceIp + reqPath;try {return new URI(source);} catch (URISyntaxException e) {log.error("根据source:{}构建URI异常", source);}return url;}/*** 方法实现说明:从服务列表中 随机选举一个ip** @param serviceInstanceList 服务列表* @return: 调用的ip* @exception:*/private String chooseTargetIp(List<ServiceInstance> serviceInstanceList) {//采取随机的获取一个Random random = new Random();Integer randomIndex = random.nextInt(serviceInstanceList.size());String serviceIp = serviceInstanceList.get(randomIndex).getUri().toString();log.info("随机选举的服务IP:{}", serviceIp);return serviceIp;}
}

调用

【配置方式一】

【调用】

测试

访问 : http://localhost:8080/v2/selectOrderInfoById/1


源码

https://github.com/yangshangwei/SpringCloudAlibabMaster

Spring Cloud Alibaba - 06 RestTemplate 实现自定义负载均衡算法相关推荐

  1. 最新版Spring Cloud Alibaba微服务架构-Ribbon负载均衡篇

    文章目录 前言 一.Ribbon核心概念 二.服务器端负载均衡和Riboon客户端负载均衡 1.服务器端负载均衡: 2.Riboon客户端负载均衡: 三.Ribbon策略 四.Ribbon配置使用 五 ...

  2. 基于Spring cloud Ribbon和Eureka实现客户端负载均衡

    前言 本案例将基于Spring cloud Ribbon和Eureka实现客户端负载均衡,其中Ribbon用于实现客户端负载均衡,Eureka主要是用于服务注册及发现: 传统的服务端负载均衡 常见的服 ...

  3. Ribbon自定义负载均衡算法

    Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连接超时 ...

  4. Spring Cloud Alibaba(2)---RestTemplate微服务项目

    前言 因为要运用 Spring Cloud Alibaba 开源组件到分布式项目中,所以这里先搭建一个不通过 Spring Cloud只通过 RestTemplate 来让SpringBoot和Myb ...

  5. Spring Cloud入门教程(二):客户端负载均衡(Ribbon)

    对于大型应用系统负载均衡(LB:Load Balancing)是首要被解决一个问题.在微服务之前LB方案主要是集中式负载均衡方案,在服务消费者和服务提供者之间又一个独立的LB,LB通常是专门的硬件,如 ...

  6. Spring Cloud源码分析——Ribbon客户端负载均衡

    年前聊了Eureka和Zookeeper的区别,然后微服务架构系列就鸽了三个多月,一直沉迷逛B站,无法自拔.最近公司复工,工作状态慢慢恢复(又是元气满满地划水).本文从以下3个方面进行分析(参考了翟永 ...

  7. Spring Cloud Ribbon 中的 7 种负载均衡策略

    负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而我们今天的主角 Ribbon 就属于后者--客户端负载均衡器. 服务端负载均衡器的问题是,它提供了更强的流量控制权,但 ...

  8. SpringCloud的Ribbon自定义负载均衡算法

    1.Ribbon默认使用RoundRobinRule策略轮询选择server 策略名 策略声明 策略描述 实现说明 BestAvailableRule public class BestAvailab ...

  9. SPring cloud (3)A Ribbon 负载均衡 配置初步

    1.引用pom <dependency><groupId>org.springframework.cloud</groupId><artifactId> ...

最新文章

  1. Hessian使用记录
  2. ELK实时日志分析平台的搭建部署及使用
  3. C# 如何转换生成长整型的时间
  4. LwIP之网络接口管理
  5. AI + 3D!英伟达开源3D深度学习框架Kaolin
  6. 用FTP命令进行文件批量上传或下载
  7. [译] Node.js 流: 你需要知道的一切
  8. c# DateTime常用用法
  9. 将list中的数据组成用逗号分隔的字符串
  10. hql语句关联查询(select new )
  11. Datalogic得利捷Memor™ 10入选“安卓企业推荐计划”
  12. 淘宝京东查看价格历史的chrome插件
  13. 一个真实的用户画像实例。
  14. 推荐系统遇上深度学习(十二)--推荐系统中的EE问题及基本Bandit算法
  15. 发票专用驱动sjz_停机前未勾选完的发票,升完级后这样操作
  16. 友价商城源码插件-百度链接主动提交
  17. 金蝶 EAS WebService 发布过程
  18. unity EZ Replay Manager 1.53
  19. 构建U盘启动的嵌入式linux
  20. 一些设计上的基本常识 - 梁飞

热门文章

  1. NC集成旺店通使用JSONObject获取数据
  2. Yii2权威指南中文版及众包翻译平台
  3. 一些基础提(选择题)
  4. 基于QT实现的P2P聊天系统
  5. linux查看程序recvfrom,linux udp 客户端recvfrom,一直没有数据接收,谁能帮看看这代码哪里出了问题了????...
  6. ImageView的android:maxHeight,android:minHeight的正确设置
  7. ES(Elasticsearch)7.6.1安装教程
  8. 百万高清摄像机芯片种类及应用
  9. 【Vue】报错解决方法
  10. 十年磨一剑 新华三互联网夏季论坛完美落幕