大家好,我是苍何。

在脉脉上看到这条帖子,说阿里 P8 因为上面 P9 斗争失败走人,以超龄 35 被裁,Boss 上找工作半年,到现在还处于失业中。

微服务如何做好监控_JVM

看了下沟通记录, 沟通了 1000 多次,但没有一个邀请投递简历的,大受震撼。因为早年在阿里待过,所以对阿里 P8 这个 title 的含金量还是知道的,先不说是很高 P,但能升到 P8 这个段位的,多少还是有点能力的。

当然了无论是做 PPT 的能力还是处理问题的能力,最起码都属于一种区别于普通人的能力嘛。按理说这个级别出来工作应该是随便找,不至于找半年没找到一份工作。

于是有网友认为,有点儿扯,说到了 P8 这个级别不应该会因为上级的派系斗争被搞走,而且对其艰难找工作不大相信。

微服务如何做好监控_云原生_02

但也有人从这件事上分析原因觉得,因为这个 P8 处于 35 岁年龄高危人群,是个传话筒,薪酬高,竞争力有待考证。

微服务如何做好监控_spring_03

抛去别的不说,我觉得不至于没有一个公司给他发简历投递邀请,但这件事我觉得从侧面反映出一个问题,那就是以前互联网那套玩法行不通了,即使在大厂,该被裁还是得被裁,出来后,能接住这么高的工资的公司除了另外一个大厂基本没有,小公司和国企是很难给到他们原先在大厂工资的。

我跟很多大厂的朋友经常聊天,谈起裁员这个话题,虽说他们对现在的环境愤愤不平,但又无能为力。但我经常和他们分享我自己的观点:不管在哪儿,一定要有自己的一点小生意

在大厂可能负责的是一个大平台里面的一小处螺丝,然后就自以为创造了很多的价值,加班加点的 coding,最后甚至连平台到底吸引什么样的用户?市场在哪里?ARR 表现如何?实际带来什么样的价值都没搞明白就稀里糊涂的被裁了。

建立自己的小生意,业余时间做一点点小而美的事情,不仅仅限于 coding,从市场、营销、产品等多角度来思考这个小生意创造的价值。

我也一直在践行这个理念,包括最近业余时间投身的开源项目,也是属于小而美的事情。而且我也会持续做这方面的分享,build in public,一起成长。

今天分享的是微服务改造过程中,监控中心的搭建要领和流程。

什么是服务监控

服务监控概念

在说概念前,其实可以借助一下生活中的一个例子来理解:

想象你是一位餐馆经理。你的餐馆里有很多员工在不同岗位工作:厨师在做饭,服务员在端菜,收银员在结账。如果你想让餐馆顺利运营,你需要知道每个员工的工作状态。如果某个岗位出现问题,比如厨师突然生病了,你需要及时知道并做出调整,以确保餐馆正常运作,不会影响顾客体验。

微服务如何做好监控_spring_04

服务监控就像是餐馆经理对员工工作状态的监视。它包括以下几个方面:

  1. 系统应用状态: 就像经理需要知道每个员工在做什么,服务监控需要知道每个系统应用在做什么,是否正常运行。
  2. 内存和线程: 就像餐馆需要确保有足够的食材和员工,系统也需要足够的内存和线程来处理任务。监控这些可以确保系统不会因为资源不足而崩溃。
  3. 堆栈: 就像经理需要知道每道菜的制作流程,监控堆栈信息可以帮助了解程序的执行流程,找出哪里出了问题。
  4. 日志: 就像经理需要记录每天的销售和反馈,系统日志记录了所有的操作和错误信息,方便追踪和排查问题。

服务监控的主要目的是在问题发生或即将发生时,能准确快速地发现问题,从而减小影响范围。就像餐馆经理能及时发现并处理员工的问题,以避免影响整个餐馆的运营。

服务监控在微服务改造过程中的重要性不言而喻,没有强大的监控能力,改造成微服务架构后,就无法掌控各个不同服务的情况,在遇到调用失败时,如果不能快速发现系统的问题,对于业务来说就是一场灾难。

服务常用技术栈

1、Spring Boot Actuator

Spring Boot Actuator 提供了一系列内置的端点,用于监控和管理 Spring Boot 应用程序。它可以暴露健康检查、应用信息、环境变量、JVM 指标、HTTP 请求追踪等。

适用于使用 Spring Boot 构建的微服务应用,集成简单,功能强大。

以下是一些常见端点:

地址

描述

/beans

显示所有的Spring bean列表

/caches

显示所有的缓存相关信息

/scheduledtasks

显示所有的定时任务相关信息

/loggers

显示所有的日志相关信息

/configprops

显示所有的配置信息

/env

显示所有的环境变量信息

/mappings

显示所有控制器相关信息

/info

显示自定义用户信息配置

/metrics

显示应用指标相关信息

/health

显示健康检查状态信息,up表示成功 down表示失败

/threaddump

显示程序线程的信息

2、Micrometer

Micrometer 是一个用于 JVM 应用程序的应用指标度量库。它提供与多种监控系统的集成,如 Prometheus、Graphite、JMX、New Relic、Datadog 等。需要在 Spring Boot 之外的 JVM 应用中进行指标监控,或者需要集成到多种监控系统中。优势是其有统一的 API,便于扩展和集成。

3、Dropwizard Metrics

Dropwizard Metrics 提供了一组用于度量 JVM 应用程序性能的工具,包括计数器、计时器、仪表等。它可以与多种后端系统集成,如 Graphite、Ganglia、Prometheus 等。需要在非 Spring Boot 应用中实现详细的性能度量。优势:轻量级,易于集成,功能全面。

