(二)Spring Cloud Finchley.SR4 增加Spring Boot Admin监控和Hystrix熔断与Turbine集群监控

版权声明:本文为博主原创文章,版权归烟台华东数据科技有限公司与博主本人共同所有。烟台华东数据科技有限公司及其下属机构毋须博主授权即可在任意用途下转载、使用!

目录

Environment

Spring Boot Admin简介

演示效果

Hystrix简介与使用、Turbine集群监控

Hystrix注意事项

1、单个方法配置Hystrix

2、对Feign进行熔断配置

题外话

集成Turbine集群监控

Turbine集群监控微服务

演示效果


Environment

  • Intellij Idea version : 2019.1.2
  • JavaSDK version : 1.8
  • Maven version : 3.6.1
  • Spring Cloud version : Finchley.SR4
  • SpringBoot version : 2.0.9.RELEASE
  • Spring Boot Admin 2.0.6

Spring Boot Admin简介

Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序。 应用程序作为Spring Boot Admin Client向为Spring Boot Admin Server注册(通过HTTP)或使用SpringCloud注册中心(例如Eureka,Consul)发现。 UI是的AngularJs应用程序,展示Spring Boot Admin Client的Actuator端点上的一些监控。常见的功能或者监控如下:

  • 显示健康状况
  • 显示详细信息,例如
    • JVM和内存指标
    • micrometer.io指标
    • 数据源指标
    • 缓存指标
  • 显示构建信息编号
  • 关注并下载日志文件
  • 查看jvm系统和环境属性
  • 查看Spring Boot配置属性
  • 支持Spring Cloud的postable / env-和/ refresh-endpoint
  • 轻松的日志级管理
  • 与JMX-beans交互
  • 查看线程转储
  • 查看http跟踪
  • 查看auditevents
  • 查看http-endpoints
  • 查看计划任务
  • 查看和删除活动会话(使用spring-session)
  • 查看Flyway / Liquibase数据库迁移
  • 下载heapdump
  • 状态变更通知(通过电子邮件,Slack,Hipchat,......)
  • 状态更改的事件日志(非持久性)

详细的学习与配置,本文不再介绍,可以参考以下博客:

SpringBoot Admin 2.0配置

Spring Boot Admin 详解(Spring Boot 2.0,基于 Eureka 的实现)

Spring Boot Admin使用及心跳检测原理

本文只把项目中需要注意的问题列明如下:

启动类:

package net.huadong;

import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableDiscoveryClient
@EnableAdminServer
@SpringBootApplication
public class HddSpringAdminApplication {

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

安全登录配置类:

package net.huadong;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

/**
 * @author yangzj
 * @desc Security配置类,用于配置admin server的安全控制
 * @create 2019-06-30 15:16
 **/
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {

    private final String adminContextPath;

    public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
        this.adminContextPath = adminServerProperties.getContextPath();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 登录成功处理类
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(adminContextPath + "/");

        http.authorizeRequests()
                //静态文件允许访问
                .antMatchers(adminContextPath + "/assets/**").permitAll()
                //登录页面允许访问
                .antMatchers(adminContextPath + "/login").permitAll()
                //其他所有请求需要登录
                .anyRequest().authenticated()
                .and()
                //登录页面配置,用于替换security默认页面
                .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
                //登出页面配置,用于替换security默认页面
                .logout().logoutUrl(adminContextPath + "/logout").and()
                .httpBasic().and()
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .ignoringAntMatchers(
                        "/instances",
                        "/actuator/**"
                );
    }

}

bootstrap.yml 在这里配置的账号密码,详细说明解释请查看上面推荐的博客或者文档

spring:
  application:
    name: springAdmin
  cloud:
    config:
      enabled: true
      discovery:
        enabled: true
        service-id: config #1
  security:
    user:
      name: 'hdd'
      password: 'ok'
eureka:
  instance:
    non-secure-port: ${server.port:8110}
    health-check-url-path: /actuator/health
    metadata-map:
      instanceId: ${spring.application.name}:${random.value} #4
      user.name: ${spring.security.user.name}
      user.password: ${spring.security.user.password}
  client:
    service-url:
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8101}/eureka/

pom文件:

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>2.0.6</version>
		</dependency>
		<dependency>
			<groupId>org.jolokia</groupId>
			<artifactId>jolokia-core</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-security</artifactId>
        </dependency>
	</dependencies>

