ES8生产实践——日志清洗过滤(vector方案)

前言

什么是vector

以下描述摘自官方文档:https://vector.dev/docs/about/what-is-vector/

Vector 是一个高性能的可观测性数据管道,可帮助企业控制其可观测性数据。收集、转换和路由所有日志、度量指标和跟踪数据,并将其提供给今天需要的任何供应商和明天可能需要的任何其他供应商。Vector 可在您需要的地方,而不是在供应商最方便的地方,大幅降低成本、丰富新颖的数据并确保数据安全。开放源代码,速度比其他任何替代方案快 10 倍。

简单来说由于logstash使用java语言开发,在处理海量数据时存在性能低下,占用资源过高的问题。而vector使用Rust语言编写,除了使用极少的资源实现logstash数据处理能力外,还具备配置文件简单、处理函数强大、智能均衡kafka分区消费、自适应并发请求等特色功能。

vector架构图

与logstash管道处理类似,vector主要包含数据输入、数据处理、数据输出三部分。
ES8生产实践——日志清洗过滤(vector方案)_第1张图片

vector优势

  • 超级快速可靠:Vector采用Rust构建,速度极快,内存效率高,旨在处理最苛刻的工作负载
  • 端到端:Vector 致力于成为从 A 到 B 获取可观测性数据所需的唯一工具,并作为守护程序、边车或聚合器进行部署
  • 统一:Vector 支持日志和指标,使您可以轻松收集和处理所有可观测性数据
  • 供应商中立:Vector 不偏向任何特定的供应商平台,并以您的最佳利益为出发点,培育公平、开放的生态系统。免锁定且面向未来
  • 可编程转换:Vector 的高度可配置转换为您提供可编程运行时的全部功能。无限制地处理复杂的用例

对比测试

性能对比

下图是 Vector 与其它日志收集器的性能测试结果对比,可以看到,Vector 的各项性能指标都优于 Logstash,综合性能也不错,加上其丰富的功能,完全可以满足我们的日志处理需求。

Test Vector Filebeat FluentBit FluentD Logstash SplunkUF SplunkHF
TCP to Blackhole 86mib/s n/a 64.4mib/s 27.7mib/s 40.6mib/s n/a n/a
File to TCP 76.7mib/s 7.8mib/s 35mib/s 26.1mib/s 3.1mib/s 40.1mib/s 39mib/s
Regex Parsing 13.2mib/s n/a 20.5mib/s 2.6mib/s 4.6mib/s n/a 7.8mib/s
TCP to HTTP 26.7mib/s n/a 19.6mib/s <1mib/s 2.7mib/s n/a n/a
TCP to TCP 69.9mib/s 5mib/s 67.1mib/s 3.9mib/s 10mib/s 70.4mib/s 7.6mib/s

可靠性对比

Test Vector Filebeat FluentBit FluentD Logstash Splunk UF Splunk HF
Disk Buffer Persistence
Disk Buffer Persistence
File Rotate (copytruncate)
File Truncation
Process (SIGHUP)
JSON (wrapped)

功能性对比

Vector Beats Fluentbit Fluentd Logstash Splunk UF Splunk HF Telegraf
End-to-end
Agent
Aggregator
Unified
Logs
Metrics
Open
Open-source
Vendor-neutral
Reliability
Memory-safe
Delivery guarantees
Multi-core

快速上手

安装部署

官方为我们提供了安装包、docker等多种安装方式,下载地址:https://vector.dev/download/,此处以rpm包部署为例。

[root@tiaoban ~]# wget https://packages.timber.io/vector/0.34.0/vector-0.34.0-1.x86_64.rpm
[root@tiaoban ~]# rpm -ivh vector-0.34.0-1.x86_64.rpm
[root@tiaoban ~]# systemctl start vector --now

配置测试

与logstash类似,在调试数据处理规则时,通常会从文件中读取数据,经过一系列处理后最后输出至控制台。其作用是读取 /var/log/messages日志文件,然后把 syslog 格式的日志转换成 json 格式,最后输出到标准输出:

[root@tiaoban ~]# cd /etc/vector/
[root@tiaoban vector]# ls
examples  vector.yaml  vector.yaml.back
[root@tiaoban vector]# cat vector.yaml
sources:
  in:
    type: "stdin"

sinks:
  print:
    type: "console"
    inputs: ["in"]
    encoding:
      codec: "json"
[root@tiaoban vector]# vector -c vector.yaml
2023-11-12T13:40:06.995872Z  INFO vector::app: Log level is enabled. level="vector=info,codec=info,vrl=info,file_source=info,tower_limit=info,rdkafka=info,buffers=info,lapin=info,kube=info"
2023-11-12T13:40:06.996328Z  INFO vector::app: Loading configs. paths=["vector.yaml"]
2023-11-12T13:40:06.998137Z  INFO vector::topology::running: Running healthchecks.
2023-11-12T13:40:06.998206Z  INFO vector: Vector has started. debug="false" version="0.34.0" arch="x86_64" revision="c909b66 2023-11-07 15:07:26.748571656"
2023-11-12T13:40:06.998219Z  INFO vector::app: API is disabled, enable by setting `api.enabled` to `true` and use commands like `vector top`.
2023-11-12T13:40:06.998590Z  INFO vector::topology::builder: Healthcheck passed.
2023-11-12T13:40:06.998766Z  INFO vector::sources::file_descriptors: Capturing stdin.
hello vector
{"host":"tiaoban","message":"hello vector","source_type":"stdin","timestamp":"2023-11-12T13:40:13.368669601Z"}

当控制台开始打印日志,就说明正常采集到了数据,而且转换成了 json 并打印到了控制台,实验成功。接下来详细介绍vector各个配置段具体内容。

多配置文件

当项目、环境、规则等十分庞杂时,推荐对配置文件根据需要进行拆分,而默认的 vector.toml 文件中可以写入一些全局配置。
修改systemctl 命令管理相关配置,让 Vector 读取指定目录下所有配置文件,而非默认的 vector.toml 文件。
将 Vector systemd 配置文件第 12 行由 ExecStart=/usr/bin/vector 修改为:ExecStart=/usr/bin/vector “–config-dir” “/etc/vector”:

# /usr/lib/systemd/system/vector.service
[Unit]
Description=Vector
Documentation=https://vector.dev
After=network-online.target
Requires=network-online.target


[Service]
User=vector
Group=vector
ExecStartPre=/usr/bin/vector validate
ExecStart=/usr/bin/vector "--config-dir" "/etc/vector"
ExecReload=/usr/bin/vector validate
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
AmbientCapabilities=CAP_NET_BIND_SERVICE
EnvironmentFile=-/etc/default/vector
# Since systemd 229, should be in [Unit] but in order to support systemd <229,
# it is also supported to have it here.
StartLimitInterval=10
StartLimitBurst=5
[Install]
WantedBy=multi-user.target

修改 vector 配置目录环境变量,将 VECTOR_CONFIG_DIR="/etc/vector/"追加到 /etc/default/vector 文件最后:

# /etc/default/vector
# This file can theoretically contain a bunch of environment variables
# for Vector.  See https://vector.dev/docs/setup/configuration/#environment-variables
# for details.
VECTOR_CONFIG_DIR="/etc/vector/"

重新加载 systemd 配置并重启 Vector:

systemctl daemon-reload
systemctl restart vector

配置文件详解

配置文件构成

根据架构图可知,Vector由 Sources、Transforms和Sinks三个部分构成,Vector作为一款管道处理工具,日志数据可以从多个源头(source)流入管道,比如 HTTP、Syslog、File、Kafka 等等,当日志数据流入管道后,就可以被进行一系列处理,处理的过程就是转换(Transform),比如增减日志中的一些字段,对日志进行重新格式化等操作,日志被处理成想要的样子后,就可以传输给接收器(Sink)处理,也就是日志最终流向何处,可以是 Elasticsearch、ClickHouse、AWS S3 等等,配置文件基本格式如下

sources:	# 源
  my_source_id:   # 数据源名称
    type: "***" # 数据源类型
    
transforms: # 转换
  my_transform_id: # 转换名称
    type: remap # 转换类型
    inputs: # 转换操作的源
      - my_source_id

源(source)

Vector 提供了丰富的 Sources 供使用,常用的有控制台、模拟数据、File、http、Kafka等,并且支持的种类还在不断增加,详情参考官方文档https://vector.dev/docs/reference/configuration/sources/。

  • 控制台输入
sources:
  my_source_id:   # 数据源名称
    type: "stdin"
  • 模拟日志数据输入
sources:
  my_source_id:  # 数据源名称
    type: "demo_logs"
    format: "apache_common"  # 模拟数据类型
    count:  10 # 模拟数据条数
  • file输入示例:
sources:
  my_source_id:   # 数据源名称
    type: "file"
    include:			# 采集路径
      - /var/log/**/*.log
  • http输入示例:
sources:
  my_source_id:  # 数据源名称
    type: "http_server"
    address: "0.0.0.0:80" # 监听地址
  • kafka输入示例:
sources:
  my_source_id: # 数据源名称
    type: "kafka"
    bootstrap_servers: "10.14.22.123:9092,10.14.23.332:9092" # kafka地址
    group_id: "consumer-group-name"	# 消费组id
    topics: # 消费主题,支持多个topic使用正则匹配
      - ^(prefix1|prefix2)-.+
    decoding: # 编码格式
      codec: "json"
    auto_offset_reset: "latest" # 消费偏移

转换(transforms)-VRL

在Vector传输数据时,可能涉及数据解析、过滤、新增等操作,跟Logstash组件类似,Vector 提供了诸多 Transforms插件来对日志进行处理。 更多transforms插件参考文档:https://vector.dev/docs/reference/configuration/transforms/
Vector推荐使用remap插件处理数据,它使用VRL语言对日志进行处理,它提供了非常丰富的函数,可以拿来即用。在线调试地址:https://playground.vrl.dev/,VRL语言快速入门参考文档:https://vector.dev/docs/reference/vrl/
接下来列举几个常用的转换案例

  • 字段增删改
# 配置文件
sources:
  my_source:   # 数据源名称
    type: "stdin"

transforms:
  my_transform:
    type: remap
    inputs:    # 匹配输入源
      - my_source
    source: |
      . = parse_json!(.message) # 解析json数据
      .@timestamp = now() # 新增字段
      del(.user) # 删除字段
      .age = del(.value) # 重命名字段

sinks:
  my_print:
    type: "console"
    inputs: ["my_transform"] # 匹配过滤项
    encoding:
      codec: "json"
# 执行结果
{"hello":"world","user":"张三","value":18}
{"@timestamp":"2023-11-19T03:02:07.060420199Z","age":18,"hello":"world"}
  • 字段值操作
# 配置文件
sources:
  my_source:   # 数据源名称
    type: "stdin"

transforms:
  my_transform:
    type: remap
    inputs:    # 匹配输入源
      - my_source
    source: |
      . = parse_json!(.message) # 解析json数据
      .msg = downcase(string!(.msg)) # 转小写
      .user = replace(string!(.user), "三", "四") # 字符串替换
      .value = floor(float!(.value), precision: 2) # 小数保留指定长度

sinks:
  my_print:
    type: "console"
    inputs: ["my_transform"] # 匹配过滤项
    encoding:
      codec: "json"
# 执行结果
{"msg":"Hello, World!","user":"张三","value":3.1415926}
{"msg":"hello, world!","user":"张四","value":3.14}
  • 正则解析
# 配置文件
sources:
  my_source:   # 数据源名称
    type: "stdin"

transforms:
  my_transform:
    type: remap
    inputs:    # 匹配输入源
      - my_source
    source: |
      . = parse_regex!(.message, r'^\[(?[^\]]*)\] (?[^ ]*) (?[^ ]*) (?<id>\d*)$')</span>

<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"my_transform"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配过滤项</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span>
<span class="token comment"># 执行结果</span>
<span class="token punctuation">[</span>2023<span class="token punctuation">-</span>11<span class="token punctuation">-</span>11 12<span class="token punctuation">:</span>00<span class="token punctuation">:</span>00 +0800<span class="token punctuation">]</span> alice engineer 1
<span class="token punctuation">{</span>"id"<span class="token punctuation">:</span><span class="token string">"1"</span><span class="token punctuation">,</span>"logtime"<span class="token punctuation">:</span><span class="token string">"2023-11-11 12:00:00 +0800"</span><span class="token punctuation">,</span>"name"<span class="token punctuation">:</span><span class="token string">"alice"</span><span class="token punctuation">,</span>"title"<span class="token punctuation">:</span><span class="token string">"engineer"</span><span class="token punctuation">}</span>
</code></pre> 
  <ul> 
   <li>时间格式化</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token comment"># 配置文件</span>
<span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_source</span><span class="token punctuation">:</span>   <span class="token comment"># 数据源名称</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"stdin"</span>

