hystrix的斷路功能
引用上個項目,創建新的model ,cloud-hystrix
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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> <groupId>com.zhaowb.springcloud</groupId> <artifactId>cloud-hystrix</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>cloud-hystrix</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.example</groupId> <artifactId>cloud-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>com.zhaowb.springcloud</groupId> <artifactId>cloud-api</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
主要的依賴是
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
在啟動類上加上注解
package com.zhaowb.springcloud.cloudhystrix; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; @SpringBootApplication @EnableDiscoveryClient @EnableEurekaClient @EnableHystrix public class CloudHystrixApplication { public static void main(String[] args) { SpringApplication.run(CloudHystrixApplication.class, args); } }
然后將eureka-hi 的 controller ,dao,service,resource 下mybatis相關 復制過來,修改DeptMapper.xml中的namespace 為當前項目下的Deptdao,這個一定要修改,否則會報找不到該類下的方法,修改controller
package com.zhaowb.springcloud.cloudhystrix.controller; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.zhaowb.springcloud.cloudapi.entities.Dept; import com.zhaowb.springcloud.cloudhystrix.service.DeptService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController public class DeptController { @Autowired private DeptService service; @RequestMapping(value = "/dept/add", method = RequestMethod.POST) public boolean add(@RequestBody Dept dept) { return service.add(dept); } @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET) @HystrixCommand(fallbackMethod = "getDeptError") public Dept get(@PathVariable("id") Long id) { Dept dept = service.get(id); if (dept == null){ throw new RuntimeException("dept is null id =" + id); } return service.get(id); } public Dept getDeptError(@PathVariable("id") Long id){ Dept dept = new Dept(); dept.setDeptno(id); dept.setDname("該ID:" + id + "沒有沒有對應的信息,null--@HystrixCommand"); dept.setDb_source("no this database in MySQL"); return dept; } @RequestMapping(value = "/dept/list", method = RequestMethod.GET) public List<Dept> list() { return service.list(); } }
代碼已經完成,啟動eureka-server ,cloud-hystrix,在瀏覽器輸入http://localhost:8766/dept/get/1,
顯示查詢結果,eptno":1,"dname":"部門1","db_source":"clouddb01"},
然后在瀏覽器輸入http://localhost:8766/dept/get/555,查詢結果為{"deptno":555,"dname":"該ID:555沒有沒有對應的信息,null--@HystrixCommand","db_source":"no this database in MySQL"}。說明hystrix的斷路功能實現成功。我數據庫只有幾條數據,555為在數據庫沒有該id的任意數字都可。
hystrix 的fallbackFactory實現
修改cloud-api ,類
package com.zhaowb.springcloud.cloudapi.service; import com.zhaowb.springcloud.cloudapi.entities.Dept; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import feign.hystrix.FallbackFactory; import java.util.List; @Component public class IDeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> { private static final Logger logger = LoggerFactory.getLogger(IDeptClientServiceFallbackFactory.class); @Override public DeptClientService create(Throwable cause) { return new DeptClientService() { @Override public Dept get(long id) { logger.info("DeptClientServiceFallbackFactory.DeptClientService.get id= " + id); logger.info("錯誤信息:" + cause); Dept dept = new Dept(); dept.setDeptno(id); dept.setDname("該ID:" + id + "沒有沒有對應的信息,Consumer客戶端提供的降級信息,此刻服務Provider已經關閉"); dept.setDb_source("no this database in MySQL"); return dept; } @Override public List<Dept> list() { return null; } @Override public boolean add(Dept dept) { return false; } }; } }
@Component 必須要有。
在DeptClientService增加
@FeignClient(value = "eureka-client-hi", fallbackFactory = IDeptClientServiceFallbackFactory.class)
修改cloud-feign,增加依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
Feign是自帶斷路器的,在D版本的Spring Cloud之后,它沒有默認打開。需要在配置文件中配置打開它,修改配置文件,application.yml
feign:
hystrix:
enabled: true
這樣基本上可以了,如果依然掃描不到包,怎添加上下邊這個注解
@ComponentScan(basePackages = {"com.zhaowb.springcloud.servicefeign","com.zhaowb.springcloud.cloudapi.service"}) // 參考https://my.oschina.net/u/2948566/blog/1591147
然后啟動,eureka-server,eureka-hi,cloud-feign,在瀏覽器輸入http://localhost:8765//consumer/dept/get/1,能正常訪問,然后關閉eureka-hi,刷新瀏覽器,
{"deptno":1,"dname":"該ID:1沒有沒有對應的信息,Consumer客戶端提供的降級信息,此刻服務Provider已經關閉","db_source":"no this database in MySQL"}驗證成功。
Hystrix Dashboard監控
在微服務架構中為例保證程序的可用性,防止程序出錯導致網絡阻塞,出現了斷路器模型。斷路器的狀況反應了一個程序的可用性和健壯性,它是一個重要指標。Hystrix Dashboard是作為斷路器狀態的一個組件,提供了數據監控和友好的圖形化界面。
新建model,cloud-hystrix-dashboard,引入依賴,有人說spring-boot-starter-actuato也是必須引用的 ,但是我沒有引入,也能運行,就沒有引入。
<?xml version="1.0" encoding="UTF-8"?> <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> <groupId>com.zhaowb.springcloud</groupId> <artifactId>cloud-hystrix-dashboard</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>cloud-hystrix-dashboard</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.example</groupId> <artifactId>cloud-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>com.zhaowb.springcloud</groupId> <artifactId>cloud-api</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
配置application.yml
server: port: 8767 management: endpoints: web: exposure: include: hystrix.stream
在啟動類上加上@EnableHystrixDashboard開啟HystrixDashboard
package com.zhaowb.springcloud.cloudhystrixdashboard; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; @SpringBootApplication @EnableHystrixDashboard public class CloudHystrixDashboardApplication { public static void main(String[] args) { SpringApplication.run(CloudHystrixDashboardApplication.class, args); } }
修改cloud-hystrix的啟動類,在啟動類上CloudHystrixApplication添加@EnableHystrix注解開啟斷路器。
依次啟動eureka-server,cloud-hystrix,cloud-hystrix-dashboard,打開,http://localhost:8766/dept/get/1,
http://localhost:8766/actuator/hystrix.stream 會有ping: data:{...}
打開locahost:8767/hystrix會有一個豪豬的圖片顯示說明成功。在界面一次填入http://localhost:8766/actuator/hystrix.stream ,2000,hellokity,分別為,監控的微服務的hystrix地址,延遲時間毫秒,title,點擊Monitor Stream ,刷新http://localhost:8766/dept/get/1,就會有圖像頁面顯示。