服务监控平台:SpringBoot Admin入门应用

前言

在日常工作中,我们需要有一款监控平台来帮助我们管理服务,监控服务是否宕机、服务运行指标(内存、虚拟机、线程、请求等)、监控日志、管理服务(服务下线)等,SpringBoot Admin作为一款开源的监控平台,开发对接方便,只需要配置好服务和监控信息,定时拉取即可。其github地址为https://github.com/topics/spring-boot-admin

SpringBoot Admin简单使用

首先,创建我们的监控服务端,注意,spring-boot-admin-starter-server的版本和spring-boot-starter的版本要一致,引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.5.4</version>
</dependency>
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
    <version>2.5.4</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.5.4</version>
</dependency>

在启动类上添加@EnableAdminServer注解,启动,访问localhost:8080
在这里插入图片描述
接下来,创建一个被监控服务,这里,需要引入的就是client,引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.5.4</version>
</dependency>
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.5.4</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.5.4</version>
</dependency>

接着,在配置文件配置服务端地址,表示客户端可被监控并启动客户端

spring.boot.admin.client.url=http://localhost:8080

在这里插入图片描述
可以看到,监控平台上注册了一个客户端服务,点击可以查看详情,然后我们配置默认的health配置,因为health默认开启,所以只需要配置详细信息展示即可,添加配置management.endpoint.health.show-details=always
在这里插入图片描述
当然,除了健康信息外,还有其他很多指标,我们添加配置开启所有监控项

##默认health,*代表所有,开放的监控信息
management.endpoints.web.exposure.include=*
##注意,如果是yml配置文件,*值需要用单引号或双引号标记,"*"或'*'

在这里插入图片描述
从上图可以看到,我么你可以健康服务的性能、jvm、缓存等多种信息

端点actuator

在映射中,有很多请求,大部分由/actuator开头,我们访问localhost:8081/actuator可以获取数据,注意,这里是监控的服务,不是监控本身,返回的是一系列端点路径
在这里插入图片描述
actuator提供了springboot生产就绪功能,通过端点的配置与访问,获取端点信息,端点描述了一组监控信息,SpringBoot提供了多个内置端点,也可以自定义端点(监控原理),访问当前应用所有端点信息:/actuator,访问端点详细信息:/actuator/端点名称
在这里插入图片描述
在应用程序启动日志可以看到,开放了13个端点,而上面我们配置中*号是web端展示的端点(对外暴露),实际端点是否开放,是由management.endpoint.xxx.enable决定的,例如

#关闭信息端点
management.endpoint.info.enabled=false

注意,对于health属性,enable必须为true,默认开放

日志

监控控制台还可以查看服务日志,我们先配置好服务端的日志配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--<include resource="org/springframework/boot/logging/logback/defaults.xml" />-->
    <contextName>logback</contextName>
    <property name="log.path" value="./logs/my.log"/>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
            </pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    </root>
</configuration>

新建一个测试方法,主要打印各种级别的日志信息

@RequestMapping("/log")
public void log(){
    logger.info("我是info级别日志===========");
    logger.warn("我是warn级别日志===========");
    logger.error("我是error级别日志=========");
}

然后,最重要的是,在配置文件开启日志,并配置好日志的路径

#日志
management.endpoint.logfile.enabled=true
management.endpoint.logfile.external-file=D:/project/springboot_service/logs/my.log

启动项目,调用接口http://localhost:8081/test/log可以在控制台的日志栏看到我们配置的日志,先看日志文件
在这里插入图片描述
在下面还有一个日志配置,点进去可以发现,是针对日志级别和对应类的配置,最上面可以管理所有类的日志打印级别,下面也可以分别设置单独的类的级别,我们将所有日志改成error,再查看日志
在这里插入图片描述
再次请求接口,查看日志,发现只有error级别的日志,其他日志不显示
在这里插入图片描述

自定义端点

1、info端点

自定义信息,例如配置文件添加info.author=zy info.desc=spring_boot_admin_test,可以看到监控控制台如下
在这里插入图片描述
当然,这些只是基本的静态信息,那么如何获取动态信息呢?
我们定义一个InfoConfig,实现InfoContributor接口,重写contribute方法,通过builder.withDetails或builder.withDetail构建想要动态获取的信息,每次刷新,信息动态变化