<span class="token key atrule">transforms</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_transform</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> remap
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>    <span class="token comment"># 匹配输入源</span>
      <span class="token punctuation">-</span> my_source
    <span class="token key atrule">source</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
      . = parse_regex!(.message, r'^\[(?<logtime>[^\]]*)\] (?<name>[^ ]*) (?<title>[^ ]*) (?<id>\d*)$')
      .logtime = parse_timestamp!((.logtime), format:"%Y-%m-%d %H:%M:%S %:z")</span>
<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"my_transform"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配过滤项</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span>
<span class="token comment"># 执行结果</span>
<span class="token punctuation">[</span>2023<span class="token punctuation">-</span>11<span class="token punctuation">-</span>11 12<span class="token punctuation">:</span>00<span class="token punctuation">:</span>00 +0800<span class="token punctuation">]</span> alice engineer 1
<span class="token punctuation">{</span>"id"<span class="token punctuation">:</span><span class="token string">"1"</span><span class="token punctuation">,</span>"logtime"<span class="token punctuation">:</span><span class="token string">"2023-11-11T04:00:00Z"</span><span class="token punctuation">,</span>"name"<span class="token punctuation">:</span><span class="token string">"alice"</span><span class="token punctuation">,</span>"title"<span class="token punctuation">:</span><span class="token string">"engineer"</span><span class="token punctuation">}</span>
</code></pre> 
  <ul> 
   <li>geoip解析</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token comment"># 配置文件</span>
<span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_source</span><span class="token punctuation">:</span>   <span class="token comment"># 数据源名称</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"stdin"</span>

<span class="token key atrule">transforms</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_transform</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> remap
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>    <span class="token comment"># 匹配输入源</span>
      <span class="token punctuation">-</span> my_source
    <span class="token key atrule">source</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
      . = parse_json!(.message) # 解析json数据
      .geoip = get_enrichment_table_record!("geoip_table",
        {
          "ip": .ip_address
        })</span>

<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"my_transform"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配过滤项</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span>

<span class="token key atrule">enrichment_tables</span><span class="token punctuation">:</span>
  <span class="token key atrule">geoip_table</span><span class="token punctuation">:</span> <span class="token comment"># 指定geoip数据库文件</span>
    <span class="token key atrule">path</span><span class="token punctuation">:</span> <span class="token string">"/root/GeoLite2-City.mmdb"</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> geoip
<span class="token comment"># 执行结果</span>
<span class="token punctuation">{</span>"ip_address"<span class="token punctuation">:</span><span class="token string">"185.14.47.131"</span><span class="token punctuation">}</span>
<span class="token punctuation">{</span>"geoip"<span class="token punctuation">:</span><span class="token punctuation">{</span>"city_name"<span class="token punctuation">:</span><span class="token string">"Hong Kong"</span><span class="token punctuation">,</span>"continent_code"<span class="token punctuation">:</span><span class="token string">"AS"</span><span class="token punctuation">,</span>"country_code"<span class="token punctuation">:</span><span class="token string">"HK"</span><span class="token punctuation">,</span>"country_name"<span class="token punctuation">:</span><span class="token string">"Hong Kong"</span><span class="token punctuation">,</span>"latitude"<span class="token punctuation">:</span><span class="token number">22.2842</span><span class="token punctuation">,</span>"longitude"<span class="token punctuation">:</span><span class="token number">114.1759</span><span class="token punctuation">,</span>"metro_code"<span class="token punctuation">:</span><span class="token null important">null</span><span class="token punctuation">,</span>"postal_code"<span class="token punctuation">:</span><span class="token null important">null</span><span class="token punctuation">,</span>"region_code"<span class="token punctuation">:</span><span class="token string">"HCW"</span><span class="token punctuation">,</span>"region_name"<span class="token punctuation">:</span><span class="token string">"Central and Western District"</span><span class="token punctuation">,</span>"timezone"<span class="token punctuation">:</span><span class="token string">"Asia/Hong_Kong"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>"ip_address"<span class="token punctuation">:</span><span class="token string">"185.14.47.131"</span><span class="token punctuation">}</span>
</code></pre> 
  <h3>转换(transforms)-Lua</h3> 
  <p>如果 VRL 不能满足用户对日志的处理需求,Vector 也支持嵌入 Lua 语言对日志进行处理,但是这种方式要比 VRL 慢将近 60 %。具体内容可参考文档:https://vector.dev/docs/reference/configuration/transforms/lua/,此处不再做过多介绍,推荐优先使用VRL语言转换。</p> 
  <h3>转换(transforms)-过滤</h3> 
  <p>很多时候从数据源采集过来的数据我们并不是全部都需要,filter顾名思义便是用来解决这一问题的,例如删除debug等级的日志信息。</p> 
  <pre><code class="prism language-yaml"><span class="token comment"># 配置文件</span>
<span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_source</span><span class="token punctuation">:</span>   <span class="token comment"># 数据源名称</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"stdin"</span>

<span class="token key atrule">transforms</span><span class="token punctuation">:</span>
  <span class="token key atrule">transform_json</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> remap
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>    <span class="token comment"># 匹配输入源</span>
      <span class="token punctuation">-</span> my_source
    <span class="token key atrule">source</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
      . = parse_json!(.message) # 解析json数据</span>
    
  <span class="token key atrule">transform_filter</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> filter
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> transform_json
    <span class="token key atrule">condition</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
      .level != "debug"</span>
  

<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"transform_filter"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配过滤项</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span>
<span class="token comment"># 执行结果</span>
<span class="token punctuation">{</span>"level"<span class="token punctuation">:</span><span class="token string">"debug"</span><span class="token punctuation">,</span>"msg"<span class="token punctuation">:</span><span class="token string">"hello"</span><span class="token punctuation">}</span>
<span class="token punctuation">{</span>"level"<span class="token punctuation">:</span><span class="token string">"waring"</span><span class="token punctuation">,</span>"msg"<span class="token punctuation">:</span><span class="token string">"hello"</span><span class="token punctuation">}</span>
<span class="token punctuation">{</span>"level"<span class="token punctuation">:</span><span class="token string">"waring"</span><span class="token punctuation">,</span>"msg"<span class="token punctuation">:</span><span class="token string">"hello"</span><span class="token punctuation">}</span>
</code></pre> 
  <h3>接收器(sinks)</h3> 
  <p>接收器是事件的目的地,Vector同样提供了很多 Sinks 类型,其中有些和 Sources 是重合的,比如 Kafka、AWS S3 等,更多支持的接收器类型可参考文档:https://vector.dev/docs/reference/configuration/sinks/</p> 
  <ul> 
   <li>输出到控制台</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"in"</span><span class="token punctuation">]</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span> <span class="token comment"># 输出为json格式,也可设置为text文件</span>
</code></pre> 
  <ul> 
   <li>输出到文件</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_sink_id</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> file
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> my<span class="token punctuation">-</span>source<span class="token punctuation">-</span>or<span class="token punctuation">-</span>transform<span class="token punctuation">-</span>id
    <span class="token key atrule">path</span><span class="token punctuation">:</span> /tmp/vector<span class="token punctuation">-</span>%Y<span class="token punctuation">-</span>%m<span class="token punctuation">-</span>%d.log
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"text"</span>
</code></pre> 
  <ul> 
   <li>输出到kafka</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_sink_id</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> kafka
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> my<span class="token punctuation">-</span>source<span class="token punctuation">-</span>or<span class="token punctuation">-</span>transform<span class="token punctuation">-</span>id
    <span class="token key atrule">bootstrap_servers</span><span class="token punctuation">:</span> 10.14.22.123<span class="token punctuation">:</span><span class="token number">9092</span><span class="token punctuation">,</span>10.14.23.332<span class="token punctuation">:</span><span class="token number">9092</span>
    <span class="token key atrule">topic</span><span class="token punctuation">:</span> topic<span class="token punctuation">-</span><span class="token number">1234</span>
</code></pre> 
  <ul> 
   <li>输出到elasticsearch</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_es</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> elasticsearch
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"my_transform"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配转换配置</span>
    <span class="token key atrule">api_version</span><span class="token punctuation">:</span> <span class="token string">"v8"</span>        <span class="token comment"># ES版本,非必填</span>
    <span class="token key atrule">mode</span><span class="token punctuation">:</span> <span class="token string">"data_stream"</span> <span class="token comment"># 数据流方式写入</span>
    <span class="token key atrule">auth</span><span class="token punctuation">:</span> <span class="token comment"># es认证信息 </span>
      <span class="token key atrule">strategy</span><span class="token punctuation">:</span> <span class="token string">"basic"</span>
      <span class="token key atrule">user</span><span class="token punctuation">:</span> <span class="token string">"elastic"</span>
      <span class="token key atrule">password</span><span class="token punctuation">:</span> <span class="token string">"WbZN3xfa5M4uy+UcxJeH"</span>
    <span class="token key atrule">data_stream</span><span class="token punctuation">:</span> <span class="token comment"># 数据流名称配置</span>
      <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"logs"</span>
      <span class="token key atrule">dataset</span><span class="token punctuation">:</span> <span class="token string">"vector"</span>
      <span class="token key atrule">namespace</span><span class="token punctuation">:</span> <span class="token string">"default"</span>
    <span class="token key atrule">endpoints</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"https://192.168.10.50:9200"</span><span class="token punctuation">]</span> <span class="token comment"># es连接地址</span>
    <span class="token key atrule">tls</span><span class="token punctuation">:</span> <span class="token comment"># tls证书配置</span>
      <span class="token key atrule">verify_certificate</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># 跳过证书验证</span>
      <span class="token comment"># ca_file: "XXXXX" # ca证书路径</span>
</code></pre> 
  <p>写入es中的数据流信息如下所示:<br> <a href="http://img.e-com-net.com/image/info8/a5827c6a3cc04b86af3db19c51dbc9b3.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a5827c6a3cc04b86af3db19c51dbc9b3.jpg" alt="ES8生产实践——日志清洗过滤(vector方案)_第2张图片" width="650" height="189" style="border:1px solid black;"></a></p> 
  <h3>全局配置</h3> 
  <ul> 
   <li>数据目录</li> 
  </ul> 
  <p>用于持久化 Vector 状态的目录,例如 作为磁盘缓冲区、文件检查点等功能。</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">data_dir</span><span class="token punctuation">:</span> <span class="token string">"/var/lib/vector"</span>
</code></pre> 
  <ul> 
   <li>API</li> 
  </ul> 
  <p>vector为我们提供了常用的API接口,可以很方便的进行监控检查与状态信息获取。<br> 首先打开 Vector 的 api 功能,在 vector.toml 配置文件中加入以下内容即可:</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">api</span><span class="token punctuation">:</span>
  <span class="token key atrule">enabled</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>
  <span class="token key atrule">address</span><span class="token punctuation">:</span> <span class="token string">"0.0.0.0:8686"</span>
</code></pre> 
  <p>重启 Vector,获取 Vector 的健康状态:</p> 
  <pre><code class="prism language-javascript">$ curl localhost<span class="token operator">:</span><span class="token number">8686</span><span class="token operator">/</span>health
