Spring Cloud Ribbon 客户端负载均衡 4.3

news/2025/2/23 22:13:48
   在分布式架构中,服务器端负载均衡通常是由Nginx实现分发请求的,而客户端的同一个实例部署在多个应用上时,也需要实现负载均衡。那么Spring Cloud中是否提供了这种负载均衡的功能呢?答案是肯定的。我们可以通过Spring Cloud中的Ribbon来实现此功能。本节将对Spring Cloud中的Ribbon进行详细讲解。

Ribbon介绍

  Ribbon是Netflix发布的开源项目,其主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon的客户端组件提供了一系列完善的配置项,例如连接超时、重试等。
  在Eureka的自动配置依赖模块spring-cloud-starter-eureka中,已经集成了Ribbon,我们可以直接使用Ribbon来实现客户端的负载均衡。二者同时使用时,Ribbon会利用从Eureka读取到的服务信息列表,在调用服务实例时,以合理的方式进行负载。

Ribbon的使用

  在Eureka中使用Ribbon十分简单,只需要在实例化Rest-Template的方法上添加@LoadBalanced注解,并在其执行方法中使用服务实例的名称即可。具体实现过程如下:
  (1)添加@LoadBalanced注解。在xcservice-eureka-user工程引导类中的restTemplate()方法上添加@LoadBalanced注解,其代码如下:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

 

  (2)使用服务实例名称。在用户服务实例的查询方法中,使用服务提供者(订单服务)的实例名称来执行已注册服务列表中实例的方法,具体如下:

@GetMapping("/findOrdersByUser/{id}")
public String findOrdersByUser(@PathVariable String id) {
    // 假设用户只有一个订单,并且订单id为123
    int oid = 123;
    // return restTemplate.getForObject("http://localhost:7900/order/" + oid, String.class);
    return restTemplate.getForObject("http://xcservice-eureka-order/" + id, String.class);
}

  从上述代码中可以看出,getForObject()方法的URI中使用的已经不是“主机地址+端口号”的形式,而使用的是注册中心中的订单服务实例名称。


  (3)创建服务监听类。为了演示负载均衡的实现效果,这里在xcservice-eureka-order工程中创建一个用于监听服务实例端口的工具类ServiceInfoUtil,其实现代码如下。
package com.xc.xcserviceeurekaorder.util;

import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;

@Configuration//注册组件
public class ServiceInfoUtil implements ApplicationListener<EmbeddedServletContainerInitializedEvent> {
    /**
     * 声明event对象,该对象用于获取运行服务器的本地端口
     */
    private static EmbeddedServletContainerInitializedEvent event;

    @Override
    public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
        ServiceInfoUtil.event = event;
    }

    /**
     * 获取端口号
     */
    public static int getPort() {
        int port = event.getEmbeddedServletContainer().getPort();
        return port;
    }
}

  上述工具类实现了ApplicationListener接口,该接口在Spring3.0中添加了泛型来声明所需要监听的事件类型,其中EmbeddedServletContainerInitializedEvent主要用于获取运行服务器的本地端口号。


  (4)添加输出语句。在订单控制器类OrderController的查询订单方法中,增加一行执行输出当前实例端口号的语句。具体如下:
  
System.out.println(ServiceInfoUtil.getPort());

 

  (5)启动服务,测试应用。分别启动注册中心、用户服务和订单服务,然后修改订单服务的端口号(如7901),再次启动一个订单服务后,Eureka信息页面的注册信息如图4-10所示。

 


  从图4-10中可以看到,名称为xcservice-eureka-order的实例名称下包含两个不同端口号(7900和7901)的实例应用。
  当通过浏览器连续4次访问地址http://localhost:8000/findOrdersByUser/1后,用户服务实例通过Ribbon分别调用了端口为7900和7901的订单服务实例,这说明已成功通过Ribbon实现了客户端的负载均衡。
  其实Ribbon在工作时主要分为两步:第1步先选择EurekaServer,它会优先选择在同一个区域且负载较少的Server;第2步会根据用户指定的策略(如轮询、随机等)从Server取到的服务注册列表中选择一个地址。本案例中,Ribbon所使用的策略就是轮询。 

转载于:https://www.cnblogs.com/ooo0/p/11183419.html


http://www.niftyadmin.cn/n/711259.html

相关文章

Elasticsearch——核心概念 系统架构 集群中常见问题 路由计算 分片控制

1.ES核心概念 1.1 索引&#xff08;index&#xff09; 一个索引就是一个拥有几分相似特征的文档的集合。 比如说&#xff0c;你可以有一个客户数据的索引&#xff0c;另一个产品目录的索引&#xff0c;还有一个订单数据的索引。一个索引由一个名字来标识&#xff08;必须全部是…

第二周Java学习

这已经是假期的第二周了&#xff0c;在Java的学习上感觉到了自己的一点懈怠&#xff0c;导致对Java的学习没有之前那么用心。可能是回家的原因&#xff0c;我会尽力克服。这周我完成了Java环境的配置&#xff0c;以后我会努力的完成Java的程序运行。转载于:https://www.cnblogs…

oracle 空表处理

oracle空表处理&#xff1a;1.动态生成给空表分配segment的命令&#xff1a;SQL>Select alter table ||table_name|| allocate extent; from user_tables where num_rows0&#xff1b;2.在命令窗口右键‘标记’&#xff0c;复制生成的命令并执行&#xff0c;回车。3.导出数据…

野狗云学习

十分感谢博客园 Jacey http://www.cnblogs.com/jeacy/p/6439639.html 野狗云是一个实时后端云服务&#xff0c;通过SDK向用户提供数据储存和实时通信服务&#xff0c; Javascript SDK 使用野狗云需要在页面上使用Javascript SDK 加入script标签 <script src "https:/…

MySQL高级篇——索引、视图、存储过程和函数、触发器的相关概念及操作

文章目录&#xff1a; 1.索引 1.1 索引的优势及劣势 1.2 索引结构 1.2.1 BTREE结构&#xff08;B树&#xff09; 1.2.2 BTREE结构&#xff08;B树&#xff09; 1.2.3 MySQL中的BTree 1.3 索引分类 1.4 索引语法 1.5 索引设计原则 2.视图 3.存储过程和函数 3.1 创建…

安装完操作系统后,必备开发软件安装

WinRAROfficeESETChromeFireFoxJavaSkypeTeamViewerGitHubXshell、XftpPowerDesignerStarUMLNotepadMyEclipseZendStudioVisualStudioReSharperAnkhSVNMySQLOracleSqlServerPlSql迅雷万能五笔UltraISOColorPicAdobeReaderIntelliJ IDEA

day16--HTML、CSS、JavaScript总结

HTML 一大堆的标签&#xff1a;块级、行内 CSS position background text-align padding font-size background-image z-index opacity float(clear:both) line-height border color display 补充&#xff1a;页面布局 JavaScript 6.for循环 for (var item in [11,22,33,44…

常用RGB色值表

RGB值 RGB值 RGB值黑色000#000000黄色2552550#FFFF00浅灰蓝色176224230#B0E0E6象牙黑413633#292421香蕉色22720787#E3CF57品蓝65105225#4169E1灰色192192192#C0C0C0镉黄25515318#FF9912石板蓝10690205#6A5ACD冷灰128138135#808A87dougello23514285#EB8E55天蓝135206235#87CEEB石…