1. 什么是服務(wù)災(zāi)難性雪崩效應(yīng)
image
造成雪崩原因是什么?
image
2. 如何解決災(zāi)難性雪崩效應(yīng)
image
什么是請(qǐng)求緩存?
image
解決災(zāi)難性雪崩效應(yīng)-請(qǐng)求緩存-請(qǐng)求緩存處理
- @CacheConfig注解的作用是什么?
image
- @CacheEvict注解的作用是什么?
image
解決災(zāi)難性雪崩效應(yīng)-請(qǐng)求合并-創(chuàng)建項(xiàng)目
- 什么是請(qǐng)求合并?
image
- 請(qǐng)求合并有哪些缺點(diǎn)?
image
- 解決災(zāi)難性雪崩效應(yīng)-請(qǐng)求合并-請(qǐng)求合并處理
image
-
解決災(zāi)難性雪崩效應(yīng)-服務(wù)熔斷-服務(wù)熔斷處理
- 什么是服務(wù)熔斷?
image
image
解決災(zāi)難性雪崩效應(yīng)-隔離機(jī)制-線程池隔離-創(chuàng)建項(xiàng)目
什么是線程池隔離?
image
- 線程池隔離的優(yōu)點(diǎn)是什么?
image
- 解決災(zāi)難性雪崩效應(yīng)-隔離機(jī)制-線程池隔離-線程池隔離處理
image
代碼示例
請(qǐng)求緩存
pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>springcloud-eureka-consumer-ribbon-cache</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springcloud-eureka-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- springCache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.application.name=eureka-consumer-ribbon-cache
server.port=9010
#設(shè)置服務(wù)注冊(cè)中心地址,指向另一個(gè)注冊(cè)中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
# Redis
spring.redis.database=0
#Redis服務(wù)器地址
spring.redis.host=192.168.2.129
#Redis服務(wù)器連接端口
spring.redis.port=6379
#Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=
#連接池最大連接數(shù)(負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-active=100
#連接池最大阻塞等待時(shí)間(負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-wait=3000
#連接池最大空閉連接數(shù)
spring.redis.pool.max-idle=200
#連接漢最小空閑連接數(shù)
spring.redis.pool.min-idle=50
#連接超時(shí)時(shí)間(毫秒)
spring.redis.pool.timeout=600
ProductService
@CacheConfig(cacheNames={"com.bjsxt.ego.product"})
@Service
public class ProductService {
@Autowired
private LoadBalancerClient loadBalancerClient;// ribbon負(fù)載均衡器
@HystrixCommand(fallbackMethod="fallback")
public List<Product> getUsers() {
// 選擇調(diào)用的服務(wù)的名稱
// ServiceInstance 封裝了服務(wù)的基本信息,如 IP,端口
ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider");
// 拼接訪問(wèn)服務(wù)的URL
StringBuffer sb = new StringBuffer();
// http://localhost:9001/product/findAll
sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
System.out.println(sb.toString());
// springMVC RestTemplate
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
};
// ResponseEntity:封裝了返回值信息
ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
List<Product> list = response.getBody();
return list;
}
//返回托底數(shù)據(jù)的方法
public List<Product> fallback(){
List<Product> list = new ArrayList<>();
list.add(new Product(-1, "我是托底數(shù)據(jù)"));
return list;
}
//根據(jù)ID查詢商品
@Cacheable(key="'product' + #id")
public Product getProductById(Integer id){
System.out.println("=========Get======"+id);
return new Product(id, "新的商品");
}
//根據(jù)ID刪除商品
@CacheEvict(key="'product' + #id")
public void delProductById(Integer id){
System.out.println("=========Del======"+id);
}
}
ProductController
@RestController
public class ProductController {
@Autowired
private ProductService userService;
@RequestMapping("/consumer")
public List<Product> getUsers() {
return this.userService.getUsers();
}
@RequestMapping(value="/get",method=RequestMethod.GET)
public Product get(Integer id){
return this.userService.getProductById(id);
}
@RequestMapping(value="/del",method=RequestMethod.GET)
public void del(Integer id){
this.userService.delProductById(id);
}
}
請(qǐng)求合并
pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>springcloud-eureka-consumer-ribbon-batch</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springcloud-eureka-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.application.name=eureka-consumer-ribbon-batch
server.port=9010
#設(shè)置服務(wù)注冊(cè)中心地址,指向另一個(gè)注冊(cè)中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
ProductControlle
@RestController
public class ProductController {
@Autowired
private ProductService userService;
@RequestMapping("/consumer")
public void getUsers() throws Exception{
Future<Product> p1 = this.userService.getProduct(1);
Future<Product> p2 = this.userService.getProduct(2);
Future<Product> p3 = this.userService.getProduct(3);
System.out.println(p1.get().toString());
System.out.println(p2.get().toString());
System.out.println(p3.get().toString());
}
}
ProductService
@Service
public class ProductService {
//利用hystrix合并請(qǐng)求
@HystrixCollapser(batchMethod = "batchProduct", scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
collapserProperties = {
//請(qǐng)求時(shí)間間隔在20ms之內(nèi)的請(qǐng)求會(huì)被合并為一個(gè)請(qǐng)求,默認(rèn)為10ms
@HystrixProperty(name = "timerDelayInMilliseconds", value = "20"),
//設(shè)置觸發(fā)批處理執(zhí)行之前,在批處理中允許的最大請(qǐng)求數(shù)。
@HystrixProperty(name = "maxRequestsInBatch", value = "200"),
})
//consumer的controller調(diào)用的方法 該方法返回值必須要返回Future類型
public Future<Product> getProduct(Integer id){
System.out.println("=========="+id+"==========");
return null;
}
@HystrixCommand
//調(diào)用Provider服務(wù)的方法
public List<Product> batchProduct(List<Integer> ids){
for(Integer id:ids){
System.out.println(id);
}
//假設(shè)是調(diào)用provider服務(wù)后返回的list
List<Product> list = new ArrayList<>();
list.add(new Product(1, "電視"));
list.add(new Product(2, "電腦"));
list.add(new Product(3, "冰箱"));
list.add(new Product(4, "手電筒"));
list.add(new Product(100,"list............"));
System.out.println("ddddddddddddddddddddddd");
return list;
}
}
服務(wù)熔斷
pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>springcloud-eureka-consumer-ribbon-breaker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springcloud-eureka-consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.application.name=eureka-consumer-ribbon-breaker
server.port=9010
#設(shè)置服務(wù)注冊(cè)中心地址,指向另一個(gè)注冊(cè)中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
ProductController
@RestController
public class ProductController {
@Autowired
private ProductService userService;
@RequestMapping("/consumer")
public List<Product> getUsers(@RequestParam("flag") Integer flag){
return this.userService.getUsers(flag);
}
}
ProductService
@Service
public class ProductService {
@Autowired
private LoadBalancerClient loadBalancerClient;// ribbon負(fù)載均衡器
@HystrixCommand(fallbackMethod = "fallback",
commandProperties = {
//默認(rèn)20個(gè);10s內(nèi)請(qǐng)求數(shù)大于20個(gè)時(shí)就啟動(dòng)熔斷器,當(dāng)請(qǐng)求符合熔斷條件時(shí)將觸發(fā)getFallback()。
@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,
value="10"),
//請(qǐng)求錯(cuò)誤率大于50%時(shí)就熔斷,然后for循環(huán)發(fā)起請(qǐng)求,當(dāng)請(qǐng)求符合熔斷條件時(shí)將觸發(fā)getFallback()。
@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,
value="50"),
//默認(rèn)5秒;熔斷多少秒后去嘗試請(qǐng)求
@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,
value="5000"),
})
public List<Product> getUsers(int flag) {
System.out.println(flag);
if(flag == 1){
throw new RuntimeException();
}
// 選擇調(diào)用的服務(wù)的名稱
// ServiceInstance 封裝了服務(wù)的基本信息,如 IP,端口
ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider");
// 拼接訪問(wèn)服務(wù)的URL
StringBuffer sb = new StringBuffer();
// http://localhost:9001/product/findAll
sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
System.out.println(sb.toString());
// springMVC RestTemplate
RestTemplate rt = new RestTemplate();
ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
};
// ResponseEntity:封裝了返回值信息
ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
List<Product> list = response.getBody();
return list;
}
//返回托底數(shù)據(jù)的方法
public List<Product> fallback(int flag){
List<Product> list = new ArrayList<>();
list.add(new Product(-1, "我是托底數(shù)據(jù)"));
return list;
}
}