【微服务笔记08】微服务组件之Hystrix实现请求合并功能

news2025/6/21 5:59:51

这篇文章,主要介绍微服务组件之Hystrix实现请求合并功能。

目录

一、Hystrix请求合并

1.1、什么是请求合并

1.2、请求合并的实现

(1)引入依赖

(2)编写服务提供者

(3)消费者(Service层代码)

(4)消费者(Controller层代码)

(5)测试请求合并


一、Hystrix请求合并

1.1、什么是请求合并

微服务和微服务之间的调用,都是需要建立通信连接的,就拿HTTP接口来说,每一次的通信都需要建立和断开连接,如果微服务之间的调用非常频繁,那就会有很多的连接在建立和断开,为了减少请求连接的数量,Hystrix提出了请求合并的功能。

请求合并,也就是将多个相同的请求合并成一个请求,然后只调用一次接口将所有的数据获取到,数据拿到之后,还需要将数据一次分发给合并之前的请求,这样每一个请求才能够正常的拿到属于自己的那一个返回结果。

当开启请求合并之后,Hystrix针对那些相同的URI请求,会将其合并成一个请求,然后再去调用微服务接口,通过这里就可以看到,请求合并之后,原先多次调用的接口,现在只需要一次接口调用,减少了很多的请求连接,这也就能够提高系统的高可用性。

要实现请求合并,下游系统必须支持批处理接口,因为原先单次调用的接口,结果请求合并之后也就相当于是将多个接口的请求参数放到了一个接口里面,这样下游系统就必须能够支持批量处理多个请求参数的数据查询。

使用请求合并,一般来说,也就是针对查询类的接口,相当于下游系统要支持批量查询功能。到这你是不是想问,既然下游系统支持批量查询,那我直接调用批量查询接口不就可以了吗,干嘛还有多次一举,使用请求合并呢???

  • 首先你要明白,你一个用户发起的接口,你直接调用批处理接口,那确实可以。
  • 但是互联网中,一个应用系统存在很多的用户,每一个用户都可能调用相同的接口查询不同的数据,这个时候,请求合并就起作用啦。

要实现请求合并,可以使用【@HystrixCollapser】注解和【@HystrixCommand】注解。@HystrixCollapser 注解:指定某个方法需要开启请求合并功能。@HystrixCommand 注解:标记某个方法作为 Hystrix 的命令。

1.2、请求合并的实现

(1)引入依赖

  • 在服务消费者端,引入hystrix的依赖。
<!--hystrix 依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

(2)编写服务提供者

前面说了,要实现请求合并功能,下游系统必须提供批处理的接口,所以在这里,服务提供者需要提供一个批量查询的接口。

package com.gitcode.hystrix.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @version 1.0.0
 * @Date: 2023/4/9 10:11
 * @Copyright (C) ZhuYouBin
 * @Description: hystrix 请求合并
 */
@RestController
@RequestMapping("/hystrix/provider")
public class CollapseController {

    /**
     * 根据id批量查询
     */
    @PostMapping("/hystrixCollapse")
    public List<String> hystrixCollapse(@RequestBody List<String> ids) {
        List<String> ans = new ArrayList<>();
        // 这里模拟批处理的过程
        ids.forEach(key -> {
            ans.add("这是key=" + key + "的响应结果.");
        });
        return ans;
    }
    
}

(3)消费者(Service层代码)

  • 在消费者的Service服务层中,我们需要使用【@HystrixCollapser】注解和【@HystrixCommand】注解,声明需要实现请求合并的方法。
  • 【@HystrixCollapser】注解:使用在需要开启请求合并的方法上面。
  • 【@HystrixCommand】注解:使用在请求合并之后,执行批处理的接口方法上面。
package com.gitcode.hystrix.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.Future;

/**
 * @version 1.0.0
 * @Date: 2023/4/9 10:16
 * @Copyright (C) ZhuYouBin
 * @Description: Hystrix 请求合并
 */
@Service
public class HystrixCollapseService {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 根据ID查询
     */
    @HystrixCollapser(collapserKey = "请求合并的唯一key",
            // 作用域: 这里设置成全局的
            scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
            // 批处理方法: 当请求合并之后, hystrix 会调用这个批处理方法发起接口的调用【这个方法是自己写的】
            batchMethod = "batchQueryData",
            // 请求合并的属性: 满足什么条件才进行请求合并
            collapserProperties = {
                    // 定义属性
                    // timerDelayInMilliseconds: 在指定时间内的所有相同请求,都将被请求合并, 单位毫秒, 默认10ms
                    // 200 毫秒内的请求将全部被合并
                    @HystrixProperty(name = "timerDelayInMilliseconds", value = "5000"),
                    // maxRequestsInBatch: 请求合并最大的请求数量,当到达这个数量之后,就会执行一次请求合并
                    @HystrixProperty(name = "maxRequestsInBatch", value = "4"),
            }
    )
    // TODO 需要注意的是,请求合并的方法返回值必须是:Future 类型
    public Future<String> queryById(String id) {
        // 这个方法没啥作用了,所以不需要方法体,因为单个请求都将合并,之后统一的调用批处理方法
        System.out.println("调用queryById方法......");
        return null;
    }

