Elastic Stack--ELFK架构

news2024/12/23 22:40:37

 前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除

 学习B站博主教程笔记: 

最新版适合自学的ElasticStack全套视频(Elk零基础入门到精通教程)Linux运维必备—ElasticSearch+Logstash+Kibana精讲_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1VMW3e6Ezk/?spm_id_from=333.1007.tianma.1-1-1.click&vd_source=e539f90574cdb0bc2bc30a8b5cb3fc00

一、部署logstash环境

 # 官方下载搜索地址
 https://www.elastic.co/cn/downloads/past-releases#elasticsearch
 ​
 # 使用wget在master节点进行下载安装
 wget https://artifacts.elastic.co/downloads/logstash/logstash-7.17.3-x86_64.rpm
 yum -y localinstall logstash-7.17.3-x86_64.rpm

创建软链接:

 [root@k8s-master ~]# systemctl cat logstash
 ...
 ExecStart=/usr/share/logstash/bin/logstash "--path.settings" "/etc/logstash"
 ...
 ​
 # 创建一个软链接方便操作
 ln -sv /usr/share/logstash/bin/logstash /usr/local/bin
 logstash -h     # 检查
 ​
 # 创建一个用于存放配置文件的目录
 [root@k8s-master ~]# mkdir config-logstash

二、input插件

1、收集标准输入

 #(1)编写配置文件
 # vim config-logstash/01--sdtin-to-stdout.yml
 input { stdin {} }
 output { stdout {} }
 ​
 #(2)检查配置文件语法
 logstash -tf config-logstash/01-stdin-to-stdout.conf
 ​
 #(3)启动logstash实例
 logstash -f config-logstash/01-stdin-to-stdout.conf

2、文件输入插件

 input {
   file {
      #指定文件路径
      path => ["/tmp/test/*.txt"]
      #指定文件的读取位置,仅在".sincedb*"文件中没有记录的情况下生效
      #默认从末尾开始读取
      start_position => "beginning"      # /"end"
   }
 }
 ​
 output { stdout {} }

选择 Logstash 开始初始读取文件的位置:在开始时或在最后。默认行为将文件视为实时流,因此从最后开始

3、tcp输入插件,实现日志聚合

 input { tcp { port => 8888 }}
 output { stdout {} }

4、基于http案例

 input {
   http { port => 8888 }
   http { port => 9999 }
 }
 ​
 output { stdout {} }

5、input插件基于redis案例

 input {
   redis {
     data_type => "list"         # 指定的redis的键的类型
     db => 5                     # 指定数据库的编号,默认值是0号数据库
     host => "192.168.1.10"      # 指定数据库的IP地址,默认值是localhost
     port => 6379                # 指定数据库的端口号,默认值为6379
     password => "cluster"       # 指定redis的认证密码
     key => "xxxx"               # 指定从redis的哪个key取数据
   }
   http { port => 8888 }}
 ​
 output { stdout {} }

6、input插件基于beats案例

 # filebeat配置:
 filebeat.inputs:
 - type: tcp
   host: "0.0.0.0:9000"
 ​
 output.logstash:
   hosts: ["192.168.1.10:5044"]
 ​
 # logstash配置:
 input { beats { port => 5044 } }
 output { stdout {} }

三、output插件

1、logstash发送数据到redis环境

(1)编写配置文件

 input { tcp { port => 9999 } }
 ​
 ouput {
   stdout {}
   redis {
     host => "192.168.1.10"      # 指定redis的主机地址
     port => "6379"              # 指定redis的端口号
     db => 10                    # 指定redis的数据库编号
     password => "cluster"       # 指定redis的密码
     data_type => "list"         # 指定写入数据的key类型
     key => "cluster-linux-logstash" # 指定写入的key名称
   }
 }

(2)启动测试

 logstash -f config/tcp-to-redis.conf
 # 发送测试数据
 echo 111111 | nc 192.168.1.10 9999
 # 在redis中查看数据
 192.168.1.10:6379[10]>KEYS *
 1) "cluster-linux-logstash"
 192.168.1.10:6379[10]>type cluster-linux-logstash
 list