<span class="token punctuation">{</span><span class="token string-property property">"ok"</span><span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">}</span>
</code></pre> 
  <p>开启api后,我们还可以通过命令行<code>vector top</code>命令获取各个任务的性能信息<br> <a href="http://img.e-com-net.com/image/info8/c3990f46428145249e816bf77c4fe716.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c3990f46428145249e816bf77c4fe716.jpg" alt="ES8生产实践——日志清洗过滤(vector方案)_第3张图片" width="650" height="159" style="border:1px solid black;"></a></p> 
  <h2>监控</h2> 
  <h3>指标</h3> 
  <ul> 
   <li>prometheus_remote_write</li> 
  </ul> 
  <p>将 Vector 内部指标 Sink 到 Prometheus,据此建立更为详细的 Dashboard 和告警。<br> 在 vector.toml 配置文件中加入以下内容即可,vector 内置的指标通过远程写入的方式写入指定的 Prometheus中。</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">vector_metrics</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> internal_metrics
<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">prometheus</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> prometheus_remote_write
    <span class="token key atrule">endpoint</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> https<span class="token punctuation">:</span>//<prometheus_ip_address<span class="token punctuation">></span><span class="token punctuation">:</span>8087/
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> vector_metrics
</code></pre> 
  <ul> 
   <li>prometheus_exporter</li> 
  </ul> 
  <p>除了远程写入外,vector也支持通过exporter方式保留指标数据供Prometheus抓取,配置文件如下</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">metrics</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> internal_metrics
    <span class="token key atrule">namespace</span><span class="token punctuation">:</span> vector
    <span class="token key atrule">scrape_interval_secs</span><span class="token punctuation">:</span> <span class="token number">30</span>

<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">prometheus</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> prometheus_exporter
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> metrics
    <span class="token key atrule">address</span><span class="token punctuation">:</span> 0.0.0.0<span class="token punctuation">:</span><span class="token number">9598</span>
    <span class="token key atrule">default_namespace</span><span class="token punctuation">:</span> service
</code></pre> 
  <p>然后在Prometheus的job中配置地址为<code>http://IP:9598/metrics</code>即可。</p> 
  <h3>日志</h3> 
  <p>将vector的运行日志写入本地文件或者elasticsearch中存储,以本地存储为例:</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">logs</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"internal_logs"</span>

<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">files</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> file
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> logs
    <span class="token key atrule">path</span><span class="token punctuation">:</span> /tmp/vector<span class="token punctuation">-</span>%Y<span class="token punctuation">-</span>%m<span class="token punctuation">-</span>%d.log
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> text
</code></pre> 
  <h2>特色功能</h2> 
  <h3>vector自动均衡kafka消费</h3> 
  <p>在之前使用logstash消费kafka数据时,需要根据topic数据量大小配置kafka partition数、Logstash副本数、每个logstash线程数,而这些数量只能根据性能监控图和数据量逐个调整至合适的大小。例如有6台logstash机器,其中5台机器专门用于消费数据量大的topic,其他机器消费小数据量的topic,经常存在logstash节点负载不均衡的问题。<br> 使用vector后,我们只需要让所有机器使用相同的配置,借助Kafka的Consumer Group技术,不同配置文件通过同一个group_id即可一起消费所有的topic,vector在消费的过程中会自动均衡kafka消费速率。</p> 
  <h3>自适应并发请求</h3> 
  <p>在0.11.0版本后默认启用了自适应并发,这是一个智能、强大的功能,官方介绍https://vector.dev/blog/adaptive-request-concurrency/#rate-limiting-problem<br> 在之前的版本中,为了保障数据正常写入下游Elasticsearch或Clickhouse时,需要进行速率限制。但限制速率值设定存在以下问题</p> 
  <ul> 
   <li>将限制设置得太高,从而使服务不堪重负,从而损害系统可靠性。</li> 
   <li>设置的限制太低,浪费资源。</li> 
  </ul> 
  <p>为了解决这个问题,vector推出了自适应并发的功能,它会重点观察两件事:请求的往返时间 (RTT) 和 HTTP 响应代码(失败与成功),从而决策出一个最佳的速率!<br> <a href="http://img.e-com-net.com/image/info8/1385baef10dc49c0afa7d46dea1db6fb.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/1385baef10dc49c0afa7d46dea1db6fb.jpg" alt="ES8生产实践——日志清洗过滤(vector方案)_第4张图片" width="650" height="232" style="border:1px solid black;"></a><br> 在写入Elasticsearch或Clickhouse时,默认已将其设为启用, 不需要进一步的配置。</p> 
  <h2>vector解析日志实践</h2> 
  <h3>调试解析配置</h3> 
  <p>假设线上应用原始日志格式如下,接下来我们通过vector解析日志内容。</p> 
  <pre><code>2023-07-23 09:35:18.987 | INFO     | __main__:debug_log:49 - {'access_status': 200, 'request_method': 'GET', 'request_uri': '/account/', 'request_length': 67, 'remote_address': '185.14.47.131', 'server_name': 'cu-36.cn', 'time_start': '2023-07-23T09:35:18.879+08:00', 'time_finish': '2023-07-23T09:35:19.638+08:00', 'http_user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2999.0 Safari/537.36'}
</code></pre> 
  <ol> 
   <li>修改vector配置文件,添加sources配置项,从控制台读取数据。并新增sinks配置项,输出到控制台,vector配置文件如下所示:</li> 
  </ol> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_source</span><span class="token punctuation">:</span>   
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"stdin"</span>
  
<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"my_source"</span><span class="token punctuation">]</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span> 
</code></pre> 
  <p>观察控制台输出内容,已经将控制台输出的日志数据添加到了message字段中</p> 
  <pre><code class="prism language-bash"><span class="token number">2023</span>-07-23 09:35:18.987 <span class="token operator">|</span> INFO     <span class="token operator">|</span> __main__:debug_log:49 - <span class="token punctuation">{</span><span class="token string">'access_status'</span><span class="token builtin class-name">:</span> <span class="token number">200</span>, <span class="token string">'request_method'</span><span class="token builtin class-name">:</span> <span class="token string">'GET'</span>, <span class="token string">'request_uri'</span><span class="token builtin class-name">:</span> <span class="token string">'/account/'</span>, <span class="token string">'request_length'</span><span class="token builtin class-name">:</span> <span class="token number">67</span>, <span class="token string">'remote_address'</span><span class="token builtin class-name">:</span> <span class="token string">'185.14.47.131'</span>, <span class="token string">'server_name'</span><span class="token builtin class-name">:</span> <span class="token string">'cu-36.cn'</span>, <span class="token string">'time_start'</span><span class="token builtin class-name">:</span> <span class="token string">'2023-07-23T09:35:18.879+08:00'</span>, <span class="token string">'time_finish'</span><span class="token builtin class-name">:</span> <span class="token string">'2023-07-23T09:35:19.638+08:00'</span>, <span class="token string">'http_user_agent'</span><span class="token builtin class-name">:</span> <span class="token string">'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2999.0 Safari/537.36'</span><span class="token punctuation">}</span>
<span class="token punctuation">{</span><span class="token string">"host"</span><span class="token builtin class-name">:</span><span class="token string">"huanbao"</span>,<span class="token string">"message"</span><span class="token builtin class-name">:</span><span class="token string">"2023-07-23 09:35:18.987 | INFO     | __main__:debug_log:49 - {'access_status': 200, 'request_method': 'GET', 'request_uri': '/account/', 'request_length': 67, 'remote_address': '185.14.47.131', 'server_name': 'cu-36.cn', 'time_start': '2023-07-23T09:35:18.879+08:00', 'time_finish': '2023-07-23T09:35:19.638+08:00', 'http_user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2999.0 Safari/537.36'}"</span>,<span class="token string">"source_type"</span><span class="token builtin class-name">:</span><span class="token string">"stdin"</span>,<span class="token string">"timestamp"</span><span class="token builtin class-name">:</span><span class="token string">"2023-11-19T08:07:07.270947582Z"</span><span class="token punctuation">}</span>
</code></pre> 
  <ol start="2"> 
   <li>接下来调试VRL解析配置,推荐使用在线调试工具https://playground.vrl.dev/<a href="http://img.e-com-net.com/image/info8/a5e49e332d79490394cb208c49f2c427.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a5e49e332d79490394cb208c49f2c427.jpg" alt="ES8生产实践——日志清洗过滤(vector方案)_第5张图片" width="650" height="367" style="border:1px solid black;"></a></li> 
  </ol> 
  <p>调试无误后,将VRL处理语句添加到vector配置中。</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_source</span><span class="token punctuation">:</span>   
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"stdin"</span>
  
<span class="token key atrule">transforms</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_transform</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> remap
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>    <span class="token comment"># 匹配输入源</span>
      <span class="token punctuation">-</span> my_source
    <span class="token key atrule">source</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
      . = parse_regex!(.message, r'^(?<logtime>[^|]+) \| (?<level>[A-Z]*) *\| __main__:(?<class>\D*:\d*) - (?<content>.*)$') # 正则提取logtime、level、class、content
      .content = replace(.content, "'", "\"") # 将content单引号替换为双引号
      .content = parse_json!(.content) # json解析content内容
      .access_status = (.content.access_status) # 将content中的子字段提取到根级
      .http_user_agent = (.content.http_user_agent)
      .remote_address = (.content.remote_address)
      .request_length = (.content.request_length)
      .request_method = (.content.request_method)
      .request_uri = (.content.request_uri)
      .server_name = (.content.server_name)
      .time_finish = (.content.time_finish)
      .access_status = (.content.access_status)
      .time_start = (.content.time_start)
      del(.content) # 删除content字段
      .logtime = parse_timestamp!((.logtime), format:"%Y-%m-%d %H:%M:%S.%3f") # 格式化时间字段
      .time_start = parse_timestamp!((.time_start), format:"%Y-%m-%dT%H:%M:%S.%3f%:z") 
      .time_finish = parse_timestamp!((.time_finish), format:"%Y-%m-%dT%H:%M:%S.%3f%:z")
      .level = downcase(.level) # 将level字段值转小写</span>

<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"my_transform"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配转换配置</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span> 
</code></pre> 
  <p>添加VRL解析规则后,控制台输出内容如下,已成功对原始数据完成解析处理</p> 
  <pre><code>2023-07-23 09:35:18.987 | INFO     | __main__:debug_log:49 - {'access_status': 200, 'request_method': 'GET', 'request_uri': '/account/', 'request_length': 67, 'remote_address': '185.14.47.131', 'server_name': 'cu-36.cn', 'time_start': '2023-07-23T09:35:18.879+08:00', 'time_finish': '2023-07-23T09:35:19.638+08:00', 'http_user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2999.0 Safari/537.36'}
{"access_status":200,"class":"debug_log:49","http_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2999.0 Safari/537.36","level":"info","logtime":"2023-07-23T01:35:18.987Z","remote_address":"185.14.47.131","request_length":67,"request_method":"GET","request_uri":"/account/","server_name":"cu-36.cn","time_finish":"2023-07-23T01:35:19.638Z","time_start":"2023-07-23T01:35:18.879Z"}
</code></pre> 
  <ol start="3"> 
   <li>我们已经成功解析到了remote_address字段,接下来从geoip数据库中查询ip的地理位置信息。</li> 
  </ol> 
  <pre><code class="prism language-yaml"><span class="token key atrule">sources</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_source</span><span class="token punctuation">:</span>   
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"stdin"</span>
  
<span class="token key atrule">transforms</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_transform</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> remap
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span>    <span class="token comment"># 匹配输入源</span>
      <span class="token punctuation">-</span> my_source
    <span class="token key atrule">source</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
      . = parse_regex!(.message, r'^(?<logtime>[^|]+) \| (?<level>[A-Z]*) *\| __main__:(?<class>\D*:\d*) - (?<content>.*)$') # 正则提取logtime、level、class、content
      .content = replace(.content, "'", "\"") # 将content单引号替换为双引号
      .content = parse_json!(.content) # json解析content内容
      .access_status = (.content.access_status) # 将content中的子字段提取到根级
      .http_user_agent = (.content.http_user_agent)
      .remote_address = (.content.remote_address)
      .request_length = (.content.request_length)
      .request_method = (.content.request_method)
      .request_uri = (.content.request_uri)
      .server_name = (.content.server_name)
      .time_finish = (.content.time_finish)
      .access_status = (.content.access_status)
      .time_start = (.content.time_start)
      del(.content) # 删除content字段
      .logtime = parse_timestamp!((.logtime), format:"%Y-%m-%d %H:%M:%S.%3f") # 格式化时间字段
      .time_start = parse_timestamp!((.time_start), format:"%Y-%m-%dT%H:%M:%S.%3f%:z") 
      .time_finish = parse_timestamp!((.time_finish), format:"%Y-%m-%dT%H:%M:%S.%3f%:z")
      .level = downcase(.level) # 将level字段值转小写
      .geoip = get_enrichment_table_record!("geoip_table", # ip地理位置信息解析
        {
          "ip": .remote_address
        })</span>

<span class="token key atrule">sinks</span><span class="token punctuation">:</span>
  <span class="token key atrule">my_print</span><span class="token punctuation">:</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"console"</span>
    <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"my_transform"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配转换配置</span>
    <span class="token key atrule">encoding</span><span class="token punctuation">:</span>
      <span class="token key atrule">codec</span><span class="token punctuation">:</span> <span class="token string">"json"</span> 

<span class="token key atrule">enrichment_tables</span><span class="token punctuation">:</span>
  <span class="token key atrule">geoip_table</span><span class="token punctuation">:</span> <span class="token comment"># 指定geoip数据库文件</span>
    <span class="token key atrule">path</span><span class="token punctuation">:</span> <span class="token string">"/root/GeoLite2-City.mmdb"</span>
    <span class="token key atrule">type</span><span class="token punctuation">:</span> geoip