package org.example.actuator;

import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class InfoConfig implements InfoContributor {
    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    @Override
    public void contribute(Info.Builder builder) {
        Map map = new HashMap();
        map.put("runTime",sdf.format(new Date()));
        builder.withDetails(map);
    }
}

在这里插入图片描述

2、health端点

首先要说明,health端点不能同上配置文件操作,我们可以添加pom文件中中间件,例如redis,控制台
在这里插入图片描述
当然,也支持自定义,方式同上,继承AbstractHealthIndicator类,实现doHealthCheck方法,builder有三个方法去自定义,支持多个状态信息up、down、unknown等,也可以通过builder.status(xxx)设置,通过这个可以自定义监控组件信息
在这里插入图片描述

package org.example.actuator;

import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;

@Component
public class HealthConfig extends AbstractHealthIndicator {
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        builder.withDetail("test",System.currentTimeMillis());
        builder.up();
    }
}

在这里插入图片描述

3、metrics端点

通过融合业务,去操作,这里主要监控性能,即接口调用信息

package org.example.ctrl;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class controller {
    @RequestMapping("/hello")
    public String hello(){
        //每次执行,监控+1
        counter.increment();
        return "hello";
    }
    private Counter counter;
    public controller(MeterRegistry meterRegistry){
        counter = meterRegistry.counter("用户操作次数:");
    }
}

在这里插入图片描述
然后调用接口,http://localhost:8081/test/hello观察指标
在这里插入图片描述

4、自定义端点

新建自定义端点类,在类上声明@Endpoint(id = "my",enableByDefault = true)注解将其定义为端点,其中,id为端点的名称,名称不可包含特殊字符,例如"_",否则会报错;enableByDefault代表是否开启端点,也可以通过上面配置文件的方式开启,记下来,定义端点的行为,声明一个方法,用@ReadOperation注解声明,当启动项目的时候可被actuator读取管理

package org.example.actuator;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

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

@Component
//定义端点,后面enable可通过配置文件开启,名称不可包含特殊字符,例如_,否则会报错
@Endpoint(id = "my",enableByDefault = true)
public class MyEndpoint {
    @ReadOperation
    public Map test(){
        System.out.println("======================================");
        System.out.println("===============hello==================");
        System.out.println("======================================");
        Map map = new HashMap();
        map.put("aaa","111");
        return map;
    }
}

在这里插入图片描述
在这里插入图片描述

Admin的安全性

直到现在,我们的Admin控制台是可以直接访问的,现在考虑给它设置账号密码,首先,引入security依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.5.4</version>
</dependency>

创建一个SecurityConfig配置类,设置好拦截路径

package org.example.config;
import de.codecentric.boot.admin.server.config.AdminServerProperties;
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.stereotype.Component;

@Component
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final String adminContextPath;
    public SecurityConfig(AdminServerProperties adminServerProperties){
        this.adminContextPath = adminServerProperties.getContextPath();
    }

    @Override
    protected void configure(HttpSecurity security) throws Exception {
        SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
        handler.setTargetUrlParameter("redirectTo");
        security.authorizeRequests()
                .antMatchers( adminContextPath + "/assets/**" ).permitAll()
                .antMatchers( adminContextPath + "/login" ).permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage( adminContextPath + "/login" ).successHandler( handler ).and()
                .logout().logoutUrl( adminContextPath + "/logout" ).and()
                .httpBasic().and()
                .csrf().disable();
    }
}

然后,在配置文件配置用户名和密码,重新启动,即可看到需要账号密码登录

spring.security.user.name=admin
spring.security.user.password=123456

在这里插入图片描述
登录之后,发现我们的客户端虽然启动,但是没有服务实例,这是因为我们的客户端连不上admin了,需要在客户端的配置文件添加admin的账户信息,然后重启,注册成功

spring.boot.admin.client.username=admin
spring.boot.admin.client.password=123456

监控通知

既然是服务监控,那么就要求它能够实时提醒我们服务的状态,也就是做到即时通知,这里,我们采用邮件的方式实现。首先,我们需要有一个可以对外发送邮件的邮箱,我这里使用的163邮箱,我们在设置里找到SMTP,并开启,这里会给一个授权码,一定保存好不要泄露
在这里插入图片描述
然后,在Admin服务添加邮箱依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>2.5.4</version>
</dependency>

