五、SpringCloud五大神兽之Hystrix

    Netflix的创造了一个调用的库Hystrix实现了断路器图案。在微服务架构中,通常有多层服务调用。

HystrixGraph

图1.微服务图

较低级别的服务中的服务故障可能导致用户级联故障。当对特定服务的呼叫达到一定阈值时(Hystrix中的默认值为5秒内的20次故障),电路打开,不进行通话。在错误和开路的情况下,开发人员可以提供后备。

HystrixFallback

图2. Hystrix回退防止级联故障

开放式电路会停止级联故障,并允许不必要的或失败的服务时间来愈合。回退可以是另一个Hystrix保护的调用,静态数据或一个正常的空值。回退可能被链接,所以第一个回退使得一些其他业务电话又回到静态数据

如何使用?

一、服务熔断

根据之前的8001、8002、8003新建个模块

1、pom

<?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">
    <parent>
        <artifactId>microservicecloud</artifactId>
        <groupId>com.zhanghf</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microservisecloud-provider-dept-8001-hystrix</artifactId>

    <name>microservisecloud-provider-dept-8001-hystrix</name>


    <dependencies>
        <!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
        <dependency>
            <groupId>com.zhanghf</groupId>
            <artifactId>microservisecloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </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>

2.application.yml配置文件

server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.xml        # mybatis配置文件所在路径
  type-aliases-package: com.zhanghf.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:
    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/  #集群
#在eureka界面使微服务提供者显示更直观:显示名称和ip
  instance:
    instance-id: microservicecloud-dept8001-histrix  #改成具有熔断的8001服务提供者
    prefer-ip-address: true     #访问路径可以显示IP地址

#eureka服务器中注册的服务的info页面的显示内容
info:
  app.name: microservicecloud
  company.name: www.zhanghf.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

3、controller里面和之前的8001、8002、8003的区别是加入了 @HystrixCommand(fallbackMethod = "processHystrix"),即该注解的方法报错后会执行fallbackMethod里面的方法,防止服务由于单个业务功能出错导致雪崩效应

package com.zhanghf.springcloud.controller;


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.zhanghf.springcloud.entities.Dept;
import com.zhanghf.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DeptController
{
	@Autowired
	private DeptService service;

	@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
	@HystrixCommand(fallbackMethod = "processHystrix")//一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
	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(@PathVariable("id") Long id)
	{
		return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,null--@HystrixCommand")
				.setDb_source("no this database in MySQL");

	}

}

 上述例子是贼get方法中如果查不到对应的部门则报错,根据熔断机制,报错后会执行processHystrix方法。

4、启动类的区别是加入熔断支持的注解@EnableCircuitBreaker

5、测试

分别启动7001、7002、7003和带熔断支持的8001。数据库中部门有5个,因此访问id为1到5都正常,访问http://localhost:8001/dept/get/55则无法查出部门信息,触发熔断机制:

二、服务降级

服务降级,简单地理解就是其中一个服务的资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开启回来。

该操作执行在微服务客户端的消费者上,依托于之前带feign的80服务,服务提供者是否支持服务熔断的8001都可以

1、pom

<?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">
    <parent>
        <artifactId>microservicecloud</artifactId>
        <groupId>com.zhanghf</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microservisecloud-consumer-dept-feign</artifactId>


    <dependencies>
        <!-- 引入自己定义的api通用包,可以使用Dept部门Entity -->
        <dependency>
            <groupId>com.zhanghf</groupId>
            <artifactId>microservisecloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--feign相关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <!-- Ribbon相关  Spring Cloud Ribbon是基于Netflix 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>
        <!--Ribbon相关end-->
        <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>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>


</project>

2、application.yml配置文件开启服务降级支持

feign:
  hystrix:
    enabled: true

3、在feign讲解一篇中的api模块的DeptClientService接口那个包下编写类FallbackDeptClientService,实现接口FallbackFactory,接口里面实现DeptClientService类,在重载方法里面返回DeptClientService对象,里面根据相应的方法执行相应的降级操作。最后用@Commonnet注解标注这个类

package com.zhanghf.springcloud.service;

import com.zhanghf.springcloud.entities.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

/**
 * 用途:服务降级
 */
@Component
public class FallbackDeptClientService implements FallbackFactory<DeptClientService> {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public Dept get(@PathVariable("id") long id) {
                 return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
                        .setDb_source("no this database in MySQL");
            }

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

            @Override
            public boolean add(Dept dept) {
                return false;
            }
        };
    }
}

4、在DeptClientService接口的@FeignClient注解里面添加fallbackFactory

package com.zhanghf.springcloud.service;

import com.zhanghf.springcloud.entities.Dept;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

/**
 * @Description: 修改microservicecloud-api工程,根据已经有的DeptClientService接口
 * Created by YQ11053 on 2018/10/5 0005.
 */
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory = FallbackDeptClientService.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);
}

5、测试

分别启动7001、7002、7003、8001、带feign的8080

访问http://localhost:8080/consumer/dept/get/5正常

关闭8001,再访问 http://localhost:8080/consumer/dept/get/5

 三、服务监控

1、pom

<?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">
    <parent>
        <artifactId>microservicecloud</artifactId>
        <groupId>com.zhanghf</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>microservicecloud-consumer-hystrix-dashboard</artifactId>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- 自己定义的api -->
        <dependency>
            <groupId>com.zhanghf</groupId>
            <artifactId>microservisecloud-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>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>


</project>

2、配置文件application.yml

server:
  port: 9001

3、启动类添加注解@EnableHystrixDashboard

package com.zhanghf;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

/**
 * HystrixDashboard监控,在监控的服务中记得添加actuator的pom配置
 *
 */
@SpringBootApplication
@EnableHystrixDashboard
public class DeptConsumer_DashBoard_App
{
    public static void main( String[] args )
    {
        SpringApplication.run(DeptConsumer_DashBoard_App.class,args);
    }
    
}

4、分别启动7001、7002、7003、带hyxtrix的8001、访问9001http://localhost:9001/hystrix,出现如下界面则监控配置成功

 输入http://localhost:8001/hystrix.stream进入监控页面,此页面为监控带Hystrix的8001的微服务状态页面

 

next:SpringCloud五大神兽之Zuul 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值