k8s部署elk+filebeat。springCloud集成elk+filebeat+kafka+zipkin实现多个服务日志链路追踪聚合到es

news2024/9/22 13:40:42

一、目的

如今2023了,大多数javaweb架构都是springboot微服务,一个前端功能请求后台可能是多个不同的服务共同协做完成的。例如用户下单功能,js转发到后台网关gateway服务,然后到鉴权spring-sercurity服务,然后到业务订单服务,然后到支付服务,后续还有发货、客户标签等等服务。
其中每个服务会启动多个实例做负载均衡,这样一来我们想看这个功能的完成流程日志,需要找到对应的服务器ip,日志文件在哪,其中又要确定具体负载转发到哪些台服务器上了。 如果是生产问题想要快速定位原因,需要一套解决方案!
在这里插入图片描述

二、涉及技术栈

  1. 基本架构:spring cloud(springBoot+服务发现+网关+负载熔断等netflex)。本人目前使用的是springboot+eureka+gateway+springSercurity+openfeign+springConfig 配合业务功能涉及中间件redis、quartz、kafka、mysql、elasticsearch
  2. 日志采集处理展现:ELK
    • elasticsearch:海量json数据存储即席查询
    • logstash: 源头采集数据(tcp、file、redis、mq)、格式化处理、推送es存储
    • kibana: 官方es可视化交互curd工具
  3. 高效轻量数据采集工具: filebeat。 监控日志文件实时获取,可以推送到kafka
  4. kafka:接收filebeat数据,供logstash消费
  5. 多服务链路追踪:sleuth-zipkin。无代码侵入。简单来说就是打印的日志内容新增了tranceId、spanId。例如 在这里插入图片描述

三、流程

  1. js发起ajax请求后台网关服务

  2. 网关服务集成了maven<artifactId>spring-cloud-starter-zipkin</artifactId>依赖,会自动给当前的请求header中添加tranceId字段和spanId字段。这两个字段值随机生成。其中tranceId等于spanId在header中没有这两个字段的时候:例如tranceId=123a,spanId=123a 并添加到header中。并且打印日志的时候会把这个信息打印出来

  3. 之后网关根据请求路径转发到业务服务A,A服务的zipkin发现header中有tranceId信息,就只生成spanId,例如tranceId=123a,spanId=231b 并添加到header中。并且打印日志的时候会把这个信息打印出来。

  4. A服务又rpc调用了B服务。B服务的zipkin发现header中有tranceId信息,就只生成spanId,例如tranceId=123a,spanId=342h 并添加到header中。并且打印日志的时候会把这个信息打印出来。

  5. 调用完结返回前端响应。

  6. 到此服务器的日志文件就会新增上述的日志。然后filebeat工具监听到了各个服务的新日志,读取并推送到kafka

  7. 消息队列的topic下生产新数据,logstash工具提前配置并启动消费kafka, 处理并保存数据到elasticsearch。这里好奇为什么不直接通过filebeat直接推送es,或者springboot的log框架直接通过appender直接推送es呢?

    • 使用filebeat解耦,不影响springboot性能。并且轻量
    • 使用kafka是应对大量并发数据,减少logstash压力
    • 最终经过logstash推送es是为了加工格式化源数据,再保存到es,这样更加方便es查询日志
  8. 持久化es之后,通过kibana查询日志,查询条件是tranceId=123a即可查询出完整的日志。

四、整合配置filebeat、kafka、logstash例子

我分了两部分,有些是部署在服务器上的jar,我就通过filebeat采集;有些是部署到本地笔记本上的服务,直接在logback.xml配置一个appender输出到kafka,不经过filebeat。

logstash.conf

input {
  kafka{
    bootstrap_servers => "node101:30701"
    client_id => "logstash_kafka_consumer_id"
    group_id => "logstash_kafka_consumer_group"
    auto_offset_reset => "latest" 
    consumer_threads => 1
    decorate_events => true 
    topics => ["logstash"]
  }

}

filter{
}
 
output{
    elasticsearch{
    hosts => ["node101:30600"]
    index => "logstash-%{+YYYY.MM.dd}"
    }
}

filebeat.yml