    /**
     * 请求合并之后的批处理方法
     */
    @HystrixCommand
    private List<String> batchQueryData(List<String> ids) {
        // 在这里实现批量请求的调用
        String url = "http://127.0.0.1:5678/hystrix/provider/hystrixCollapse";
        final List<String> list = restTemplate.postForObject(url, ids, List.class);
        System.out.println("调用batchQueryData批处理接口......");
        return list;
    }

}
  • PS:这里留下一个疑问,Hystrix是怎么知道批量接口中,哪些数据应该是哪些请求的响应结果。

(4)消费者(Controller层代码)

在controller控制层,我们就只需要调用Service层的queryById()方法查询数据就可以啦,由于这个方法是Future类型,所以调用【Future.get()】方法就可以获取到返回值,需要注意的是:get()方法是阻塞的,返回值没有准备好,会一直处于阻塞等待状态。

package com.gitcode.hystrix.controller;

import com.gitcode.hystrix.service.HystrixCollapseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.security.SecureRandom;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @version 1.0.0
 * @Date: 2023/4/9 10:16
 * @Copyright (C) ZhuYouBin
 * @Description:
 */
@RestController
@RequestMapping("/hystrix/consumer")
public class CollapseController {

    @Autowired
    private HystrixCollapseService hystrixCollapseService;

    @GetMapping("/requestCollapse")
    public String requestCollapse() throws ExecutionException, InterruptedException {
        String id = new SecureRandom().nextInt() + "";
        final Future<String> future = hystrixCollapseService.queryById(id);
        // 获取方法的返回值,阻塞等待
        final String result = future.get();
        System.out.println("返回值: " + result);
        return "success,接口返回值是: " + result;
    }
}

(5)测试请求合并

依次启动eureka注册中心、consumer服务消费者、provider服务提供者工程,我这里采用jemeter进行并发请求测试,当然,你也可以直接浏览器多次刷新访问接口进行测试。

调用接口之后,查看控制台输入日志:

到此,Hystrix实现请求合并就介绍啦。

综上,这篇文章结束了,主要介绍微服务组件之Hystrix实现请求合并功能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React | 认识React开发

✨ 个人主页&#xff1a;CoderHing &#x1f5a5;️ Node.js专栏&#xff1a;Node.js 初级知识 &#x1f64b;‍♂️ 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; &#x1f4ab; 系列专栏&#xff1a;吊打面试官系列 16天学会Vue 11天学会React Node专栏 &#x…

【分享】免梯子的GPT,玩 ChatGPT 的正确姿势

火了一周的 ChatGPT&#xff0c;HG 不允许还有小伙伴不知道这个东西是什么&#xff1f;简单来说就是&#xff0c;你可以让它扮演任何事物&#xff0c;据说已经有人用它开始了颜色文学创作。因为它太火了&#xff0c;所以&#xff0c;本周特推在几十个带有“chatgpt”的项目中选…

双交叉注意学习用于细粒度视觉分类和目标重新识别

目录Dual Cross-Attention Learning for Fine-Grained Visual Categorization and Object Re-Identification摘要本文方法消融实验Dual Cross-Attention Learning for Fine-Grained Visual Categorization and Object Re-Identification 摘要 目的&#xff1a; 探索了如何扩展…

JDK8——新增时间类、有关时间数据的交互问题

目录 一、实体类 二、数据库 三、数据交换 四、关于LocalDateTime类型 (java 8) 4.1 旧版本日期时间问题 4.2 新版日期时间API介绍 4.2.1 LocalDate、LocalTime、LocalDateTime 4.2.2 日期时间的修改与比较 4.2.3 格式化和解析操作 4.2.4 Instant: 时间戳 4.2.5 Duration 与…

Doris(6):数据导入(Load)之Stream Load

Broker load是一个同步的导入方式&#xff0c;用户通过发送HTTP协议将本地文件或者数据流导入到Doris中&#xff0c;Stream Load同步执行导入并返回结果&#xff0c;用户可以通过返回判断导入是否成功。 1 适用场景 Stream load 主要适用于导入本地文件&#xff0c;或通过程序…

小厂实习要不要去?

大家好&#xff0c;我是帅地。 最近暑假实习招聘&#xff0c;不少 训练营 学员都拿到了小厂实习来保底&#xff0c;但是很多小厂基本要求一周内给答复&#xff0c;中大厂就还在流程之中&#xff0c;所以很纠结小厂实习要不要去。 不知道你是否有这样的纠结&#xff0c;今天帅地…

【测试面试汇总2】

目录Linux操作系统1.Linux操作命令2.在Linux中find和grep的区别&#xff1f;3.绝对路径用什么符号表示&#xff1f;4.当前目录、上层目录用什么表示&#xff1f;5.主目录用什么表示&#xff1f;6.怎么查看进程信息&#xff1f;7.保存文件并退出vi 编辑?8.怎么查看当前用户id&a…

