链路追踪Skywalking

一、什么是Skywalking

分布式链路追踪的一种方式:Spring Cloud Sleuth+ZipKin,这种方案目前也是有很多企业在用,但是作为程序员要的追逐一些新奇的技术,Skywalking作为后起之秀也是值得大家去学习的。

Skywalking是一个优秀的国产开源框架,2015年由个人吴晟(华为开发者)开源 , 2017年加入Apache孵化器。短短两年就被Apache收入麾下,实力可见一斑。

Skywalking支持dubbo,SpringCloud,SpringBoot集成,代码无侵入,通信方式采用GRPC,性能较好,实现方式是java探针,支持告警,支持JVM监控,支持全局调用统计等等,功能较完善。

二、Skywalking和Spring Cloud Sleuth+ZipKin如何选型

Skywalking相比于zipkin还是有很大的优势的,如下:

  • skywalking采用字节码增强的技术实现代码无侵入,zipKin代码侵入性比较高
  • skywalking功能比较丰富,报表统计,UI界面更加人性化

个人建议:如果是新的架构,建议优先选择Skywalking

三、Skywalking架构 

skywalking和zipkin一样,也分为服务端和客户端,服务端负责收集日志数据并且展示,架构如下:

上述架构图中主要分为四个部分,如下:

  • 上面的Agent:负责收集日志数据,并且传递给中间的OAP服务器
  • 中间的OAP:负责接收Agent发送的Tracing 和Metric的数据信息,然后进行分析(Analysis Core) ,存储到外部存储器( Storage ),最终提供查询( Query )功能。
  • 左面的UI:负责提供web控制台,查看链路,查看各种指标,性能等等。
  • 右面Storage:负责数据的存储,支持多种存储类型。

看了架构图之后,思路很清晰了,Agent负责收集日志传输数据,通过GRPC的方式传递给OAP进行分析并且存储到数据库中,最终通过UI界面将分析的统计报表、服务依赖、拓扑关系图展示出来。

四、服务端如何搭建 

提前说明:当前所使用的版本为8.7.0,不同的版本其启动方式存在差异,需要另外查询资料。

3.1 下载安装包

SkyWalking是通过jar包方式启动,需要下载jar包,我们可以通过下述地址找到并下载Skywalking的8.7.0版本,如下所示:

https://archive.apache.org/dist/skywalking/

3.2 OAP服务的配置

将上述压缩包进行解压,解压以后首先找到 /config/application.yml 目录文件,这个是oap服务的配置文件,需要将配置中心修改为nacos,如下所示:

修改默认注册中心选择nacos,这样就不用在启动参数中指定了。另外由于nacos服务是本地启动的,所以相关的配置不需要修改。

3.3 UI服务的配置 

UI服务的配置文件是 /webapp/webapp.yml,其中有一个server.port配置,是UI服务的端口,默认为8080,为避免端口冲突,将其改成8888。

3.4 启动

启动命令在/bin目录下,这里需要启动两个服务,如下所示:

  • oap服务:对应的启动脚本oapService.bat,Linux下对应的后缀是sh
  • UI服务:对应的启动脚本webappService.bat,Linux下对应的后缀是sh

还有一个startup.bat启动文件,可以直接启动上述两个服务,我们可以直接使用这个脚本,直接双击,将会弹出两个窗口则表示启动成功,如下所示:

浏览器访问localhost:8888,直接进入UI端,如下所示:

再回看Skywalkingj解压后的完整目录,如下所示:

重要的目录结构分析如下:

  • agent:客户端需要指定的目录,其中有一个jar,就是负责和客户端整合收集日志
  • bin:服务端启动的脚本
  • config:一些配置文件的目录
  • logs:oap服务的日志目录
  • oap-libs:oap所需的依赖目录
  • webapp:UI服务的目录

五、客户端如何搭建

客户端也就是单个微服务,由于Skywalking采用字节码增强技术,因此对于微服务无代码侵入,只要是普通的微服务即可,不需要引入什么依赖。

想要传输数据必须借助skywalking提供的agent,只需要在对应服务的启动参数指定agent即可,命令如下:

-javaagent:D:\demo\apache-skywalking-apm-8.7.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=demo
-Dskywalking.collector.backend_service=127.0.0.1:11800

上述命令解析如下:

  • -javaagent:指定skywalking中的agent中的skywalking-agent.jar的路径
  • -Dskywalking.agent.service_name:指定在skywalking中的服务名称,一般是微服务的spring.application.name
  • -Dskywalking.collector.backend_service:指定oap服务绑定的地址,由于这里是在本地环境中启动oap,并且oap服务默认的端口是11800,因此只需要配置为127.0.0.1:11800