</code></pre> 
  <p>观察控制台输出,已经成功通过remote_address字段的ip地址获取到了地理位置信息内容。</p> 
  <pre><code>2023-07-23 09:35:18.987 | INFO     | __main__:debug_log:49 - {'access_status': 200, 'request_method': 'GET', 'request_uri': '/account/', 'request_length': 67, 'remote_address': '185.14.47.131', 'server_name': 'cu-36.cn', 'time_start': '2023-07-23T09:35:18.879+08:00', 'time_finish': '2023-07-23T09:35:19.638+08:00', 'http_user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2999.0 Safari/537.36'}
{"access_status":200,"class":"debug_log:49","geoip":{"city_name":"Hong Kong","continent_code":"AS","country_code":"HK","country_name":"Hong Kong","latitude":22.2842,"longitude":114.1759,"metro_code":null,"postal_code":null,"region_code":"HCW","region_name":"Central and Western District","timezone":"Asia/Hong_Kong"},"http_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.2999.0 Safari/537.36","level":"info","logtime":"2023-07-23T01:35:18.987Z","remote_address":"185.14.47.131","request_length":67,"request_method":"GET","request_uri":"/account/","server_name":"cu-36.cn","time_finish":"2023-07-23T01:35:19.638Z","time_start":"2023-07-23T01:35:18.879Z"}
</code></pre> 
  <h3>构建vector镜像</h3> 
  <p>由于vector镜像未包含geoip数据库文件,如果需要根据IP地址解析获取地理位置信息,则需要提前构建包含geoip文件的vector镜像,并上传至harbor仓库中。</p> 
  <pre><code class="prism language-bash"><span class="token punctuation">[</span>root@tiaoban evk<span class="token punctuation">]</span><span class="token comment"># ls</span>
Dockerfile  filebeat  GeoLite2-City.mmdb  kafka  log-demo.yaml  strimzi-kafka-operator  vector
<span class="token punctuation">[</span>root@tiaoban evk<span class="token punctuation">]</span><span class="token comment"># cat Dockerfile </span>
FROM timberio/vector:0.34.1-debian
ADD GeoLite2-City.mmdb /etc/vector/GeoLite2-City.mmdb
<span class="token punctuation">[</span>root@tiaoban evk<span class="token punctuation">]</span><span class="token comment"># docker build -t harbor.local.com/elk/vector:v0.34.1 .</span>
<span class="token punctuation">[</span>root@tiaoban evk<span class="token punctuation">]</span><span class="token comment"># docker push harbor.local.com/elk/vector:v0.34.1</span>
</code></pre> 
  <h3>k8s资源清单</h3> 
  <ul> 
   <li>vector-config.yaml</li> 
  </ul> 
  <p>此配置文件为vector的全局通用配置文件,主要配置了api和监控指标。</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> ConfigMap
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
  <span class="token key atrule">name</span><span class="token punctuation">:</span> vector<span class="token punctuation">-</span>config
  <span class="token key atrule">namespace</span><span class="token punctuation">:</span> elk
<span class="token key atrule">data</span><span class="token punctuation">:</span>
  <span class="token key atrule">vector.yaml</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
    data_dir: "/var/lib/vector"
    api:
      enabled: true
      address: "0.0.0.0:8686"
      
    sources:
      metrics:
        type: internal_metrics
        namespace: vector
        scrape_interval_secs: 30</span>

    <span class="token key atrule">sinks</span><span class="token punctuation">:</span>
      <span class="token key atrule">prometheus</span><span class="token punctuation">:</span>
        <span class="token key atrule">type</span><span class="token punctuation">:</span> prometheus_exporter
        <span class="token key atrule">inputs</span><span class="token punctuation">:</span>
          <span class="token punctuation">-</span> metrics
        <span class="token key atrule">address</span><span class="token punctuation">:</span> 0.0.0.0<span class="token punctuation">:</span><span class="token number">9598</span>
        <span class="token key atrule">default_namespace</span><span class="token punctuation">:</span> service
</code></pre> 
  <ul> 
   <li>pod-config.yaml</li> 
  </ul> 
  <p>此配置文件主要是从kafka中读取数据,然后移除非必要的字段信息,最后写入es中</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> ConfigMap
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
  <span class="token key atrule">name</span><span class="token punctuation">:</span> pod<span class="token punctuation">-</span>config
  <span class="token key atrule">namespace</span><span class="token punctuation">:</span> elk
<span class="token key atrule">data</span><span class="token punctuation">:</span>
  <span class="token key atrule">pod.yaml</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
    sources:
      pod_kafka:
        type: "kafka"
        bootstrap_servers: "my-cluster-kafka-brokers.kafka.svc:9092"
        group_id: "pod"
        topics:
          - "pod_logs"
        decoding:
          codec: "json"
        auto_offset_reset: "latest"</span>

    <span class="token key atrule">transforms</span><span class="token punctuation">:</span>
      <span class="token key atrule">pod_transform</span><span class="token punctuation">:</span>
        <span class="token key atrule">type</span><span class="token punctuation">:</span> remap
        <span class="token key atrule">inputs</span><span class="token punctuation">:</span>    <span class="token comment"># 匹配输入源</span>
          <span class="token punctuation">-</span> pod_kafka
        <span class="token key atrule">source</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
          del(.agent)
          del(.event)
          del(.ecs)
          del(.host)
          del(.input)
          del(.kubernetes.labels)
          del(.log)
          del(.orchestrator)
          del(.stream)</span>
    
    <span class="token key atrule">sinks</span><span class="token punctuation">:</span>
      <span class="token key atrule">pod_es</span><span class="token punctuation">:</span>
        <span class="token key atrule">type</span><span class="token punctuation">:</span> elasticsearch
        <span class="token key atrule">inputs</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"pod_transform"</span><span class="token punctuation">]</span> <span class="token comment"># 匹配转换配置</span>
        <span class="token key atrule">api_version</span><span class="token punctuation">:</span> <span class="token string">"v8"</span>        <span class="token comment"># ES版本,非必填</span>
        <span class="token key atrule">mode</span><span class="token punctuation">:</span> <span class="token string">"data_stream"</span> <span class="token comment"># 数据流方式写入</span>
        <span class="token key atrule">auth</span><span class="token punctuation">:</span> <span class="token comment"># es认证信息 </span>
          <span class="token key atrule">strategy</span><span class="token punctuation">:</span> <span class="token string">"basic"</span>
          <span class="token key atrule">user</span><span class="token punctuation">:</span> <span class="token string">"elastic"</span>
          <span class="token key atrule">password</span><span class="token punctuation">:</span> <span class="token string">"2zg5q6AU7xW5jY649yuEpZ47"</span>
        <span class="token key atrule">data_stream</span><span class="token punctuation">:</span> <span class="token comment"># 数据流名称配置</span>
          <span class="token key atrule">type</span><span class="token punctuation">:</span> <span class="token string">"logs"</span>
          <span class="token key atrule">dataset</span><span class="token punctuation">:</span> <span class="token string">"pod"</span>
          <span class="token key atrule">namespace</span><span class="token punctuation">:</span> <span class="token string">"elk"</span>
        <span class="token key atrule">endpoints</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"https://elasticsearch-es-http.elk.svc:9200"</span><span class="token punctuation">]</span> <span class="token comment"># es连接地址</span>
        <span class="token key atrule">tls</span><span class="token punctuation">:</span> <span class="token comment"># tls证书配置</span>
          <span class="token key atrule">verify_certificate</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token comment"># 跳过证书验证</span>
</code></pre> 
  <ul> 
   <li>myapp-config.yaml</li> 
  </ul> 
  <p>此配置文件从kafka中读取pod日志数据,然后通过filter过滤出log-demo的日志数据,做进一步解析处理后写入es中</p> 
  <pre><code class="prism language-yaml"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> ConfigMap
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
  <span class="token key atrule">name</span><span class="token punctuation">:</span> myapp<span class="token punctuation">-</span>config
  <span class="token key atrule">namespace</span><span class="token punctuation">:</span> elk
<span class="token key atrule">data</span><span class="token punctuation">:</span>
  <span class="token key atrule">myapp.yaml</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string">
    sources:
      myapp_kafka:
        type: "kafka"
        bootstrap_servers: "my-cluster-kafka-brokers.kafka.svc:9092"
        group_id: "myapp"
        topics:
          - "pod_logs"
        decoding:
          codec: "json"
        auto_offset_reset: "latest"
      
    transforms:
      myapp_filter:
        type: filter
        inputs:    # 匹配输入源
          - myapp_kafka
        condition: |
          .kubernetes.deployment.name == "log-demo"
      myapp_transform:
        type: remap
        inputs:    # 匹配输入源
          - myapp_filter
        source: |
          . = parse_regex!(.message, r'^(?<logtime>[^|]+) \| (?<level>[A-Z]*) *\| __main__:(?<class>\D*:\d*) - (?<content>.*)$') # 正则提取logtime、level、class、content
          .content = replace(.content, "'", "\"") # 将content单引号替换为双引号
          .content = parse_json!(.content) # json解析content内容
          .access_status = (.content.access_status) # 将content中的子字段提取到根级
          .http_user_agent = (.content.http_user_agent)
          .remote_address = (.content.remote_address)
          .request_length = (.content.request_length)
          .request_method = (.content.request_method)
          .request_uri = (.content.request_uri)
          .server_name = (.content.server_name)
          .time_finish = (.content.time_finish)
          .access_status = (.content.access_status)
          .time_start = (.content.time_start)
          del(.content) # 删除content字段
          .logtime = parse_timestamp!((.logtime), format:"%Y-%m-%d %H:%M:%S.%3f") # 格式化时间字段
          .time_start = parse_timestamp!((.time_start), format:"%Y-%m-%dT%H:%M:%S.%3f%:z") 
          .time_finish = parse_timestamp!((.time_finish), format:"%Y-%m-%dT%H:%M:%S.%3f%:z")
          .level = downcase(.level) # 将level字段值转小写
          .geoip = get_enrichment_table_record!("geoip_table",
          {
            "ip": .remote_address
          }) # 地理位置信息解析
        
    sinks:
      myapp_es:
        type: elasticsearch
        inputs: ["myapp_transform"] # 匹配转换配置
        api_version: "v8"        # ES版本,非必填
        mode: "data_stream" # 数据流方式写入
        auth: # es认证信息 
          strategy: "basic"
          user: "elastic"
          password: "2zg5q6AU7xW5jY649yuEpZ47"
        data_stream: # 数据流名称配置
          type: "logs"
          dataset: "myapp"
          namespace: "elk"
        endpoints: ["https://elasticsearch-es-http.elk.svc:9200"] # es连接地址
        tls: # tls证书配置
          verify_certificate: false # 跳过证书验证 </span>
    
    <span class="token key atrule">enrichment_tables</span><span class="token punctuation">:</span>
      <span class="token key atrule">geoip_table</span><span class="token punctuation">:</span> <span class="token comment"># 指定geoip数据库文件</span>
        <span class="token key atrule">path</span><span class="token punctuation">:</span> <span class="token string">"/etc/vector/GeoLite2-City.mmdb"</span>
        <span class="token key atrule">type</span><span class="token punctuation">:</span> geoip
