1.線程隔離,服務降級(服務的消費方做降級處理)
當服務繁忙時,如果服務出現異常,不是粗暴的直接報錯,而是返回一個友好的提示,雖然拒絕了用戶的訪問,但是會返回一個結果。
這就好比去買魚,平常超市買魚會額外贈送殺魚的服務。等到逢年過節,超時繁忙時,可能就不提供殺魚服務了,這就是服務的降級。
系統特別繁忙時,一些次要服務暫時中斷,優先保證主要服務的暢通,一切資源優先讓給主要服務來使用,在雙十一、618時,京東天貓都會采用這樣的策略。
pom.xml
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
UserConsumerApplication.java
package cn.itcast.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
//@EnableDiscoveryClient
//@SpringBootApplication
//@EnableCircuitBreaker //服務的熔斷
@SpringCloudApplication //SpringCloudApplication可以替代上面三個
public class UserConsumerDemoApplication {
@Bean
@LoadBalanced //負載均衡
public RestTemplate restTemplate() {
// 這次我們使用了OkHttp客戶端,只需要注入工廠即可
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}
?
?3.UserHController.java
package cn.itcast.user.controller;import cn.itcast.user.pojo.User; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 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("consumerH") public class UserHController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("{id}")@HystrixCommand(fallbackMethod = "queryUserByIdFallback") //單個方法的超時返回public String queryUserById(@PathVariable("id") Long id){String url = "http://user-service/user/" + id;//User user = restTemplate.getForObject(url, User.class);//return user;String user = restTemplate.getForObject(url, String.class);return user;}public String queryUserByIdFallback(@PathVariable("id") Long id){return "用戶信息查詢出現異常!"; // User user = new User(); // user.setId(id); // user.setNickName("用戶信息查詢出現異常!"); // return user; } }
==========================
配置統一超時信息
package cn.itcast.user.controller;
import cn.itcast.user.pojo.User;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
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("consumerH")
@DefaultProperties(defaultFallback = "queryUserByIdFallback")
public class UserHController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
//@HystrixCommand(fallbackMethod = "queryUserByIdFallback")
@HystrixCommand
public String queryUserById(@PathVariable("id") Long id){
String url = "http://user-service/user/" + id;
//User user = restTemplate.getForObject(url, User.class);
//return user;
String user = restTemplate.getForObject(url, String.class);
return user;
}
//public String queryUserByIdFallback(@PathVariable("id") Long id){
//return "用戶信息查詢出現異常!";
// User user = new User();
// user.setId(id);
// user.setNickName("用戶信息查詢出現異常!");
// return user;
//}
public String queryUserByIdFallback(){
return "用戶信息查詢出現異常!";
}
}
=============================================================
package cn.itcast.user.controller;
import cn.itcast.user.pojo.User;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
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("consumerH")
@DefaultProperties(defaultFallback = "queryUserByIdFallback")
public class UserHController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000"), //響應超時時間
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60")
})
public String queryUserById(@PathVariable("id") Long id){
if(id % 2 ==0){
throw new RuntimeException("");
}
String url = "http://user-service/user/" + id;
String user = restTemplate.getForObject(url, String.class);
return user;
}
public String queryUserByIdFallback(){
return "用戶信息查詢出現異常!";
}
}
?
?