上述参数可以在命令行通过 java -jar xxx 指定,在IDEA中操作如下所示:

如果是在微服务中,每一个微服务都需要配置Skywalking的agent启动配置,配置成功后正常启动即可。

注意:agent的jar包路径不能包含中文,不能有空格,否则运行不成功。

此处构造测试使用的接口/api/hello和/api/chain,后续其它模块也会使用到。

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/api")
public class DemoController {@GetMapping("/hello")public String hello() {log.info("调用了hello方法");return "Hello, SkyWalking!";}@GetMapping("/chain")public String chain() {log.info("调用了chain方法");doSomeThing();return callAnotherService();}private String callAnotherService() {// 模拟调用另一个服务return "Service call chain";}private void doSomeThing(){try{Thread.sleep(1000);}catch (Exception e){e.printStackTrace();}}
}

在准备工作完成以后,启动服务,分别访问localhost:8001/api/hello和localhost:8001/api/chain,然后再去查看Skywalking的UI端。 这里如果想在下述三个模块中可以尽快的看到相关数据,那么建议打开UI界面右上角的 “自动刷新” 功能。(PS:第一次使用时,由于不了解相关的功能特性,所以花了很长的时间研究为什么这三个模块中没有数据,呜呜呜!!!)

查看 “仪表盘模块”,可以看到demo服务已经被监控成功了,如下所示:

查看 “拓扑图模块”,可以看到服务之前的依赖关系,如下所示: 

查看 “追踪模块“,请求链路的信息也是能够很清楚的看到,比如请求的url,执行时间、调用的服务,如下所示:

六、数据持久化 

你会发现只要服务端重启之后,这些链路追踪数据将会丢失了,因为Skywalking默认持久化的方式是存储在内存中。我们是可以通过插拔方式的替换掉存储中间件,企业中往往是使用ES存储,这里介绍的是MySQL的方式存储。

6.1 修改配置文件

修改config/application.yml文件中的存储方式,总共需要修改两处地方。

第一个地方:修改默认的存储方式为mysql

第二个地方:修改mysql相关的信息,此处我新建了一个名为skywalking_config的数据库

6.2 添加MySQL的jdbc依赖

默认的oap中是没有jdbc驱动依赖,因此需要我们手动添加一下,只需要将驱动的jar放在oap-libs文件夹中,如下所示:

配置完成以后,启动服务端,在skywalking_config这个数据库中将会自动创建表,如下所示:

数据库中新建的表是逐步缓慢创建的,最终一共会有142张表,所以提前创建一个独有的数据库还是很有必要的,与业务数据库分隔开。

七、日志监控

在skywalking的UI端有一个日志的模块,用于收集客户端的日志,默认是没有数据的,我们可以相关的日志框架将日志数据推送到Skywalking中。

日志框架的种类很多,比较出名的有log4j、log4j2、logback,其官方文档如下。

log4j日志框架的文档:

https://skywalking.apache.org/docs/skywalking-java/v8.7.0/en/setup/service-agent/java-agent/application-toolkit-log4j-1.x/

log4j2日志框架的文档:

https://skywalking.apache.org/docs/skywalking-java/v8.7.0/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x/

logback日志框架的文档:

https://skywalking.apache.org/docs/skywalking-java/v8.7.0/en/setup/service-agent/java-agent/application-toolkit-logback-1.x/

下面就以logback日志框架为例子介绍一下如何配置。 

7.1 添加依赖

在pom.xml文件中添加下述依赖,如下所示:

<dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version>8.7.0</version>
</dependency>

7.2 添加配置文件

新建一个 logback-spring.xml 放在resource目录下,配置如下:

<configuration scan="true" scanPeriod=" 5 seconds"><!-- 控制台打印tracId的格式,只需要加一个%tid --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender><!--异步打印--><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>1024</queueSize><neverBlock>true</neverBlock><appender-ref ref="STDOUT"/></appender><!--日志传输到Skywalking中的appender,通过grpc传输--><appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern></layout></encoder></appender><!-- 日志级别为INFO,控制台打印,并且传输到Skywalking --><root level="INFO"><appender-ref ref="ASYNC"/><appender-ref ref="grpc-log"/></root>
</configuration>

7.3 测试日志传输 

在上述配置完成以后,启动对应的服务,访问localhost:8001/api/hello和localhost:8001/api/chain接口,控制台打印的日志如下所示:

可以看到控制台中已经打印出了traceId,接着再去Skywalking的日志模块中查看相关的日志,如下所示:

可以看到日志已经传输到了skywalking中,那么则说明前面的配置已经成功!!! 

特别说明:在当前Skywalking的8.7.0版本中日志模块的 时间范围” 选项,在默认情况下不会自动更新数据范围,这样就会给使用者造成一种困扰,当IDEA控制台打印了相关日志以后,我们去Skywalking的日志模块中查询会发现没有数据。那么针对这种情况,就需要我们手动去调整时间范围,然后再点击“搜索”按钮查询相关日志信息。

注意:如果agent和oap服务不在同一台服务器上,需要在/agent/config/agent.config配置文件末尾添加下述4行配置。

plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:10.10.10.1}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}

