在之前的18次文章中,我们实现了广告系统的广告投放广告检索业务功能,中间使用到了 服务发现Eureka服务调用Feign,网关路由Zuul以及错误熔断HystrixSpring Cloud组件。

简单调用关系:

但是系统往往都会报错,我们之前定义了一些容错类和方法,但是只是在控制台可以看到错误信息,我们想要统计一些数据,怎么才能更直观的看到我们的服务调用情况呢,接下来,和大家讨论一个新的熔断监控组件Hystrix Dashboard,顾名思义,从名字上我们就能看出来,它是监控的图形化界面。

Hystrix 在服务中的使用

结合openfeign使用

在我们实际的项目当中,使用的最多的就是结合FeignClient#fallbackHystrix一起来实现熔断,我们看一下我们在mscx-ad-feign-sdk中的实现。

@FeignClient(value = "mscx-ad-sponsor", fallback = SponsorClientHystrix.class)
public interface ISponsorFeignClient {
@RequestMapping(value = "/ad-sponsor/plan/get", method = RequestMethod.POST)
CommonResponse<List<AdPlanVO>> getAdPlansUseFeign(@RequestBody AdPlanGetRequestVO requestVO); @RequestMapping(value = "/ad-sponsor/user/get", method = RequestMethod.GET)
/**
* Feign 埋坑之 如果是Get请求,必须在所有参数前添加{@link RequestParam},不能使用{@link Param}
* 会被自动转发为POST请求。
*/
CommonResponse getUsers(@RequestParam(value = "username") String username);
}

在上述代码中,我们自定义了一个feignclient,并且给了这个client一个fallback的实现类:

@Component
public class SponsorClientHystrix implements ISponsorFeignClient {
@Override
public CommonResponse<List<AdPlanVO>> getAdPlansUseFeign(AdPlanGetRequestVO requestVO) {
return new CommonResponse<>(-1, "mscx-ad-sponsor feign & hystrix get plan error.");
} @Override
public CommonResponse getUsers(String username) {
return new CommonResponse<>(-1, "mscx-ad-sponsor feign & hystrix get user error.");
}
}

这个fallback类实现了我们自定义的ISponsorFeignClient,那是因为fallback的方法必须和原始执行类的方法签名保持一致,这样在执行失败的时候,可以通过反射映射到响应的降级方法/容错方法。

mscx-ad-search服务中,我们通过注入ISponsorFeignClient来调用我们的mscz-ad-sponsor服务。

@RestController
@Slf4j
@RequestMapping(path = "/search-feign")
public class SearchFeignController { /**
* 注入我们自定义的FeignClient
*/
private final ISponsorFeignClient sponsorFeignClient;
@Autowired
public SearchFeignController(ISponsorFeignClient sponsorFeignClient) {
this.sponsorFeignClient = sponsorFeignClient;
} @GetMapping(path = "/user/get")
public CommonResponse getUsers(@Param(value = "username") String username) {
log.info("ad-search::getUsersFeign -> {}", JSON.toJSONString(username));
CommonResponse commonResponse = sponsorFeignClient.getUsers(username);
return commonResponse;
}
}
使用HystrixCommand

其实Hystrix本身提供了一种直接在方法中应用的方式,就是使用@ com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand,我们看一下这个类的源码:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HystrixCommand {
... /**
* Specifies a method to process fallback logic.
* A fallback method should be defined in the same class where is HystrixCommand.
* Also a fallback method should have same signature to a method which was invoked as hystrix command.
* for example:
* <code>
* @HystrixCommand(fallbackMethod = "getByIdFallback")
* public String getById(String id) {...}
*
* private String getByIdFallback(String id) {...}
* </code>
* Also a fallback method can be annotated with {@link HystrixCommand}
* <p/>
* default => see {@link com.netflix.hystrix.contrib.javanica.command.GenericCommand#getFallback()}
*
* @return method name
*/
String fallbackMethod() default ""; ...
}

