Hystrix集羣及監控turbine、服務降級、集羣超時時間設置

Hystrix集羣及監控turbine

前面Dashboard演示的僅僅是單機服務監控,實際項目基本都是集羣,所以這裏集羣監控用的是turbine。

說明:本篇博客基於上一篇的配置 springCould 之 Hystrix斷路器
新建服務提供這集羣項目(這是一個項目,通過不同配置達到集羣的目的)和上片博客中microservice-book-provider-hystrix-1005一樣copy就行了,下面是不同的部分

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/cpc?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  application:
    name: microservice-book
  profiles: provider-hystrix-1004

eureka:
  instance:
    hostname: localhost
    appname: microservice-book
    instance-id: microservice-book:1004
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://eureka2001.cpc.com:2001/eureka/,http://eureka2002.cpc.com:2002/eureka/,http://eureka2003.cpc.com:2003/eureka/

info:
  groupId: com.cpc.testSpringcloud
  artifactId: microservice-book-provider-hystrix-1004
  version: 1.0-SNAPSHOT
  userName: http://cpc.com
  phone: 123456

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds:  1500

---
server:
  port: 1005
  context-path: /
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cpc?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  application:
    name: microservice-book
  profiles: provider-hystrix-1005

eureka:
  instance:
    hostname: localhost
    appname: microservice-book
    instance-id: microservice-book:1005
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://eureka2001.cpc.com:2001/eureka/,http://eureka2002.cpc.com:2002/eureka/,http://eureka2003.cpc.com:2003/eureka/

info:
  groupId: com.cpc.testSpringcloud
  artifactId: microservice-book-provider-hystrix-1005
  version: 1.0-SNAPSHOT
  userName: http://cpc.com
  phone: 123456

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000

---
server:
  port: 1006
  context-path: /
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cpc?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  application:
    name: microservice-book
  profiles: provider-hystrix-1006

eureka:
  instance:
    hostname: localhost
    appname: microservice-book
    instance-id: microservice-book:1006
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://eureka2001.cpc.com:2001/eureka/,http://eureka2002.cpc.com:2002/eureka/,http://eureka2003.cpc.com:2003/eureka/

info:
  groupId: com.cpc.testSpringcloud
  artifactId: microservice-book-provider-hystrix-1006
  version: 1.0-SNAPSHOT
  userName: http://cpc.com
  phone: 123456

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000     

啓動類:

package com.cpc.microservicebookproviderhystrix;

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.cpc.*.*")
@EnableEurekaClient
@SpringBootApplication
public class MicroserviceBookProviderHystrixApplication {

  public static void main(String[] args) {
      SpringApplication.run(MicroserviceBookProviderHystrixApplication.class, args);
  }

}

Run/Debug Configurations
在這裏插入圖片描述
消費者集羣配置完成了

新建項目microservice-book-consumer-hystrix-turbine-91

pom.xml加下依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>

application.yml

server:
  port: 91
  context-path: /
eureka:
  client:
    service-url:
      defaultZone: http://eureka2001.cpc.com:2001/eureka/,http://eureka2002.cpc.com:2002/eureka/,http://eureka2003.cpc.com:2003/eureka/
turbine:
  app-config: microservice-book   # 指定要監控的應用名稱
  clusterNameExpression: "'default'" #表示集羣的名字爲default
spring:
  application:
    name: turbine

啓動類

package com.cpc.microservicebookconsumerhystrixturbine91;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.netflix.turbine.EnableTurbine;

@EnableTurbine
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class MicroserviceBookConsumerHystrixTurbine91Application {

   public static void main(String[] args) {
       SpringApplication.run(MicroserviceBookConsumerHystrixTurbine91Application.class, args);
   }

}

測試
先啓動三個eureka,然後把帶剛剛配置帶的 hystrix 的服務都啓動;
microservice-book-consumer-80(消費者)這個也啓動,方便測試;啓動dashboard服務,啓動turbine服務;

http://localhost:91/turbine.stream 可以監控數據,實時ping 返回data
在這裏插入圖片描述
輸入http://localhost:90/hystrix進入儀表盤,輸入地址
在這裏插入圖片描述
點擊 進入集羣監控儀表:
在這裏插入圖片描述

服務降級

所謂降級,一般是從整體負荷考慮。就是當某個服務熔斷之後,服務器將不再被調用此時客戶端可以自己準備一個本地的fallback回調,返回一個缺省值。這樣做,雖然服務水平下降,但好歹可用,比直接掛掉要強。

整體資源快不夠了,忍痛將某些服務先關閉,待度過難關,再開啓回來.例如:
假設銀行有3個窗口A,B,C,每個窗口提供不同的業務,現在A窗口的服務人員,人手不夠急需從C或者B窗口調人處理業務,C或者B窗口掛起暫停服務的牌子

服務降級處理是在客戶端,也就是消費者(調用方)實現完成的,與服務端沒有關係

服務熔斷的做法需要一個方法就需要一個回覆的方法,並且回覆的方法和業務邏輯方法在一起,代碼過於耦合,所以接下來試試這個服務降級的操作:

