ribbon服務
1.pom依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.配置
創建CommandForIndex類
public class CommandForIndex extends HystrixCommand<Object> {
private final RestTemplate template;
private String id;
public CommandForIndex(String id, RestTemplate restTemplate) {
// java代碼配置, 只針對這個命令
super(Setter
// 必填項,用於統計,指定命令分組名
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("Hello-Group"))
// 熔斷配置依賴名稱,默認值command實現類的類名(比如這個就是CommandForIndex),如果是服務調用,則寫具體的接口名
.andCommandKey(HystrixCommandKey.Factory.asKey("ConsumerController"))
// 線程池配置依賴名稱,默認值HystrixCommandGroupKey的名稱
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("User-ThreadPool"))
// command 熔斷相關參數配置
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
// 配置隔離方式:默認採用線程池隔離。(還有信號量隔離方式)
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
// 超時時間500毫秒
.withExecutionTimeoutInMilliseconds(500)
// 信號量隔離的模式下,最大的請求數。和線程池大小的意義一樣
// .withExecutionIsolationSemaphoreMaxConcurrentRequests(2)
// 熔斷時間(熔斷開啓後,各5秒後進入半開啓狀態,試探是否恢復正常)
// .withCircuitBreakerSleepWindowInMilliseconds(5000)
)
// 設置線程池參數
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
// 線程池大小
.withCoreSize(1)
//允許最大的緩衝區大小
// .withMaxQueueSize(2)
));
// super(HystrixCommandGroupKey.Factory.asKey("User-command"),100);
this.id = id;
this.template = restTemplate;
}
@Override
protected Object run() throws Exception {
System.out.println("###command#######" + Thread.currentThread().toString());
Object result = template.getForObject("http://helloclient/user?id="+id+"",Object.class);
System.out.println(
"###command結束#######" + Thread.currentThread().toString() + ">><>>>執行結果:" + result.toString());
return result;
}
@Override
protected Object getFallback() {
System.out.println("###降級啦####" + Thread.currentThread().toString());
return "出錯了,我降級了";
//降級的處理:
//1.返回一個固定的值
//2.去查詢緩存
//3.調用一個備用接口
}
}
測試
修改Controller層
@RestController
public class ConsumerController {
@Autowired
RestTemplate restTemplate;
@GetMapping("")
public Object index(@RequestParam("id")String id){
//localhost:8001和http://helloclient等同 ,在配置文件中有相關配置
//return restTemplate.getForObject("http://localhost:8001/user?id="+id+"",Object.class);
//return restTemplate.getForObject("http://helloclient/user?id="+id+"",Object.class);
return new CommandForIndex(id,restTemplate).execute();
}
@GetMapping("/get-teacher")
public Object getTeacher(){
//return restTemplate.getForEntity("http://localhost:8001",Teacher.class);
return restTemplate.getForEntity("http://helloclient",Teacher.class);
}
public Object callTimeoutFallback(){
return "查詢超時啦,我降級了。";
}
}
修改hello-demo和ribbon服務的application.yml,將服務註冊到註冊中心上去
server:
port: 8092
###定義實例名
spring:
application:
name: spring-cloud-ribbon-consumer
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10000/eureka/
修改hello-demo服務的controller層,將第一個hello-demo請求接口sleep一秒鐘
@GetMapping("user")
public Object getUser(@Param("id")String id) throws InterruptedException {
System.out.println("客戶端1返回了請求");
Thread.sleep(1000L);
return helloService.get(id);
}
啓動服務
服務請求超時,服務降級
再次請求
請求成功
示例代碼:
碼雲