zoukankan      html  css  js  c++  java
  • 微服务架构的高并发问题

    准备工作

    修改代码,模拟请求超时的代码

    先写一个直接返回的代码

        @RequestMapping(value = "/find/{id}",method = RequestMethod.GET)
        public String find(@PathVariable Long id) {
            return "查询成功";
        }

    在被调用端,加入线程睡眠

    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
        public Product findById(@PathVariable Long id) {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Product product = productService.findById(id);
            product.setProductName("访问的服务地址:"+ip + ":" + port);
            return product;
        }

    然后再调用端修改配置,增大请求时间,不然直接会报错

    feign:
      client:
        config:
          service-product:
            readTimeout: 6000
            connectTimeout: 6000
            loggerLevel: FULL

    然后开始调用,发现find接口很快返回

     性能工具Jmetter

    Apache JMeter 是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计
    用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、
    Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网
    络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。另外JMeter能够对应
    用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限
    度的灵活性,JMeter允许使用正则表达式创建断言。

    安装Jmetter
    Jmetter安装十分简单,使用资料中的 apache -jmeter-2.13.zip 完整压缩包,解压找到安装目录下
    bin/jmeter.bat 已管理员身份启动即可。

    配置Jmetter
    (1)创建新的测试计划

     ( 2)测试计划下创建发起请求的线程组

    可以配置请求的线程数,以及每个请求发送的请求次数

    (3)创建http请求模板

     ( 4)配置测试的接口信息

     开始测试,发现请求直接返回的接口都卡住了。

    问题分析
    在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用,由于网络原因或者
    自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络
    延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪。
    在SpringBoot程序中,默认使用内置tomcat作为web服务器。单tomcat支持最大的并发请求是有限
    的,如果某一接口阻塞,待执行的任务积压越来越多,那么势必会影响其他接口的调用。

    线程池的形式实现服务隔离

    ( 1) 配置坐标
    为了方便实现线以线程池的形式完成资源隔离,需要引入如下依赖

     <!--hystrix-->
            <dependency>
                <groupId>com.netflix.hystrix</groupId>
                <artifactId>hystrix-metrics-event-stream</artifactId>
                <version>1.5.12</version>
            </dependency>
            <dependency>
                <groupId>com.netflix.hystrix</groupId>
                <artifactId>hystrix-javanica</artifactId>
                <version>1.5.12</version>
            </dependency>

    ( 2) 配置线程池
    配置HystrixCommand接口的实现类,再实现类中可以对线程池进行配置

    package com.topcheer.order.command;
    
    import com.netflix.hystrix.*;
    import com.topcheer.order.entity.Product;
    import org.springframework.web.client.RestTemplate;
    
    public class OrderCommand extends HystrixCommand<Product> {
    
        private RestTemplate restTemplate;
        
        private Long id;
    
        public OrderCommand(RestTemplate restTemplate, Long id) {
            super(setter());
            this.restTemplate = restTemplate;
            this.id = id;
        }
    
        private static Setter setter() {
    
            // 服务分组
            HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("order_product");
            // 服务标识
            HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("product");
            // 线程池名称
            HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory.asKey("order_product_pool");
            /**
             * 线程池配置
             *     withCoreSize :  线程池大小为10
             *     withKeepAliveTimeMinutes:  线程存活时间15秒
             *     withQueueSizeRejectionThreshold  :队列等待的阈值为100,超过100执行拒绝策略
             */
            HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter().withCoreSize(50)
                    .withKeepAliveTimeMinutes(15).withQueueSizeRejectionThreshold(100);
    
            // 命令属性配置Hystrix 开启超时
            HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
                    // 采用线程池方式实现服务隔离
                    .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                    // 禁止
                    .withExecutionTimeoutEnabled(false);
            return Setter.withGroupKey(groupKey).andCommandKey(commandKey).andThreadPoolKey(threadPoolKey)
                    .andThreadPoolPropertiesDefaults(threadPoolProperties).andCommandPropertiesDefaults(commandProperties);
    
        }
    
        @Override
        protected Product run() throws Exception {
            System.out.println(Thread.currentThread().getName());
            return restTemplate.getForObject("http://service-product/product/"+id, Product.class);
        }
    
        /**
         * 降级方法
         */
        @Override
        protected Product getFallback(){
            Product product = new Product();
            product.setProductName("不好意思,出错了");
            return product;
        }
    }

    3) 配置调用
    修改 OrderController ,使用自定义的OrderCommand完成调用

        @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
        public Product findById(@PathVariable Long id) {
            return new OrderCommand(restTemplate,id).execute();
        }

    配置以后就不卡了,这就引出了服务熔断Hystrix

  • 相关阅读:
    中国的人生路上是紧跟领导就会有回报
    重游三峡广场有感
    假如你没有我
    关于中小型软件企业技术管理的建议(转)
    街客
    游歌乐山有感
    高成就者的反常思维
    漫谈创业和管理-程序员5大思维障碍 (转)
    QQ情缘
    javascript library
  • 原文地址:https://www.cnblogs.com/dalianpai/p/12270902.html
Copyright © 2011-2022 走看看