ELK + Filebeat 部署及 logstash 的四大插件(grok、date、mutate、multiline)

news2024/11/22 21:00:58

目录

  • Filebeat
  • Filebeat 结合 logstash 带来好处:
  • Fluentd
  • ELK + Filebeat 部署
    • 1.安装 Filebeat & Httpd
    • 2.设置 filebeat 的主配置文件
    • 4.在 Logstash 组件所在节点上新建一个 Logstash 配置文件
    • 5.浏览器访问 http://192.168.60.12:5601 登录 Kibana
  • logstash 的四大插件(grok、date、mutate、multiline)
    • grok 正则捕获插件
    • mutate 数据修改插件
    • multiline 多行合并插件
    • date 时间处理插件

Filebeat

  • Filebeat:轻量级的开源日志文件数据搜集器。通常在需要采集数据的客户端安装 Filebeat,并指定目录与日志格式,Filebeat 就能快速收集数据,并发送给 logstash 进行解析,或是直接发给 Elasticsearch 存储,性能上相比运行于 JVM 上的 logstash 优势明显,是对它的替代。常应用于 EFLK 架构当中。

Filebeat 结合 logstash 带来好处:

  • 1)通过 Logstash 具有基于磁盘的自适应缓冲系统,该系统将吸收传入的吞吐量,从而减轻 Elasticsearch 持续写入数据的压力
  • 2)从其他数据源(例如数据库,S3对象存储或消息传递队列)中提取
  • 3)将数据发送到多个目的地,例如S3,HDFS(Hadoop分布式文件系统)或写入文件
  • 4)使用条件数据流逻辑组成更复杂的处理管道

Fluentd

  • Fluentd:是一个流行的开源数据收集器。由于 logstash 太重量级的缺点,Logstash 性能低、资源消耗比较多等问题,随后就有 Fluentd 的出现。相比较 logstash,Fluentd 更易用、资源消耗更少、性能更高,在数据处理上更高效可靠,受到企业欢迎,成为 logstash 的一种替代方案,常应用于 EFK 架构当中。在 Kubernetes 集群中也常使用 EFK 作为日志数据收集的方案。
  • 在 Kubernetes 集群中一般是通过 DaemonSet 来运行 Fluentd,以便它在每个 Kubernetes 工作节点上都可以运行一个 Pod。 它通过获取容器日志文件、过滤和转换日志数据,然后将数据传递到 Elasticsearch 集群,在该集群中对其进行索引和存储。

Filebeat 和 Fluentd 都可以代替 logstash 来收集日志数据

ELK + Filebeat 部署

在这里插入图片描述
服务器结构
node1节点:192.168.60.5 部署 Elasticsearch 。
node2节点:192.168.60.8 部署 Elasticsearch 。
Nginx节点:192.168.60.12 部署 kiabana、Logstash。
Filebeat节点:192.168.60.11 部署 Filebeat、httpd

//在 Filebeat 节点上操作

1.安装 Filebeat & Httpd

#上传软件包 filebeat-6.7.2-linux-x86_64.tar.gz 到/opt目录
tar zxvf filebeat-6.7.2-linux-x86_64.tar.gz
mv filebeat-6.7.2-linux-x86_64/ /usr/local/filebeat

yum -y install httpd

systemctl start httpd.service 
systemctl enable httpd.service

2.设置 filebeat 的主配置文件

cd /usr/local/filebeat