在配置文件配置我们的发送邮箱,接收邮箱以及账户信息等

#163的smtp
spring.mail.host=smtp.163.com
#邮箱
spring.mail.username=开启smtp的@163.com
#开启的授权码,保存好,不要泄露
spring.mail.password=授权码
#发件人邮箱
spring.boot.admin.notify.mail.from=开启smtp的@163.com
#收件人邮箱
spring.boot.admin.notify.mail.to=接收邮箱,可以随意

然后,重启我们的Admin服务,将客户端下线,可以在接收邮箱收到邮件
在这里插入图片描述
同理,再次上线客户端服务,也会收到上线邮件。

配置注册中心

目前,我们测试是单应用,到了实际生产过程,会有很多服务需要监控,因此,而且每个服务不止单个节点部署,甚至监控平台也不是单节点部署,那么我们再直连就不太合适,现在,考虑将监控服务和客户端接入注册中心,让监控平台自动拉取注册到注册中心的客户端信息。这步操作也很简单,只需要配置到同一个注册中心即可,下面展示几个注册中心的接入示例。

1、zookeeper

首先,我们给客户端和监控平台添加相应的依赖

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-context</artifactId>
            <version>3.0.0</version>
        </dependency>

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

	<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

有了微服务的依赖,接下来就需要开启服务注册与发现,这个只需要一个注解即可搞定

@EnableDiscoveryClient

接下来,我们先配置监控平台的配置文件,只需简单配置如下内容即可,因为我们的监控平台不需要注册从而被拉取,因此设置register属性为false

#zookeeper地址,默认localhost:2181
spring.cloud.zookeeper.connect-string=192.168.136.128:2181
#zookeeper的存储路径,node节点,默认/services
spring.cloud.zookeeper.discovery.root=/springboot_admin
#当前服务是否注册,默认true
spring.cloud.zookeeper.discovery.register=false

然后,设置服务端的配置文件,首先要把直连的配置注释spring.boot.admin.client.url=http://localhost:8080接下来配置如下内容

#应用名称
spring.application.name=springboot-service
#zookeeper地址
spring.cloud.zookeeper.connect-string=192.168.136.128:2181
#zookeeper的存储路径,node节点,默认/services
spring.cloud.zookeeper.discovery.root=/springboot_admin

然后,分别启动监控平台和客户端,查看效果,可以看到有服务暴露及zookeeper的信息
在这里插入图片描述

nacos

同上,我们引入nacos的依赖

<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.9.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        
        <dependencyManagement>
        <dependencies>
            <!--Spring Cloud Alibaba 相关依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

开启服务发现@EnableDiscoveryClient,然后配置监控服务

spring.application.name=springboot-admin
#监控服务不注册
spring.cloud.nacos.discovery.register-enabled=false
#nacos地址
spring.cloud.nacos.discovery.server-addr=192.168.136.128:8848
#nacos组
spring.cloud.nacos.discovery.group=springboot_admin
#命名空间id
spring.cloud.nacos.discovery.namespace=9cdb536e-9009-4ce4-abe9-fe33856d2a6d

然后配置客户端

#应用名称
spring.application.name=springboot-service
#nacos地址
spring.cloud.nacos.discovery.server-addr=192.168.136.128:8848
#nacos组
spring.cloud.nacos.discovery.group=springboot_admin
#命名空间id
spring.cloud.nacos.discovery.namespace=9cdb536e-9009-4ce4-abe9-fe33856d2a6d

分别启动监控服务和客户端服务,然后查看nacos服务注册列表
在这里插入图片描述
再登录监控平台,查看服务,服务注册成功
在这里插入图片描述
这里,我们简单介绍了两种常见的服务注册中心的配置,其他的还有eurake、consul等,如果需要使用,按照上述流程对照对应的注册中心配置即可,在github官网也给出了配置示例可以参考

总结

至此,我们实现了监控平台的部分功能,同时,我们实现了服务端和客户端注册到nacos等注册中心,进行微服务化的调用,当然,这里只是针对示例服务去处理的,实际应用还要结合服务场景进行具体实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/82806.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分布式 | 如何搭建 DBLE 的 JVM 指标监控系统

