【SpringCloud】SpringCloud详解之Ribbon实战

news/2024/7/10 0:49:24 标签: spring cloud, ribbon, java, 负载均衡, 微服务

目录

前言

微服务中比如用户服务部署多台服务器,怎么调用其中某一服务呢?
这里有组件的讲解 SpringCloud组件原理和面试题

SpringCloud Ribbon 负载均衡

SpringCloud Feign 远程调用实战

一需求

假设现在用户服务部署在两台或者多台服务器上,订单用户怎么去访问某一个?
在这里插入图片描述

二.RestTemplate远程调用配置负载均衡(order服务内修改)

1.修改远程调用用户的代码

java">	@Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 根据订单id查询订单
        Order order = orderMapper.findById(orderId);
        // 利用RestTemplate发起http请求,根据用户id查询用户
        // 把localhost改为服务名称
 这里这里  String url = "http://userservice/user/" + order.getUserId();
        //String url = "http://localhost:8081/user/" + order.getUserId();
        // 发送http请求,实现远程调用,现在是get请求类型
        User user = restTemplate.getForObject(url, User.class);
        // 封装user到Order
        order.setUser(user);
        // 返回值
        return order;
    }

注意: Feign集成了Ribbon,不用去特别配置负载均衡
2.RestTemplate配置类加上注解

java">	 /**
     * 创建RestTemplate并注入Spring容器
     */
    @Bean
    @LoadBalanced //负载均衡注解
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

三.Ribbon实现负载均衡的原理

Ctrl + N 快速查找类:原理是 LoadBalancerInterceptor 实现了 ClientHttpRequestInterceptor 接口。

java">
客户端http请求拦截器

@FunctionalInterface
public interface ClientHttpRequestInterceptor {
    ClientHttpResponse intercept(HttpRequest var1, byte[] var2, ClientHttpRequestExecution var3) throws IOException;
}
java"> 
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {

	重写ClientHttpRequestInterceptor接口的方法
	@Override
	public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,final ClientHttpRequestExecution execution) throws IOException {
		// 1.获取http的请求地址
		final URI originalUri = request.getURI();
		
		// 2.获取服务的名称
		String serviceName = originalUri.getHost();
		
		Assert.state(serviceName != null,"Request URI does not contain a valid hostname: " + originalUri);
		
		//3.我们进去execute方法:就是为了从Eureka-Server拉取信息
		return this.loadBalancer.execute(serviceName,this.requestFactory.createRequest(request, body, execution));
	}
}
java">public class RibbonLoadBalancerClient implements LoadBalancerClient {
	//4.进入此方法
	public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {
		//调用下面的execute方法
        return this.execute(serviceId, (LoadBalancerRequest)request, (Object)null);
    }

	public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
		
		//5.根据服务名称获取对应的服务列表,loadBalancer里面有List存有服务的地址
        ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
       
        //6.根据算法选择要使用的服务,会进入IRule接口里面,默认是轮询算法
        Server server = this.getServer(loadBalancer, hint);
       
        if (server == null) {
            throw new IllegalStateException("No instances available for " + serviceId);
        } else {
            RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
            return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);
        }
    }
}

在这里插入图片描述

四.Ribbon负载均衡策略

Ribbon负载均衡策略是 IRule接口定义的,每一个子接口都是一种策略。下面是常见负载均衡算法

1.负载均衡种类

负载均衡规则
RoundRobinRule轮询选择服务器。Ribbon默认负载均衡算法。
AvailabilitvFilteringRule(1) 默认情况,服务器连接3次失败,服务器设置为短路状态。短路状态持续30秒,如果再连接失败,短路状态持续时间就会几何级增长。      (2)并发数高的服务器。可配置该规则会忽略并发数高的服务器。并发数上限可以配置。
WeightedResponseTimeRule给服务器赋予权重。响应时间越长,权重越小。权重影响服务器的选择。
ZoneAvoidanceRule使用Zone对服务器进行分类。Zone可以是一个机房、一个机架等。然后对Zone内的服务进行轮询。例如:配置Zone是曹县机房,然后服务提供者会优先选择曹县机房的服务器。
BestAvailableRule忽略短路的服务器并选择并发数低的服务器。
RandomRule随机选择一个可用服务器。
RetryRule重试机制的选择逻辑。