filebeat.modules:
filebeat.prospectors:
- type: log
  enabled: true
  paths:
    - /spring-boot-logs/*/user.*.log
  #include_lines: ["^ERR", "^WARN"]
      # 适用于日志中每一条日志占据多行的情况,比如各种语言的报错信息调用栈
  multiline:
    pattern: '^[[:space:]]'
    negate: false
    match: after

processors:
  - drop_fields:
      fields: ["metadata", "prospector", "offset", "beat", "source","type"]

output.kafka:
  hosts: ["node101:30701"]
  topic: logstash

k8s的yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: elk
  name: ssx-elk-dm
  namespace: ssx
spec:
  replicas: 1 
  selector: #标签选择器,与上面的标签共同作用
    matchLabels: #选择包含标签app:mysql的资源
       app: elk
  template: #这是选择或创建的Pod的模板
    metadata: #Pod的元数据
      labels: #Pod的标签,上面的selector即选择包含标签app:mysql的Pod
        app: elk
    spec: #期望Pod实现的功能(即在pod中部署)
      hostAliases: #给pod添加hosts网络
      - ip: "192.168.0.101"
        hostnames:
        - "node101"
      - ip: "192.168.0.102"
        hostnames:
        - "node102"
      - ip: "192.168.0.103"
        hostnames:
        - "node103"
      containers: #生成container,与docker中的container是同一种
      - name: ssx-elasticsearch6-c
        image: 9d77v/elasticsearch:6.2.4 #配置阿里的镜像,直接pull即可
        ports:
        - containerPort: 9200  # 开启本容器的80端口可访问
        - containerPort: 9300  # 开启本容器的80端口可访问
        env:   #容器运行前需设置的环境变量列表
        - name: discovery.type  #环境变量名称
          value: "single-node" #环境变量的值 这是mysqlroot的密码 因为是纯数字,需要添加双引号 不然编译报错
        volumeMounts:
        - mountPath: /usr/share/elasticsearch/data   #这是mysql容器内保存数据的默认路径
          name: c-v-path-elasticsearch-data
        - mountPath: /usr/share/elasticsearch/logs   #这是mysql容器内保存数据的默认路径
          name: c-v-path-elasticsearch-logs
        - mountPath: /usr/share/elasticsearch/.cache   #这是mysql容器内保存数据的默认路径
          name: c-v-path-elasticsearch-cache
        - mountPath: /etc/localtime   #时间同步
          name: c-v-path-lt

      - name: ssx-kibana-c
        image: wangxiaopeng65/kibana:6.2.4 #配置阿里的镜像,直接pull即可
        ports:
        - containerPort: 5601  # 开启本容器的80端口可访问
        env:   #容器运行前需设置的环境变量列表
        - name: ELASTICSEARCH_URL  #环境变量名称
          value: "http://localhost:9200" #环境变量的值 这是mysqlroot的密码 因为是纯数字,需要添加双引号 不然编译报错
        volumeMounts:
        - mountPath: /usr/share/kibana/data2   #无用,我先看看那些挂载需要
          name: c-v-path-kibana
        - mountPath: /etc/localtime   #时间同步
          name: c-v-path-lt

      - name: ssx-logstash-c
        image: docker.elastic.co/logstash/logstash:6.2.4 #配置阿里的镜像,直接pull即可
        env:   #容器运行前需设置的环境变量列表
        - name: "xpack.monitoring.enabled"  #禁用登录验证
          value: "false" #环境变量的值 这是mysqlroot的密码 因为是纯数字,需要添加双引号 不然编译报错
        args: ["-f","/myconf/logstash.conf"]
        volumeMounts:
        - mountPath: /myconf   #配置
          name: c-v-path-logstash-conf
        - mountPath: /usr/share/logstash/data   #data
          name: c-v-path-logstash-data
        - mountPath: /etc/localtime   #时间同步
          name: c-v-path-lt

      - name: ssx-filebeat-c
        image: elastic/filebeat:6.2.4  #配置阿里的镜像,直接pull即可
        env:   #容器运行前需设置的环境变量列表
        volumeMounts:
        - mountPath: /usr/share/filebeat/filebeat.yml   #配置
          name: c-v-path-filebeat-conf
        - mountPath: /usr/share/filebeat/data  #配置
          name: c-v-path-filebeat-data
        - mountPath: /spring-boot-logs  #data
          name: c-v-path-filebeat-spring-logs
        - mountPath: /etc/localtime   #时间同步
          name: c-v-path-lt

      volumes:
      - name: c-v-path-elasticsearch-data #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/elasticsearch6/data  #此路径需要实现创建 注意要给此路径授权777权限 不然pod访问不到
      - name: c-v-path-elasticsearch-logs #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/elasticsearch6/logs  #此路径需要实现创建 注意要给此路径授权777权限 不然pod访问不到
      - name: c-v-path-elasticsearch-cache #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/elasticsearch6/.cache  #此路径需要实现创建 注意要给此路径授权777权限 不然pod访问不到
      - name: c-v-path-kibana #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/kibana  #此路径需要实现创建 注意要给此路径授权777权限 不然pod访问不到
      - name: c-v-path-logstash-conf
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/logstash/myconf
      - name: c-v-path-logstash-data
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/logstash/data
      - name: c-v-path-lt
        hostPath:
          path: /etc/localtime   #时间同步
      - name: c-v-path-filebeat-conf
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/filebeat/myconf/filebeat.yml
      - name: c-v-path-filebeat-data
        hostPath:
          path: /home/app/apps/k8s/for_docker_volume/elk/filebeat/data
      - name: c-v-path-filebeat-spring-logs
        hostPath:
          path: /home/ssx/appdata/ssx-log/docker-log

      nodeSelector: #把此pod部署到指定的node标签上
        kubernetes.io/hostname: node101
---
apiVersion: v1
kind: Service
metadata:
  labels:
   app: elk
  name: ssx-elk-sv
  namespace: ssx
spec:
  ports:
  - port: 9000 #我暂时不理解,这个设置 明明没用到?
    name: ssx-elk-last9200
    protocol: TCP
    targetPort: 9200 # 容器nginx对外开放的端口 上面的dm已经指定了
    nodePort: 30600 #外网访问的端口

  - port: 9010 #我暂时不理解,这个设置 明明没用到?
    name: ssx-elk-last9300
    protocol: TCP
    targetPort: 9300 # 容器nginx对外开放的端口 上面的dm已经指定了
    nodePort: 30601 #外网访问的端口

  - port: 9011 #我暂时不理解,这个设置 明明没用到?
    name: ssx-kibana
    protocol: TCP
    targetPort: 5601 # 容器nginx对外开放的端口 上面的dm已经指定了
    nodePort: 30602 #外网访问的端口

  selector:
    app: elk
  type: NodePort 



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

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

相关文章

mysql数据库管理-GTID详解

一、GTID概述 1 sql线程执行的事件也可以通过log_slave_updates系统变量来决定是否写入自己的二进制文件中&#xff0c;这是可以用于级联复制的场景。 GTID是MYSQL5.6新增的特性&#xff0c;GTID&#xff08;Global Transaction Identifier&#xff09;全称为全局事务标示符…

17种编程语言实现排序算法-计数排序

开源地址 https://gitee.com/lblbc/simple-works/tree/master/sort/ 覆盖语言&#xff1a;C、C、C#、Java、Kotlin、Dart、Go、JavaScript(JS)、TypeScript(TS)、ArkTS、swift、PHP。 覆盖平台&#xff1a;安卓(Java、Kotlin)、iOS(SwiftUI)、Flutter(Dart)、Window桌面(C#)、…

力扣sql简单篇练习(五)

力扣sql简单篇练习(五) 1 游戏玩法分析 I 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 第一次登录平台的日期就代表是时间靠前的日期 # 窗口函数是Mysql8版本后才能使用 SELECT e.player_id,e.event_date first_login FROM (SELECT player_id,e…

五、python-地图可视化篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. 基础地图 2. 设置分段 1. 基础地图 from pyecharts.charts import Map # 准备地图对象 map Map() # 准备数据 data[ ("北京",99), ("上海",199), ("…

17种编程语言实现排序算法-堆排序

开源地址 https://gitee.com/lblbc/simple-works/tree/master/sort/ 覆盖语言&#xff1a;C、C、C#、Java、Kotlin、Dart、Go、JavaScript(JS)、TypeScript(TS)、ArkTS、swift、PHP。 覆盖平台&#xff1a;安卓(Java、Kotlin)、iOS(SwiftUI)、Flutter(Dart)、Window桌面(C#)、…

Maplab 2.0发布:多传感器融合的SLAM框架,支持多机器人、语义回环检测功能

摘要 将多种传感器和深度学习集成到SLAM系统中是当前研究的重要领域。多模态是一块跳板&#xff0c;既可以在挑战场景下增强鲁棒性&#xff0c;又可以解决不同传感器配置的多机系统建图问题。Maplab 2.0提供了一个更加通用的开源平台&#xff0c;最初的Maplab用于创建和管理视…

5-3中央处理器-数据通路的功能和基本结构

文章目录一.功能二.基本结构三.数据流向&#xff08;一&#xff09;内部单总线方式1.寄存器之间的数据传送2.主存与CPU之间的数据传送3.执行算术或逻辑运算&#xff08;二&#xff09;专用数据通路方式一.功能 数据在功能部件之间传送的路径称为数据通路。路径上的部件称为数据…

合宙ESP32C3上手使用

概述经典款是有ch343 ttl 转usb 需要安装驱动 GPIO20/21新款使用usb 直连不需要驱动 USB GPIO18/19ESP32C3 是ESP-RISC-V CPU 是基于 RISC-V ISA 的 32 位内核&#xff0c;包括基本整数 (I)&#xff0c;乘法/除法 (M) 和压缩 (C) 标准扩展。ESP-RISC-V CPU 内核具有 4 级有序标…

【蓝桥杯】简单数论1——GCDLCM

GCD 最大公约数Greatest Common Divisor(GCD)&#xff1a;整数a和b的GCD是指能同时整除a和b的最大整数&#xff0c;记为gcd(a,b)。由于-a的因子和a的因子相同&#xff0c;因此gcd(a, b) gcd(al, |bl)。编码时只关注正整数的最大公约数。 GCD性质 (1) gcd(a, b) gcd(a, ab) …

一、python准备工作篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. python官网 2. 检查是否安装完毕 3. pycharm官网 5. phcharm更换主题 6. 新建第一个python文件 7. pycharm字体大小设置 8. 设置快捷键 设置字体大小 ​​​​​​​9. 安装中文…

Python机器学习:假设检验

方差分析这部分内容还不是很理解&#xff0c;在这里先做一个笔记&#xff0c;以后有时间再回过头来改一改。 用到的数据集→\rightarrow→Iris 什么是假设检验&#xff1f; 假设检验就是利用样本数据对某个事先做出的统计假设&#xff0c;再按照某种方法去检验&#xff0c;最后…

CSS样式基础内容2

目录 Emmet语法 快速格式化代码 CSS的复合选择器 后代选择器 子选择器 并集选择器 伪类选择器 链接伪类选择器 focus伪类选择器 CSS元素显示模式 块元素 行内元素 行内块元素 元素显示模式转换 案例-简洁版侧边栏 单行文字垂直居中 CSS的背景 背景图片 方位名词…

【蓝桥云课】最大公约数与最小公倍数

一、最大公约数gcd(a,b) 引例&#xff1a; a24&#xff0c;其因子有1、2、3、4、6、8、12、24 b15&#xff0c;其因子有1、3、5、15 最大公约数gcd(a,b)gcd(24,15)3 欧几里得辗转算法&#xff1a; a max(a,b); b min(a,b); while(b>0){t a%b;a b;b t; }运算过程&…

postgresql源码学习(53)—— vacuum②-lazy vacuum之heap_vacuum_rel函数

一、 table_relation_vacuum函数 1. 函数定义 前篇最后&#xff08;https://blog.csdn.net/Hehuyi_In/article/details/128749517&#xff09;&#xff0c;我们提到了table_relation_vacuum函数&#xff08;tableam.h文件&#xff09;&#xff0c;本篇继续学习。 如前面所说&a…

人大金仓数据库对象访问权限

数据库的表、索引、视图等&#xff0c;在数据库中的一切都可以称为数据库对象。 对象分为以下两类 模式&#xff08;SCHEMA&#xff09;对象&#xff1a;可视为一个表的集合&#xff0c;可以理解为一个存储目录&#xff0c;包含视图、索引、数据类型、函数和操作符等。非模式…

AcWing1229.日期问题——学习笔记

目录 题目 代码 AC结果 思路&#xff1a; 一、获取数据 二、验证日期合法性 三、去重 四、排序 五、主方法中调用&输出 题目 1229. 日期问题 - AcWing题库https://www.acwing.com/problem/content/description/1231/ 代码 import java.util.Scanner;public class…

XILINX FPGA OV5640 摄像头驱动(一)

影像行业是一个值得深耕的方向&#xff0c;废话不多说 先看输入和输出 输入是光照&#xff0c;输出是光照的数字信号 image area&#xff1a;说的是感光矩阵&#xff0c;CMOS图像传感器的最核心部分&#xff0c;接收光照产生电信号的部分。决定了图像质量的好坏 矩阵就会行列…

MyBatisPlus笔记

一、MyBatisPlus概述 MyBatisPlus&#xff08;简称 MP&#xff09;是一个MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 MyBatis-Plus可以节省我们大量工作时间&#xff0c;所有的CRUD代码它都可以自动化完成&…

leetcode1143 最长公共子序列

题目 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08;…

因果诊断原理

因果分析在近十来年逐渐倍受关注&#xff0c;其提供了解释因子间因果性的定量分析工具&#xff0c;广泛用于数据分析领域&#xff0c;同时也就用决策分析、作用预估等反事实因果推理中。本文首先对比了因果性和相关性的关系&#xff0c;之后确定因果关系的基本方法&#xff0c;…