本篇文章采用 Docker 方式搭建 Grafana Prometheus 实现对 DBLE 的 JVM 相关指标的监控系统。 作者&#xff1a;文韵涵 爱可生 DBLE 团队开发成员&#xff0c;主要负责 DBLE 需求开发&#xff0c;故障排查和社区问题解答。 本文来源&#xff1a;原创投稿 爱可生开源社区出品&a…

湘潭大学 湘大 XTU OJ 1217 A+B VII 题解(非常详细)

链接 1217 题目 题目描述 小明非常高兴你能帮他处理那些罗马数字&#xff0c;他想学着自己写罗马数字&#xff0c;但是他不知道自己到底写对了没有。 请你帮他写个程序&#xff0c;能正确地将10进制数字转换成罗马数字&#xff0c;以便他能进行核对。 罗马数字是使用字母组…

《修图大杀器》PS beta 25.0最新版安装(无需魔法)和Draggan(拖拽式修图)安装

个人网站&#xff1a;https://tianfeng.space 文章目录 psbeta下载安装1.注册2.安装ps beta2.安装神经网络滤镜3.使用 Draggan下载安装 psbeta下载安装 链接&#xff1a;https://pan.baidu.com/s/1XbxSAFoXh0HDz6YbkrAzDg 提取码&#xff1a;e8pn 1.注册 https://account.a…

chatGPT-对话爱因斯坦

引言 阿尔伯特爱因斯坦&#xff08; 1879年 3 月 14 日 – 1955 年 4 月 18 日&#xff09;是一位出生于德国的理论物理学家&#xff0c;被广泛认为成为有史以来最伟大、最有影响力的科学家之一。他以发展相对论而闻名&#xff0c;他还对量子力学做出了重要贡献&#xff0c;因…

通过网络流量报告监控网络性能

实时网络流量监控已被组织广泛采用&#xff0c;作为了解网络性能和拥塞问题的首选技术。但是&#xff0c;有几个网络问题需要一个超越实时流量监控的解决方案。网络中的持续滞后可能会无人值守并影响整个网络的效率&#xff0c;使用网络流量报告将有助于管理网络环境中的风险。…

QT 基本对话框

包括&#xff1a; 1.标准文件对话框 dialog.h #ifndef DIALOG_H #define DIALOG_H#include <QDialog> #include <QTextCodec> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QGridLayout> #include <QFr…

漏洞指北-VulFocus靶场专栏-初级01

漏洞指北-VulFocus靶场专栏-初级 初级001 &#x1f338;海洋CMS代码执行&#xff08;CNVD-2020-22721&#x1f338;step1&#xff1a;进入后台页面 账号密码&#xff1a;admin amdinstep2&#xff1a;点击系统&#xff0c;点击后台IP安全设置,关闭step3 启动burpsuite&#xff…

SQL助你面大厂(窗口函数)

在面试过程中窗口函数的应用可谓是数不胜数&#xff0c;前提你要知道什么是窗口函数&#xff0c;最常用的窗口函数有哪些&#xff1f;语法是什么&#xff1f;分别用的场景是什么&#xff1f;今天会以这三个问题开始我们今天的学习 什么是窗口函数&#xff1f; 所谓的窗口函数就…

SQLite数据库实现数据增删改查

当前文章介绍的设计的主要功能是利用 SQLite 数据库实现宠物投喂器上传数据的存储&#xff0c;并且支持数据的增删改查操作。其中&#xff0c;宠物投喂器上传的数据包括投喂间隔时间、水温、剩余重量等参数。 实现功能&#xff1a; 创建 SQLite 数据库表&#xff0c;用于存储宠…

【OFDM系列】DFT为什么能求频率幅度谱?DFT后的X[k]与x(n)幅度的关系?DFT/IDFT底层数学原理?

文章目录 问题引入铺垫一些小公式DFT公式证明DFT公式分解为4部分先考虑k10的情况:再考虑k1≠0的情况: DFT计算后&#xff0c;X(k)与x(n)的关系&#xff1a; Matlab FFT示例代码IDFT公式证明Matlab调用FFT/IFFT并绘图 问题引入 上面是DFT和IDFT的公式&#xff0c;IDFT先不谈。在…