2.配置负载均衡(order服务中配置)

(1) 代码类型

java">	注意:这种配置是全局的,订单服务不光调用用户服务是随机的,调用其他的服务也是随机的
	//注入新的负载均衡算法 在启动类内注入也可以自定义配置类
  	@Bean
    public IRule randomRule() {
    	//随机选取一个可用服务器
        return new RandomRule();
    }

(2) yml中配置

注意:这种局部配置,只针对用户服务去选择负载均衡的算法
userservice:  # 服务名称
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.RandomRule  # 负载均衡规则

五.Ribbon的饥饿加载配置(在order服务配置)

Ribbon默认是懒加载: 第一次加载才会创建 LoadBalancerClient ,请求时间会很长。
饥饿加载: 在项目启动时创建,降低第一次访问的耗时。

(1) 单个服务配置饥饿加载(在yml文件配置)

ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients: userservice # 指定饥饿加载的服务名称

(1) 多个服务配置饥饿加载(在yml文件配置)

ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients: # 指定饥饿加载的服务名称
      - userservice   # 用户服务
      - cangkuservice # 仓库服务
      - zhifuservice  # 支付服务

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

相关文章

1.6 独立性

1.6.1 事件的独立性1.两个事件的独立性中任意两个事件都相互独立、則称 A,.A.&#xff0c;,A.两两独立&#xff0c;显然•若&#xff0c;个事件相互独立,則一定两两独立,反之,不一定成立【例 1.251 将一个均匀的正四面体的第一面染上红、黄、蓝三色&#xff0c;将其他三百多别染…

基于Linux系统-搭建Java Web开发环境

目录 1. 安装JDK 2.安装MySQL数据库 3.安装Tomcat 4.访问Tomcat 1. 安装JDK 1.执行以下命令&#xff0c;查看yum源中JDK版本。 yum list java* 2.执行以下命令&#xff0c;使用yum安装JDK1.8。 yum -y install java-1.8.0-openjdk* 3.执行以下命令&#xff0c;查看是否安…

Java ~ Collection/Executor ~ BlockingDeque【总结】

一 概述 简介 BlockingDeque&#xff08;阻塞双端队列&#xff09;接口&#xff08;下文简称阻塞双端队列&#xff09;是BlockingQueue&#xff08;阻塞队列&#xff09;接口的子接口&#xff0c;在其的基础上进行了功能性的加强&#xff0c;新增了可在队列的两端进行插入/移除…

C++之异常

目录 一、C语言传统的处理错误的方式 二、C异常概念 三、异常的使用 异常的抛出和捕获 如何就规范异常这个问题呢&#xff1f; 在函数调用链中异常栈展开匹配原则 异常的重新抛出 如何做到把资源释放了&#xff0c;还要让异常在最外面处理呢&#xff1f; 四、自定义异…

Maven基本使用以及IDEA中配置使用的详细介绍

文章目录MavenMaven基本介绍Maven基本使用IDEA配置MavenIDEA配置MavenMaven坐标详解IDEA创建Maven项目IDEA导入Maven项目Maven依赖管理Maven Maven基本介绍 Apache Maven 是一个项目管理和构建工具&#xff0c;它基于项目对象模型(POM)的概念&#xff0c;通过一小段描述信息来…

Spring系列-8 AOP使用与原理

背景 按照软件重构的思想&#xff0c;当多个类中存在相同的代码时&#xff0c;需要提取公共部分来消除代码坏味道。Java的继承机制允许用户在纵向上通过提取公共方法或者公共部分(模版方法方式)至父类中以消除代码重复问题&#xff1b;日志、访问控制、性能监测等重复的非业务…

Java——腐烂的橘子

题目链接 leetcode在线oj题——腐烂的橘子 题目描述 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方…

python:使用 Jupyter notebook(测试 matplotlib 和 opencv)

环境&#xff1a; window1python 3.10.6 参考&#xff1a; https://jupyter.org/https://opencv.org/ 一、创建虚拟环境 这个步骤可以跳过&#xff08;因为笔者不喜欢在全局环境安装任何东西&#xff0c;所以搞一个新环境&#xff09;。 先选中一个目录&#xff1a;D:\jackl…