往期回顾

前面我们已经介绍了Nacos 的安装与配置,以及Spring Cloud 集成Nacos 作为服务的注册中心。

Nacos的安装与配置

Spring Cloud集成Nacos作为注册中心

接下来,我们接着上一讲,我们使用Spring Cloud 自带的LoadBalacer 来实现负载均衡

负载均衡

负载均衡(Load Balance) ,简单点说就是将用户的请求平摊分配到多个服务器上运行,以达到扩展服务器带宽、增强数据处理能力、增加吞吐量、提高网络的可用性和灵活性的目的。

负载均衡一般分为硬件负载均衡和软件负载均衡,硬件负载均衡因为知识受限,这里不做说明

软件负载均衡又分为:

  1. 服务端负载均衡

    服务端的负载均衡就是传统的Nginx 方式,它的一个特点是调用的客户端不知道具体是哪一个Server提供的服务,只需要将请求发送给Nginx ,再由Nginx 转发给Tomcat ,客户端只需要记住Nginx 的地址即可

  1. 客户端负载均衡

    客户端负载均衡是将负载均衡逻辑以代码的形式封装到客户端上,即负载均衡器位于客户端。客户端通过服务注册中心(例如 Eureka Nacos )获取到一份服务端提供的可用服务清单。有了服务清单后,负载均衡器会在客户端发送请求前通过负载均衡算法选择一个服务端实例再进行访问,以达到负载均衡的目的

Ribbon 就是一个很典型的客户端负载均衡器,RibbonNetflix 公司发布的开源项目(组件、框架、jar包),主要功能是提供客户端的软件负载均衡算法,它会从注册中心中获取一个可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可以正常访问的服务端节点

但是,Ribbon 已经在最新的Spring Cloud 版本中被废弃,Spring Cloud Loadbalancer 是官方正式推出的一款新负载均衡利器,在未来,LoadBalancer 很有可能取代Ribbon的地位成为新一代的负载均衡器

而今天,我们的主角就是LoadBalancer ,我们将使用它与Nacos 集成,实现客户端的负载均衡,下面让我们开始愉快的编码吧

构建项目

创建新工程

首先,我们需要在原来的项目基础上再创建一个服务消费者,用于消费,如图所示:

导入依赖

这里需要重点注意一下,Ribbon 的依赖从Nacos 的依赖中排除

        <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><!-- 将ribbon排除 --><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></exclusion></exclusions></dependency><!--添加loadbalancer依赖由于 Netflix Ribbon 进入停更维护阶段,因此 SpringCloud 2020.0.1 版本之后 删除了eureka中的ribbon,替代ribbon的是spring cloud自带的LoadBalancer,默认使用的是轮询的方式新版本的 Nacos discovery 都已经移除了 Ribbon ,此时我们需要引入 loadbalancer 代替,才能调用服务提供者提供的服务--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>

配置application.yml

server:port: 7001
spring:cloud:nacos:discovery:server-addr: 192.168.199.128application:name: UserConsumerprofiles:active: devmanagement:endpoints:web:exposure:include: "*"

配置LoadBalancer

使用RestTemplate 与注解的方式配置对应的负载均衡策略

  1. 创建LoadBalancer配置类
package cuit.epoch.pymjl.config;import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;/*** 注意不要加@Configuration** @author Pymjl* @version 1.0* @date 2022/8/26 13:05**/
public class MyLoadBalancerConfig {@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);// 随机轮询return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}
}

注意,MyLoadBalancerConfig这里有一个细节大家需要注意一下

  • 如果你在MyLoadBalancerConfig 上面加了@Configuration 注解,使用到的服务必须显式的在启动类上配置好
