我是靠谱客的博主 霸气哈密瓜,最近开发中收集的这篇文章主要介绍springCloud学习02之断路器Hystrix-turbine监控-ribbo/feign对Hystrix的支持,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

        随着Docker的推进,微服务越来越热了.在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用。为了保证其高可用,单个服务又必须集群部署。由于网络原因或者自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪,甚至导致服务“雪崩”。

       特别是app和api是通过http(如httpClient工具)进行连接通信时,我们一般都是设置个超时而已。但是这仍然有弊端,比如超时设置为2s,网络不稳定出问题了或者api挂了,app不知道啊,仍然会向api发出请求,如果一个业务需要调用多个3个api时,那响应给用户客户端(如浏览器)就起码超过6s了;如果并发量高,还会倒是app积累非常多的进程或线程,消耗了系统资源。如果有这么一个工具,在app端帮助app对api的响应情况进行记录,如果某个api的不响应了或者经常响应超时,那app再次请求该api时,那工具立刻识别到该api是不正常的,立刻告诉app。当api又正常了,那app的请求又会正常到达api。

      Hystrix就是专门为解决这些问题的。

  本博文的代码例子,github上。

 熔断器

   我们先简单了解下什么叫熔断器。


   spring cloud已经集成了Hystrix了。上一篇博文学习了eureka服务发现-提供者-消费者ribbo-feign,spring cloud也已经对ribbon和feign集成了Hystrix.下面我们分别学习下。

  ribbon对Hystrix的支持

   在上一篇博文中,已经创建有ribbon的项目了eureka-app-ribbon,复制一份修改名称为eureka-app-ribbon-hystrix,
pom.xml增加
<!-- hystrix的支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- 健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

application.properties
logging.config=classpath:logback.xml
logging.path=d:/logs
##tomcat set###
# eureka的默认端口是8761
server.port=7081
server.session-timeout=60
###########
spring.application.name=app-user
#像eureka服务注册信息时,使用ip地址,默认使用hostname
eureka.instance.preferIpAddress=true
#服务的instance-id默认默认值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,
#也就是机器主机名:应用名称:应用端口
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
# 开启健康检查(需要spring-boot-starter-actuator依赖)
eureka.client.healthcheck.enabled=true;
# 续约更新时间间隔(默认30秒)
eureka.instance.lease-renewal-interval-in-seconds=30
# 续约到期时间(默认90秒)
eureka.instance.lease-expiration-duration-in-seconds=10
#eureka的服务地址
eureka.client.serviceUrl.defaultZone=http://01.server.eureka:8081/eureka/
#ribbo负载均衡策略配置,默认是依次轮询
API-USER-SERVER.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#Hystrix是否启用超时时间
hystrix.command.default.execution.timeout.enabled=true;
#Hystrix断路器的超时时间,默认是1s
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000

UserController.java
package com.fei.springcloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "findError") //如果请求失败或超时
@GetMapping(value = "/find")
@ResponseBody
public String find() {
//url中对应api提供者的名称,全大写
System.out.println("向api提供者发起请求........");
String s = restTemplate.getForEntity("http://API-USER-SERVER/user/find/123", String.class).getBody();
return s;
}
public String findError(){
return "查询用户,调用api失败....";
}
}

看到在接受请求的方法上添加注解@HystrixCommand(fallbackMethod = "findError"),如果Hystrix中对该请求进行了无效处理,则立即执行findError()方法。@HystrixCommand有好几个属性,后面再深入研究
启动类Application.java
package com.fei.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableEurekaClient
@SpringBootApplication
@EnableHystrix
//增加hystrix断路器
public class Application {
@Bean //定义REST客户端,RestTemplate实例
@LoadBalanced //开启负债均衡的能力
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

增加了注解@EnableHystrix。
测试,启动eureka服务,启动eureka-app-ribbon-hystrix,先不用启动api提供者。浏览器访问http://127.0.0.1:7081/user/find,发现返回的是“查询用户,调用api失败....”,然后启动api提供者,稍等一会,再次发起请求,返回的是“张三 服务端端口:9082

