當一個請求依賴多個服務的時候:java
正常狀況下的訪問 :mysql
可是,當請求的服務中出現沒法訪問、異常、超時等問題時(圖中的I),那麼用戶的請求將會被阻塞。web
若是多個用戶的請求中,都存在沒法訪問的服務,那麼他們都將陷入阻塞的狀態中。spring
Hystrix的引入,能夠經過服務熔斷和服務降級來解決這個問題。sql
Hystrix斷路器簡介mybatis
hystrix對應的中文名字是「豪豬」,豪豬周身長滿了刺,能保護本身不受天敵的傷害,表明了一種防護機制,這與hystrix自己的功能不謀而合,所以Netflix團隊將該框架命名爲Hystrix,並使用了對應的卡通形象作做爲logo。app
在一個分佈式系統裏,許多依賴不可避免的會調用失敗,好比超時、異常等,如何可以保證在一個依賴出問題的狀況下,不會致使總體服務失敗,這個就是Hystrix須要作的事情。Hystrix提供了熔斷、隔離、Fallback、cache、監控等功能,可以在一個、或多個依賴同時出現問題時保證系統依然可用。框架
Hystrix服務熔斷服務降級@HystrixCommand fallbackMethoddom
熔斷機制是應對雪崩效應的一種微服務鏈路保護機制。分佈式
當某個服務不可用或者響應時間超時,會進行服務降級,進而熔斷該節點的服務調用,快速返回自定義的錯誤影響頁面信息。
咱們寫個項目來測試下;
咱們寫一個新的帶服務熔斷的服務提供者項目 microservice-student-provider-hystrix-1004
把 配置和 代碼 都複製一份到這個項目裏;
pom.xml加 hystrix支持
<!--Hystrix相關依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
application.yml
server: port: 1004 context-path: / spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8 username: root password: 123 jpa: hibernate: ddl-auto: update show-sql: true application: name: microservice-student profiles: provider-hystrix-1004 eureka: instance: hostname: localhost appname: microservice-student instance-id: microservice-student:1004 prefer-ip-address: true client: service-url: defaultZone: http://eureka2001.lingerqi.com:2001/eureka/,http://eureka2002.lingerqi.com:2002/eureka/,http://eureka2003.lingerqi.com:2003/eureka/ info: groupId: com.lingerqi.testSpringcloud artifactId: microservice-student-provider-hystrix-1004 version: 1.0-SNAPSHOT userName: http://lingerqi.com phone: 123456
StudentProviderHystrixApplication_1004
package com.lingerqi.microservicestudentproviderhystrix1004; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableCircuitBreaker @EntityScan("com.lingerqi.*.*") @EnableEurekaClient @SpringBootApplication public class MicroserviceStudentProviderHystrix1004Application { public static void main(String[] args) { SpringApplication.run(MicroserviceStudentProviderHystrix1004Application.class, args); } }
4,服務提供者1004中controller新增
package com.lingerqi.microservicestudentproviderhystrix1004.controller; import com.lingerqi.microservicecommon.entity.Student; import com.lingerqi.microservicestudentproviderhystrix1004.service.StudentService; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController @RequestMapping("/student") public class StudentProviderController { @Autowired private StudentService studentService; @Value("${server.port}") private String port; @PostMapping(value="/save") public boolean save(Student student){ try{ studentService.save(student); return true; }catch(Exception e){ return false; } } @GetMapping(value="/list") public List<Student> list(){ return studentService.list(); } @GetMapping(value="/get/{id}") public Student get(@PathVariable("id") Integer id){ return studentService.findById(id); } @GetMapping(value="/delete/{id}") public boolean delete(@PathVariable("id") Integer id){ try{ studentService.delete(id); return true; }catch(Exception e){ return false; } } @RequestMapping("/ribbon") public String ribbon(){ return "工號【"+port+"】正在爲您服務"; } /** * 測試Hystrix服務降級 * @return * @throws InterruptedException */ @ResponseBody @GetMapping(value="/hystrix") @HystrixCommand(fallbackMethod="hystrixFallback") public Map<String,Object> hystrix() throws InterruptedException{ // Thread.sleep(2000); Map<String,Object> map=new HashMap<String,Object>(); map.put("code", 200); map.put("info","工號【"+port+"】正在爲您服務"); return map; } public Map<String,Object> hystrixFallback() throws InterruptedException{ Map<String,Object> map=new HashMap<String,Object>(); map.put("code", 500); map.put("info", "系統【"+port+"】繁忙,稍後重試"); return map; } }
這裏我正常訪問 返回的是 200 業務數據xxxxx
可是咱們這裏Thread.sleep(2000) 模擬超時;
這裏的話 咱們加上@HystrixCommand註解 以及 fallbackMethod
代表這個方法咱們再 沒有異常以及沒有超時(hystrix默認1秒算超時)的狀況,才返回正常的業務數據;
不然,進入咱們fallback指定的本地方法,咱們搞的是500 系統出錯,稍後重試,有效的解決雪崩效應,以及返回給用戶界面
很好的報錯提示信息;
microservice-student-consumer-80項目也要對應的加個方法:
/** * 測試Hystrix服務降級 * @return */ @GetMapping(value="/hystrix") @ResponseBody public Map<String,Object> hystrix(){ return restTemplate.getForObject(SERVER_IP_PORT+"/student/hystrix/", Map.class); }
測試下先啓動三個eureka,再啓動帶hystrix的provider,最後啓動普通的consumer;
由於 Hystrix默認1算超時,全部 sleep了2秒 因此進入自定義fallback方法,防止服務雪崩;
咱們這裏改sleep修改爲100毫秒;
Hystrix默認超時時間是1秒,咱們能夠經過hystrix源碼看到,
找到 hystrix-core.jar com.netflix.hystrix包下的HystrixCommandProperties類
default_executionTimeoutInMilliseconds屬性局勢默認的超時時間
咱們系統裏假如要自定義設置hystrix的默認時間的話;
application.yml配置文件加上
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 3000
改爲3秒 而後 咱們代碼裏sleep修改爲2秒測試;
sleep修改爲4秒;
Hystrix服務監控Dashboard儀表盤
Hystrix提供了 準實時的服務調用監控項目Dashboard,可以實時記錄經過Hystrix發起的請求執行狀況,
能夠經過圖表的形式展示給用戶看。
咱們新建項目:microservice-student-consumer-hystrix-dashboard-90
加pom依賴:
<!--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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
啓動類加註解:
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) @EnableHystrixDashboard
啓動項目輸入:http://localhost:90/hystrix,出現以上圖表示OK
測試下;
咱們啓動三個eureka,而後再啓動microservice-student-provider-hystrix-1004
咱們直接請求 : http://localhost:1004/student/hystrix
返回正常業務