当前位置:   article > 正文

Hystrix-请求合并_hystrix 请求合并

hystrix 请求合并

一)请求合并处理雪崩

1)下图为一个的Constomer调用Provider的图
下图为在同一时间下共有的6个Customer要消费的Provider,那么此时就要通过的TOmcat的线程池创建6个线程访问的Provider,此时是没什么问题的。但是如果是500、1000个呢?Tomcat线程池是有上限的这样的势必是对Provider一个的跳转,如果压力过大Provider肯定是要出现问题的。那么我们就可以使用Hystrix的请求合并进行处理。
在这里插入图片描述

请求合并
下图为一个的请求合并之后的图,Hystrix会在指定的时间能,将所有的Constomer接收的请求合并成一个的请求,然后在将请求发送给的Provider,以此减少Provider的压力。

在这里插入图片描述

什么情况下使用请求合并
在微服务架构中,我们将一个项目拆分成很多个独立的模块,这些独立的模块通过远程 调用来互相配合工作,但是,在高并发情况下,通信次数的增加会导致总的通信时间增加, 同时,线程池的资源也是有限的,高并发环境会导致有大量的线程处于等待状态,进而导致 响应延迟,为了解决这些问题,我们需要来了解 Hystrix 的请求合并。

请求合并的缺点
设置请求合并之后,本来一个请求可能 5ms 就搞定了,但是现在必须再等 10ms 看看还 有没有其他的请求一起的,这样一个请求的耗时就从 5ms 增加到 15ms 了,不过,如果我们 要发起的命令本身就是一个高延迟的命令,那么这个时候就可以使用请求合并了,因为这个 时候时间窗的时间消耗就显得微不足道了,另外高并发也是请求合并的一个非常重要的场 景。

二)创建项目测试请求合并

1.创建项目19-hystrix-requsetmerge

在这里插入图片描述

2.pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sxt</groupId>
    <artifactId>19-hystrix-requestmerge</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>19-hystrix-requestmerge</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

3.修改全局配置文件

spring.application.name=19-hystrix-requestmerge
server.port=9096
eureka.client.service-url.defaultZone=http://peer1:8081/eureka/,http://peer2:8082/eureka/,http://peer3:8083/eureka/
  • 1
  • 2
  • 3

修改启动器

@SpringBootApplication
@EnableEurekaClient //开启服务注册
@EnableCircuitBreaker //开启熔断器
public class Application
{

    public static void main(String[] args)
    {
        SpringApplication.run(Application.class, args);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4.测试

创建ProviderService

@HystrixCollapser:该注解的作用是标识当前的方法是一个的合并请求的方法,并且此方法内的逻辑是不会被执行的
* batchMethod:请求合并完毕的后触发的方法
* scope:请求合并的模式
* collapserProperties:请求合并的设置
* timerDelayInMilliseconds:请求合并的等待的时间
* maxRequestsInBatch:指定时间内对请求合并的请求的最大数
* @retun: Future:注意请求的合并的方法的返回值必须为Future
在这里插入图片描述

@Service
public class ProductService
{
    /**
     * @param null
     * @description: 1.@HystrixCollapser:该注解的作用是标识当前的方法是一个的合并请求的方法,并且此方法内的逻辑是不会被执行的
     * batchMethod:请求合并完毕的后触发的方法
     * scope:请求合并的模式
     * collapserProperties:请求合并的设置
     * timerDelayInMilliseconds:请求合并的等待的时间
     * maxRequestsInBatch:指定时间内对请求合并的请求的最大数
     * @retun: Future:注意请求的合并的方法的返回值必须为Future
     * @author: shinelon
     * @time: 2019/9/3:17:30
     */
    @HystrixCollapser(batchMethod = "batchMethod", scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
            //请求时间间隔在 20ms 之内的请求会被合并为一个请求,默认为 10ms
            collapserProperties = {
                    @HystrixProperty(name = "timerDelayInMilliseconds", value = "20"),
                    //设置触发批处理执行之前,在批处理中允许的最大请求数。
                    @HystrixProperty(name = "maxRequestsInBatch", value = "200")
            })
    public Future<Product> mergeRequest(Integer id)
    {
        System.out.println("========+" + id + "+======");
        return null;
    }


    /**
     * 1.@HystrixCommand:表示当前的方法开启熔断
       2.请求合并完毕后触发的方法,要和batchMethod 内的名字一致
       3.在请求合并完毕后会将合并的参数的使用list集合的方式进行传递
     *
     * @return
     */
    @HystrixCommand
    public List<Product> batchMethod(List<Integer> ids)
    {
        for (Integer id : ids)
        {
            System.out.println(ids + "batchMethod------------");
        }
        //相当于调用了Provider返回的数据
        List<Product> list = Arrays.asList(new Product("电视", 1), new Product("电视", 2), new Product("电视", 3), new Product("电视", 4));
        return list;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

编写测试的ProductController

@Controller
public class ProductController
{

    @Autowired
    private ProductService productService;


    /**
     * 模拟测试请求的合并
     * @throws ExecutionException
     * @throws InterruptedException
     */
  @GetMapping(value = "/customer")
public String setProductService() throws Exception
{
    Future<Product> productFuture1 = this.productService.mergeRequest(1);
    Future<Product> productFuture2 = this.productService.mergeRequest(2);
    Future<Product> productFuture3 = this.productService.mergeRequest(3);
    Future<Product> productFuture4 = this.productService.mergeRequest(4);

    System.out.println(productFuture1.get().toString());
    System.out.println(productFuture2.get().toString());
    System.out.println(productFuture3.get().toString());
    System.out.println(productFuture4.get().toString());

    return "";
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

控制台输出的结果

1.合并的方法并没执行
2.Controller的调用是将所有的ID,被合并方法收集
3.返回的值存在于单个的结果并不是list,注意这里有个很大的弯,我们在使用请求的是的单个参数的请求,所以在请求合并之后是返回的单独的对象,虽然我们在合并之后的方法返回值为一个的List集合任意一个的。(因为我没有拿着传递的数据进行Provider的访问,别搞混了)

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/843110
推荐阅读
相关标签
  

闽ICP备14008679号