  feign对Hystrix的支持

  feign已经自带断路器了,就像自带了ribbon的负载均衡,如果想关闭feign自带的断路器,application.properties中添加
feign.hystrix.enabled=false

  既然已经自带hystrix,那pom.xml就不需要添加hystrix的支持了。细心的人在上一篇博文学习feign的时候,使用@FeignClient的时候,看@FeignClient的源码就会发现有个fallback支持。
  上篇博文已经有项目eureka-app-feign了,复制一份名称为eureka-app-feign-hystrix.

UserService.java
package com.fei.springcloud.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value="API-USER-SERVER",fallback=UserServiceErrorImpl.class)
public interface UserService {
@GetMapping(value="/user/find/{id}")
String find(@PathVariable("id") String id);
}
增加fallback的支持,UserServiceErrorImpl是UserService的实现类
package com.fei.springcloud.service;
import org.springframework.stereotype.Component;
@Component
public class UserServiceErrorImpl implements UserService{
@Override
public String find(String id) {
return "根据id查询用户,调用api提供者失败...";
}
}

application.properties
logging.config=classpath:logback.xml
logging.path=d:/logs
##tomcat set###
# eureka的默认端口是8761
server.port=7081
server.session-timeout=60
###########
spring.application.name=app-user
#像eureka服务注册信息时,使用ip地址,默认使用hostname
eureka.instance.preferIpAddress=true
# 续约更新时间间隔(默认30秒)
eureka.instance.lease-renewal-interval-in-seconds=30
# 续约到期时间(默认90秒)
eureka.instance.lease-expiration-duration-in-seconds=10
#服务的instance-id默认默认值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,
#也就是机器主机名:应用名称:应用端口
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
#eureka的服务地址
eureka.client.serviceUrl.defaultZone=http://01.server.eureka:8081/eureka/
#开启健康检查
eureka.client.healthcheck.enabled=true
#开启hystrix,默认是false,这个是必须的开放,否则会出现找不到消费者或者拒绝连接的错误
feign.hystrix.enabled=true
#ribbo负载均衡策略配置,默认是依次轮询
API-USER-SERVER.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#Hystrix是否启用超时时间
hystrix.command.default.execution.timeout.enabled=true;
#Hystrix断路器的超时时间,默认是1s
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
feign.hystrix.enabled=true这个默认是false,如果使用了hystrix,则必须配置为true,否则会出现找不到消费者就报错,或者拒绝连接等异常报错.


启动类Application.java也增加注解@EnableHystrix
启动eureka服务,启动eureka-app-feign-hystrix,暂时不启动api提供者。
访问http://127.0.0.1:7081/user/find,返回“根据id查询用户,调用api提供者失败...

Hystrix Dashboard

 上面学习了ribbon和feign的情况下使用hystrix对url的监控。现在学习下hystrix dashboard界面的查看。

pom.xml文件中,必须有

<!-- hystrix的支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!-- 健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- hystrix dashboard的支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
启动类加上@EnableHystrixDashboard,如
package com.fei.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //用于启动Fegin功能
@EnableHystrix
//增加hystrix断路器
@EnableHystrixDashboard
//支持hystrix dashboard
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

启动后,访问消费者app的ip+端口/hystrix,如http://127.0.0.1:7081/hystrix


图中的那几行英文
Cluster via Turbine (default cluster): http://turbine-hostname:port/turbine.stream
Cluster via Turbine (custom cluster): http://turbine-hostname:port/turbine.stream?cluster=[clusterName]
Single Hystrix App: http://hystrix-app:port/hystrix.stream

大概意思就是如果查看默认集群使用第一个url,查看指定集群使用第二个url,单个应用的监控使用最后一个,我们暂时只演示单个应用的所以在输入框中输入:
http://127.0.0.1:7081/hystrix.stream输入之后点击 monitor,进入页面。