</code></pre> 
  <ul> 
   <li>deployment.yaml</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> apps/v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Deployment
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
  <span class="token key atrule">name</span><span class="token punctuation">:</span> vector
  <span class="token key atrule">namespace</span><span class="token punctuation">:</span> elk
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
  <span class="token key atrule">replicas</span><span class="token punctuation">:</span> <span class="token number">2</span>
  <span class="token key atrule">selector</span><span class="token punctuation">:</span>
    <span class="token key atrule">matchLabels</span><span class="token punctuation">:</span>
      <span class="token key atrule">app</span><span class="token punctuation">:</span> vector
  <span class="token key atrule">template</span><span class="token punctuation">:</span>
    <span class="token key atrule">metadata</span><span class="token punctuation">:</span>
      <span class="token key atrule">labels</span><span class="token punctuation">:</span>
        <span class="token key atrule">app</span><span class="token punctuation">:</span> vector
    <span class="token key atrule">spec</span><span class="token punctuation">:</span>
      <span class="token key atrule">securityContext</span><span class="token punctuation">:</span>
        <span class="token key atrule">runAsUser</span><span class="token punctuation">:</span> <span class="token number">0</span>
      <span class="token key atrule">containers</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> <span class="token key atrule">image</span><span class="token punctuation">:</span> harbor.local.com/elk/vector<span class="token punctuation">:</span>v0.34.1
        <span class="token key atrule">name</span><span class="token punctuation">:</span> vector
        <span class="token key atrule">resources</span><span class="token punctuation">:</span>
          <span class="token key atrule">limits</span><span class="token punctuation">:</span>
            <span class="token key atrule">cpu</span><span class="token punctuation">:</span> <span class="token string">"1"</span>
            <span class="token key atrule">memory</span><span class="token punctuation">:</span> 1Gi
        <span class="token key atrule">args</span><span class="token punctuation">:</span>
        <span class="token punctuation">-</span> <span class="token punctuation">-</span>c
        <span class="token punctuation">-</span> /etc/vector/<span class="token important">*.yaml</span>
        <span class="token key atrule">ports</span><span class="token punctuation">:</span>
          <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> exporter
            <span class="token key atrule">containerPort</span><span class="token punctuation">:</span> <span class="token number">9598</span>
          <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> api
            <span class="token key atrule">containerPort</span><span class="token punctuation">:</span> <span class="token number">8686</span>
        <span class="token key atrule">volumeMounts</span><span class="token punctuation">:</span>
        <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> timezone
          <span class="token key atrule">mountPath</span><span class="token punctuation">:</span> /etc/localtime
        <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> data
          <span class="token key atrule">mountPath</span><span class="token punctuation">:</span> /var/lib/vector
        <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> vector<span class="token punctuation">-</span>config
          <span class="token key atrule">mountPath</span><span class="token punctuation">:</span> /etc/vector/vector.yaml
          <span class="token key atrule">subPath</span><span class="token punctuation">:</span> vector.yaml
        <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> pod<span class="token punctuation">-</span>config
          <span class="token key atrule">mountPath</span><span class="token punctuation">:</span> /etc/vector/pod.yaml
          <span class="token key atrule">subPath</span><span class="token punctuation">:</span> pod.yaml
        <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> myapp<span class="token punctuation">-</span>config
          <span class="token key atrule">mountPath</span><span class="token punctuation">:</span> /etc/vector/myapp.yaml
          <span class="token key atrule">subPath</span><span class="token punctuation">:</span> myapp.yaml
        <span class="token key atrule">readinessProbe</span><span class="token punctuation">:</span>
          <span class="token key atrule">httpGet</span><span class="token punctuation">:</span>
            <span class="token key atrule">path</span><span class="token punctuation">:</span> /health
            <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8686</span>
        <span class="token key atrule">livenessProbe</span><span class="token punctuation">:</span>
          <span class="token key atrule">httpGet</span><span class="token punctuation">:</span>
            <span class="token key atrule">path</span><span class="token punctuation">:</span> /health
            <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8686</span>
      <span class="token key atrule">volumes</span><span class="token punctuation">:</span>
      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> timezone
        <span class="token key atrule">hostPath</span><span class="token punctuation">:</span>
          <span class="token key atrule">path</span><span class="token punctuation">:</span> /usr/share/zoneinfo/Asia/Shanghai
      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> data
        <span class="token key atrule">hostPath</span><span class="token punctuation">:</span>
          <span class="token key atrule">path</span><span class="token punctuation">:</span> /data/vector
          <span class="token key atrule">type</span><span class="token punctuation">:</span> DirectoryOrCreate
      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> vector<span class="token punctuation">-</span>config
        <span class="token key atrule">configMap</span><span class="token punctuation">:</span>
          <span class="token key atrule">name</span><span class="token punctuation">:</span> vector<span class="token punctuation">-</span>config
      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> pod<span class="token punctuation">-</span>config
        <span class="token key atrule">configMap</span><span class="token punctuation">:</span>
          <span class="token key atrule">name</span><span class="token punctuation">:</span> pod<span class="token punctuation">-</span>config
      <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> myapp<span class="token punctuation">-</span>config
        <span class="token key atrule">configMap</span><span class="token punctuation">:</span>
          <span class="token key atrule">name</span><span class="token punctuation">:</span> myapp<span class="token punctuation">-</span>config
</code></pre> 
  <ul> 
   <li>service.yaml</li> 
  </ul> 
  <pre><code class="prism language-yaml"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> v1
<span class="token key atrule">kind</span><span class="token punctuation">:</span> Service
<span class="token key atrule">metadata</span><span class="token punctuation">:</span>
  <span class="token key atrule">name</span><span class="token punctuation">:</span> vector<span class="token punctuation">-</span>exporter
  <span class="token key atrule">namespace</span><span class="token punctuation">:</span> elk
<span class="token key atrule">spec</span><span class="token punctuation">:</span>
  <span class="token key atrule">selector</span><span class="token punctuation">:</span>
    <span class="token key atrule">app</span><span class="token punctuation">:</span> vector
  <span class="token key atrule">ports</span><span class="token punctuation">:</span>
  <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> exporter 
    <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">9598</span> 
    <span class="token key atrule">targetPort</span><span class="token punctuation">:</span> <span class="token number">9598</span>