//假设项目中使用了2个服务,stock-service和product-service//都配置好不会报错
@LoadBalancerClients(value = {@LoadBalancerClient(name = "stock-services",configuration = MyLoadBalancerConfig.class),@LoadBalancerClient(name = "product-service",configuration = MyLoadBalancerConfig.class)
})//调用stock-service不会报错,调用product-service会报错
@LoadBalancerClients(value = {@LoadBalancerClient(name = "stock-services",configuration = MyLoadBalancerConfig.class)
  • 如果没有加@Configuration 注解那么配了的服务会使用配置的负载均衡策略,没有配的服务会使用默认的策略

  • 或者将对应的配置类放在Spring 的扫描包外,效果同第二点一样

  1. 配置RestTemplates
package cuit.epoch.pymjl.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;/*** 在这里配置我们自定义的LoadBalancer策略 如果想自己扩展算法 需要实现ReactorServiceInstanceLoadBalancer接口* /@LoadBalancerClients(defaultConfiguration = {name = "CLOUD-PAYMENT-SERVICE", configuration = MyLoadBalancerConfig.class})* 注意这里的name属性 需要和Nacos页面中的服务提供者名字一致** @author Pymjl* @version 1.0* @date 2022/8/26 12:20**/
@Configuration
@LoadBalancerClient(name = "UserService", configuration = MyLoadBalancerConfig.class)
public class RestTemplateConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

编写Controller

package cuit.epoch.pymjl.controller;import cuit.epoch.pymjl.result.CommonResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;/*** @author Pymjl* @version 1.0* @date 2022/8/26 12:17**/
@RestController
@RequestMapping("/consumer")
public class TestController {private static final String SERVICE_URL = "http://UserService";@ResourceRestTemplate restTemplate;@GetMapping("/test")public CommonResult consumerTest() {return restTemplate.getForObject(SERVICE_URL + "/user/test", CommonResult.class);}
}

你也可以采用直接使用LoadBalanceClient 不使用注解的方式(这是我Copy的Nacos官方的样例,使用方法是一样的,就不再演示)

@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApp {@RestControllerpublic class NacosController{@Autowiredprivate LoadBalancerClient loadBalancerClient;@Autowiredprivate RestTemplate restTemplate;@Value("${spring.application.name}")private String appName;@GetMapping("/echo/app-name")public String echoAppName(){//使用 LoadBalanceClient 和 RestTemolate 结合的方式来访问ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider");String url = String.format("http://%s:%s/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);System.out.println("request url:"+url);return restTemplate.getForObject(url,String.class);}}//实例化 RestTemplate 实例@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(NacosConsumerApp.class,args);}
}

开始测试

  1. 我们先启动UserService ,因为涉及到负载均衡,所以我们需要使用idea配置启动类,启动多个UserService,点击如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aNMyQJJi-1662117457388)(https://pymjl.oss-cn-shanghai.aliyuncs.com/picgo/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202022-08-26%20163659.png)]

然后点击启动服务提供者和消费者,如图所示:

调用接口

经过多次刷新后你会发现消费者会随机的去调用服务提供者的服务,两者的概率大概是相同的

项目源码:gitee github
62117457390)]

[外链图片转存中…(img-Z73V2blX-1662117457391)]

经过多次刷新后你会发现消费者会随机的去调用服务提供者的服务,两者的概率大概是相同的

[外链图片转存中…(img-fojNGyVX-1662117457392)]

[外链图片转存中…(img-O63oaM6O-1662117457393)]

项目源码:gitee github

LoadBalancer集成Nacos实现负载均衡相关推荐

  1. SpringBoot 整合 Spring Cloud Alibaba Nacos 连通性+负载均衡

    文章目录 一.整合版本说明 1. 毕业版本依赖关系(推荐使用) 2. 组件版本关系 3. 演示版本 二.整合实战 2.1. 聚合模块设计 2.2. 创建聚合parent 2.3. 依次创建子项目 三. ...

  2. nacos之负载均衡

    简介 随着Eureka宣告闭源,更多人开始转向Zookeeper和Nacos.Nacos不仅有着优秀 的注册中心,还拥有远程配置和服务总线的的功能,当前的功能已经远超Eureka, 后续发展不可估量. ...

  3. tedu 四阶段springcloud学习day02学习总结(idea连接数据库/nacos远端调用及负载均衡策略/Feign方式远端调用)

    目录 查看接口有哪些实现类 ctrl + h 一.cmd方式启动Nacos的命令 二.在IDEA中打开MySQL数据库 第一步: 打开View中数据库的工具栏 第二步:添加数据库为MySql 第三步: ...

  4. Ribbon负载均衡原理,Feign是如何整合Ribbon的?

    文章目录 1. 什么是负载均衡? 2. Ribbon的使用 ①:自定义负载均衡策略 ②:Ribbon的饥饿加载 3. Ribbon的负载均衡原理 ①:收集带有@LoadBalanced注解的RestT ...

  5. 负载均衡Ribbon和Feign---SpringCloud

    负载均衡Ribbon和Feign Ribbon负载均衡(基于客户端) 6.1 负载均衡以及Ribbon Ribbon是什么? Spring Cloud Ribbon 是基于Netflix Ribbon ...

  6. SpringCloud Ribbon中的7种负载均衡策略!

    作者 | 磊哥 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) 负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端负载均衡器,而 ...

  7. SpringCloud[04]Ribbon负载均衡服务调用

    文章目录 Ribbon负载均衡服务调用 1. 概述 1. Ribbon是什么 2. Ribbon能做什么 2. Ribbon负载均衡演示 1. 架构说明 2. Ribbon的POM依赖 3. Rest ...

  8. springcloud -netflix-Ribbon 负载均衡的实现

    Ribbon:负载均衡(基于客户端) 负载均衡以及Ribbon Ribbon是什么? Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具. 简单 ...

  9. SpringCloud集群的搭建,分布式的实现,负载均衡的几种方式,路由,页面监听

    SpringCloud 服务注册与发现--Netflix Eureka 负载均衡: 客户端负载均衡--Netflix Ribbon 服务端负载均衡:--Feign(其也是依赖于Ribbon,只是将调用 ...

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

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

最新文章

  1. 分布式任务队列 Celery — 应用基础
  2. 大快搜索城市运河大数据政务管理平台案例解读
  3. 从程序集/类库下面取文件
  4. sql 计算两个小数乘积_数学家是如何计算出π的?
  5. python算法与数据结构-冒泡排序算法
  6. 并发编程——进程——Process对象的属性和方法
  7. 教你阿里云企业版服务器配置到底怎么选?阿里云ECS相关术语汇总
  8. DOM BOM document window 区别
  9. OO第一单元总结__多项式求导问题
  10. java5错误_Error:java: 错误: 不支持发行版本 5
  11. 在Blazor中构建数据库应用程序——第2部分——服务——构建CRUD数据层
  12. IDEA 插件 Material Theme UI收费后 免费的办法
  13. datetime与timestamp的区别
  14. IT系统对接方案汇总
  15. STL之算法——排序算法
  16. 域名转入Godaddy教程
  17. 关闭和重启脚本合二为一orderlist.sh
  18. Promise的九大方法(resolve、reject、then、catch、finally、all、allSettled、race、any)你都用过那些?
  19. 优化Android手机的GPS定位系统,加速搜星,定位准确
  20. 技巧 | 如何画出漂亮的深度学习模型图

热门文章

  1. 导入com.google.android.maps.jar安装包问题
  2. B树,B+树,树,二叉树,满二叉树,完全二叉树,二叉搜索树,平衡二叉树,
  3. 序列化-Kryo的使用详解
  4. Win10玩红警2突然就卡住不动?
  5. 【程序员必备】七夕表白攻略:教你用代码轻松打动她的内心!
  6. 蓝桥云课 鲁卡斯队列
  7. cv2颜色空间(2)——交互式的颜色检测
  8. 不属于项目管理常用计算机模块的事,管理信息系统题库及答案(4)
  9. 动态二维码签到系统~第一节(Python动态二维码生成)
  10. 2021-2027全球与中国SD WAN托管服务市场现状及未来发展趋势