vim filebeat.yml
filebeat.inputs:
- type: log         #指定 log 类型,从日志文件中读取消息
  enabled: true
  paths:
    - /var/log/messages       #指定监控的日志文件
    - /var/log/*.log
  tags: ["sys"]		#设置索引标签
  fields:           #可以使用 fields 配置选项设置一些参数字段添加到 output 中
    service_name: filebeat
    log_type: syslog
    from: 192.168.80.13

--------------Elasticsearch output-------------------
(全部注释掉)

----------------Logstash output---------------------
output.logstash:
  hosts: ["192.168.60.12:5044"]      #指定 logstash 的 IP 和端口

#启动 filebeat
nohup ./filebeat -e -c filebeat.yml > filebeat.out &
#-e:输出到标准输出,禁用syslog/文件输出
#-c:指定配置文件
#nohup:在系统后台不挂断地运行命令,退出终端不会影响程序的运行

在这里插入图片描述
修改配置文件
在这里插入图片描述
在这里插入图片描述

4.在 Logstash 组件所在节点上新建一个 Logstash 配置文件

cd /etc/logstash/conf.d

vim filebeat.conf
input {
    beats {
        port => "5044"
    }
}

output {
    elasticsearch {
        hosts => ["192.168.80.10:9200","192.168.80.11:9200"]
        index => "%{[fields][service_name]}-%{+YYYY.MM.dd}"
    }
    stdout {
        codec => rubydebu=
    }
}

#启动 logstash
logstash -f filebeat.conf

在这里插入图片描述

5.浏览器访问 http://192.168.60.12:5601 登录 Kibana

单击“Create Index Pattern”按钮添加索引“httpd-*”,单击 “create” 按钮创建,单击 “Discover” 按钮可查看图表信息及日志信息。

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

logstash 的四大插件(grok、date、mutate、multiline)

  • grok :将大文本字段进行分片成多个小字段 %{内置正则:字段名} (?<字段名>自定义正则)
  • date :将logstash收集的日志事件时间与实际记录的日志时间进行格式统一,需要配合grok模块使用
  • mutate :对logstash收集的日志事件字段进行再处理,可以重命名,删除,替换和修改事件中的字段
  • multiline :将多行日志内容合并成一整行

链接: 内置正则大全

grok 正则捕获插件

grok 使用文本片段切分的方式来切分日志事件

  • //内置正则表达式调用
    %{SYNTAX:SEMANTIC}

  • SYNTAX代表匹配值的类型,例如,0.11可以NUMBER类型所匹配,10.222.22.25可以使用IP匹配。

  • SEMANTIC表示存储该值的一个变量声明,它会存储在elasticsearch当中方便kibana做字段搜索和统计,你可以将一个IP定义为客户端IP地址client_ip_address,如%{IP:client_ip_address},所匹配到的值就会存储到client_ip_address这个字段里边,类似数据库的列名,也可以把 event log 中的数字当成数字类型存储在一个指定的变量当中,比如响应时间http_response_time,假设event log record如下:

    • message: 192.168.60.12 GET /index.html 15824 0.043
      可以使用如下grok pattern来匹配这种记录
      %{IP:client_id_address} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:http_response_time}

在这里插入图片描述
结合logstash

input {
    beats {
        port => "5044"
    }
}

filter {
  grok {
    match => ["message", "%{IP:remote_addr} - - \[%{HTTPDATE:log_time}\] \"%{WORD:http_method} %{URIPATH:request_url} (?<http_ver>.+)\" %{NUMBER:response_code} .+ \".+\" \"(?<user_angent>.+)\""]
  }
}
#用match进行匹配 ["匹配字段", "表达式匹配并将其添加到指定字段"]

output {
    elasticsearch {
        hosts => ["192.168.60.5:9200","192.168.60.8:9200"]
        index => "%{[fields][service_name]}-%{+yyyy.MM.dd}"
    }
    stdout {
        codec => rubydebug
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
自定义表达式
自定义表达式格式:(?<自定义名称>正则表达式)
在这里插入图片描述

mutate 数据修改插件

它提供了丰富的基础类型数据处理能力。可以重命名,删除,替换和修改事件中的字段。

  • //Mutate 过滤器常用的配置选项
    • add_field : 向事件添加新字段,也可以添加多个字段
    • remove_field : 从事件中删除任意字段(他只能删除logstash自己的字段或者日志的字段无法删除通过filedeat生成的字段)
    • add_tag : 向事件添加任意标签,在tag字段中添加一段自定义的内容,当tag字段中超过一个内容的时候会变成数组
    • remove_tag : 从事件中删除标签(如果存在)
    • convert : 将字段值转换为另一种数据类型
    • id : 向现场事件添加唯一的ID
    • lowercase : 将字符串字段转换为其小写形式
    • replace : 用新值替换字段
    • strip : 删除开头和结尾的空格
    • uppercase : 将字符串字段转换为等效的大写字母
    • update : 用新值更新现有字段
    • rename : 重命名事件中的字段
    • gsub : 通过正则表达式替换字段中匹配到的值
    • merge : 合并数组或 hash 事件
      split : 通过指定的分隔符分割字段中的字符串为数组

//示例:

●将字段old_field重命名为new_field
input 
。。。。
filter {
    mutate {
	    #写法1,使用中括号括起来
        rename => ["old_field" => "new_field"]

        #写法2,使用大括号{}括起来
	    rename => { "old_field" => "new_field" }		
    }
}
output
。。。
●添加字段
input 
。。。。
filter {
    mutate {
        add_field => {
        	"f1" => "field1"
        	"f2" => "field2"
        	#添加f1字段 以及他的值field1
        }
    }
}
output
。。。
●将字段删除
input 
。。。。
filter {
    mutate {
        remove_field  =>  ["message", "@version", "tags"]
    }
}
output
。。。
●将filedName1字段数据类型转换成string类型,filedName2字段数据类型转换成float类型
input 
。。。。
filter {
    mutate {
        #写法1,使用中括号括起来
        convert  =>  ["filedName1", "string"]
		
        #写法2,使用大括号{}括起来
		convert => { "filedName2" => "float" }
    }
}
output
。。。
●将filedName字段中所有"/“字符替换为”_"
input 
。。。。
filter {
    mutate {
        gsub => ["filedName", "/" , "_"]
    }
}
output
。。。
●将filedName字段中所有",“字符后面添加空格
input 
。。。。
filter {
    mutate {
        gsub => ["filedName", "," , ", "]
    }
}
output
。。。
●将filedName字段以"|"为分割符拆分数据成为数组
input 
。。。。
filter {
    mutate {
        split => ["filedName", "|"]
    }
}
output
。。。
●合并 “filedName1” 和 “ filedName2” 两个字段
input 
。。。。
filter {
    merge  { "filedName2" => "filedName1" }
}
output
。。。
●用新值替换filedName字段的值
input 
。。。。
filter {
    mutate {
        replace => { "filedName" => "new_value" }
    }
}
output
。。。
●添加字段first,值为message数组的第一个元素的值
input 
。。。。
filter {
    mutate {
        split => ["message", "|"]
        add_field => {
            "first" => "%{[message][0]}"    
        } 
    }
}
output
。。。
●有条件的添加标签
input 
。。。。
filter {
    #在日志文件路径包含 access 的条件下添加标签内容
    if [path] =~ "access" {
        mutate {
            add_tag => ["Nginx Access Log"]
        }
    }
    
    #在日志文件路径是 /var/log/nginx/error.log 的条件下添加标签内容
    if [path] == "/var/log/nginx/error.log" {
        mutate {
            add_tag => ["Nginx Error Log"]
        }
    }
}
output
。。。

multiline 多行合并插件

java错误日志一般都是一条日志很多行的,会把堆栈信息打印出来,当经过 logstash 解析后,每一行都会当做一条记录存放到 ES, 那这种情况肯定是需要处理的。 这里就需要使用 multiline 插件,对属于同一个条日志的记录进行拼接。

例:

2022-11-11 17:09:19.774[XNIo-1 task-1]ERROR com.passjava.controlle .NembercController-查询用户 活动数据失败,异常信息为:
    com.passjava.exception.MemberException: 当前没有配置活动规则
    at com.passjava.service.impL.queryAdmin(DailyServiceImpl.java:1444)
    at com.passjava.service.impl.dailyserviceImpL$$FastcLass
2022-11-11 17:10:56.256][KxNIo-1 task-1] ERROR com.passjava.controlle .NemberControl1er-查询员工 饭活动数据失败,异常信息为:
    com.passjava.exception.MemberException: 当前没有配置活动规则
    at com.passjava.service.impL.queryAdmin(DailyServiceImpl.java:1444)
    at com.passjava.service.impL.daiLyserviceImpL$$FastcLass

//安装 multiline 插件

在线安装插件
cd /usr/share/logstash
bin/logstash-plugin install logstash-filter-multiline

离线安装插件
先在有网的机器上在线安装插件,然后打包,拷贝到服务器,执行安装命令
bin/logstash-plugin prepare-offline-pack --overwrite --output logstash-filter-multiline.zip logstash-filter-multiline

bin/logstash-plugin install file:///usr/share/logstash/logstash-filter-multiline.zip

检查下插件是否安装成功,可以执行以下命令查看插件列表
bin/logstash-plugin list

//使用 multiline 插件

第一步:每一条日志的第一行开头都是一个时间,可以用时间的正则表达式匹配到第一行。
第二步:然后将后面每一行的日志与第一行合并。
第三步:当遇到某一行的开头是可以匹配正则表达式的时间的,就停止第一条日志的合并,开始合并第二条日志。
第四步:重复第二步和第三步。

filter {
  multiline {
    pattern => "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}.\d{3}"
    negate => true
    what => "previous"
  }
}

●pattern:用来匹配文本的表达式,也可以是grok表达式

●what:如果pattern匹配成功的话,那么匹配行是归属于上一个事件,还是归属于下一个事件。previous: 归属于上一个事件,向上合并。next: 归属于下一个事件,向下合并

●negate:是否对pattern的结果取反。false:不取反,是默认值。true:取反。将多行事件扫描过程中的行匹配逻辑取反(如果pattern匹配失败,则认为当前行是多行事件的组成部分)

date 时间处理插件

用于分析字段中的日期,然后使用该日期或时间戳作为事件的logstash时间戳。

在Logstash产生了一个Event对象的时候,会给该Event设置一个时间,字段为“@timestamp”,同时,我们的日志内容一般也会有时间,但是这两个时间是不一样的,因为日志内容的时间是该日志打印出来的时间,而“@timestamp”字段的时间是input插件接收到了一条数据并创建Event的时间,所有一般来说的话“@timestamp”的时间要比日志内容的时间晚一点,因为Logstash监控数据变化,数据输入,创建Event导致的时间延迟。这两个时间都可以使用,具体要根据自己的需求来定。

filter {
    date {
        match => ["access_time", "dd/MMM/YYYY:HH:mm:ss Z", "UNIX", "yyyy-MM-dd HH:mm:ss", "dd-MMM-yyyy HH:mm:ss"]
		target => "@timestamp"
		timezone => "Asia/Shanghai"
    } 
}

●match:用于配置具体的匹配内容规则,前半部分内容表示匹配实际日志当中的时间戳的名称,后半部分则用于匹配实际日志当中的时间戳格式,这个地方是整条配置的核心内容,如果此处规则匹配是无效的,则生成后的日志时间戳将会被input插件读取的时间替代。
如果时间格式匹配失败,会生成一个tags字段,字段值为 _dateparsefailure,需要重新检查上边的match配置解析是否正确。

●target:将匹配的时间戳存储到给定的目标字段中。如果未提供,则默认更新事件的@timestamp字段。

●timezone:当需要配置的date里面没有时区信息,而且不是UTC时间,需要设置timezone参数。

//时间戳详解:
●年
yyyy #全年号码。 例如:2015。
yy #两位数年份。 例如:2015年的15。

●月
M #最小数字月份。 例如:1 for January and 12 for December.。
MM #两位数月份。 如果需要,填充零。 例如:01 for January and 12 for Decembe
MMM #缩短的月份文本。 例如: Jan for January。 注意:使用的语言取决于您的语言环境。 请参阅区域设置以了解如何更改语言。
MMMM #全月文本,例如:January。 注意:使用的语言取决于您的语言环境。

●日
d #最少数字的一天。 例如:1月份的第一天1。
dd #两位数的日子,如果需要的话可以填零.例如:01 for the 1st of the month。

●时
H #最小数字小时。 例如:0表示午夜。
HH #两位数小时,如果需要填零。 例如:午夜00。

●分
m #最小的数字分钟。 例如:0。
mm #两位数分钟,如果需要填零。 例如:00。

●秒
s #最小数字秒。 例如:0。
ss #两位数字,如果需要填零。 例如:00。

●毫秒( 秒的小数部分最大精度是毫秒(SSS)。除此之外,零附加。)
S #十分之一秒。例如:0为亚秒值012
SS #百分之一秒 例如:01为亚秒值01
SSS #千分之一秒 例如:012为亚秒值012

●时区偏移或身份
Z #时区偏移,结构为HHmm(Zulu/UTC的小时和分钟偏移量)。例如:-0700。
ZZ #时区偏移结构为HH:mm(小时偏移和分钟偏移之间的冒号)。 例如:-07:00。
ZZZ #时区身份。例如:America/Los_Angeles。 注意:有效的ID在列表中列出http://joda-time.sourceforge.net/timezones.html

//案例:
192.168.80.10 - - [07/Feb/2022:16:24:19 +0800] “GET /HTTP/1.1” 403 5039

现在我们想转换时间,那就要写出"dd/MMM/yyyy:HH:mm:ss Z"
你发现中间有三个M,你要是写出两个就不行了,因为两个大写的M表示两位数字的月份,可是我们要解析的文本中,月份则是使用简写的英文,所以只能去找三个M。还有最后为什么要加上个大写字母Z,因为要解析的文本中含有“+0800”时区偏移,因此我们要加上去,否则filter就不能正确解析文本数据,从而转换时间戳失败。

filter{
      grok{
           match => {"message" => ".* -\ -\ \[%{HTTPDATE:timestamp}\]"}
      }
      date{
           match => ["timestamp","dd/MMM/yyyy:HH:mm:ss Z"]
    }
}

运行结果:
{
          "host" => "localhost",
     "timestamp" => "07/Feb/2022:16:24:19 +0800",
    "@timestamp" => 2022-02-07T08:24:19.000Z,
       "message" => "192.168.80.10 - - [07/Feb/2022:16:24:19 +0800] \"GET /HTTP/1.1\" 403 5039",
      "@version" => "1"
}

在上面那段rubydebug编码格式的输出中,@timestamp字段虽然已经获取了timestamp字段的时间,但是仍然比北京时间晚了8个小时,这是因为在Elasticsearch内部,对时间类型字段都是统一采用UTC时间,而日志统一采用UTC时间存储,是国际安全、运维界的一个共识。其实这并不影响什么,因为ELK已经给出了解决方案,那就是在Kibana平台上,程序会自动读取浏览器的当前时区,然后在web页面自动将UTC时间转换为当前时区的时间。

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

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

相关文章

凯迪正大数显电动调压控制台

数显电动调压控制台使用方法 1、核对试验变压器&#xff0c;测量绕阻额定输出电压&#xff0c;使之与操作箱&#xff08;台&#xff09;相吻合。 2、按接线示意图接好试验变压器与操作箱&#xff08;台&#xff09;及感应调压器之间的联线。 3、接通电源&#xff0c;通电源指…

el-select 右侧icon样式问题

el-select 右侧icon样式问题 样式问题如图&#xff1a; 解决方法&#xff1a; el-input__suffix {display: flex;align-items: center;justify-content: center; }注意&#xff1a;样式需写在没有scoped的style标签里

在VSCODE编辑器是用ctrl+c和ctrl+s(复制粘贴)失效怎么办

有时我们在开发过程中&#xff0c;由于使用vsccode太长时间导致复制ctrlc和ctrls会失效&#xff0c;之前我的处理方式是重启浏览器&#xff0c;但有时候这样太耗时间了&#xff0c;但发现一个方法可以解决&#xff0c;就是刷新下编辑器的timeline就行&#xff0c;如下图&#x…

快速构建一个 GitLab + Jenkins + Harbor 的云原生 DevOps 环境

今天我们要搭建一条怎样的工具链呢&#xff1f;且看效果图&#xff1a; GitLab Jenkins Harbor Toolchain Workflow 首先我们需要完成 GitLab、Jenkins 和 Harbor 三个工具的部署&#xff1b; 接着我们需要在 GitLab 上创建一个代码库&#xff0c;并且在 Jenkins 上创建相应…

若依系统学习笔记记录1

下载后的文件列表 先按照nocos. Nacos: 概览 欢迎来到 Nacos 的世界&#xff01; Nacos 致力于帮助您发现、配置和管理微服务Nacos: 概览 欢迎来到 Nacos 的世界&#xff01; Nacos 致力于帮助您发现、配置和管理微服务 cd nacos/ mvn命令如果是idea,需要用Ctrlshiftenter来执…

【软件测试】MySQL数据库场景问题+解决方案

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 问题1&#xff1a…

2023年测试岗,自动化测试如何学?如何卷出测试圈?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 怎么学习自动化测…

初识FreeRTOS

一、FreeRTOS 介绍 什么是 FreeRTOS &#xff1f; Free即免费的&#xff0c;RTOS的全称是Real time operating system&#xff0c;中文就是实时操作系统。 注意&#xff1a;RTOS不是指某一个确定的系统&#xff0c;而是指一类操作系统。比如&#xff1a;uc/OS&#xff0c;Fre…

STM32 Proteus仿真LCD12864火灾检测烟雾火焰温度报警器MQ2 -0064

STM32 Proteus仿真LCD12864火灾检测烟雾火焰温度报警器MQ2 -0064 Proteus仿真小实验&#xff1a; STM32 Proteus仿真LCD12864火灾检测烟雾火焰温度报警器MQ2 -0064 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 LCD12864 液晶显示DS18B20 温度传感器多个按键电位…

阿里云配置端口安全组策略

文章目录 为何配置安全组安全组设置安全组应用到实例中 为何配置安全组 nginx正确配置了83端口&#xff0c;却无法访问资源&#xff0c;报502错误&#xff0c;这大概就是服务器的安全策略原因 安全组设置 安全组配置地址 安全组应用到实例中 配置地址

pandas 各种存储格式速度对比:CSV、hdf5、SQL、pickle、feather、parquet

前言&#xff1a;目前我在做一个callback函数&#xff0c;需要将数据重复的读取、写入&#xff0c;再供使用&#xff0c;并且数据量比较大&#xff0c;所以需要使用一个读写速度快的存储方式&#xff0c;不太考虑占用的磁盘空间 直接看结果 csv的文件存储&#xff0c;在读取的…

Java虚拟机(JVM)

Java虚拟机&#xff08;JVM&#xff09; 类加载 类加载 Java类加载的过程可以分为以下几个步骤&#xff1a; 加载&#xff08;Loading&#xff09;&#xff1a;类加载的第一步是将类的字节码文件加载到内存中。 通过类的全名&#xff0c;全限定名&#xff08;包括包名和类名&…

C++之std::enable_if_t用法(一百五十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

“人工智能的崛起:挑战与机遇并存“

近日&#xff0c;一位美国网络安全高级官员发出警告&#xff0c;称如果科技公司未能自我约束并与政府合作控制人工智能的力量&#xff0c;我们可能面临着巨大的风险。这位官员的言论是在数百名科技领袖和公众人物支持的联合声明之后发表的&#xff0c;该声明将人工智能的存在威…

mysql练习---存储过程/存储函数

创建表并插入数据 字段名 数据类型 主键 外键 非空 唯一 自增 id INT 是 否 是 是 否 name VARCHAR(50) 否 否 是 否 否 glass VARCHAR(50) 否 否 是 否 否 sch 表内容 id name glass 1 xiaommg glass 1 2 xiaojun glass 2 1、创建一个可以统计表格内记录条数的存储函数 &#…

W波段超外差LO两种倍频链路的比较

W波段&#xff08;75-110GHz&#xff09;由于其衰减小&#xff0c;分辨率高&#xff0c;超宽带等优势&#xff0c;受到越来越多的关注。之前由于成本高昂&#xff0c;主要是军事方面的应用。近些年随着Gotmic等厂家毫米波芯片的量产&#xff0c;成本大大降低&#xff0c;已被很…

LRU 缓存

题目链接 LRU 缓存 题目描述 注意点 如果插入操作导致关键字数量超过 capacity &#xff0c;则应该 逐出 最久未使用的关键字函数 get 和 put 必须以 O(1) 的平均时间复杂度运行 解答思路 如果想以O(1)的速度进行get&#xff0c;则需要将对应的key、value存到map中如果想…

word 公式序号自动按章节排序

1.在普通视图下&#xff0c;使用Alt和F9切换到域代码模式。 普通视图 域代码模式 2.光标放在章节标题最后一个字后面&#xff0c;使用Ctrl和F9添加域代码的大括号 3.在大括号中键入 SEQ ch \h 4.光标放在刚刚的大括号后面&#xff0c;再次按下Ctrl和F9添加域代码的大括号 5.…

SAP MESSAGE ID LB31的问题和解决办法

外协采购订单判退时报错 EA 返回交货(原因)-> 3700006717 /00009 (0000) 1 EA 不正确过帐返回给供应商&#xff0c;错误信息:对所需数量 XXXXXX00003122&#xff0c;1.000 PCS 仍然未清LB 31 搜索到lb31是和批次相关的错误 https://www.michaelmanagement.com/sap-error-mes…

YoloX训练报错“IndexError: list index out of range”

问题描述 在训练Yolox时报错&#xff0c;IndexError: list index out of range 解决方案 在/yolox/data/datasets/voc.py修改第138行 (self._imgpath % self.ids[i]).split(self.root "\\")[1]修改完代码就没问题了&#xff0c;开始训练