通用模塊配置

服務降級要配合 feign 調用方式才能使用,降級是在消費者方做的 所以直接修改通用模塊的代碼,先寫一個降級處理類,實現FallbackFactory<StudentClientService>接口;

package com.cpc.common.service;

import com.cpc.common.entity.Book;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 這是降級處理類
 * @Author: cpc
 * @Date: 2019-11-22 18:34
 * @Version: V1.0
 */
@Component // 不要忘記添加,不要忘記添加,千萬不要忘記 這是一個巨大的坑
public class BookServiceFallbackFactory implements FallbackFactory<BookClientService> {

    @Override
    public BookClientService create(Throwable throwable) {
       	//實現BookClientService 這個接口,當調用服務端失敗的時候就走這裏面對應方法的邏輯
        return new BookClientService() {
            @Override
            public Map<String, Object> hystrix() {
                Map<String,Object> map=new HashMap<String,Object>();
                map.put("code", 500);
                map.put("info", "這是在客戶端做服務降級");
                return map;
            }

            @Override
            public Book get(Integer id) {
                return null;
            }

            @Override
            public List<Book> list() {
                return null;
            }

            @Override
            public boolean save(Book book) {
                return false;
            }

            @Override
            public boolean delete(Integer id) {
                return false;
            }

            @Override
            public String ribbon() {
                return null;
            }
        };
    }
}

feign 調用接口:重點是在FeignClient註解上加了fallbackFactory 這個參數

package com.cpc.common.service;

import com.cpc.common.entity.Book;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;
import java.util.Map;

/**
 * Book Feign接口客戶端
 * @author Administrator
 *
 */
 // fallbackFactory 是指定降級處理實現類 
@FeignClient(value = "MICROSERVICE-BOOK", fallbackFactory = BookServiceFallbackFactory.class)
public interface BookClientService {
 
    /**
     * 根據id查詢學生信息
     * @param id
     * @return
     */
    @GetMapping(value="/book/get/{id}")
    public Book get(@PathVariable("id") Integer id);
     
    /**
     * 查詢學生信息
     * @return
     */
    @GetMapping(value="/book/list")
    public List<Book> list();
     
    /**
     * 添加或者修改學生信息
     * @param book
     * @return
     */
    @PostMapping(value="/book/save")
    public boolean save(Book book);
     
    /**
     * 根據id刪除學生信息
     * @return
     */
    @GetMapping(value="/book/delete/{id}")
    public boolean delete(@PathVariable("id") Integer id);

    @RequestMapping("/book/ribbon")
    public String ribbon();


    /**
     * 這是測試服務熔斷的
     * @return
     */
    @RequestMapping("/book/hystrix")
    public Map<String, Object> hystrix();
}

microservice-feign-consumer-feign-80修改(具體的服務調用方)
BookConsumerController

package com.cpc.microservicebookconsumerfeign80.controller;

import com.cpc.common.entity.Book;
import com.cpc.common.service.BookClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/book")
public class BookConsumerController  {

    @Autowired
    private BookClientService bookClientService;

    @PostMapping(value = "/save")
    private boolean save(Book book) {
        return bookClientService.save(book);
    }

    @GetMapping(value = "/list")
    public List<Book> list() {
        return bookClientService.list();
    }

    @GetMapping(value = "/get/{id}")
    public Book get(@PathVariable("id") Integer id) {
        return bookClientService.get(id);
    }

    @GetMapping(value = "/delete/{id}")
    public boolean delete(@PathVariable("id") Integer id) {
        try {
            bookClientService.delete(id);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @RequestMapping("/ribbon")
    public String ribbon(){
        return bookClientService.ribbon();
    }

    @RequestMapping("/hystrix")
    public Map<String, Object> hystrix(){
        return bookClientService.hystrix();
    }

}

啓動類配置

package com.cpc.microservicebookconsumerfeign80;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.cpc"})
//注意這裏,如果通用模塊包名不同那麼是可能無法將對應的類加入ioc容器,這個配置非常的重要
@ComponentScan(basePackages = {"com.cpc.common.service", "com.cpc.microservicebookconsumerfeign80"})
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class MicroserviceBookConsumerFeign80Application {

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceBookConsumerFeign80Application.class, args);
    }

}

application.yml 中添加如下配置

feign:    #feign負載均衡啓動 hystrix
  hystrix:
    enabled: true

測試
啓動eureka集羣,啓動服務提供者集羣,啓動服務消費者,測試調用 http://localhost/book/hystrix,當服務提供者那邊調用不到,或者超時異常的時候
在這裏插入圖片描述

消費者超時設置

使用Feign調用接口分兩層,ribbon的調用和hystrix的調用,所以ribbon的超時時間和Hystrix的超時時間的結合就是Feign的超時時間

# 這是 ribbon 調用超時時間設置
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 9000

#hystrix的超時時間
hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 9000

一般情況下 都是 ribbon 的超時時間(<)hystrix的超時時間(因爲涉及到ribbon的重試機制)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章