我们主要关注2个点:

  1. @Target({ElementType.METHOD})表明当前的注解只能应用在方法上面。
  2. 可直接定义fallbackMethod来保证容错。这个方法有一个缺陷,就是必须和执行方法在同一个类文件中,这就会造成我们的方法在实现的时候,显得特别的冗余和不够优雅。

以我们的mscx-ad-search中的广告查询为例:

@Service
@Slf4j
public class SearchImpl implements ISearch { /**
* 查询广告容错方法
*
* @param e 第二个参数可以不指定,如果需要跟踪错误,就指定上
* @return 返回一个空map 对象
*/
public SearchResponse fetchAdsFallback(SearchRequest request, Throwable e) { System.out.println("查询广告失败,进入容错降级 : %s" + e.getMessage());
return new SearchResponse().builder().adSlotRelationAds(Collections.emptyMap()).build();
} @HystrixCommand(fallbackMethod = "fetchAdsFallback")
@Override
public SearchResponse fetchAds(SearchRequest request) {
...
}
}

在我们请求出错的时候,会转到我们的fallback方法,这个实现是通过在应用启动的时候,我们开始了@EnableCircuitBreaker注解,这个注解会通过AOP拦截所有的HystrixCommand方法,将HystrixCommand整合到springboot的容器中,并且将注解标注的方法放入hystrix的线程中,一旦失败,通过反射调用fallback方法来实现。

创建dashboard project

上述代码我们看了Hystrix实现熔断的2种方式,接下来我们来实现请求监控的图形化界面,创建mscx-ad-dashboard,Let's code.

