熔斷器Hystrix及服務監控Dashboard

服務雪崩效應

當一個請求依賴多個服務的時候: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默認超時時間設置

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提供了 準實時的服務調用監控項目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

返回正常業務

 

 

 

 

 

 

 

 

 

相關文章
相關標籤/搜索