一)信号量隔离介绍
什么是信号量隔离?
信号量隔离的其实很简单,就是在Constumer和Provider之间加上一个的消息队列,在指定的时间内只允许指定的请求量能够访问到Provider,如果请求超出,则返回托底数据。
如下图:
Constumer访问的Provider之间的请求量是的10万次,那么么此时的Porvider肯定是接收不了的,如果使用的信号量隔离,就是在两者之间加上一个的消息队列,当大量请求涌进来的时候,设定一个阀值,加入涌进来100条请求,但是的设置的阀值为20,那么此时只有前20个能够访问Provider得到数据,其余的80个请求只能拿到的托底数据。消息队列中的请求在完成后会归还阀值,允许其余的请求进入对列中。
1.创建项目演示信号量隔离
1.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>22-hystrix-sign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>22-hystrix-sign</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>
2.全局配置文件
spring.application.name=21-hystrix-threadpool
server.port=9096
eureka.client.service-url.defaultZone=http://peer1:8081/eureka/,http://peer2:8082/eureka/,http://peer3:8083/eureka/
spring.profiles.active=
3.设置启动类
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class Application
{
public static void main(String[] args)
{
SpringApplication.run(Application.class, args);
}
}
4.修改ProviderService进行信号量设置
@Service
public class ProductService
{
/**
* 信号量隔离:
* @注解:@HystrixCommand:设置熔断策略
* @HystrixProperty:配置熔断属性
* HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY:设置隔离类型,默认为线程隔离(THREAD),SEMAPHORE为线程隔离
* HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS:设置消息对列的个数
*
*
*/
@HystrixCommand(fallbackMethod = "fallbackMethod", commandProperties = {
@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"),// 信号量 隔离
@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "100")//信号量最大并度
})
public Product getProduct(int flag)
{
System.out.println(Thread.currentThread().getName());
if (flag == 1)
{
throw new RuntimeException();
}
return new Product("熔断器", flag);
}
/**
* @param
* @description: 托底方法 在使用线程隔离的时候,托底方法的数据隔离的方法在一个的线程池中
* @return:
* @author: shinelon
* @time: 2019/9/3:19:53
*/
public Product fallbackMethod(int flag)
{
System.out.println(Thread.currentThread().getName());
return new Product("托底数据", flag);
}
}
5.Controller的设置
@Controller
public class ProductController
{
@Autowired
private ProductService productService;
/**
* 模拟测试请求的合并
* @throws ExecutionException
* @throws InterruptedException
*/
@GetMapping(value = "/customer")
@ResponseBody
public Product setProductService(int id) throws Exception
{
return this.productService.getProduct(id);
}
}