1. 什么是服务灾难性雪崩效应
造成雪崩原因是什么?
2. 如何解决灾难性雪崩效应
什么是请求缓存?
解决灾难性雪崩效应-请求缓存-请求缓存处理
- @CacheConfig注解的作用是什么?
- @CacheEvict注解的作用是什么?
解决灾难性雪崩效应-请求合并-创建项目
- 什么是请求合并?
- 请求合并有哪些缺点?
- 解决灾难性雪崩效应-请求合并-请求合并处理
-
解决灾难性雪崩效应-服务熔断-服务熔断处理
- 什么是服务熔断?
解决灾难性雪崩效应-隔离机制-线程池隔离-创建项目
什么是线程池隔离?
- 线程池隔离的优点是什么?
- 解决灾难性雪崩效应-隔离机制-线程池隔离-线程池隔离处理
代码示例
请求缓存
pom.xml
4.0.0
com.bjsxt
springcloud-eureka-consumer-ribbon-cache
0.0.1-SNAPSHOT
jar
springcloud-eureka-consumer
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.13.RELEASE
UTF-8
UTF-8
1.8
org.springframework.cloud
spring-cloud-dependencies
Dalston.SR5
pom
import
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-config
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-hystrix
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.boot
spring-boot-maven-plugin
application.properties
spring.application.name=eureka-consumer-ribbon-cache
server.port=9010
#设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
# Redis
spring.redis.database=0
#Redis服务器地址
spring.redis.host=192.168.2.129
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码(默认为空)
spring.redis.password=
#连接池最大连接数(负值表示没有限制)
spring.redis.pool.max-active=100
#连接池最大阻塞等待时间(负值表示没有限制)
spring.redis.pool.max-wait=3000
#连接池最大空闭连接数
spring.redis.pool.max-idle=200
#连接汉最小空闲连接数
spring.redis.pool.min-idle=50
#连接超时时间(毫秒)
spring.redis.pool.timeout=600
ProductService
@CacheConfig(cacheNames={"com.bjsxt.ego.product"})
@Service
public class ProductService {
@Autowired
private LoadBalancerClient loadBalancerClient;// ribbon负载均衡器
@HystrixCommand(fallbackMethod="fallback")
public List getUsers() {
// 选择调用的服务的名称
// ServiceInstance 封装了服务的基本信息,如 IP,端口
ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider");
// 拼接访问服务的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> type = new ParameterizedTypeReference>() {
};
// ResponseEntity:封装了返回值信息
ResponseEntity> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
List list = response.getBody();
return list;
}
//返回托底数据的方法
public List fallback(){
List list = new ArrayList<>();
list.add(new Product(-1, "我是托底数据"));
return list;
}
//根据ID查询商品
@Cacheable(key="'product' + #id")
public Product getProductById(Integer id){
System.out.println("=========Get======"+id);
return new Product(id, "新的商品");
}
//根据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 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);
}
}
请求合并
pom.xml
4.0.0
com.bjsxt
springcloud-eureka-consumer-ribbon-batch
0.0.1-SNAPSHOT
jar
springcloud-eureka-consumer
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.13.RELEASE
UTF-8
UTF-8
1.8
org.springframework.cloud
spring-cloud-dependencies
Dalston.SR5
pom
import
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-config
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-hystrix
org.springframework.boot
spring-boot-maven-plugin
application.properties
spring.application.name=eureka-consumer-ribbon-batch
server.port=9010
#设置服务注册中心地址,指向另一个注册中心
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 p1 = this.userService.getProduct(1);
Future p2 = this.userService.getProduct(2);
Future 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合并请求
@HystrixCollapser(batchMethod = "batchProduct", scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
collapserProperties = {
//请求时间间隔在20ms之内的请求会被合并为一个请求,默认为10ms
@HystrixProperty(name = "timerDelayInMilliseconds", value = "20"),
//设置触发批处理执行之前,在批处理中允许的最大请求数。
@HystrixProperty(name = "maxRequestsInBatch", value = "200"),
})
//consumer的controller调用的方法 该方法返回值必须要返回Future类型
public Future getProduct(Integer id){
System.out.println("=========="+id+"==========");
return null;
}
@HystrixCommand
//调用Provider服务的方法
public List batchProduct(List ids){
for(Integer id:ids){
System.out.println(id);
}
//假设是调用provider服务后返回的list
List 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;
}
}
服务熔断
pom.xml
4.0.0
com.bjsxt
springcloud-eureka-consumer-ribbon-breaker
0.0.1-SNAPSHOT
jar
springcloud-eureka-consumer
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.13.RELEASE
UTF-8
UTF-8
1.8
org.springframework.cloud
spring-cloud-dependencies
Dalston.SR5
pom
import
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-config
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-hystrix
org.springframework.boot
spring-boot-maven-plugin
application.properties
spring.application.name=eureka-consumer-ribbon-breaker
server.port=9010
#设置服务注册中心地址,指向另一个注册中心
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 getUsers(@RequestParam("flag") Integer flag){
return this.userService.getUsers(flag);
}
}
ProductService
@Service
public class ProductService {
@Autowired
private LoadBalancerClient loadBalancerClient;// ribbon负载均衡器
@HystrixCommand(fallbackMethod = "fallback",
commandProperties = {
//默认20个;10s内请求数大于20个时就启动熔断器,当请求符合熔断条件时将触发getFallback()。
@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,
value="10"),
//请求错误率大于50%时就熔断,然后for循环发起请求,当请求符合熔断条件时将触发getFallback()。
@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,
value="50"),
//默认5秒;熔断多少秒后去尝试请求
@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,
value="5000"),
})
public List getUsers(int flag) {
System.out.println(flag);
if(flag == 1){
throw new RuntimeException();
}
// 选择调用的服务的名称
// ServiceInstance 封装了服务的基本信息,如 IP,端口
ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider");
// 拼接访问服务的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> type = new ParameterizedTypeReference>() {
};
// ResponseEntity:封装了返回值信息
ResponseEntity> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
List list = response.getBody();
return list;
}
//返回托底数据的方法
public List fallback(int flag){
List list = new ArrayList<>();
list.add(new Product(-1, "我是托底数据"));
return list;
}
}