但是照这样开启后,会发现并不能正常监控,原因是从Spring Boot 2.0开始 Actuator 只暴露了 /health、/info 两个端口(为了安全考虑),所以要配置 management.endpoints.web.exposure.include 的属性,下面的配置文件中直接暴露了所有的端点,详细的端点介绍配置,可以查看官方文档。

或者可以参考此博文:一起来学SpringBoot | 第十四篇:强大的 actuator 服务监控与管理

此处我们给上一篇博文提到的RedisService暴露端口

HDD_REDIS_SERVICE中的application.yml文件:

server:
  port: 8889
logging:
  config: classpath:logback.xml
  level:
    org.springframework: error
debug: false

#actuator  启用所有的监控端点 “*”号代表启用所有的监控端点,可以单独启用,例如,health,info,metrics
#  spring boot 升为 2.0 后,为了安全,默认 Actuator 只暴露了2个端点,heath 和 info,继续
# 访问  http://localhost:8889/actuator/metrics
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

演示效果

访问http://localhost:8110 会自动跳转到登录界面

登录后,显示各个已经注册的微服务模块:

选择一个微服务模块后进去,会有详细的描述界面

在Web——HTTP Traces中有详细的访问描述

Hystrix简介与使用、Turbine集群监控

在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。

有关Hystrix的介绍网上面有很多,此处不再赘述,Hystrix的简介、原理、实现的目的可以参考如下资料:

Hystrix介绍

详细的熔断使用开发介绍

SpringBoot集成Hystrix

Hystrix注意事项

经过上面的资料介绍,Hystrix的熔断有两种配置模式:

  1. 直接配置在Controller方法中,并且针对每一个需要实现熔断处理的方法实现一个对应的熔断处理方法
  2. 针对提供Service服务的Feign进行熔断监控

而我们项目里面是两种模式都有可能使用,网上面很多资料都没有详细描述这两种模式的区别,我在这里分开描述一下各自的用法和说明

1、单个方法配置Hystrix

如在HDD_REDIS_SERVICE的Controller中

    @ApiOperation(value = "设置redis缓存值", notes = "设置redis缓存值")
    @RequestMapping(value = "/setRedis", method = RequestMethod.POST)
    @HystrixCommand(fallbackMethod = "setRedisFall")
    void setRedis(@RequestBody Map<String, Object> map) {
        String key = (String) map.get("key");
        Object obj = map.get("value");
        redisService.set(key, obj);
    }

    void setRedisFall(Map<String, Object> map) {
        logger.error("RedisService setRedis Failed!");
    }

很简单的设置,这种一般是正针对于微服务内部的错误,比如底层的数据库出问题了或者SpringMVC中的redisService层报错了,从而进行的熔断处理。

2、对Feign进行熔断配置

在HDD_REDIS_SERVICE_INTERFACE中

RedisService

package net.huadong.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@FeignClient(name = "redisService", fallbackFactory = RedisServiceFallback.class)
@Component
public interface RedisService {

    /**
     * 根据传入的map(key,value)值设置redis
     *
     * @param map
     * @return
     */
    @RequestMapping(value = "/Redis/setRedis", method = RequestMethod.POST)
    void set(@RequestBody Map<String, Object> map);

    /**
     * 传入key获取对应的redis 值
     *
     * @return obj
     */
    @RequestMapping(value = "/Redis/getRedis", method = RequestMethod.POST)
    @ResponseBody
    Object get(@RequestParam("key") String key);

}

RedisServiceFallback

package net.huadong.service;

import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

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

/**
 * @author yangzj
 * @desc 熔断降级方法
 * @create 2019-06-30 17:12
 **/
@Component
public class RedisServiceFallback implements FallbackFactory<RedisService> {

    @Override
    public RedisService create(Throwable throwable) {
        throwable.printStackTrace();
        return new RedisService() {
            @Override
            public void set(Map<String, Object> map) {
                System.out.println(throwable.getMessage());
            }

            @Override
            public Object get(String key) {
                return throwable.getMessage();
            }
        };
    }
}

这个与方法1最大的区别是,这个是在调用方进行熔断控制,比如其他项目A使用这个INTERFACE接口调用Redis的微服务,出现了问题,可能是网络问题、接口不可访问等,熔断的控制其实是在项目A中进行的。而方法1中的熔断控制是直接在微服务中控制的。