如何做好监控

我本次使用的是利用 Spring Boot Actuator 配合 Admin-Ui,整合 Nacos,来做的各个微服务的系统监控。以下是具体的步骤:

新建监控中心微服务

监控中心一定是单独部署的一个微服务,不要和其他微服务做藕和,其中建微服务系统其实就是 4 步:

  • 建 Module
  • 改 pom
  • 加 yml
  • 启动类启动

在 idea 中右键项目新建 Module 命名 monitor,建监控中心微服务:

微服务如何做好监控_微服务_05

一个微服务就建好了,接下来需要添加必要的依赖和配置。

添加依赖

因为需要整合 Nacos,以及配合 web ui 和登录认证,故引入以下 jar:

<dependencies>

  <!-- SpringBoot Admin -->
  <dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
    <version>${spring-boot-admin.version}</version>
  </dependency>

  <!-- SpringCloud Alibaba Nacos -->
  <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  </dependency>

  <!-- SpringCloud Alibaba Nacos Config -->
  <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  </dependency>

  <!-- Spring Cloud Config Client,用于配置的动态刷新 -->
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
  </dependency>

  <!-- SpringCloud Alibaba Sentinel -->
  <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  </dependency>

  <!-- SpringBoot Web -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <!-- Spring Security -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
  </dependency>

</dependencies>

添加配置

配置有独立服务配置和 Nacos 共享配置以及微服务 Nacos 配置,三份配置共同作用于微服务系统,其中优先级顺序是Nacos 共享配置>微服务 Nacos 配置>独立服务配置

对于每个微服务都需要的配置放在共享配置中,本次这部分不做改动,另外是微服务的 Nacos 配置和本地配置如下:

本地配置:bootstrap.yml

# Tomcat
server:
  port: 端口

# Spring
spring: 
  application:
    # 应用名称
    name: monitor
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:端口
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:端口
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

Nacos 配置:monitor-dev.yml

# spring
spring:
  security:
    user:
      name: web页面中的用户名
      password: 密码
  boot:
    admin:
      ui:
        title: 服务状态监控

通过以上步骤直接访问微服务地址即可直接访问,这里监控中心的微服务没有直接走网关,而是直接暴露出来,因为其内部自己做了鉴权处理,就不走网关通用鉴权了。

监控有用功能

web ui 页面

在 UI 页面上可以清晰的看出服务系统的情况,方便直观,而且耦合性比较低。以下是我项目的监控情况:

微服务如何做好监控_微服务_06

点进去每一个微服务可看到具体监控信息:

微服务如何做好监控_微服务_07

登录认证

配合 admin,加上 Spring security 权限控制,我们只需要按照步骤配置一下账户和密码即可。权限配置类:

/**
 * 监控权限配置
 * 
 * @author ruoyi
 */
@EnableWebSecurity
public class WebSecurityConfigurer
{
    private final String adminContextPath;

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

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
    {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(adminContextPath + "/");

        return httpSecurity
        .headers().frameOptions().disable()
        .and().authorizeRequests()
        .antMatchers(adminContextPath + "/assets/**"
                     , adminContextPath + "/login"
                     , adminContextPath + "/actuator/**"
                     , adminContextPath + "/instances/**"
                    ).permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin().loginPage(adminContextPath + "/login")
        .successHandler(successHandler).and()
        .logout().logoutUrl(adminContextPath + "/logout")
        .and()
        .httpBasic().and()
        .csrf()
        .disable()
        .build();
    }
}

这样,每次登录 UI 页面就需要进行账号密码登录鉴权,其走的不是网关统一鉴权所以需要单独配置。

实时日志

Spring Boot Admin提供了基于Web页面的方式实时查看服务输出的本地日志,前提是服务中配置了logging.file.name。

需要在单个微服务的 bootstrap.yml配置logging.file.name配置:

logging:
  file:
    name: logs/${spring.application.name}/info.log

微服务如何做好监控_JVM_08

对于单独差某个微服务信息来说,实时日志还是挺方便的。

监控通知

当微服务监控检查没通过,或者服务上线、离线或者服务发生未知异常,希望发送通知到制定的人,就可以直接通过如下配置即可:

/**
 * @author canghe
 * @description 通知发送配置
 * @create 2024-05-16-17:32
 */
@Component
public class PmHubStatusChangeNotifier extends AbstractStatusChangeNotifier {
    public PmHubStatusChangeNotifier(InstanceRepository repository) {
        super(repository);
    }

    @Override
    protected Mono<Void> doNotify(InstanceEvent event,
                                  de.codecentric.boot.admin.server.domain.entities.Instance instance) {
        return Mono.fromRunnable(() -> {
            if (event instanceof InstanceStatusChangedEvent) {
                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();
                switch (status) {
                    // 健康检查没通过
                    case "DOWN":
                        System.out.println("发送 健康检查没通过 的通知!");
                        break;
                    // 服务离线
                    case "OFFLINE":
                        System.out.println("发送 服务离线 的通知!");
                        break;
                    // 服务上线
                    case "UP":
                        System.out.println("发送 服务上线 的通知!");
                        break;
                    // 服务未知异常
                    case "UNKNOWN":
                        System.out.println("发送 服务未知异常 的通知!");
                        break;
                    default:
                        break;
                }
            }
        });
    }
}

通过以上步骤,微服务系统中的服务监控就简单集成了,对于监控中的业务逻辑,比如通知消息等就可以自己去实现他。

以上是今天的分享,感谢您的阅读!