2、logstash输出插件file案例

(1)编写配置文件

 input { tcp { port => 9999 } }
 ​
 output {
   stdout{}
   file { 
     path => "/tmp/cluster-linux-logstash.log"       # 指定磁盘的落地位置
   }
 }

(2)测试运行

 logstash -f /config-logstash/tcp-to-file.conf
 ​
 # 同样的对9999端口发送测试数据
 echo 老男孩教育 | nc 192.168.1.10 9999
 cat /tmp/cluster-linux-logstash.log
 ...

3、logstash的输出插件到ES案例

(1)配置文件编写

 input { tcp { port => 9999 } }
 ​
 output {
   stdout{}
   elasticsearch {
     hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
     index => "cluster-linux-logstash-%{+yyyy.MM.dd}"
   }
 }

(2)启动测试

 logstash -rf config-logstash/tcp-to-es.conf

四、logstash综合案例

1、根据架构图收集日志

 # many-to-es.conf
 input {
   tcp {
     type => "tcp"
     port => 6666
   }
   beats {
     type => "beat"
     port => 7777
   }
   redis {
     type => "redis"
     data_type => "list" 
     db => 5
     host => "192.168.1.10"  
     port => "6379"                      
     password => "cluster"   
     key => "cluster-linux-filebeat"
   }  
 }
 ​
 output {
   # stdout{}    # 生产环境注释,输出到屏幕(调试使用)
   if [type] == "tcp" {
     elasticsearch {
       hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
       index => "cluster-linux-tcp-%{+yyyy.MM.dd}"
     }
   }else if [type] == "beat" {
     elasticsearch {
       hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
       index => "cluster-linux-beat-%{+yyyy.MM.dd}"
     }
   }else if [type] == "redis" {
     elasticsearch {
       hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
       index => "cluster-linux-redis-%{+yyyy.MM.dd}"
     }
   }else {
     elasticsearch {
       hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
       index => "cluster-linux-other-%{+yyyy.MM.dd}"
     }
   }
 }
 ​
 # 收集9999端口服务的日志信息:tcp-to-logstash.yml
 filebeat.inputs:
 - type: tcp
   host: "0.0.0.0:9999"
 output.logstash:
   host: ["192.168.1.10:7777"]
   
 # 收集redis服务端口日志信息:tcp-to-redis.yml
 filebeat.inputs:
 - type: tcp
   host: "0.0.0.0:8888"
 output.redis:
   hosts: ["192.168.1.10:6379"]
   password: "cluster"
   db: 5
   key: "cluster-linux-filebeat"
   timeout: 3

启动测试:

 filebeat -e -c tcp-to-logstash.yml
 filebeat -e -c tcp-to-redis.yml --path.data /tmp/filebeat/
 logstash -rf many-to-es.conf

2、收集Nginx与Tomcat日志

(1)收集Nginx日志到redis步骤:

 #1、nginx-to-redis.yml
 filebeat.inputs:
 - type: log
   paths: 
     - /var/log/nginx/access.log*
   json.keys_under_root: true
   
 output.redis:
   hosts: ["192.168.1.10:6379"]
   password: "cluster"
   db: 8
   key: "cluster-linux-filebeat"
   timeout: 3
   
 #2、运行测试
 [root@k8s-node1 config]# rm -rf /var/lib/filebeat/*
 [root@k8s-node1 config]# filebeat -e -c /etc/filebeat/config/32-nginx-to-redis.yml 
 [root@k8s-master ~]# redis-cli -a cluster -n 8
 127.0.0.1:6379[8]> keys *
 1) "cluster-linux-filebeat"
 127.0.0.1:6379[8]> lrange cluster-linux-filebeat 0 -1
 1) "{\"@timestamp\":\"202...    # 发现数据已经送达redis