构建 NodeJS 影院微服务并使用 docker 部署它(02/4)

一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 图片取自网络 — 封面由我制作 这是✌️“构建 NodeJS 影院微服务”系列的第二篇文章。 二、对第一部分的…

netty(一):NIO——处理消息边界

处理消息边界 为什么要处理边界 因为会存在半包和粘包的问题 1.客户端和服务端约定一个固定长度 优点&#xff1a;简单 缺点&#xff1a;可能造成浪费 2.客户端与服务端约定一个固定分割符 *缺点 效率低 3.先发送长度&#xff0c;再发送数据 TLV格式&#xff1a; type…

Git分布式版本控制系统

目录 2、安装git 2.1 初始环境 2.2 Yum安装Git 2.3 编译安装 2.4 初次运行 Git 前的配置 2.5 初始化及获取 Git 仓库 2.6 Git命令常规操作 2.6.2 添加新文件 2.6.3 删除git内的文件 2.6.4 重命名暂存区数据 2.6.5 查看历史记录 2.6.6 还原历史数据 2.6.7 还原未来…

星际争霸之小霸王之小蜜蜂(四)--事件监听-让小蜜蜂动起来

目录 前言 一、监听按键并作出判断 二、持续移动 三、左右移动 总结&#xff1a; 前言 今天开始正式操控我们的小蜜蜂了&#xff0c;之前学java的时候是有一个函数监听鼠标和键盘的操作&#xff0c;我们通过传过来不同的值进行判断&#xff0c;现在来看看python是否一样的实现…

lvs-DR

lvs-DR数据包流向分析 client向目标VIP发出请求。 DIR根据负载均衡算法一台active的RS&#xff08;RIR1&#xff09;&#xff0c;将RIP1所在的网卡的mac地址作为目标的mac地址&#xff0c;发送到局域网里。 RIRI在局域网中的收到这个帧&#xff0c;拆开后发现目标&#xff08…

【ARM】Day4 点亮LED灯

1. 思维导图 2. 自己编写代码实现三盏灯点亮 .text .global _start _start: /**********LED1&#xff0c;LED2,LED3点灯:PE10,PF10,PE8**************/ RCC_INIT:使能GPIOE组/GPIOF组控制器,通过RXCC_MP_AHB4ENSETR设置第[5:4]位写1,地址:0x50000A28[5:4]1ldr r0,0x50000A28 …

【SA8295P 源码分析】03 - SA8295P QNX Host上电开机流程分析

【SA8295P 源码分析】03 - SA8295P QNX Host上电开机流程分析 一、阶段1 固件开机自检 (SM BIST)&#xff1a;APPS PBL加载XBL后触发 INT_RESET进行Warm Reset二、阶段2 固件开机自检 (SM BIST)&#xff1a;加载TZ&#xff0c;初始Hypervisor&#xff0c;启动QNX Kernel&#x…

22年电赛B题——具有自动泊车功能的电动车——做题记录以及经验分享

前言 这道题目也是小车类电赛题目&#xff0c;十月份的电赛题&#xff0c;由于之前积累了一些经验&#xff0c;这道题目在做下来的感觉还行,但是我们看题目没有仔细审题&#xff0c;和题目要求有一些些偏差&#xff0c;但是基础大功能还是做出来辽&#xff0c;大家还是可以参考…

LeetCode283.移动零

这道题还是很简单的&#xff0c;我用的是双指针&#xff0c;左指针i从头开始遍历数组&#xff0c;右指针j是从i后面第一个数开始遍历&#xff0c;当左指针i等于0的时候&#xff0c;右指针j去寻找i右边第一个为0的数和i交换位置&#xff0c;交换完了就break内层循环&#xff0c;…

Linux网络编程:网络基础

文章目录&#xff1a; 一&#xff1a;协议 二&#xff1a;网络应用设计模式_BS模式和CS模式 三&#xff1a;网络分层模型&#xff08;OSI七层 TCP/IP四层&#xff09; 四&#xff1a;通信过程 五&#xff1a;协议格式 1.数据包封装 2.以太网帧格式和ARP数据报格式 …