依然遵从我们springboot项目的三部曲:

  1. 加依赖

    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.2.7.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    <version>1.2.7.RELEASE</version>
    </dependency>
    <!--eureka client-->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    </dependencies>
  2. 加注解

    /**
    * AdDashboardApplication for Hystrix Dashboard 启动类
    *
    * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
    * @since 2019/8/15
    */
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableHystrixDashboard
    public class AdDashboardApplication { public static void main(String[] args) {
    SpringApplication.run(AdDashboardApplication.class, args);
    }
    }
  3. 改配置

        server:
    port: 1234
    spring:
    application:
    name: mscx-ad-dashboard
    eureka:
    client:
    service-url:
    defaultZone: http://server1:7777/eureka/,http://server2:8888/eureka/,http://server3:9999/eureka/
    management:
    endpoints:
    web:
    exposure:
    include: "*"`

直接启动,可以看到如下页面:

添加要监控的服务地址:

[Spring cloud 一步步实现广告系统] 19. 监控Hystrix Dashboard的更多相关文章

  1. [Spring cloud 一步步实现广告系统] 21. 系统错误汇总

    广告系统学习过程中问题答疑 博客园 Eureka集群启动报错 Answer 因为Eureka在集群启动过程中,会连接集群中其他的机器进行数据同步,在这个过程中,如果别的服务还没有启动完成,就会出现Co ...

  2. [Spring cloud 一步步实现广告系统] 2. 配置&Eureka服务

    父项目管理 首先,我们在创建投放系统之前,先看一下我们的工程结构: mscx-ad-sponsor就是我们的广告投放系统.如上结构,我们需要首先创建一个Parent Project mscx-ad 来 ...

  3. [Spring cloud 一步步实现广告系统] 22. 广告系统回顾总结

    到目前为止,我们整个初级广告检索系统就初步开发完成了,我们来整体回顾一下我们的广告系统. 整个广告系统编码结构如下: mscx-ad 父模块 主要是为了方便我们项目的统一管理 mscx-ad-db 这 ...

  4. [Spring cloud 一步步实现广告系统] 7. 中期总结回顾

    在前面的过程中,我们创建了4个project: 服务发现 我们使用Eureka 作为服务发现组件,学习了Eureka Server,Eureka Client的使用. Eureka Server 加依 ...

  5. [Spring cloud 一步步实现广告系统] 1. 业务架构分析

    什么是广告系统? 主要包含: 广告主投放广告的<广告投放系统> 媒体方(广告展示媒介-)检索广告用的<广告检索系统> 广告计费系统(按次,曝光量等等) 报表系统 Etc. 使用 ...

  6. [Spring cloud 一步步实现广告系统] 13. 索引服务编码实现

    上一节我们分析了广告索引的维护有2种,全量索引加载和增量索引维护.因为广告检索是广告系统中最为重要的环节,大家一定要认真理解我们索引设计的思路,接下来我们来编码实现索引维护功能. 我们来定义一个接口, ...

  7. [Spring cloud 一步步实现广告系统] 12. 广告索引介绍

    索引设计介绍 在我们广告系统中,为了我们能更快的拿到我们想要的广告数据,我们需要对广告数据添加类似于数据库index一样的索引结构,分两大类:正向索引和倒排索引. 正向索引 通过唯一键/主键生成与对象 ...

  8. [Spring cloud 一步步实现广告系统] 11. 使用Feign实现微服务调用

    上一节我们使用了Ribbon(基于Http/Tcp)进行微服务的调用,Ribbon的调用比较简单,通过Ribbon组件对请求的服务进行拦截,通过Eureka Server 获取到服务实例的IP:Por ...

  9. [Spring cloud 一步步实现广告系统] 6. Service实现&Zuul配置&Test

    DAO层设计实现 这里我们使用Spring DATA JPA来实现数据库操作,当然大家也可以使用Mybatis,都是一样的,我们依然以用户表操作为例: /** * AdUserRepository f ...

随机推荐

  1. SQL Server 函数的定义及使用

    一.定义函数 1. 标量值函数: 返回一个确定类型的标量值,例如:int,char,bit等 --创建标量值函数 create function func_1(@func_parameter_1 in ...

  2. Python解题技巧

    Python解题技巧 一直都是用C++和C解题,某题简单解完后便心血来潮想用Python解一次,发现一些问题,特写此篇随笔来记录. 一. 输入格式: 例:输入第1行给出正整数n和整数m:第2行给出n个 ...

  3. I/O:ByteBuffer

    ByteBuffer: static ByteBuffer allocate(int capacity) :分配一个新的字节缓冲区. static ByteBuffer allocateDirect( ...

  4. Spring Boot2(十四):单文件上传/下载,文件批量上传

    文件上传和下载在项目中经常用到,这里主要学习SpringBoot完成单个文件上传/下载,批量文件上传的场景应用.结合mysql数据库.jpa数据层操作.thymeleaf页面模板. 一.准备 添加ma ...

  5. 洛谷P3905 道路重建

    题目:https://www.luogu.org/problemnew/show/P3905 分析: 此题是显然的最短路算法,只是看到一起删掉的一堆边感到十分棘手,而且还要求出的是最短添加边的总长度 ...

  6. JAVA面试题 线程的生命周期包括哪几个阶段?

    面试官:您知道线程的生命周期包括哪几个阶段? 应聘者: 线程的生命周期包含5个阶段,包括:新建.就绪.运行.阻塞.销毁. 新建:就是刚使用new方法,new出来的线程: 就绪:就是调用的线程的star ...

  7. spark 源码分析之十八 -- Spark存储体系剖析

    本篇文章主要剖析BlockManager相关的类以及总结Spark底层存储体系. 总述 先看 BlockManager相关类之间的关系如下: 我们从NettyRpcEnv 开始,做一下简单说明. Ne ...

  8. 线程锁,threadinglocal,线程池,生产者消费者模型

    1.线程锁 1.锁Lock(只能锁一次) import threading import time v = [] lock = threading.Lock() def func(arg): lock ...

  9. lnmp php使用命令行去备份数据库

    <?php //备份数据库we8和foshan $time = date("Y-m-d",time()); $backtime = date("Y-m-d" ...

  10. webstorm mac 版破解

    一.打开终端,输入: sudo vim /etc/hosts 回车后输入密码,编辑 hosts 文件,如图: 二.进入编辑模式(按 i 键),在最后一行添加如下代码: 0.0.0.0 account. ...