springcloud 服務熔斷和降級 和 服務監控
阿新 • • 發佈:2019-01-10
一、概念部分
1.什麼是熔斷器?
熔斷,就是斷開與伺服器的連線,熔斷器是在服務不可用的時候主動斷開,以免造成更多的雪崩效應,他是保護服務高可用的最後一道防線。
2.為什麼需要熔斷器?
為保證服務高可用,最先想到的是服務叢集,但叢集並不能完全的保證服務高可用,
當某個服務出現故障時,在負載均衡的時候可能多次被呼叫到,呼叫方由於無法得到呼叫結果,會出現請求超時會其他異常,這時候如果不及時的熔斷服務,就有可能會有更多的呼叫者去呼叫已經出現故障的服務節點,造成大量呼叫失敗,甚至引發聯級故障的雪崩。
在分散式系統中,通常會有很多的服務呼叫,比如服務呼叫關係:AB->C->D。
基礎服務的故障可能會導致聯級故障,如下圖所示:
我們需要一個熔斷機制,當某個節點出現故障時,及時的做熔斷處理,防止更多的服務呼叫失敗。
二:程式碼例項
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
server: port: 8001 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml #mybatis所在路徑 type-aliases-package: com.atguigu.springcloud.entities #entity別名類 mapper-locations: - classpath:mybatis/mapper/**/*.xml #mapper對映檔案 spring: application: name: microservicecloud-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/cloudDB01 username: root password: 123456 dbcp2: min-idle: 5 initial-size: 5 max-total: 5 max-wait-millis: 200 eureka: client: #客戶端註冊進eureka服務列表內 service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ instance: instance-id: microservicecloud-dept8001-hystrix #自定義hystrix相關的服務名稱資訊 prefer-ip-address: true #訪問路徑可以顯示IP地址 info: app.name: atguigu-microservicecloud company.name: www.atguigu.com build.artifactId: $project.artifactId$ build.version: $project.version$
介面
package com.atguigu.springcloud.service; import java.util.List; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.atguigu.springcloud.entities.Dept; /** * * @Description: 修改microservicecloud-api工程,根據已經有的DeptClientService介面 新建 一個實現了FallbackFactory介面的類DeptClientServiceFallbackFactory * @author zzyy * @date 2018年4月21日 */ //@FeignClient(value = "MICROSERVICECLOUD-DEPT") @FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory=DeptClientServiceFallbackFactory.class) public interface DeptClientService { @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET) public Dept get(@PathVariable("id") long id); @RequestMapping(value = "/dept/list", method = RequestMethod.GET) public List<Dept> list(); @RequestMapping(value = "/dept/add", method = RequestMethod.POST) public boolean add(Dept dept); }
在每個介面上定義熔斷機制,當介面呼叫失敗時,會呼叫DeptClientServiceFallbackFactory中的方法進行回撥
package com.atguigu.springcloud.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.atguigu.springcloud.entities.Dept;
import feign.hystrix.FallbackFactory;
@Component // 不要忘記新增,不要忘記新增
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>
{
@Override
public DeptClientService create(Throwable throwable)
{
return new DeptClientService() {
@Override
public Dept get(long id)
{
return new Dept().setDeptno(id).setDname("該ID:" + id + "沒有沒有對應的資訊,Consumer客戶端提供的降級資訊,此刻服務Provider已經關閉")
.setDb_source("no this database in MySQL");
}
@Override
public List<Dept> list()
{
return null;
}
@Override
public boolean add(Dept dept)
{
return false;
}
};
}
}
測試conrtoller層
package com.atguigu.springcloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.atguigu.springcloud.entities.Dept;
import com.atguigu.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@RestController
public class DeptController
{
@Autowired
private DeptService service = null;
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
//一旦呼叫服務方法失敗並丟擲了錯誤資訊後,會自動呼叫@HystrixCommand標註好的fallbackMethod呼叫類中的指定方法
//@HystrixCommand(fallbackMethod = "processHystrix_Get")
public Dept get(@PathVariable("id") Long id)
{
Dept dept = this.service.get(id);
if (null == dept) {
throw new RuntimeException("該ID:" + id + "沒有沒有對應的資訊");
}
return dept;
}
}
總結
:
發現遠端呼叫不成功,但是不會因為呼叫不成功導致服務異常,而是熔斷了遠端服務的連線並以友好的方式觸發了我們的遠端呼叫失敗時指定的本地回撥方法,輸出了自定義資訊。證明熔斷成功。
服務監控
依賴
<!-- hystrix和 hystrix-dashboard相關 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
要想某個服務被監控,需要在需要監控的服務中新增依賴才能生效
<!-- actuator監控資訊完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
測試:
localhost:9001/hystrix
填寫監控地址
詳解:
可以監控某一時刻呼叫的峰值狀況