4个配置分析如下:

  • plugin.toolkit.log.transmit_formatted:是否以格式化或未格式化的格式传输记录的数据,默认值为true
  • plugin.toolkit.log.grpc.reporter.server_host:指定要向其报告日志数据的grpc服务器的主机,例如192.168.1.2
  • plugin.toolkit.log.grpc.reporter.server_port:指定要向其报告日志数据的grpc服务器的端口,默认为11800
  • plugin.toolkit.log.grpc.reporter.max message size:指定grpc客户端要报告的日志数据的最大大小,默认值为10485760
  • plugin.toolkit.log.grpc,reporter.upstream timeout:客户端向上游发送数据时将超时多长时间,单位是秒,默认值是30

八、性能剖析

Skywalking在性能剖析方面真的是非常强大,提供到基于堆栈的分析结果,能够让运维人员一眼定位到问题。

新建一个/order/list接口,如下所示:

import cn.hutool.core.util.RandomUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/order")
public class OrderController {@GetMapping("/list")public void list() throws Exception {Thread.sleep(2000);int sum = 1 + RandomUtil.randomInt(10);System.out.println(sum);}
}

上述代码中休眠了2秒,看看如何在Skywalking中定位这个问题。

在 “性能剖析模块” -“新建任务” ->选择服务、填写端点、监控时间,如下所示:

上图中选择了最大采样数为5,则直接访问5次localhost:8001/order/list,然后选择这个任务将会出现监控到的数据,如下所示:

上图中可以看到 {GET}/order/list 这个接口上耗费了2秒以上,因此选择这个接口点击分析,可以看到详细的堆栈信息,如下所示:

如何定位到睡眠2秒钟的那一行代码呢?直接往下翻,如下所示:

此时就很清楚了,在OrderController这个接口中线程睡眠了两秒!!!

九、监控告警

Skywalking中有一些默认的告警规则,如下所示:

  • 最近3分钟内服务的平均响应时间超过1秒
  • 最近2分钟服务成功率低于80%
  • 最近3分钟90%服务响应时间超过1秒
  • 最近2分钟内服务实例的平均响应时间超过1秒

当然除了上述四种告警规则,随着Skywalking不断迭代也会新增其它规则,这些规则的配置在 config/alarm-settings.yml 配置文件中,如下所示:

每个规则都由相同的属性组成,这些属性的含义如下:

  • metrics-name:监控的指标名称(如 service_resp_time)
  • threshold:触发告警的阈值(如 > 1000、< 90%)
  • op:比较运算符(>,<,=,>=,<=)
  • period:多久检查一次当前的指标数据是否符合告警规则,单位是分钟
  • count:连续多少次触发阈值才发送告警(如值为3,则表示连续3次超阈值才告警)
  • silence-period:在多久之内,忽略相同的告警消息
  • message:告警消息内容
  • include-names:本规则告警生效的服务列表

如果想要调整默认的规则,比如监控返回的信息,监控的参数等等,只需要改动上述配置文件中的参数即可。

当然除了以上默认的几种规则,Skywalking还适配了一些钩子(webhooks)。其实就是相当于一个回调,一旦触发了上述规则告警,Skywalking则会调用配置的webhook,这样开发者就可以定制一些处理方法,比如发送邮件、微信、钉钉通知运维人员处理。

当然这个钩子也是有些规则的,如下所示:

  • POST请求
  • application/json 接收数据
  • 接收的参数必须是AlarmMessage中指定的参数