当然网络上有的人其实是把这两个混在一起了,Redis的微服务既是单独的服务实例,同时提供对外的Feign连接,或者不提供Feign,直接需要其他项目使用Rest的方式进行访问。个人觉得远不及使用Feign方便,直接隐藏了下一层的网络处理代码。

pom文件:

方法1中需要引用:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

方法2中不需要额外引用,只要引用了Feign即可,如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

题外话

Hystrix已经于2018年年末官方正式宣布不再开发,但是还是会持续维护一段时间。当前还是可以继续使用的。

替代品官方推荐使用Resilience4J

或者使用Alibaba Sentinel


集成Turbine集群监控

上面提到的Hystrix只是针对单个方法的情况或者单个Service,而在实际的生成环境中,都是大范围的集群。

Turbine是聚合服务器发送事件流数据的一个工具,Hystrix的监控中,只能监控单个节点,实际生产中都为集群,因此可以通过Turbine来监控集群下Hystrix的metrics情况。

例如,我们在上一篇说的HDD_REDIS_SERVICE增加集群监控示例

pom引用

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>

启动类:

package net.huadong;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;

@EnableEurekaClient
@SpringBootApplication
@EnableCircuitBreaker
@EnableHystrixDashboard
@EnableTurbine
public class HddRedisServiceApplication {

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

最后关键的一步:application.yml

server:
  port: 8889
logging:
  config: classpath:logback.xml
  level:
    org.springframework: error
debug: false
eureka:
  client:
    healthcheck:
      enabled: true
feign:
  hystrix:
    enabled: true
hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 30000
#actuator  启用所有的监控端点 “*”号代表启用所有的监控端点,可以单独启用,例如,health,info,metrics
#  spring boot 升为 2.0 后,为了安全,默认 Actuator 只暴露了2个端点,heath 和 info,继续
# 访问  http://localhost:8889/actuator/metrics
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

一定要在配置中开启Hystrix的控制。

综合以上,要实现Turbine集群监控,第一步就是微服务中要实现了Hystrix,然后启动类上增加了相应注解,然后在application.yml配置文件中进行了相应配置。

Turbine集群监控微服务

启动类

package net.huadong;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;

/**
 * 断路器监控
 */
@SpringBootApplication
@EnableEurekaClient
@EnableHystrixDashboard
@EnableTurbine
public class HddBreakMonitorApplication {

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

bootstrap.yml

spring:
  application:
    name: monitor

eureka:
  instance:
    nonSecurePort: ${server.port:8989}
    lease-renewal-interval-in-seconds: 20
    lease-expiration-duration-in-seconds: 30
  client:
    serviceUrl:
      defaultZone: http://${eureka.host:localhost}:${eureka.port:8101}/eureka/

turbine:
  combine-host-port: true
  app-config: redisService
  cluster-name-expression: new String("default")
  aggregator:
    cluster-config: default
  #更改turbine连接的默认uri ,默认为actuator/hystrix.stream
  instanceUrlSuffix: actuator/hystrix.stream

其中有一个关键的turbine.app-config配置,这里配置的就是需要监控哪一个Service

pom文件

    <parent>
        <artifactId>HDD_SHJJHY_PLATFORM</artifactId>
        <groupId>net.huadong</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>HDD_BREAK_MONITOR</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>HDD_BREAK_MONITOR</name>
    <description>EUREKA的熔断器和监控器</description>

	<properties>
		<start-class>net.huadong.HddBreakMonitorApplication</start-class>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
		</dependency>
	</dependencies>

演示效果

启动监控微服务后,进入地址:http://localhost:8989/hystrix

在这里输入监控地址:http://localhost:8989/turbine.stream

进入后,刚开始很多人也许会显示Loading...

出现Loading的原因很多,我初步总结如下:

  • app-config中设置的Service并没有使用方法1或者方法2的Hystrix
  • 没有暴露端口
  • 需要监控的微服务中没有加上相应的注解或者相关引用
  • 启动后,需要有数据流转起来才能监控,一般是项目刚启动后,没有对相关配置了熔断的方法进行了调用
  • 参考资料:https://www.cnblogs.com/houzheng/p/9906800.html

成功后的效果如下:

一个监控的方法就会出现一个监控,相关数据项目的解释说明请查看以下博文资料:

Spring Cloud Turbine(集群监控)

 

下一章,如何让其他非Spring Cloud项目使用微服务

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值