发现都是loading...
这是因为还没有任何请求,如果我们访问http://127.0.0.1:7081/hystrix.stream,你会看到页面打印很多ping。
那我们先发起一个访问请求http://127.0.0.1:7081/user/find,然后再回到监控界面,就发现loading...没有了

由于没有启动api消费者,所以刚刚上面的请求其实是404,也就是失败Failure,所以看到1是红色的。
至于其他都是什么意思,可以看官网的Hystrix Dashboard Wiki


Turbine

   上面查看hystrix dashboard的时候,是直接访问单个app的hystrix dashboard的,那如果有很多个app消费者呢?总不能一一打开来看吧。为此,Netflix提供了一个开源项目(Turbine)来提供把多个hystrix.stream的内容聚合为一个数据源供Dashboard展示。

  使用sping boot搭建个hystrix-dashboard-turbine项目,用来收集各个app消费者的hystrix监控信息。
pom.xml
<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.fei.springcloud</groupId>
<artifactId>springcloud-eureka-hystrix-turbine</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>turbine收集显示各个hystrix的信息</description>
<!-- 依赖仓库 设置从aliyun仓库下载 -->
<repositories>
<repository>
<id>alimaven</id>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<!-- 插件依赖仓库 -->
<pluginRepositories>
<pluginRepository>
<id>alimaven</id>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
<properties>
<!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RELEASE</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>

配置文件application.properties
logging.config=classpath:logback.xml
logging.path=d:/logs
##tomcat set###
server.port=6081
server.session-timeout=60
###########
spring.application.name=hystrix-turebin
#配置Eureka中的serviceId列表,表明监控哪些服务,也就是app消费者的应用名称,多个时用英文逗号隔开
#turbine.appConfig=app-user-ribbon-hystrix,app-user-feign-hystrix
turbine.appConfig=APP-USER-RIBBON-HYSTRIX,APP-USER-FEIGN-HYSTRIX
turbine.aggregator.clusterConfig=default
turbine.clusterNameExpression=new String("default")
#像eureka服务注册信息时,使用ip地址,默认使用hostname
eureka.instance.preferIpAddress=true
#服务的instance-id默认默认值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,
#也就是机器主机名:应用名称:应用端口
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
#eureka的服务地址,/eureka是固定的
eureka.client.serviceUrl.defaultZone=http://01.server.eureka:8081/eureka/

我们上面学习的时候,已经有2个app消费者了eureka-app-ribbon-hystrix和eureka-app-feign-hystrix,修改他们的配置文件中的端口号和应用名称,比如eureka-app-ribbon-hystrix是7081,eureka-app-feign-hystrix是7082,

turbine的启动类Application.java
package com.fei.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@SpringBootApplication
@EnableHystrixDashboard
@EnableTurbine
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

将eureka-server服务,eureka-app-ribbon-hystrix,eureka-app-feign-hystrix,eureka-turbine都启动起来。访问eureka服务http://127.0.0.1:8081/,看到这样(由于配置文件里面配置了一些过期时间之类,可能显示不完整,多刷新几次页面)


为了防止监控界面出现loading...,先都调用下ribbon和feign的访问http://127.0.0.1:7081/user/find,http://127.0.0.1:7082/user/find,然后访问turbine的监控界面http://127.0.0.1:6081/hystrix,出现那小熊界面


 然后再输入框输入http://127.0.0.1:6081/turbine.stream,注意是turbine.stream,而不是hystrix.stream了,然后点击监控,看到出现2个监控列表了。


例子的完整源码


最后

以上就是霸气哈密瓜为你收集整理的springCloud学习02之断路器Hystrix-turbine监控-ribbo/feign对Hystrix的支持的全部内容,希望文章能够帮你解决springCloud学习02之断路器Hystrix-turbine监控-ribbo/feign对Hystrix的支持所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部