特别注意:AlarmMessage这个类随着Skywalking版本的迭代可能出现不同,一定要到对应版本源码中去找到这个类,拷贝其中的属性,这个类在源码的路径:org.apache.skywalking.oap.server.core.alarm。

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
public class Tag {private String key;private String value;@Overridepublic String toString() {return key + "=" + value;}public static class Util {public static List<String> toStringList(List<Tag> list) {if (CollectionUtil.isEmpty(list)) {return Collections.emptyList();}return list.stream().map(Tag::toString).collect(Collectors.toList());}}
}
import lombok.Getter;
import lombok.Setter;import java.util.List;@Setter
@Getter
public class AlarmMessage {private int scopeId;private String scope;private String name;private String id0;private String id1;private String ruleName;private String alarmMessage;private List<Tag> tags;private long startTime;private transient int period;private transient boolean onlyAsCondition;
}

定义一个用于回调的钩子接口,如下所示:

import cn.hutool.json.JSONUtil;
import com.example.demo.dto.AlarmMessage;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/alarm")
public class AlarmController {@PostMapping("/receive")public void receive(@RequestBody List<AlarmMessage> list) {// todo::仅仅打印JSON,至于发送邮件、微信、钉钉自己根据业务需求完成System.out.println(JSONUtil.toJsonPrettyStr(list));}
}

钩子接口完成以后,只需要在 config/alarm-settings.yml 配置文件中添加这个钩子:

好了,这就已经配置完成了,测试也很简单,还是调用上面案例中的睡眠两秒的接口localhost:8001/order/list,多调用几次,则会触发告警,控制台打印日志如下:

对于服务的异常信息,比如接口有较长延迟,Skywalking的 “告警模块” UI界面也会有相关的展示,如下所示:

特别说明:此处我发现了一个问题,就是控制台的钩子接口会先打印出告警信息,在稍微等待一会后(需要一会时间)UI界面才会有相关的告警展示。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

websocket获取客服端真实ip

在websocket建立连接时,获取访问客户端的真实ip 1. websocket建立连接过程 2. pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>3. 添加配置,握…

NSSCTF(MISC)—[justCTF 2020]pdf

相应的做题地址&#xff1a;https://www.nssctf.cn/problem/920 binwalk分离 解压文件2AE59A.zip mutool 得到一张图片 B5F31内容 B5FFD内容 转换成图片 justCTF{BytesAreNotRealWakeUpSheeple}

部分国产服务器CPU及内存性能测试情况

近日对部分国产服务器进行了CPU和内存的性能测试&#xff0c; 服务器包括华锟振宇、新华三和中兴三家&#xff0c;CPU包括鲲鹏、海光和Intel&#xff0c;初步测试结果如下&#xff1a; 服务器厂商四川华锟振宇新华三中兴中兴服务器HuaKun TG225 B1R4930 G5R5930 G2R5300 G4操作…

【无标题】Scala函数基础

函数和方法的区别 1&#xff09; 核心概念 &#xff08;1&#xff09; 为完成某一功能的程序语句的集合&#xff0c;称为函数。 &#xff08;2&#xff09; 类中的函数称之方法。 2&#xff09; 案例实操 &#xff08;1&#xff09; Scala 语言可以在任何的语法结构中声明…

uniapp -- 列表垂直方向拖拽drag组件

背景 需要在小程序中实现拖拽排序功能,所以就用到了m-drag拖拽组件,在开发的过程中,发现该组件在特殊的场景下会有些问题,并对其进行了拓展。 效果 组件代码 <template><!-- 创建一个垂直滚动视图,类名为m-drag --><scroll

conda安装python 遇到 pip is configured with locations that require TLS/SSL问题本质解决方案

以前写了一篇文章&#xff0c;不过不是专门为了解决这个问题的&#xff0c;但是不能访问pip install 不能安装来自https 协议的包问题几乎每次都出现&#xff0c;之前解决方案只是治标不治本 https://blog.csdn.net/wangsenling/article/details/130194456​​​​​​​https…

【初阶数据结构】队列

文章目录 目录 一、概念与结构 二、队列的实现 队列的定义 1.初始化 2.入队列 3.判断队列是否为空 4.出队列 5.取队头数据 6.取队尾数据 7.队列有效个数 8.销毁队列 三.完整源码 总结 一、概念与结构 概念&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除…

Apache Shiro 全面指南:从入门到高级应用

一、Shiro 概述与核心架构 1.1 什么是 Shiro&#xff1f; Apache Shiro 是一个强大且易用的 Java 安全框架&#xff0c;它提供了认证&#xff08;Authentication&#xff09;、授权&#xff08;Authorization&#xff09;、加密&#xff08;Cryptography&#xff09;和会话管…

es 3期 第28节-深入掌握集群组建与集群设置

#### 1.Elasticsearch是数据库&#xff0c;不是普通的Java应用程序&#xff0c;传统数据库需要的硬件资源同样需要&#xff0c;提升性能最有效的就是升级硬件。 #### 2.Elasticsearch是文档型数据库&#xff0c;不是关系型数据库&#xff0c;不具备严格的ACID事务特性&#xff…

Android学习总结之通信篇

一、Binder跨进程通信的底层实现细节&#xff08;挂科率35%&#xff09; 高频问题&#xff1a;“Binder如何实现一次跨进程方法调用&#xff1f;”   候选人常见错误&#xff1a;   仅回答“通过Binder驱动传输数据”&#xff0c;缺乏对内存映射和线程调度的描述混淆Binde…

数据结构C语言练习(两个栈实现队列)

一、引言 在数据结构的学习中&#xff0c;我们经常会遇到一些有趣的问题&#xff0c;比如如何用一种数据结构去实现另一种数据结构的功能。本文将深入探讨 “用栈实现队列” 这一经典问题&#xff0c;详细解析解题思路、代码实现以及每个函数的作用&#xff0c;帮助读者更好地…

前端如何导入谷歌字体库

#谷歌字体库内容丰富&#xff0c;涵盖上千种多语言支持的字体&#xff0c;学习导入谷歌字体库来增加网站的阅读性&#xff0c;是必不可少的一项技能# 1&#xff0c;前往谷歌字体网站 要会魔法&#xff0c;裸连很卡 2&#xff0c; 寻找心仪字体 Googles Fonts下面的filters可…

SnapdragonCamera骁龙相机源码解析

骁龙相机是高通开发的一个测试系统摄像头的demo&#xff0c;代码完善&#xff0c;功能强大。可以配合Camera驱动进行功能联调。 很多逻辑代码在CaptureModule.java里。 CaptureModule有8000多行&#xff0c;包罗万象。 涉及到界面显示要结合CaptureUI.java 一起来实现。 Ca…

多线程猜数问题

题目&#xff1a;线程 A 生成随机数&#xff0c;另外两个线程来猜数&#xff0c;线程 A 可以告诉猜的结果是大还是小&#xff0c;两个线程都猜对后&#xff0c;游戏结束&#xff0c;编写代码完成。 一、Semaphore 多个线程可以同时操作同一信号量&#xff0c;由此实现线程同步…

seq2seq

理解 transformer 中的 encoder decoder 详细的 transformer 教程见&#xff1a;【极速版 – 大模型入门到进阶】Transformer 文章目录 &#x1f30a; Encoder: 给一排向量输出另外一排向量&#x1f30a; Encoder vs. Decoder: multi-head attention vs. masked multi-head at…

Proxmox pct 部署ubuntu

pct 前言 PCT(Proxmox Container Tool)是 PVE 中用于管理 Linux 容器(LXC)的命令行工具。通过 PCT,用户可以执行各种容器管理任务,例如创建新的容器、启动和停止容器、更新容器、安装软件包、导出和导入容器等。PCT 提供了与 Web 界面相同的功能,但通过命令行进行操作,…

Google Play关键字优化:关键排名因素与实战策略

如果您准备发布应用程序或开始专注于关键字优化&#xff0c;您可能想知道如何向Google Play上的应用程序添加关键字。Google Play上的搜索量和排名与App Store不同&#xff0c;而且被索引排名的关键字也不同。在此文中&#xff0c;我们将确定Google Play上的关键排名因素&#…

Kafka延迟队列实现分级重试

技术方案 方案背景 Kafka队列消息消费处理过程中&#xff0c;发生处理异常&#xff0c;需要实现重试机制&#xff0c;并基于重试次数实现不同延迟时间重试方案。 方案介绍 通过实现Kafka延迟队列来实现消息重试机制。 目标&#xff1a; 支持所有业务场景的延迟重试支持多…

Maven核心配置文件深度解析:pom.xml完全指南

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、全栈领域优质创作者、高级开发工程师、高级信息系统项目管理师、系统架构师&#xff0c;数学与应用数学专业&#xff0c;10年以上多种混合语言开发经验&#xff0c;从事DICOM医学影像开发领域多年&#xff0c;熟悉DICOM协议及…

MSTP多域生成树

协议信息 MSTP 兼容 STP 和 RSTP&#xff0c;既可以快速收敛&#xff0c;又提供了数据转发的多个冗余路径&#xff0c;在数据转发过程中实现 VLAN 数据的负载均衡。 MSTP 可以将一个或多个 VLAN 映射到一个 Instance&#xff08;实例&#xff09;&#xff08;一个或多个 VLAN…