千家信息网

微服务架构的高并发问题有哪些

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要介绍"微服务架构的高并发问题有哪些",在日常操作中,相信很多人在微服务架构的高并发问题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"微服务架构的高并发
千家信息网最后更新 2025年11月07日微服务架构的高并发问题有哪些

这篇文章主要介绍"微服务架构的高并发问题有哪些",在日常操作中,相信很多人在微服务架构的高并发问题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"微服务架构的高并发问题有哪些"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1 准备环境

1.1 准备商品微服务和订单微服务

  • 其中商品微服务的findById()方法设置休眠2秒,用来模拟网络波动等情况:

package com.sunxiaping.product.controller;import com.sunxiaping.product.domain.Product;import com.sunxiaping.product.service.ProductService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping(value = "/product")public class ProductController {    @Autowired    private ProductService productService;    @Value("${server.port}")    private String port;    @Value("${spring.cloud.client.ip-address}")    private String ip;    @PostMapping(value = "/save")    public String save(@RequestBody Product product) {        productService.save(product);        return "新增成功";    }    @GetMapping(value = "/findById/{id}")    public Product findById(@PathVariable(value = "id") Long id) {                try {            //休眠2秒,用来模拟 网络波动等情况            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }        Product product = productService.findById(id);        product.setProductName("访问的地址是:" + ip + ":" + port);        return product;    }}
  • 设置订单微服务的Tomcat的最大线程数是10:

server:  port: 9002 # 微服务的端口号  tomcat:    max-threads: 10 # 最大线程数是10spring:  application:    name: service-order # 微服务的名称  datasource:    url: jdbc:mysql://192.168.1.57:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true    driver-class-name: com.mysql.cj.jdbc.Driver    username: root    password: 123456  jpa:    generate-ddl: true    show-sql: true    open-in-view: true    database: mysql  jmx:    unique-names: true# 配置Eurekaeureka:  instance:    # 实例的名称    instance-id: service-order:9002    # 显示IP信息    prefer-ip-address: true    lease-renewal-interval-in-seconds: 5 # 发送心跳续约间隔(默认30秒)    lease-expiration-duration-in-seconds: 10 # Eureka Client发送心跳给Eureka Server端后,续约到期时间(默认90秒)  client:    healthcheck:      enabled: true    service-url: # Eureka Server的地址      #      defaultZone: http://localhost:9000/eureka/      defaultZone:  http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/# Ribbon的重试机制service-product:  ribbon:    #    修改ribbon的负载均衡策略 服务名 - ribbon - NFLoadBalancerRuleClassName :负载均衡策略    #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 修改ribbon的负载均衡策略为权重策略    # Ribbon的重试机制参数    ConnectTimeout: 250 # Ribbon的连接超时时间    ReadTimeout: 1000 # Ribbon的数据读取超时时间    OkToRetryOnAllOperations: true # 是否对所有操作都进行重试    MaxAutoRetriesNextServer: 50 # 切换实例的重试次数    MaxAutoRetries: 1 # 对当前实例的重试次数# 微服务info内容详细信息info:  app.name: xxx  company.name: xxx  build.artifactId: $project.artifactId$  build.version: $project.version$# 开启日志debuglogging:  level:    root: info
  • 订单微服务中的SpringConfig.java

package com.sunxiaping.order.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configurationpublic class SpringConfig {    @Bean//    @LoadBalanced    public RestTemplate restTemplate() {        return new RestTemplate();    }}
  • 订单微服务的OrderController.java

package com.sunxiaping.order.controller;import com.sunxiaping.order.domain.Product;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestController@RequestMapping(value = "/order")public class OrderController {    @Autowired    private RestTemplate restTemplate;    /**     * @param id     * @return     */    @GetMapping(value = "/buy/{id}")    public Product buy(@PathVariable(value = "id") Long id) {        Product product = restTemplate.getForObject("http://localhost:9001/product/findById/" + id, Product.class);        return product;    }    @GetMapping(value = "/findOrder")    public String findOrder() {        return "商品查询到了";    }}

2 使用Jmeter测试接口

  • 使用JMeter性能测试工具以50个线程每个线程循环50次测试:http://localhost:9002/order/buy/1接口,然后通过浏览器调用http://localhost:9002/order/findOrder接口,发现特别慢。

3 系统负载过高存在的问题

3.1 问题分析

  • 在微服务架构中,我们将业务拆成一个个的服务,服务和服务之间可以相互调用,由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时如果有大量的网络请求涌入,会形成任务累计,导致服务瘫痪。

  • 换句话说,Tomcat等容器会以线程池的方式对所有的请求进行统一的管理,如果某个方法可能存着耗时问题,随着外面积压的请求越来越多,势必会造成系统的崩溃、瘫痪等。

  • 为了不影响其他接口的正常访问:对多个服务之间进行隔离。

  • 服务隔离的方式:

    • :two:信号量隔离(计数器,就是对某个方法进行设置阈值,如果超过了阈值,直接报错)。

    • :one:线程池隔离。

4 线程池隔离的方式处理积压问题

4.1 在订单微服务中引入相关jar包的Maven坐标

    com.netflix.hystrix    hystrix-metrics-event-stream    1.5.12    com.netflix.hystrix    hystrix-javanica    1.5.12

4.2 配置线程池

  • 配置HystrixCommand接口的实现类,在实现类中可以对线程池进行配置:

package com.sunxiaping.order.command;import com.netflix.hystrix.*;import com.sunxiaping.order.domain.Product;import org.springframework.web.client.RestTemplate;public class OrderCommand extends HystrixCommand {    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://localhost:9001/product/findById/" + id, Product.class);    }    /**     * 服务降级     *     * @return     */    @Override    protected Product getFallback() {        Product product = new Product();        product.setProductName("不好意思,出错了");        return product;    }}

4.3 修改Controller

package com.sunxiaping.order.controller;import com.sunxiaping.order.command.OrderCommand;import com.sunxiaping.order.domain.Product;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestController@RequestMapping(value = "/order")public class OrderController {    @Autowired    private RestTemplate restTemplate;    /**     * 使用OrderCommand调用远程远程服务     *     * @param id     * @return     */    @GetMapping(value = "/buy/{id}")    public Product buy(@PathVariable(value = "id") Long id) {        return new OrderCommand(restTemplate, id).execute();    }    @GetMapping(value = "/findOrder")    public String findOrder() {        System.out.println(Thread.currentThread().getName());        return "商品查询到了";    }}

到此,关于"微服务架构的高并发问题有哪些"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0