(2)logstash收集日志到ES

 # many-to-es.conf
 input {
   beats {
     port => 8888
   }
   redis {
     data_type => "list"
     db => 8
     host => "192.168.1.10"
     port => 6379
     password => "cluster"
     key => "cluster-linux-filebeat"
   }
 }
 ​
 output {
   stdout{}
   elasticsearch {
     hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
     index => "cluster-linux-logstash-%{+yyyy.MM.dd}"
   }
 }
 ​
 #运行测试
 [root@k8s-master ~]# logstash -f config-logstash/11-many-to-es.conf

(3)收集Tomcat日志到logstash:

 #1、tomcat-to-logstash.yml
 filebeat.inputs:
 - type: log
   paths:
     - /root/software/apache-tomcat-10.1.28/logs/*.txt
   json.keys_under_root: true
 ​
 output.logstash:
   hosts: ["192.168.1.10:8888"]
   
 #2、运行测试
 [root@k8s-node1 config]# filebeat -e -c /etc/filebeat/config/33-tomcat-to-logstash.yml --path.data /tmp/filebeat/

五、filter插件

1、gork

1.1、基本的gork使用

Grok将非结构化日志数据解析为结构化和可查询的好方法;非常适合syslog日志、apache和其他网络服务器日志、Mysql日志,以及通常为人类而非计算机消耗而编写的任何日志格式。内置120种匹配模式,当然也可自定义匹配模式;

(1)还原nginx日志格式,使用原生日志

 vim /etc/ngin/nginx.conf

(2)编写filebeat收集Nginx原生日志文件输出到logstash的8888端口文件:

 # nginx-to-logstash.yml文件内容如下:
 filebeat.inputs:
 - type: log
   paths:
     - /var/log/nginx/access.log
 ​
 output.logstash:
   hosts: ["192.168.1.10:8888"]

(3)编写logstash收集8888端口收到的文件并发送的ES集群中文件:

使用grok过滤器对原生日志进行拆分;

 # beat-to-es.conf文件内容如下:
 input {
   beats {
     port => 8888
   }
 }
 filter {
   grok {
     match => {
       # "message" => "%{COMBINEDAPACHELOG}"   # 官方GitHub已经废弃,建议使用下面的匹配模式
       "message" => "%{HTTPD_COMMONLOG}"
     }
   }
 }
 output {
   stdout {}
   elasticsearch {
     hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
     index => "cluster-linux-logstash-%{-yyyy.MM.dd}"
   }
 }

(4)运行测试

 filebeat -e -c /etc/config/nginx-to-logstash.yml
 logstash -rf config-logstash/beat-to-es.conf

1.2、gork自定义的正则案例(知识储备)

有时候logstash没有我们需要的模式;我们自定义方法为:

首先使用 Oniguruma syntax 进行命名捕获,可让我们匹配一段文本并将其保存为字段:

 (?<field_name>这里的模式)
 ​
 # 例如,后缀日志有queue id一个10或11个字符的十六进制值,我们可以
 (?<queue_id>[0 - 9A - F]{10,11})

或者创建自定义模式文件:

  • 创建一个目录,包含一个名为patterns的文件extra
  • 在该文件中,将需要的模式写为模式名称、一个空格,然后是该模式的正则表达式。例如上述可以写成:

 # ./patterns/posifix的内容:
 POSITION_QUEUEID [0 - 9A - F]{10,11}

然后使用patterns_dir这个插件中的设置告诉logstash你的自定义模式目录在哪。完整示例:

 Jan  1 06:25:43 mailserver14 postfix/cleanup[21403]: BEF25A72965: message-id=<20130101142543.5828399CCAF@mailserver14.example.com>
 ​
 filter {
   grok {
     patterns_dir => ["./patterns"]
     match => { "message" => "%{SYSLOGBASE} %{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:syslog_message}" }
   }
 }

这会匹配并生成出一下字段:

 timestamp: Jan  1 06:25:43
 logsource: mailserver14
 program: postfix/cleanup
 pid: 21403
 queue_id: BEF25A72965
 syslog_message: message-id=<20130101142543.5828399CCAF@mailserver14.example.com>

1.3、remove_field与add_field子弹

如果此筛选器成功,将此事件中删除任意字段。 字段名称可以是动态的,并使用 %{field} 包含事件的一部分 例:

 filter {
   grok {
     # 移除指定的字段
     remove_field => [ "需要移除的字段1", "需要移除的字段2" ]
     # 添加指定的字段
     add_filed => { 
        "oldboyedu-clientip" => "clientip ---> %{clientip}"
        "school" => "北京大学"   
     }
   }
 }

1.4、add_tag与remove_tag字段

添加与移除tag标签:

 filter {
   grok {
     # 添加tag
     add_tag => [ "linux","zookeeper","kafka","elk" ]
     # 移除tag
     remove_tag => [ "zookeeper","kafka" ]
   }
 }

1.5、id字段

ID为插件配置添加一个唯一的。若有两个或多个相同类型的插件时建议使用。

 filter {
   grok {
     ...
     id => "nginx"
   }
 }

2、date插件修改写入ES的时间

 filter {
   grok {...}
   date {
     # 两种写法均可
     match => ["timestamp","dd/MMM/yyyy:HH:mm:ss Z"]
     match => ["timestamp","dd/MMM/yyyy:HH:mm:ss +0800"]
     # 可选项;
     timezone => "Asia/Shanghai"
     # 将匹配到的时间字段解析后存储到目标字段,若不指定,则默认字段为"@timestamp"字段
     target => "cluster-linux-access-time"
   }
 }

3、geoip分析源地址的地理位置

geoip字段对IP地址进行分析

 filter {
   grok {..}
   date {..}
   geoip {
       # 指定基于哪个IP进行分析
       source => "clientip"
       # 可设置只展示指定字段,若不设置,表示显示所有的查询字段
       fields => ["city_name","country_name","ip"]
       # 指定geoip的输出字段,对多个IP地址进行分析
       target => "cluster-linux-geoip"
   }
 }

4、useragent分析客户端的设备类型

 filter {
   date {..}
   geoip {..}
   useragent {
      source => "http_user_agent"            # 指定客户端的设备相关信息的字段
      target => "cluster-linux-useragent"    # 将分析的数据存储在一个指定的字段中,若不指定,则默认存储在target字段中
   }
 }

5、mutate组件数据准备

(1)python脚本准备数据

 cat > generate_log.py <<EOF
 #!/usr/bin/env/ python
 import datetime
 import random
 import logging
 import time
 import sys
 ​
 LOG_FORMAT = "%(levelname)s %(asctime)s [com.oldboyedu.%(module)s] - %(message)s "
 DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
 ​
 # 配置root的logging.Logger实例的基本配置
 logging.basicConfig(level=logging.INFO,format=LOG_FORMAT,detefmt=DATE_FORMAT,filename=sys.argv[1],filemode='a',)
 actions = ["浏览页面","评论商品","加入收藏","加入购物车","提交订单","使用优惠券","领取优惠券","搜索","查看订单","付款","清空购物车"]
 ​
 while True:
     time.sleep(random.randint(1,5))
     user_id = random.randint(1,10000)
     price = round(random.uniform(15000,30000),2)
     action = random.choice(actions)
     svip = random.choice([0,1])
     logging.info("DAU|{0}|{1}|{2}".format(user_id,action,svip,price))
 EOF
 # 运行、生成数据
 nohup python generate_log.py /tmp/app.log &>/dev/null &

(2)编写filebeat文件收集日志,并发送到logstash服务器的8888端口,以便接收:

 filebeat.inputs:
 - type: log
   enabled: true
   paths:
     - /tmp/app.log*
 output.logstash:
   hosts: ["192.168.1.10:8888"]

(3)在logstash服务器编写文件收集日志并发送到ES

 input {
   beats {
     port => 8888
   }
 }
 filter {
   mutate {
     add_field => { "school" => "B站大学老男孩IT教育" }
     remove_field => [ "@timestamp","agent","host","@version","ecs","tags","input","log"] }
   # 对"message"字段内容使用"|"进行切分"
   mutate { split => { "message" => "|" }}
   mutate {
     # 添加字段,其中引用到了变量
     add_field => {
        "user_id" => "%{[message][1]}"
        "action" => "%{[message][2]}"
        "svip" => "%{[message][3]}"
        "price" => "%{[message][4]}"
     }
   }
   mutate {
     # 将指定字段转换成相应的数据类型
     convert => {
        "user_id" => "integer"
        "svip" => "boolean"
        "price" => "float"
     }
   }
   mutate { strip => ["svip"] }      # 去除空格
   mutate { copy => { "price" => "cluster-linux-price" } }   #拷贝字段
   mutate { rename => { "message" => "cluster-ssvip" }}      #重命名
   mutate { replace => { "message" => "%{message}:My new message"}}  #替换
   mutate { uppercase => [ "message" ]}  # 首字母大写
 }
 ​
 output {
   stdout {}
   elasticsearch {
     hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
   }
 }

6、多if分支判断

(1)架构图如下:

(2)通过filebeat收集nginx的access.log日志:

 filebeat.inputs:
 - type: log
   paths:
     - /var/log/nginx/access.log*
   json.keys_under_root: true
 output.logstash:
   hosts: ["192.168.1.10:8888"]

(2)logstash收集端口日志文件如下:

 input {
   beats {
     type => "cluster-beats"
     port => 8888
   }
   tcp {
     type => "cluster-tcp"
     port => 9999
   }
   tcp {
     type => "cluster-tcp-new"
     port => 7777
   }
   tcp {
     type => "cluster-http"
     port => 6666
   }
   tcp {
     type => "cluster-file"
     path => "/tmp/apps.log"
   }
 }
 filter {
   mutate {
     add_field => {
       "school" => "B站大学老男孩IT"
     }
   }
   if [type] == ["cluster-beats","cluster-tcp-new","cluster-http"] {
     mutate {
       remove_field => ["agent","host","@version","ecs","tags","input","log"]
     }
     geoip {
       source => "clientip"
       target => "cluster-linux-geoip"
     }
     useragent {
       source => "http_user_agent"
       target => "cluster-linux-useragent"
     } else if [type] == "cluster-file" {
       mutate {
         add_field => {
           "class" => "cluster-linux80"
           "address" => "xxx"
           "hobby" => ["LOL","王者荣耀"]
         }
         remove_field => ["host","@version","school"]
       }
     }  
   } else {
     mutate {
       remove_field => ["port","@version","host"]
     }
     mutate { 
       split => { "message" => "|" }}
       add_field => {
         "user_id" => "%{[message][1]}"
         "action" => "%{[message][2]}"
         "svip" => "%{[message][3]}"
         "price" => "%{[message][4]}"
       }
       remove_field => ["message"]
       strip => ["svip"]
     }
     mutate {
       # 将指定字段转换成相应的数据类型
       convert => {
          "user_id" => "integer"
          "svip" => "boolean"
          "price" => "float"
       }
     }
   }
 } 
 output {
   stdout {}
   if [type] == "cluster-beats" {
     elasticsearch {
       hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
       index => "cluster-linux-logstash-beats-%{+YYYY.MM.dd}"
     }  
   } else {
     elasticsearch {
       hosts => ["192.168.1.10:9200","192.168.1.11:9200","192.168.1.12:9200"]
       index => "cluster-linux-logstash-tcp-%{+YYYY.MM.dd}"      
     }
   }
 ​
 }

(3)通过filebeat收集app.log的日志:

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /tmp/app.log*
output.logstash:
  hosts: ["192.168.1.10:9999"]

六、Kibana的样例数添加

...

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

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

相关文章

肿瘤免疫新视野:揭秘CXCL13+ T细胞对免疫检查点阻断的响应

肿瘤免疫新视野&#xff1a;揭秘CXCL13 T细胞对免疫检查点阻断的响应 在免疫治疗领域&#xff0c;探索肿瘤反应性T细胞对免疫检查点阻断&#xff08;ICB&#xff09;的响应机制一直是研究热点。一篇2022年发表在《Nature Cancer》上的研究——“Single-cell meta-analyses rev…

C++set与map容器

目录 一、关联式容器和序列式容器 二、树形结构的关联式容器 三、set容器 1.set容器的定义 2.set的构造 3.set的迭代器 4.set的容量 5.set的修改操作&#xff08;set容器不支持修改数据&#xff09; 6.set的一些其他常用接口 &#xff08;1&#xff09;find函数 &…

Google Earth Engine:对NDVI进行惠特克平滑算法进行长时序分析

目录 简介 函数 ee.Array.identity(size) Arguments: Returns: Array transpose(axis1, axis2) Arguments: Returns: Array matrixMultiply(image2) Arguments: Returns: Image matrixSolve(image2) Arguments: Returns: Image arrayFlatten(coordinateLabels, …

Ajax day-01

目录 一. Ajax 1.1 创建XMLHttpRequest对象 1.2 Ajax向服务器发送请求 1.3 设置http请求头 1.4 发送请求 1.5 获得响应 1.6 监听请求状态的改变 1.7 获取响应头 1.8 获得响应主体 1.9 处理服务器返回的数据 1.10 怎样向服务器传递数据&#xff1f; 二. 接口文档 三…

线性表之数组

数组&#xff08;Array&#xff09;是 C/C 中最基础和重要的数据结构之一&#xff0c;它提供了一种有效存储和访问固定大小元素集合的方式。关于数组的定义和使用相信大家都已经熟练掌握&#xff0c;本文将着重为大家剖析数组的物理结构和逻辑结构。 1. 数组的物理结构 数组的…

视频技术未来展望:EasyCVR如何引领汇聚融合平台新趋势

随着科技的飞速发展&#xff0c;视频技术已成为现代社会不可或缺的一部分&#xff0c;广泛应用于安防监控、娱乐传播、在线教育、电商直播等多个领域。本文将探讨视频技术的未来发展趋势&#xff0c;并深入分析TSINGSEE青犀EasyCVR视频汇聚融合平台的技术优势&#xff0c;展现其…

【SolidWorks2024 详细安装教程【附安装包】】

提示&#xff1a;【SolidWorks2024 详细安装教程【附安装包】】 文章目录 安装包获取一、安装步骤总结 安装包获取 提示&#xff1a;这里可以获得软件安装包&#xff1a; SolidWorks2024详细安装教程&#xff0c;百度网盘 链接&#xff1a;https://pan.baidu.com/s/1UyipwXokK…

rsync搭建全网备份

rsync搭建全网备份 1. 总体概述1.1 目标1.2 简易指导图1.3 涉及工具或命令1.4 环境 2. 实施2.1 配置备份服务器2.2 备份文件准备2.3 整合命令2.4 扩展功能 1. 总体概述 1.1 目标 本次搭建目标&#xff1a; 每天定时把服务器数据备份到备份服务器备份完成后进行校验把过期数据…

【python】turtle的使用

文章目录 1.初始化2.颜色3.画笔4.其他案例&#xff1a;分形树的绘制 1.初始化 import turtle# 创建一支画笔 pen turtle.Turtle()# ...# 暂停屏幕&#xff0c;防止程序关闭 turtle.done()2.颜色 # 设置颜色模式(如果要使用颜色相关设置&#xff0c;必须要使用这个) turtle.c…

基于STM32的RFID高速收费系统(论文+源码+实物)

1系统方案设计 本文基于STM32的RFID高速收费系统&#xff0c;其可以实现小车和货车两种车型收费&#xff0c;当车辆超过了规定的重量后&#xff0c;出现声光报警提示&#xff0c;并且启动杆不会抬起&#xff0c;只有当车辆重量低于设置值时&#xff0c;启动杆才会自动抬起&…

零基础学习Redis(7) -- hash类型命令使用

Redis本身就是通过哈希表的方式组织数据&#xff0c;同时redis中的value也可以是另一个哈希表。 1. 常用命令 1. hset / hsetnx hset key filed1 value1 filed2 value2 ... hset 用于把键值对存入value中&#xff0c;这里的key为redis组织的键&#xff0c; filed1 value1 fil…

SpringData-ElasticSearch入门

文章目录 1、创建demo工程2、application.properties3、Goods 实体类4、EsDemoApplicationTests 测试类5、pom.xml6、查看索引库7、查看单个索引&#xff08;数据库&#xff09;8、从goods索引中检索出符合特定搜索条件的文档&#xff08;或记录&#xff09; 1、创建demo工程 2…

Elasticsearch:使用 LTR 进行个性化搜索

作者&#xff1a;来自 Elastic Max Jakob 如今&#xff0c;用户已经开始期待根据个人兴趣定制搜索结果。如果我们听的所有歌曲都是摇滚歌曲&#xff0c;那么在搜索 “Crazy” 时&#xff0c;我们会期望 Aerosmith 的歌曲排在搜索结果的首位&#xff0c;而不是 Gnarls Barkley 的…

使用安信可Ai-WB2-12F开启wifi与手机通信TCP-IP(AT指令)

当时在做两个单片机之间无线通信&#xff0c;或者单片机与手机无线通信&#xff0c;就像找一个蓝牙和wifi双模的无线模块&#xff0c;一开始看ESP8684&#xff08;ESP32-C2&#xff09;这个芯片模组是有wifi和蓝牙的&#xff0c;买回来后才发现他不可以在程序运行中更换蓝牙或者…

《黑神话·悟空》这款游戏到底是用什么编程语言开发的?

你也有被这段游戏试玩视频刷屏吗&#xff1f; 13分钟、国产团队出品、B站上线不到24小时&#xff0c;播放量已经破千万&#xff0c;迅速火爆全网。 这就是来自国内游戏团队游戏科学&#xff08;Game Science&#xff09;开发的3A大作《黑神话&#xff1a;悟空》。 《黑神话悟…

vscode开发小程序

1 安装 "微信小程序开发工具" 2 安装 "WXML - Language Service" 3 安装 "wxmp-api-plugin" 或 "wechat-snippet" 4 安装"WXSS"

顶级的python入门教程!小白到大师,从这篇教程开始!

1. 为什么要学习Python&#xff1f; 学习Python的原因有很多&#xff0c;以下是几个主要的原因&#xff1a; 广泛应用&#xff1a;Python被广泛应用于Web开发、数据科学、人工智能、机器学习、自动化运维、网络爬虫、科学计算、游戏开发等多个领域。掌握Python意味着你可以在这…

嵌入式全栈开发学习笔记---Linux系统编程(进程间通信)

目录 进程间通信概述 进程通信目的 进程间通信的发展 进程间通信分类 管道通信 无名管道 有名管道mkfifo() 信号 发送信号kill & raise 忽略信号signal() 发送信号alarm() 消息队列 消息队列使用的步骤 创建消息队列msgget() 读写消息队列msgrcv()/msgsnd()…

ip地址一天变化好几次

‌IP地址每天变化的原因主要取决于其分配方式&#xff1a;静态或动态。静态IP地址是长期固定分配给一台设备的&#xff0c;除非进行手动更改或网络配置发生变化&#xff0c;否则该设备的IP地址将保持不变。而动态IP地址则是根据网络环境和需求动态分配给设备的&#xff0c;可能…

一些评估模型的总结(1)

最近学习了评估模型&#xff08;如下所示&#xff09;&#xff0c;对这四种方法进行小总结。 目录 1. 层次分析法。&#xff08;主观赋权方法&#xff0c;主观确定成对比较矩阵&#xff09; 2. 熵权法&#xff08;基于数据的客观赋权的方法&#xff09; 3. topsis方法&…