</code></pre> 
  <h3>效果演示</h3> 
  <p>查看kibana数据流信息,已成功创建myapp和pod日志的索引。<br> <a href="http://img.e-com-net.com/image/info8/c8555e17b5ff4252b2281209d7ca4fe2.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c8555e17b5ff4252b2281209d7ca4fe2.jpg" alt="ES8生产实践——日志清洗过滤(vector方案)_第6张图片" width="650" height="203" style="border:1px solid black;"></a><br> 查看pod索引数据信息<br> <a href="http://img.e-com-net.com/image/info8/d1822172e1c14184a2d46b02e568c643.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/d1822172e1c14184a2d46b02e568c643.jpg" alt="ES8生产实践——日志清洗过滤(vector方案)_第7张图片" width="650" height="468" style="border:1px solid black;"></a><br> 查看myapp索引数据信息<br> <a href="http://img.e-com-net.com/image/info8/004b335402e8434597fb179551e02dd0.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/004b335402e8434597fb179551e02dd0.jpg" alt="ES8生产实践——日志清洗过滤(vector方案)_第8张图片" width="650" height="468" style="border:1px solid black;"></a></p> 
  <h2>注意事项</h2> 
  <h3>多配置文件启动</h3> 
  <p>我们可以通过<code>-c /etc/vector/*.yaml</code>方式指定多个配置文件启动,此时vector会扫描指定路径下的所有yaml配置文件并加载启动。这样配置便于管理各个管道处理规则配置,使配置文件结构更加清晰,便于日后维护工作。</p> 
  <h3>管道名称全局唯一</h3> 
  <p>sources、transforms、sinks的自定义名称,全局必须唯一,尤其是多个vector配置文件时,唯一名称尤为重要。</p> 
  <h2>完整资源清单</h2> 
  <p>本实验案例所有yaml文件已上传至git仓库。访问地址如下:</p> 
  <h3>github</h3> 
  <p>https://github.com/cuiliang0302/blog-demo</p> 
  <h3>gitee</h3> 
  <p>https://gitee.com/cuiliang0302/blog_demo</p> 
  <h2>参考文档</h2> 
  <p>VRL常用函数:https://vector.dev/docs/reference/vrl/functions/<br> VRL常用案例:https://vector.dev/docs/reference/vrl/examples/<br> VRL时间格式化:https://docs.rs/chrono/latest/chrono/format/strftime/index.html#specifiers</p> 
  <h2>查看更多</h2> 
  <h3>微信公众号</h3> 
  <p>微信公众号同步更新,欢迎关注微信公众号《崔亮的博客》第一时间获取最近文章。</p> 
  <h3>博客网站</h3> 
  <p>崔亮的博客-专注devops自动化运维,传播优秀it运维技术文章。更多原创运维开发相关文章,欢迎访问https://www.cuiliangblog.cn</p> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1728761113983660032"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(ELK,Stack,elasticsearch)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1950153513166237696.htm"
                           title="记录自己第n次面试(n>3)" target="_blank">记录自己第n次面试(n>3)</a>
                        <span class="text-muted">Warren98</span>
<a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E8%81%8C%E5%9C%BA%E5%92%8C%E5%8F%91%E5%B1%95/1.htm">职场和发展</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>1.Spring Boot可执行JAR的内存分配答:“在Spring Boot可执行JAR中,JVM的内存通常分为两大块:堆(Heap)和栈(Stack)。堆内存:存放对象实例和数组,通过-Xms(初始)和-Xmx(最大)控制。比如java-Xms512m-Xmx1024m-jarapp.jar,表示启动时给512 MB堆,最大可以到1 024 MB。栈内存:每个线程有独立的栈帧,用来保存方法调用</div>
                    </li>
                    <li><a href="/article/1950139770009088000.htm"
                           title="Day10--栈与队列--232. 用栈实现队列,225. 用队列实现栈,20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值" target="_blank">Day10--栈与队列--232. 用栈实现队列,225. 用队列实现栈,20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值</a>
                        <span class="text-muted"></span>

                        <div>Day10–栈与队列–232.用栈实现队列,225.用队列实现栈,20.有效的括号,1047.删除字符串中的所有相邻重复项,150.逆波兰表达式求值232.用栈实现队列思路:用ArrayDeque来实现;有趣的dumpToStackOut();classMyQueue{DequestackIn;DequestackOut;publicMyQueue(){stackIn=newArrayDeque(</div>
                    </li>
                    <li><a href="/article/1950095963980886016.htm"
                           title="elasticsearch启动时遇到的错误max virtual memory areas vm.max_map_count [65530\] is too low, increase to a..." target="_blank">elasticsearch启动时遇到的错误max virtual memory areas vm.max_map_count [65530\] is too low, increase to a...</a>
                        <span class="text-muted">Hello小五</span>

                        <div>maxvirtualmemoryareasvm.max_map_count[65530]istoolow,increasetoatleast[262144]elasticsearch启动时遇到的错误问题翻译过来就是:elasticsearch用户拥有的内存权限太小,至少需要262144;在宿主机/etc/sysctl.conf文件最后添加一行vm.max_map_count=262144执行命令s</div>
                    </li>
                    <li><a href="/article/1950019961619542016.htm"
                           title="elasticsearch vm.max_map_count" target="_blank">elasticsearch vm.max_map_count</a>
                        <span class="text-muted">small瓜瓜</span>

                        <div>maxvirtualmemoryareasvm.max_map_count[65530]istoolow,increasetoatleast[262144]elasticsearch启动时遇到的错误问题翻译过来就是:elasticsearch用户拥有的内存权限太小,至少需要262144解决:切换到root用户执行命令:sysctl-wvm.max_map_count=262144查看结果:sysc</div>
                    </li>
                    <li><a href="/article/1949964644726665216.htm"
                           title="【C++】类和对象(上)" target="_blank">【C++】类和对象(上)</a>
                        <span class="text-muted">许怀楠</span>
<a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a>
                        <div>1.类的定义1.1类定义格式class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员;类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。为了区分成员变量,一般习惯上成员变量会加上一个特殊标识,如成员变量前面或者后面加_或者m开头,注意C++中这个并不是强制的,只是一些公司的惯例,具体看公司的要求。C++中str</div>
                    </li>
                    <li><a href="/article/1949915978255101952.htm"
                           title="Elasticsearch创建快照与快照恢复" target="_blank">Elasticsearch创建快照与快照恢复</a>
                        <span class="text-muted">写bug的羊羊</span>
<a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a>
                        <div>使用了kibana进行请求发送1.旧es创建快照1.查看elasticsearch.yml配置的仓库路径,没有添加上,重启espath.repo:["E:/develop/elasticsearch-7.9.3/backups"]2.注册仓库,如仓库名backup1PUT/_snapshot/backup1{"type":"fs","settings":{"location":"backup1"}</div>
                    </li>
                    <li><a href="/article/1949892638496845824.htm"
                           title="Openstack Neutron 专题" target="_blank">Openstack Neutron 专题</a>
                        <span class="text-muted"></span>

                        <div>1.构架2.代码3.cmdneutronnet-listneutronrouter-listneutronsecurity-group-listneutronsecurity-group-showb4850001-security-group-idneutronsecurity-group-rule-listneutronsecurity-group-rule-show2ca442c7-secur</div>
                    </li>
                    <li><a href="/article/1949886836209938432.htm"
                           title="SpringBoot集成ELK收集日志管理" target="_blank">SpringBoot集成ELK收集日志管理</a>
                        <span class="text-muted">嗝屁小孩纸</span>
<a class="tag" taget="_blank" href="/search/%E4%BC%81%E4%B8%9A%E7%BA%A7%E8%BF%90%E7%BB%B4/1.htm">企业级运维</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/elk/1.htm">elk</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a>
                        <div>ELK集成是没有代码侵入的,主要是吃服务器内存,只需要部署启动这三个服务,然后项目的资源日志配置指定日志输出到logstash服务器就可以了。1、好处就是开发人员不用依赖服务器来定位异常了,服务器一般需要借助VPN登录,而且也不算所有开发人员都有分配。2、对于微服务多模块项目,精准配置日志输出格式,对定位问题非常方便,不用再拘泥与多个服务模块在哪台服务器再去定位问题了。1、环境配置1.1、下载lo</div>
                    </li>
                    <li><a href="/article/1949867547155296256.htm"
                           title="JVM 内存共享区域详解" target="_blank">JVM 内存共享区域详解</a>
                        <span class="text-muted">笑衬人心。</span>
<a class="tag" taget="_blank" href="/search/JAVA%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/1.htm">JAVA学习笔记</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a>
                        <div>Java虚拟机在执行Java程序时,会将所管理的内存划分为若干个不同的数据区域。其中,堆(Heap)和方法区(MethodArea)是所有线程共享的区域,属于JVM的共享内存区。一、JVM内存结构总览区域名称是否线程共享说明程序计数器(ProgramCounterRegister)否当前线程执行字节码的行号指示器Java虚拟机栈(JVMStack)否每个线程私有,方法调用栈帧本地方法栈(Nativ</div>
                    </li>
                    <li><a href="/article/1949851901247942656.htm"
                           title="常见的未授权访问如:Redis,MongoDb,Memcached,Jenkins,Jupyter NoteBook,Elasticsearch,Kibana等二十四个靶场复现" target="_blank">常见的未授权访问如:Redis,MongoDb,Memcached,Jenkins,Jupyter NoteBook,Elasticsearch,Kibana等二十四个靶场复现</a>
                        <span class="text-muted">终焉暴龙王</span>
<a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/web%E5%AE%89%E5%85%A8/1.htm">web安全</a>
                        <div>前言这这篇文章中我会记录24种常见的未授权访问漏洞的靶场复现,如果有错误,欢迎大家指正。在本文中,漏洞复现的靶场完全是靠自己搭建的vulhub-master以及一系列的靶场以及fofa搜索,如果之前没有用过vulhub-master靶场,请先搭建好vulhub-master靶场并且安装docker和docker-compose。另外,其中一些涉及到敏感信息的漏洞复现我就不截图了,大家切记要树立好法</div>
                    </li>
                    <li><a href="/article/1949836396927709184.htm"
                           title="Go-Elasticsearch v9 从入门到进阶 REST API 与 Typed API 双剑合璧" target="_blank">Go-Elasticsearch v9 从入门到进阶 REST API 与 Typed API 双剑合璧</a>
                        <span class="text-muted">Hello.Reader</span>
<a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/%E6%A3%80%E7%B4%A2/1.htm">检索</a><a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a><a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a>
                        <div>1、环境要求与安装项目说明Go版本1.21及以上(推荐使用近期版本1.23+)安装命令bash\ngogetgithub.com/elastic/go-elasticsearch/v9@latest\n版本对齐客户端主版本需与集群主版本一致(例如v9对ES9.x)2、快速连接Elasticsearch2.1低级API(本地9200端口)es,err:=elasticsearch.NewDefaul</div>
                    </li>
                    <li><a href="/article/1949822910088671232.htm"
                           title="Go-Elasticsearch v9 安装与版本兼容性" target="_blank">Go-Elasticsearch v9 安装与版本兼容性</a>
                        <span class="text-muted">Hello.Reader</span>
<a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a><a class="tag" taget="_blank" href="/search/%E6%A3%80%E7%B4%A2/1.htm">检索</a><a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/golang/1.htm">golang</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a>
                        <div>1、安装方式速查场景命令/代码片段说明最快体验bash\n#建议直接拉取最新版\ngogetgithub.com/elastic/go-elasticsearch/v9@latest\n在现有项目中立刻添加依赖显式锁定版本go\nrequiregithub.com/elastic/go-elasticsearch/v9v9.0.0\n在go.mod中写死具体版本,便于团队一致性源码克隆bash\n</div>
                    </li>
                    <li><a href="/article/1949787737548713984.htm"
                           title="Elasticsearch-索引原理" target="_blank">Elasticsearch-索引原理</a>
                        <span class="text-muted">ouyang+</span>

                        <div>最近在参与一个基于Elasticsearch作为底层数据框架提供大数据量(亿级)的实时统计查询的方案设计工作,花了些时间学习Elasticsearch的基础理论知识,整理了一下,希望能对Elasticsearch感兴趣/想了解的同学有所帮助。同时也希望有发现内容不正确或者有疑问的地方,望指明,一起探讨,学习,进步。介绍Elasticsearch是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文</div>
                    </li>
                    <li><a href="/article/1949773104544804864.htm"
                           title="Elasticsearch - 倒排索引原理和简易实现" target="_blank">Elasticsearch - 倒排索引原理和简易实现</a>
                        <span class="text-muted">葵续浅笑</span>
<a class="tag" taget="_blank" href="/search/Elasticsearch/1.htm">Elasticsearch</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a>
                        <div>倒排索引的功能设计倒排索引(InvertedIndex)是一种高效的数据结构,常用于全文搜索和信息检索系统。它的核心思想是将文档中每个关键字(term)与包含该关键字的文档列表进行映射。以下是实现倒排索引功能的设计步骤和代码示例:功能需求文档存储:存储一组文档,文档可以是字符串(文本内容)。索引构建:从文档中提取关键词,构建倒排索引。关键词查询:根据用户输入的关键词,快速返回包含该关键词的文档ID</div>
                    </li>
                    <li><a href="/article/1949731369336762368.htm"
                           title="【ELasticsearch】搭建有负载均衡 ELB 的 ES 集群" target="_blank">【ELasticsearch】搭建有负载均衡 ELB 的 ES 集群</a>
                        <span class="text-muted">大数据与AI实验室</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Elastic/1.htm">Elastic</a><a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1/1.htm">负载均衡</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1/1.htm">负载均衡</a><a class="tag" taget="_blank" href="/search/ELB/1.htm">ELB</a><a class="tag" taget="_blank" href="/search/%E5%85%AC%E6%9C%89%E4%BA%91/1.htm">公有云</a><a class="tag" taget="_blank" href="/search/%E9%9B%86%E7%BE%A4/1.htm">集群</a>
                        <div>搭建有负载均衡ELB的ES集群1.为什么要这样设计(封装ELB)?2.如果没有这层负载均衡呢?3.外来的请求会打到集群哪一个节点上?4.优先是专属协调节点吗?5.ELB需要对接所有节点吗,还是协调节点就可以了?在公有云上为Elasticsearch集群封装一层ELB(ElasticLoadBalancer)或类似的负载均衡器,核心目的是解耦、简化客户端访问、提高可用性、增强可维护性。1.为什么要这</div>
                    </li>
                    <li><a href="/article/1949730234861416448.htm"
                           title="【Elasticsearch】跨集群检索(Cross-Cluster Search)" target="_blank">【Elasticsearch】跨集群检索(Cross-Cluster Search)</a>
                        <span class="text-muted"></span>

                        <div>《Elasticsearch集群》系列,共包含以下文章:1️⃣冷热集群架构2️⃣合适的锅炒合适的菜:性能与成本平衡原理公式解析3️⃣ILM(IndexLifecycleManagement)策略详解4️⃣Elasticsearch跨机房部署5️⃣快照与恢复功能详解6️⃣Elasticsearch快照恢复API参数详解7️⃣安全地删除快照仓库、快照8️⃣快照生命周期管理SLM(理论篇)9️⃣快照生命</div>
                    </li>
                    <li><a href="/article/1949729856879128576.htm"
                           title="【Elasticsearch】Elasticsearch 跨机房部署" target="_blank">【Elasticsearch】Elasticsearch 跨机房部署</a>
                        <span class="text-muted">大数据与AI实验室</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Elastic/1.htm">Elastic</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a><a class="tag" taget="_blank" href="/search/%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2/1.htm">全文检索</a><a class="tag" taget="_blank" href="/search/%E9%9B%86%E7%BE%A4/1.htm">集群</a><a class="tag" taget="_blank" href="/search/%E9%9B%86%E7%BE%A4%E6%9E%B6%E6%9E%84/1.htm">集群架构</a><a class="tag" taget="_blank" href="/search/%E9%83%A8%E7%BD%B2/1.htm">部署</a>
                        <div>《Elasticsearch集群》系列,共包含以下文章:1️⃣冷热集群架构2️⃣合适的锅炒合适的菜:性能与成本平衡原理公式解析3️⃣ILM(IndexLifecycleManagement)策略详解4️⃣Elasticsearch跨机房部署5️⃣快照与恢复功能详解6️⃣Elasticsearch快照恢复API参数详解7️⃣安全地删除快照仓库、快照8️⃣快照生命周期管理SLM(理论篇)9️⃣快照生命</div>
                    </li>
                    <li><a href="/article/1949729730508943360.htm"
                           title="【Elasticsearch】Elasticsearch 快照恢复 API 参数详解" target="_blank">【Elasticsearch】Elasticsearch 快照恢复 API 参数详解</a>
                        <span class="text-muted">大数据与AI实验室</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Elastic/1.htm">Elastic</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a><a class="tag" taget="_blank" href="/search/%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2/1.htm">全文检索</a><a class="tag" taget="_blank" href="/search/%E5%BF%AB%E7%85%A7/1.htm">快照</a><a class="tag" taget="_blank" href="/search/%E5%BF%AB%E7%85%A7%E6%81%A2%E5%A4%8D/1.htm">快照恢复</a><a class="tag" taget="_blank" href="/search/kibana/1.htm">kibana</a>
                        <div>《Elasticsearch集群》系列,共包含以下文章:1️⃣冷热集群架构2️⃣合适的锅炒合适的菜:性能与成本平衡原理公式解析3️⃣ILM(IndexLifecycleManagement)策略详解4️⃣Elasticsearch跨机房部署5️⃣快照与恢复功能详解6️⃣Elasticsearch快照恢复API参数详解7️⃣安全地删除快照仓库、快照8️⃣快照生命周期管理SLM(理论篇)9️⃣快照生命</div>
                    </li>
                    <li><a href="/article/1949667446227005440.htm"
                           title="大数据编程基础" target="_blank">大数据编程基础</a>
                        <span class="text-muted">芝麻开门-新的起点</span>
<a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a>
                        <div>3.1Java基础(重点)内容讲解Java是大数据领域最重要的编程语言之一。Hadoop、HBase、Elasticsearch等众多核心框架都是用Java开发的。因此,扎实的Java基础对于深入理解这些框架的底层原理和进行二次开发至关重要。为什么Java在大数据领域如此重要?生态系统:Hadoop生态系统原生就是Java构建的,使用Java进行开发可以无缝集成。跨平台性:Java的“一次编译,到</div>
                    </li>
                    <li><a href="/article/1949636815967285248.htm"
                           title="零基础学习性能测试第五章:JVM性能分析与调优-多线程机制与运行原理" target="_blank">零基础学习性能测试第五章:JVM性能分析与调优-多线程机制与运行原理</a>
                        <span class="text-muted">试着</span>
<a class="tag" taget="_blank" href="/search/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">性能测试</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/%E9%9B%B6%E5%9F%BA%E7%A1%80/1.htm">零基础</a><a class="tag" taget="_blank" href="/search/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/1.htm">性能测试</a>
                        <div>目录一、JVM线程模型全景图二、线程生命周期与状态转换三、线程调度核心机制1.**协作式vs抢占式**2.**优先级调度**3.**上下文切换代价**四、JVM线程实现关键结构1.**线程栈(StackFrame)**2.**栈帧组成**五、多线程性能瓶颈分析1.**锁竞争(LockContention)**2.**上下文切换风暴**3.**伪共享(FalseSharing)**六、线程池运行原理</div>
                    </li>
                    <li><a href="/article/1949576296493281280.htm"
                           title="MySQL核心技术深度解析与高可用架构实战:从原理到企业级最佳实践" target="_blank">MySQL核心技术深度解析与高可用架构实战:从原理到企业级最佳实践</a>
                        <span class="text-muted">nongbe</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a>
                        <div>引言:MySQL的黄金时代2023年StackOverflow调研显示:MySQL以56.2%的使用率蝉联最受欢迎数据库榜首。从日均千级请求的创业项目到亿级并发的电商系统,MySQL凭借其线性扩展能力与成熟的生态体系持续引领开源数据库浪潮。本文将揭示MySQL内核级优化手段,并给出经过阿里、腾讯验证的生产级实践方案。一、存储引擎:InnoDB架构深度拆解1.1InnoDB内存模型(图示+三维分解)</div>
                    </li>
                    <li><a href="/article/1949492432534040576.htm"
                           title="狂神说Linux笔记" target="_blank">狂神说Linux笔记</a>
                        <span class="text-muted">是你牛天成</span>
<a class="tag" taget="_blank" href="/search/%E9%A1%B9%E7%9B%AE%E9%83%A8%E7%BD%B2/1.htm">项目部署</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>B站视频狂神说LinuxJava开发之路:JavaSE,MySQL,前端(html,css,js),javaweb,SSM框架,SpringBootvue,SpringCloud,(mybatis-plusgit)LinuxLinux操作系统:Window、Mac消息队列(Kafka,RabbitMQ,RockeetMQ)缓存(Redis)搜索引擎(ElasticSearch)集群分布式(需要购买</div>
                    </li>
                    <li><a href="/article/1949483229476089856.htm"
                           title="分布式高可用ELK平台搭建及使用保姆级教程指南 (附安装包网盘免费下载)" target="_blank">分布式高可用ELK平台搭建及使用保姆级教程指南 (附安装包网盘免费下载)</a>
                        <span class="text-muted">Mr.L-OAM</span>
<a class="tag" taget="_blank" href="/search/linux%E7%B3%BB%E7%BB%9F%E8%BF%90%E7%BB%B4/1.htm">linux系统运维</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a><a class="tag" taget="_blank" href="/search/elk/1.htm">elk</a>
                        <div>1ELK简介1.1ELK是什么ELK是一套开源免费且功能强大的日志分析管理系统,由Elasticsearch、Logstash、Kibana三部分组成,是三个软件产品的首字母缩写,简称ELK。这三款软件都是开源软件,通常是配合使用,且归于Elastic.co公司名下,所以被简称为ELK。ELK可以将系统日志、网站日志、应用系统日志等各种日志进行收集、过滤、清洗,然后进行集中存放并可用于检索、分析。</div>
                    </li>
                    <li><a href="/article/1949482850965319680.htm"
                           title="ELK学习(一) ElasticStack技术栈简介" target="_blank">ELK学习(一) ElasticStack技术栈简介</a>
                        <span class="text-muted">左边有只汪</span>
<a class="tag" taget="_blank" href="/search/ElasticSearch/1.htm">ElasticSearch</a><a class="tag" taget="_blank" href="/search/ELK/1.htm">ELK</a>
                        <div>ELK是由三个技术组成的分别是ElasticSearch核心存储和检索引擎Logstash高吞吐量数据处理引擎Kibana数据可视化主要业务是做日志分析ElasticStack不光是由这几种技术还有新的成员Beats,它可以采集一切数据Beats下还分为以下几个模块FileBeat日志文件PacketBeat网络流量MetricBeat服务指标(CPU,内存情况)WinlogBeatwin日志采集</div>
                    </li>
                    <li><a href="/article/1949473274714976256.htm"
                           title="AWS OpenSearch 搜索排序常见用法" target="_blank">AWS OpenSearch 搜索排序常见用法</a>
                        <span class="text-muted">爱埋珊瑚海~~</span>
<a class="tag" taget="_blank" href="/search/%E4%B8%AD%E9%97%B4%E4%BB%B6/1.htm">中间件</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a><a class="tag" taget="_blank" href="/search/aws/1.htm">aws</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E8%AE%A1%E7%AE%97/1.htm">云计算</a>
                        <div>背景介绍AWSOpenSearch是AWS的一个检索分析服务,是基于开源的Elasticsearch7.x分支fork出来的独立的一个代码仓库,做了独立的维护,加入了一些自己的优化,本文在这里主要介绍是常见的基础用法引入相关依赖org.opensearch.clientopensearch-java2.17.0查询返回指定属性字段按照前端要求的返回字段(“productId”,“title”,“r</div>
                    </li>
                    <li><a href="/article/1949469745736642560.htm"
                           title="ELK Stack技术栈" target="_blank">ELK Stack技术栈</a>
                        <span class="text-muted">猫先生OVO</span>
<a class="tag" taget="_blank" href="/search/elk/1.htm">elk</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>ES集群安装部署#>>>创建用于启动ES的用户$useraddes$idesuid=1000(elasticsearch)gid=1000(elasticsearch)组=1000(elasticsearch)#>>>创建ES数据目录和日志目录存放目录$mkdir-p/opt/{data,logs}$install-d/opt/{data,logs}/es-oes-ges#>>>解压es安装包到指</div>
                    </li>
                    <li><a href="/article/1949454240095203328.htm"
                           title="高通平台的 Camera HAL 架构解析:QCamera 与 CHI HAL 实战剖析" target="_blank">高通平台的 Camera HAL 架构解析:QCamera 与 CHI HAL 实战剖析</a>
                        <span class="text-muted"></span>

                        <div>高通平台的CameraHAL架构解析:QCamera与CHIHAL实战剖析关键词:QCamera3、CHIHAL、QTICameraStack、HAL3、CamX、ISPPipeline、QCamera调试、Snapdragon成像架构、CameraDriver协同摘要:高通平台是Android移动终端中主流的SoC方案之一,其CameraHAL架构发展历程丰富,从传统QCamera到模块化CHI</div>
                    </li>
                    <li><a href="/article/1949443389569167360.htm"
                           title="推荐项目:Hugo Theme Stack 快速启动模板 —— 构建静态站点的高效起点" target="_blank">推荐项目:Hugo Theme Stack 快速启动模板 —— 构建静态站点的高效起点</a>
                        <span class="text-muted">汤中岱Wonderful</span>

                        <div>推荐项目:HugoThemeStack快速启动模板——构建静态站点的高效起点在快速迭代的Web开发领域中,找到一个既高效又灵活的博客或网站搭建方案至关重要。今天,我们向您隆重推荐【HugoThemeStackStarterTemplate】——一款基于[Hugo框架]和[ThemeStack]设计的快速启动模板。它不仅简化了网站构建过程,还通过集成现代工具链,让您的个人站点或小企业网站能够在瞬间起</div>
                    </li>
                    <li><a href="/article/1949443389992792064.htm"
                           title="WebStack-Hugo 项目安装与使用教程" target="_blank">WebStack-Hugo 项目安装与使用教程</a>
                        <span class="text-muted"></span>

                        <div>WebStack-Hugo项目安装与使用教程1.项目目录结构及介绍WebStack-Hugo项目是一个基于Hugo的静态响应式网址导航主题。以下是项目的目录结构及其功能介绍:WebStack-Hugo/├──.github/#GitHub工作流文件│└──workflows/├──exampleSite/#示例网站内容│├──layouts/#网站布局文件│├──static/#静态资源文件,如图</div>
                    </li>
                    <li><a href="/article/1949429524861087744.htm"
                           title="mac m1使用docker 安装es kibana ik分词器" target="_blank">mac m1使用docker 安装es kibana ik分词器</a>
                        <span class="text-muted">Maosmallming</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/elasticsearch/1.htm">elasticsearch</a><a class="tag" taget="_blank" href="/search/macos/1.htm">macos</a>
                        <div>0.安装docker可参考以下文章http://t.csdnimg.cn/fMXu61.拉取elasticsearch镜像资源,本人下载的是8.6.2版本dockerpullelasticsearch:8.6.22.在本机中提前创建好yml文件elasticsearch.ymlhttp:host:0.0.0.0xpack.security.enabled:falsexpack.security.e</div>
                    </li>
                                <li><a href="/article/35.htm"
                                       title="JVM StackMapTable 属性的作用及理解" target="_blank">JVM StackMapTable 属性的作用及理解</a>
                                    <span class="text-muted">lijingyao8206</span>
<a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/%E5%AD%97%E8%8A%82%E7%A0%81/1.htm">字节码</a><a class="tag" taget="_blank" href="/search/Class%E6%96%87%E4%BB%B6/1.htm">Class文件</a><a class="tag" taget="_blank" href="/search/StackMapTable/1.htm">StackMapTable</a>
                                    <div>  
      在Java 6版本之后JVM引入了栈图(Stack Map Table)概念。为了提高验证过程的效率,在字节码规范中添加了Stack Map Table属性,以下简称栈图,其方法的code属性中存储了局部变量和操作数的类型验证以及字节码的偏移量。也就是一个method需要且仅对应一个Stack Map Table。在Java 7版</div>
                                </li>
                                <li><a href="/article/162.htm"
                                       title="回调函数调用方法" target="_blank">回调函数调用方法</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>最近在看大神写的代码时,.发现其中使用了很多的回调 ,以前只是在学习的时候经常用到 ,现在写个笔记 记录一下 
  
代码很简单: 
    
      MainDemo  :调用方法  得到方法的返回结果 
   
     </div>
                                </li>
                                <li><a href="/article/289.htm"
                                       title="[时间机器]制造时间机器需要一些材料" target="_blank">[时间机器]制造时间机器需要一些材料</a>
                                    <span class="text-muted">comsci</span>
<a class="tag" taget="_blank" href="/search/%E5%88%B6%E9%80%A0/1.htm">制造</a>
                                    <div>      根据我的计算和推测,要完全实现制造一台时间机器,需要某些我们这个世界不存在的物质 
    和材料... 
 
      甚至可以这样说,这种材料和物质,我们在反应堆中也无法获得...... 
 
     </div>
                                </li>
                                <li><a href="/article/416.htm"
                                       title="开口埋怨不如闭口做事" target="_blank">开口埋怨不如闭口做事</a>
                                    <span class="text-muted">邓集海</span>
<a class="tag" taget="_blank" href="/search/%E9%82%93%E9%9B%86%E6%B5%B7+%E5%81%9A%E4%BA%BA+%E5%81%9A%E4%BA%8B+%E5%B7%A5%E4%BD%9C/1.htm">邓集海 做人 做事 工作</a>
                                    <div>“开口埋怨,不如闭口做事。”不是名人名言,而是一个普通父亲对儿子的训导。但是,因为这句训导,这位普通父亲却造就了一个名人儿子。这位普通父亲造就的名人儿子,叫张明正。      张明正出身贫寒,读书时成绩差,常挨老师批评。高中毕业,张明正连普通大学的分数线都没上。高考成绩出来后,平时开口怨这怨那的张明正,不从自身找原因,而是不停地埋怨自己家庭条件不好、埋怨父母没有给他创造良好的学习环境。      </div>
                                </li>
                                <li><a href="/article/543.htm"
                                       title="jQuery插件开发全解析,类级别与对象级别开发" target="_blank">jQuery插件开发全解析,类级别与对象级别开发</a>
                                    <span class="text-muted">IT独行者</span>
<a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91/1.htm">开发</a><a class="tag" taget="_blank" href="/search/%E6%8F%92%E4%BB%B6%E3%80%80/1.htm">插件 </a><a class="tag" taget="_blank" href="/search/%E5%87%BD%E6%95%B0/1.htm">函数</a>
                                    <div>jQuery插件的开发包括两种:   一种是类级别的插件开发,即给 
jQuery添加新的全局函数,相当于给 
jQuery类本身添加方法。 
jQuery的全局函数就是属于 
jQuery命名空间的函数,另一种是对象级别的插件开发,即给 
jQuery对象添加方法。下面就两种函数的开发做详细的说明。  
   
1 
、类级别的插件开发   类级别的插件开发最直接的理解就是给jQuer</div>
                                </li>
                                <li><a href="/article/670.htm"
                                       title="Rome解析Rss" target="_blank">Rome解析Rss</a>
                                    <span class="text-muted">413277409</span>
<a class="tag" taget="_blank" href="/search/Rome%E8%A7%A3%E6%9E%90Rss/1.htm">Rome解析Rss</a>
                                    <div>import java.net.URL;  
import java.util.List;  
  
import org.junit.Test;  
  
import com.sun.syndication.feed.synd.SyndCategory;  
import com.sun.syndication.feed.synd.S</div>
                                </li>
                                <li><a href="/article/797.htm"
                                       title="RSA加密解密" target="_blank">RSA加密解密</a>
                                    <span class="text-muted">无量</span>
<a class="tag" taget="_blank" href="/search/%E5%8A%A0%E5%AF%86/1.htm">加密</a><a class="tag" taget="_blank" href="/search/%E8%A7%A3%E5%AF%86/1.htm">解密</a><a class="tag" taget="_blank" href="/search/rsa/1.htm">rsa</a>
                                    <div>RSA加密解密代码 
 
代码有待整理 
 
 
package com.tongbanjie.commons.util;


import java.security.Key;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerat</div>
                                </li>
                                <li><a href="/article/924.htm"
                                       title="linux 软件安装遇到的问题" target="_blank">linux 软件安装遇到的问题</a>
                                    <span class="text-muted">aichenglong</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/1.htm">遇到的问题</a><a class="tag" taget="_blank" href="/search/ftp/1.htm">ftp</a>
                                    <div>1 ftp配置中遇到的问题 
   500 OOPS: cannot change directory 
  出现该问题的原因:是SELinux安装机制的问题.只要disable SELinux就可以了 
  修改方法:1 修改/etc/selinux/config 中SELINUX=disabled 
    2 source /etc</div>
                                </li>
                                <li><a href="/article/1051.htm"
                                       title="面试心得" target="_blank">面试心得</a>
                                    <span class="text-muted">alafqq</span>
<a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a>
                                    <div>最近面试了好几家公司。记录下; 
支付宝,面试我的人胖胖的,看着人挺好的;博彦外包的职位,面试失败; 
阿里金融,面试官人也挺和善,只不过我让他吐血了。。。 
由于印象比较深,记录下; 
1,自我介绍 
2,说下八种基本类型;(算上string。楼主才答了3种,哈哈,string其实不是基本类型,是引用类型) 
3,什么是包装类,包装类的优点; 
4,平时看过什么书?NND,什么书都没看过。。照样</div>
                                </li>
                                <li><a href="/article/1178.htm"
                                       title="java的多态性探讨" target="_blank">java的多态性探讨</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>java的多态性是指main方法在调用属性的时候类可以对这一属性做出反应的情况 
//package 1;
class A{

    public void test(){
       System.out.println("A");
  }
}

class D extends A{

    public void test(){
       S</div>
                                </li>
                                <li><a href="/article/1305.htm"
                                       title="网络编程基础篇之JavaScript-学习笔记" target="_blank">网络编程基础篇之JavaScript-学习笔记</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div>1.documentWrite 
<html>
<head>
    <script language="JavaScript">
         document.write("这是电脑网络学校");
         document.close();
    </script>
</h</div>
                                </li>
                                <li><a href="/article/1432.htm"
                                       title="探索JUnit4扩展:深入Rule" target="_blank">探索JUnit4扩展:深入Rule</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/JUnit/1.htm">JUnit</a><a class="tag" taget="_blank" href="/search/Rule/1.htm">Rule</a><a class="tag" taget="_blank" href="/search/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/1.htm">单元测试</a>
                                    <div>        本文将进一步探究Rule的应用,展示如何使用Rule来替代@BeforeClass,@AfterClass,@Before和@After的功能。 
        在上一篇中提到,可以使用Rule替代现有的大部分Runner扩展,而且也不提倡对Runner中的withBefores(),withAfte</div>
                                </li>
                                <li><a href="/article/1559.htm"
                                       title="[CSS]CSS浮动十五条规则" target="_blank">[CSS]CSS浮动十五条规则</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/css/1.htm">css</a>
                                    <div>这些浮动规则,主要是参考CSS权威指南关于浮动规则的总结,然后添加一些简单的例子以验证和理解这些规则。 
  
1. 所有的页面元素都可以浮动 2. 一个元素浮动后,会成为块级元素,比如<span>,a, strong等都会变成块级元素 3.一个元素左浮动,会向最近的块级父元素的左上角移动,直到浮动元素的左外边界碰到块级父元素的左内边界;如果这个块级父元素已经有浮动元素停靠了</div>
                                </li>
                                <li><a href="/article/1686.htm"
                                       title="【Kafka六】Kafka Producer和Consumer多Broker、多Partition场景" target="_blank">【Kafka六】Kafka Producer和Consumer多Broker、多Partition场景</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/partition/1.htm">partition</a>
                                    <div>0.Kafka服务器配置 
3个broker 
1个topic,6个partition,副本因子是2 
2个consumer,每个consumer三个线程并发读取 
  1. Producer 
package kafka.examples.multibrokers.producers;

import java.util.Properties;
import java.util.</div>
                                </li>
                                <li><a href="/article/1813.htm"
                                       title="zabbix_agentd.conf配置文件详解" target="_blank">zabbix_agentd.conf配置文件详解</a>
                                    <span class="text-muted">ronin47</span>
<a class="tag" taget="_blank" href="/search/zabbix+%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/1.htm">zabbix 配置文件</a>
                                    <div>Aliaskey的别名,例如 Alias=ttlsa.userid:vfs.file.regexp[/etc/passwd,^ttlsa:.:([0-9]+),,,,\1], 或者ttlsa的用户ID。你可以使用key:vfs.file.regexp[/etc/passwd,^ttlsa:.: ([0-9]+),,,,\1],也可以使用ttlsa.userid。备注: 别名不能重复,但是可以有多个</div>
                                </li>
                                <li><a href="/article/1940.htm"
                                       title="java--19.用矩阵求Fibonacci数列的第N项" target="_blank">java--19.用矩阵求Fibonacci数列的第N项</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/fibonacci/1.htm">fibonacci</a>
                                    <div>参考了网上的思路,写了个Java版的: 
 
 



public class Fibonacci {

	final  static int[] A={1,1,1,0};
	
	
	public static void main(String[] args) {
		int n=7;
		for(int i=0;i<=n;i++){
			int f=fibonac</div>
                                </li>
                                <li><a href="/article/2067.htm"
                                       title="Netty源码学习-LengthFieldBasedFrameDecoder" target="_blank">Netty源码学习-LengthFieldBasedFrameDecoder</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/netty/1.htm">netty</a>
                                    <div>先看看LengthFieldBasedFrameDecoder的官方API 
 
http://docs.jboss.org/netty/3.1/api/org/jboss/netty/handler/codec/frame/LengthFieldBasedFrameDecoder.html 
 
API举例说明了LengthFieldBasedFrameDecoder的解析机制,如下: 
 
实</div>
                                </li>
                                <li><a href="/article/2194.htm"
                                       title="AES加密解密" target="_blank">AES加密解密</a>
                                    <span class="text-muted">chicony</span>
<a class="tag" taget="_blank" href="/search/%E5%8A%A0%E5%AF%86%E8%A7%A3%E5%AF%86/1.htm">加密解密</a>
                                    <div>AES加解密算法,使用Base64做转码以及辅助加密: 
package com.wintv.common;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decod</div>
                                </li>
                                <li><a href="/article/2321.htm"
                                       title="文件编码格式转换" target="_blank">文件编码格式转换</a>
                                    <span class="text-muted">ctrain</span>
<a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A0%81%E6%A0%BC%E5%BC%8F/1.htm">编码格式</a>
                                    <div>
package com.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
</div>
                                </li>
                                <li><a href="/article/2448.htm"
                                       title="mysql 在linux客户端插入数据中文乱码" target="_blank">mysql 在linux客户端插入数据中文乱码</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E4%B8%AD%E6%96%87%E4%B9%B1%E7%A0%81/1.htm">中文乱码</a>
                                    <div>1、查看系统客户端,数据库,连接层的编码 
 查看方法: http://daizj.iteye.com/blog/2174993 
进入mysql,通过如下命令查看数据库编码方式: mysql>  show variables like 'character_set_%'; +--------------------------+------</div>
                                </li>
                                <li><a href="/article/2575.htm"
                                       title="好代码是廉价的代码" target="_blank">好代码是廉价的代码</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/%E8%AF%BB%E4%B9%A6/1.htm">读书</a>
                                    <div>  
长久以来我一直主张:好代码是廉价的代码。 
当我跟做开发的同事说出这话时,他们的第一反应是一种惊愕,然后是将近一个星期的嘲笑,把它当作一个笑话来讲。 当他们走近看我的表情、知道我是认真的时,才收敛一点。 
当最初的惊愕消退后,他们会用一些这样的话来反驳: “好代码不廉价,好代码是采用经过数十年计算机科学研究和积累得出的最佳实践设计模式和方法论建立起来的精心制作的程序代码。” 
我只</div>
                                </li>
                                <li><a href="/article/2702.htm"
                                       title="Android网络请求库——android-async-http" target="_blank">Android网络请求库——android-async-http</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>在iOS开发中有大名鼎鼎的ASIHttpRequest库,用来处理网络请求操作,今天要介绍的是一个在Android上同样强大的网络请求库android-async-http,目前非常火的应用Instagram和Pinterest的Android版就是用的这个网络请求库。这个网络请求库是基于Apache HttpClient库之上的一个异步网络请求处理库,网络处理均基于Android的非UI线程,通</div>
                                </li>
                                <li><a href="/article/2829.htm"
                                       title="ORACLE 复习笔记之SQL语句的优化" target="_blank">ORACLE 复习笔记之SQL语句的优化</a>
                                    <span class="text-muted">eksliang</span>
<a class="tag" taget="_blank" href="/search/SQL%E4%BC%98%E5%8C%96/1.htm">SQL优化</a><a class="tag" taget="_blank" href="/search/Oracle+sql%E8%AF%AD%E5%8F%A5%E4%BC%98%E5%8C%96/1.htm">Oracle sql语句优化</a><a class="tag" taget="_blank" href="/search/SQL%E8%AF%AD%E5%8F%A5%E7%9A%84%E4%BC%98%E5%8C%96/1.htm">SQL语句的优化</a>
                                    <div>转载请出自出处:http://eksliang.iteye.com/blog/2097999 
  SQL语句的优化总结如下 
  
sql语句的优化可以按照如下六个步骤进行: 
 
 合理使用索引 
 避免或者简化排序 
 消除对大表的扫描 
 避免复杂的通配符匹配 
 调整子查询的性能 
 EXISTS和IN运算符 
 
下面我就按照上面这六个步骤分别进行总结: </div>
                                </li>
                                <li><a href="/article/2956.htm"
                                       title="浅析:Android 嵌套滑动机制(NestedScrolling)" target="_blank">浅析:Android 嵌套滑动机制(NestedScrolling)</a>
                                    <span class="text-muted">gg163</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/%E7%A7%BB%E5%8A%A8%E5%BC%80%E5%8F%91/1.htm">移动开发</a><a class="tag" taget="_blank" href="/search/%E6%BB%91%E5%8A%A8%E6%9C%BA%E5%88%B6/1.htm">滑动机制</a><a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%A5%97/1.htm">嵌套</a>
                                    <div>谷歌在发布安卓 Lollipop版本之后,为了更好的用户体验,Google为Android的滑动机制提供了NestedScrolling特性 
NestedScrolling的特性可以体现在哪里呢?<!--[if !supportLineBreakNewLine]--><!--[endif]--> 
比如你使用了Toolbar,下面一个ScrollView,向上滚</div>
                                </li>
                                <li><a href="/article/3083.htm"
                                       title="使用hovertree菜单作为后台导航" target="_blank">使用hovertree菜单作为后台导航</a>
                                    <span class="text-muted">hvt</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/.net/1.htm">.net</a><a class="tag" taget="_blank" href="/search/hovertree/1.htm">hovertree</a><a class="tag" taget="_blank" href="/search/asp.net/1.htm">asp.net</a>
                                    <div>  
hovertree是一个jquery菜单插件,官方网址:http://keleyi.com/jq/hovertree/ ,可以登录该网址体验效果。 
0.1.3版本:http://keleyi.com/jq/hovertree/demo/demo.0.1.3.htm 
hovertree插件包含文件: 
http://keleyi.com/jq/hovertree/css</div>
                                </li>
                                <li><a href="/article/3210.htm"
                                       title="SVG 教程 (二)矩形" target="_blank">SVG 教程 (二)矩形</a>
                                    <span class="text-muted">天梯梦</span>
<a class="tag" taget="_blank" href="/search/svg/1.htm">svg</a>
                                    <div>SVG <rect>   SVG Shapes 
SVG有一些预定义的形状元素,可被开发者使用和操作: 
 
 矩形 <rect> 
 圆形 <circle> 
 椭圆 <ellipse> 
 线 <line> 
 折线 <polyline> 
 多边形 <polygon> 
 路径 <path> 
 </div>
                                </li>
                                <li><a href="/article/3337.htm"
                                       title="一个简单的队列" target="_blank">一个简单的队列</a>
                                    <span class="text-muted">luyulong</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/%E9%98%9F%E5%88%97/1.htm">队列</a>
                                    <div>
public class MyQueue {
	private long[] arr;

	private int front;

	private int end;
	// 有效数据的大小
	private int elements;

	public MyQueue() {
		arr = new long[10];
		elements = 0;
		front </div>
                                </li>
                                <li><a href="/article/3464.htm"
                                       title="基础数据结构和算法九:Binary Search Tree" target="_blank">基础数据结构和算法九:Binary Search Tree</a>
                                    <span class="text-muted">sunwinner</span>
<a class="tag" taget="_blank" href="/search/Algorithm/1.htm">Algorithm</a>
                                    <div>  
A binary search tree (BST) is a binary tree where each node has a Comparable key (and an associated value) and satisfies the restriction that the key in any node is larger than the keys in all</div>
                                </li>
                                <li><a href="/article/3591.htm"
                                       title="项目出现的一些问题和体会" target="_blank">项目出现的一些问题和体会</a>
                                    <span class="text-muted">Steven-Walker</span>
<a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a><a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a>
                                    <div>     第一篇博客不知道要写点什么,就先来点近阶段的感悟吧。 
    这几天学了servlet和数据库等知识,就参照老方的视频写了一个简单的增删改查的,完成了最简单的一些功能,使用了三层架构。 
dao层完成的是对数据库具体的功能实现,service层调用了dao层的实现方法,具体对servlet提供支持。 
 &</div>
                                </li>
                                <li><a href="/article/3718.htm"
                                       title="高手问答:Java老A带你全面提升Java单兵作战能力!" target="_blank">高手问答:Java老A带你全面提升Java单兵作战能力!</a>
                                    <span class="text-muted">ITeye管理员</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>本期特邀《Java特种兵》作者:谢宇,CSDN论坛ID: xieyuooo 针对JAVA问题给予大家解答,欢迎网友积极提问,与专家一起讨论! 
 
 
作者简介: 
 
淘宝网资深Java工程师,CSDN超人气博主,人称“胖哥”。 
 
CSDN博客地址: 
http://blog.csdn.net/xieyuooo 
 
作者在进入大学前是一个不折不扣的计算机白痴,曾经被人笑话过不懂鼠标是什么,</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>