Hystrix是一個用於處理分佈式系統的延遲和容錯的開源庫,在分佈式系統中,許多的依賴不可避免的會調用失敗,好比超時,異常等,Hystrix可以保證在一個依賴出問題的狀況下, **不會致使總體服務的失敗,避免級聯故障,以提升分佈式系統的彈性。**斷路器自己是一種開關裝置,當某個服務單元發生故障以後,經過斷路器的故障監控(相似熔斷保險絲), 向調用方法返回一個預期的,可處理的備選響應(FallBack),而不是長時間的等待或者拋出調用方法異常沒法處理的異常,這樣就保證服務調用方的線程不會被長時間,沒必要要的佔用,從而避免了故障在分佈式系統中的蔓延。java
熔斷機制是應對雪崩效應的一種微服務鏈路保護機制,當扇出鏈路的某一個微服務不可用或者響應時間太長,會進行服務的降級, 進而熔斷該節點微服務的調用,快速返回「錯誤」的響應信息,當檢測到該節點微服務調用響應正常後恢復調用鏈路,在SpringCloud框架中熔斷機制使用Hystrix實現,Hystrix會監控微服務調用狀況,當失敗達到必定閾值。就會啓動熔斷機制,熔斷機制的註解是 @HystrixCommandmysql
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
複製代碼
<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>
<parent>
<groupId>com.luo.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-provider-dept-hystrix-8001</artifactId>
<dependencies>
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- 引入本身定義的api通用包,可使用Dept部門Entity -->
<dependency>
<groupId>com.luo.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- actuator監控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 將微服務provider側註冊進eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<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>
</dependency>
<!-- 修改後當即生效,熱部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
複製代碼
eureka:
client: #客戶端註冊進eureka服務列表內
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: microservicecloud-dept8001-hystrix #自定義服務名稱信息
prefer-ip-address: true #訪問路徑能夠顯示IP地址
複製代碼
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑
type-aliases-package: com.luo.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 # mysql驅動包
url: jdbc:mysql://localhost:3306/cloudDB01 # 數據庫名稱
username: root
password: 1234
dbcp2:
min-idle: 5 # 數據庫鏈接池的最小維持鏈接數
initial-size: 5 # 初始化鏈接數
max-total: 5 # 最大鏈接數
max-wait-millis: 200 # 等待鏈接獲取的最大超時時間
eureka:
client: #客戶端註冊進eureka服務列表內
service-url:
#defaultZone: http://localhost:7001/eureka
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: microservicecloud-dept8001-hystrix #自定義服務名稱信息
prefer-ip-address: true #訪問路徑能夠顯示IP地址
info:
app.name: luokangyuan-microservicecloud
company.name: www.luokangyuan.com
build.artifactId: $project.artifactId$
build.version: $project.version$
複製代碼
Hystrix的做用就是當調用服務出現異常時如何解決,模擬根據id查部門信息,查到null,人爲拋出運行時異常,讓Hystrix處理這種狀況。web
@RequestMapping(value="dept/get/{id}",method=RequestMethod.GET)
@HystrixCommand(fallbackMethod = "processHystrix_GET")
public Dept get(@PathVariable("id") Long id){
Dept dept = service.get(id);
if(null == dept){
throw new RuntimeException("該ID:"+id+"沒有對應的部門信息");
}
return dept;
}
public Dept processHystrix_GET(@PathVariable("id") Long id){
return new Dept().setDeptno(id)
.setDname("該ID:"+id+"沒有對應的信息,null--@HystrixCommand")
.setDb_source("no this database in Mysql");
}
複製代碼
@SpringBootApplication
@EnableEurekaClient // 本服務啓動後會註冊到Eureka服務註冊中心
@EnableDiscoveryClient // 服務發現
@EnableCircuitBreaker //對Hystrix熔斷機制的支持
public class DeptProvider8001_Hystrix_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_Hystrix_App.class, args);
}
}
複製代碼
啓動三個Eureka集羣,啓動服務主啓動類DeptProvider8001_Hystrix_App,客戶端啓動microservicecloud-consumer-dept-80,頁面訪問http://localhost/consumer/dept/get/112spring
服務降級處理是在客戶端完成的,與服務端沒有關係,在前面的服務熔斷中,咱們發現每個業務方法都要寫一個processHystrix_方法,這樣就形成了很大耦合,根據Spring的學習,咱們可將processHystrix_改寫一個異常通知。sql
根據已有的DeptClientService接口,新建一個實現了FallbackFactory接口的類DeptClientServiceFallbackFactory數據庫
package com.luo.springcloud.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.luo.springcloud.entities.Dept;
import feign.hystrix.FallbackFactory;
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>{
@Override
public DeptClientService create(Throwable arg0) {
return new DeptClientService() {
@Override
public List<Dept> list() {
return null;
}
@Override
public Dept get(long id) {
return new Dept().setDeptno(id)
.setDname("該ID:"+id+"沒有對應的信息,Consumer客戶端提供的降級信息,此服務暫停使用")
.setDb_source("no this database in Mysql");
}
@Override
public boolean add(Dept dept) {
return false;
}
};
}
}
複製代碼
注意:不要忘記新類上添加@Component註解apache
在DeptClientService接口在註解@FeignClient(value = "MICROSERVICECLOUD-DEPT")添加fallbackFactory屬性值api
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory = DeptClientServiceFallbackFactory.class)
複製代碼
@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);
}
複製代碼
server:
port: 80
feign:
hystrix:
enabled: true
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
複製代碼
啓動三個Eureka集羣,microservicecloud-provider-dept-8001啓動,microservicecloud-consumer-dept-feign啓動,正常訪問http://localhost/consumer/dept/get/1測試,故意關停microservicecloud-provider-dept-8001,客戶端本身調用提示mybatis
Hystrix還提供了準實時的調用監控Hystrix Dashboard,Hystx會持續的記錄全部經過Hystrix發起的請求的執行信息,並以統計報表的圖形的形式展現給用戶,包括每秒執行多少次請求多少成功多少失敗等,對監控內容轉換爲可視化界面。app
新建microservicecloud-consumer-hystrix-dashboard監控的一個微服務工程
<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>
<parent>
<groupId>com.luo.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-consumer-hystrix-dashboard</artifactId>
<dependencies>
<!-- 本身定義的api -->
<dependency>
<groupId>com.luo.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改後當即生效,熱部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- Ribbon相關 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- feign相關 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!-- 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>
</dependencies>
</project>
複製代碼
server:
port: 9001
複製代碼
@SpringBootApplication
@EnableHystrixDashboard
public class DeptConsumer_DashBoard_App {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_DashBoard_App.class, args);
}
}
複製代碼
全部的Provider微服務提供類(8001,8002,8003)都須要監控依賴配置,也就是pom文件添加以下依賴
<!-- actuator監控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
複製代碼
啓動microservicecloud-consumer-hystrix-dashboard,訪問http://localhost:9001/hystrix,出現豪豬頁面
啓動3個Eureka集羣,啓動microservicecloud-provider-dept-hystrix-8001,啓動了microservicecloud-consumer-hystrix-dashboard用來監控8001服務提供者,訪問http://localhost:8001/hystrix.stream
訪問http://localhost:9001/hystrix,填寫監控地址http://localhost:8001/hystrix.stream,時間2000,title:demo01,點擊按鈕
實心圓:兩種含義,它經過顏色的變化表明了實例的健康程度,健康色是從綠色<黃色<橙色<紅色遞減,該實心圓除了顏色的變化以外,他的大小也會根據實例的請求流量發生變化,流量越大該實心圓就越大,因此經過實心圓的展現就能夠在大量實例中快速的發現 故障實例和高壓力測試。