【Python从入门到进阶】15、函数的定义和使用

接上篇《14、字典高级应用》 上一篇我们学习了有关字典的高级应用操作&#xff08;字典的增删改查&#xff09;&#xff0c;本篇我们来学习Python中函数的定义和使用&#xff0c;包括函数的参数、返回值、局部变量和全景变量等操作。 一、一个思考 例如这里有一段大东北洗浴中…

2023年PMP报考时间安排攻略!

1.2023年PMP考试时间 PMP一年开考4次&#xff0c;分别为3月、6月、9月、12月&#xff0c;预计2023年PMP第一次考试时间在2023年3月左右&#xff0c;具体以基金会官方通知为准。 1&#xff09;为什么考PMP&#xff1f; 大部分人考 PMP 无非以下几个原因&#xff0c;总的来说&…

运行时内存数据区之程序计数器

内存是非常重要的系统资源&#xff0c;是硬盘和CPU的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时选行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略&#xff0c;保证了JVM的高效稳定运行。 不同的VM对于内存的划分方式和管理机制存在着部分差…

算法时间复杂度计算

目录 1.时间复杂度计算 1.1 时间复杂度例题 1.1.1例题 1.1.2例题 1.1.3例题 1.1.4例题 1.2时间复杂度leetcode例题 1.时间复杂度计算 首先&#xff0c;我们需要了解时间复杂度是什么&#xff1a;算法的时间复杂度是指算法在编写成可执行程序后&#xff0c;运行时需要耗费…

一天吃透操作系统八股文

操作系统的四个特性&#xff1f; 并发&#xff1a;同一段时间内多个程序执行&#xff08;与并行区分&#xff0c;并行指的是同一时刻有多个事件&#xff0c;多处理器系统可以使程序并行执行&#xff09; 共享&#xff1a;系统中的资源可以被内存中多个并发执行的进线程共同使…

MATLAB | 给热图整点花哨操作(三角,树状图,分组图)

前段时间写的特殊热图绘制函数迎来大更新&#xff0c;基础使用教程可以看看这一篇&#xff1a; https://slandarer.blog.csdn.net/article/details/129292679 原本的绘图代码几乎完全不变&#xff0c;主要是增添了很多新的功能&#xff01;&#xff01;&#xff01; 工具函数完…

FastChat开放,媲美ChatGPT的90%能力——从下载到安装、部署

FastChat开放&#xff0c;媲美ChatGPT的90%能力——从下载到安装、部署前言两个前置软件创建FastChat虚拟环境安装PyTorch安装 FastChat下载 LLaMA&#xff0c;并转换生成FastChat对应的模型Vicuna启动FastChat的命令行交互将模型部署为一个服务&#xff0c;提供Web GUI前言 最…

Cesium:自定义MaterialProperty

在项目中应用Cesium.js时,时常遇到需要对Cesium.js的Material材质或者MaterialProperty材质属性进行拓展的应用场景。如果对GLSL(openGL Shading Language ),即:OpenGL着色语言熟悉的话,参考Cesium官方文档,构建一个新的Material必定不是难事。而MaterialProperty材质属…

【C语言进阶:动态内存管理】动态内存函数的介绍

本节重点内容&#xff1a; malloc 和 free 函数calloc 函数realloc 函数&#x1f338;为什么存在动态内存分配 到目前为止&#xff0c;我们已经掌握的内存开辟方式有两种&#xff1a; 创建变量&#xff1a;int val 20; //在栈空间上开辟四个字节 创建数组&#xff1…

Html5钢琴块游戏制作与分享(音游可玩)

当年一款手机节奏音游&#xff0c;相信不少人都玩过或见过。最近也是将其做了出来分享给大家。 游戏的基本玩法&#xff1a;点击下落的黑色方块&#xff0c;弹奏音乐。&#xff08;下落的速度会越来越快&#xff09; 可以进行试玩&#xff0c;手机玩起来效果会更好些。 点击…

【Python】基于serial的UART串口通信(可实现AT指令自动化 以ML307A开发板为例)

【Python】基于serial的UART串口通信&#xff08;可实现AT指令自动化 以ML307A开发板为例&#xff09; Python下的串口serial库 串行口的属性&#xff1a; name:设备名字 portstr:已废弃&#xff0c;用name代替 port&#xff1a;读或者写端口 baudrate&#xff1a;波特率 byt…

Charles 安装及配置,详细步骤(不错,保存一下)

一、安装激活 1.1、下载 https://www.charlesproxy.com/download/ 1.2、激活 打开Charles > Help > Register Charles > 输入 Registered Name &#xff1a; https://zhile.io License Key&#xff1a;48891cf209c6d32bf4 二、代理配置 2.1、代理设置 Proxy > Pr…

Nodejs中的fs模块

一、文件写入操作 writeFile 直接打开文件默认是 w 模式&#xff0c;所以如果文件存在&#xff0c;该方法写入的内容会覆盖旧的文件内容 语法&#xff1a; writeFile(file, data[, options], callback)异步writeFileSync(file, data)同步 参数&#xff1a; file文件名data要…