这篇文章主要介绍“微服务架构的高并发问题有哪些”,在日常操作中,相信很多人在微服务架构的高并发问题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”微服务架构的高并发问题有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
创新互联建站从2013年开始,是专业互联网技术服务公司,拥有项目网站制作、网站建设网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元葫芦岛做网站,已为上家服务,为葫芦岛各地企业和个人服务,联系电话:028-86922220
其中商品微服务的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 # 最大线程数是10 spring: 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 # 配置Eureka eureka: 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$ # 开启日志debug logging: 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;
@Configuration
public 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 "商品查询到了";
}
}使用JMeter性能测试工具以50个线程每个线程循环50次测试:http://localhost:9002/order/buy/1接口,然后通过浏览器调用http://localhost:9002/order/findOrder接口,发现特别慢。

在微服务架构中,我们将业务拆成一个个的服务,服务和服务之间可以相互调用,由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时如果有大量的网络请求涌入,会形成任务累计,导致服务瘫痪。
换句话说,Tomcat等容器会以线程池的方式对所有的请求进行统一的管理,如果某个方法可能存着耗时问题,随着外面积压的请求越来越多,势必会造成系统的崩溃、瘫痪等。

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

:two:信号量隔离(计数器,就是对某个方法进行设置阈值,如果超过了阈值,直接报错)。
:one:线程池隔离。
com.netflix.hystrix hystrix-metrics-event-stream 1.5.12 com.netflix.hystrix hystrix-javanica 1.5.12
配置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; } }
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 "商品查询到了";
}
}到此,关于“微服务架构的高并发问题有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!