高并发高性能接口中,异步打印并采集业务日志的实现方案

news2025/1/11 22:40:51

一、背景

高并发接口中,为了提高接口的高性能,在需要保存审计及操作记录的时候,往往有以下常见方案:

  • 保存到redis数据库
  • 异步保存到mysql/mongodb/es等数据库
  • logger打印业务日志,采集与展示则交由elk模块

对于第一种方案,接口的高性能依赖于redis的性能;第二种方案的关键在于异步,可以是基于事件驱动机制,常见的CQRS设计就是例子;
本文则是介绍第三种方案,不同的是,我们的数据展示是在业务管理后台,而非kibana。

另外,生产环境,我们的应用程序是部署在k8s容器。

二、设计方案

在这里插入图片描述

  • 1、服务打印日志,持久化到nfs
  • 2、filebeat先挂载nfs,再配置采集日志
  • 3、kafka作为数据采集的削峰填谷的角色
  • 4、Logstash读取kafka的数据,解析并存储到指定es数据库
  • 5、管理后台连接并读取es数据库,展示数据

三、打印业务日志

使用logback使用不同的Logger对象,区分普通的jvm日志,把业务日志输出到指定的日志文件。

  • logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--该日志将日志级别不同的log信息保存到不同的文件中 -->
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <springProperty scope="context" name="springAppName"
                    source="spring.application.name"/>

    <springProperty scope="context" name="log_dir" source="logging.login.path" defaultValue="../logs"/>

    <!-- 日志输出位置 -->
    <property name="LOG_FILE" value="${log_dir}/${springAppName}-login"/>
    
    <!-- 文件的日志输出样式 -->
    <property name="FILE_LOG_PATTERN"
              value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
              
    <!-- 为logstash输出的JSON格式的Appender -->
    <appender name="logstash"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名 -->
            <fileNamePattern>${LOG_FILE}.log.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>20MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数 -->
            <MaxHistory>15</MaxHistory>
        </rollingPolicy>
        <!-- 日志输出编码 -->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <logger name="com.xxx.event.handler.LoginLogEventHandler" level="INFO" additivity="false">
        <appender-ref ref="logstash"/>
    </logger>
</configuration>

普通的jvm日志选择输出在console控制台,然后将流重定向到指定的日志文件里。

  • console

    <!-- 控制台的日志输出样式 -->
    <property name="CONSOLE_LOG_PATTERN"
              value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
             
    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <!-- 日志输出编码 -->
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>
    
    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="console"/>
    </root>

对于业务应用程序来说,所做的事情只需要打印一条日志即可,其高性能可想而知。

四、flebeat采集日志

申请一台机器,专门采集日志,而非在每个Pod容器里使用sidecar边车模式部署filebeat容器。

当然,这台机器必须要先挂载nfs。(nfs是购买的阿里云“文件存储NAS”服务)

在这里插入图片描述

下面是filebeat.yml示例:

# cat /etc/filebeat/filebeat.yml
filebeat.prospectors:
- input_type: log
  paths:
    - /login_output_service/auth-service.log
  multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
  multiline.negate: true
  multiline.match: after
  document_type: login_out_logs

output.kafka:
  enabled: true
  hosts: ["xxx.alikafka.aliyuncs.com:9092","yyy.alikafka.aliyuncs.com:9092","zzz.alikafka.aliyuncs.com:9092"]
  topic: 'login_out_logs'

五、kafka中间件

当然,它作为数据采集的中间件,所起的作用是削峰填谷,可以说,在整个链路中不是必须的。

建议你采用mq作为数据采集的过渡。

这里插一句,我们可以通过kafka的消息内容,反查出filebeat所在的机器。

原本的思路是想通过文件存储NAS查找ECS的挂载详情,可惜没找到入口。(也就是说,无法得到哪些ECS挂载了NFS,只能选择通过Kafka)

忘记了filebeat是部署在哪个机器,好在我们知道kafka,因为购买的是阿里云服务。

进入“消息队列Kafka版”

在这里插入图片描述
查看消息体内容:

在这里插入图片描述

{“@timestamp”:“2024-04-01T20:26:24.956Z”,“beat”:{“hostname”:“iZbp12202mumv2j30jv6l8Z”,“name”:“iZbp12202mumv2j30jv6l8Z”,“version”:“5.6.9”},“input_type”:“log”,“message”:“2024-04-02 04:25:18.486 INFO [auth-service,] 8 — [AuthService_EventPool_757886445] c.x.s.a.i.e.h.LoginLogEventHandler : LoginLogEventHandler - writeLoginLog - 登录登出日志 [id=1774895838313730083\tdate=20240402042518\tosVersion= 13]”,“offset”:10016,“source”:“/opt/server/auth-service.log”,“type”:“login_out_logs”}

从这里可以看到,filebeat机器hostname是iZbp12202mumv2j30jv6l8Z,注意需要转换,实际上是“i-bp12202mumv2j30jv6l8”。

另外从source字段,可以知道日志的源文件在哪。

  • 根据hostname查找ecs所在地

进入“云服务器ECS”

在这里插入图片描述
通过这两步,我们就通过kafka消息中间件,反查得到filebeat所在机器。关于filebeat在上一步已介绍,下面将介绍logstash的配置。

六、logstash存储业务日志

Logstash主要是用来解析业务日志,先读取kafka的数据,然后存储到es数据库。

另外logstash支持多个配置文件,建议你分开配置并加载。

# 默认配置
logstash -f /usr/share/logstash/pipeline/logstash.conf

# 修改为通配符*.conf
logstash -f /usr/share/logstash/pipeline/*.conf
  • auth.conf 详情
# cat /usr/local/logstash-6.8.23/config/auth.conf

input {
     kafka {
        bootstrap_servers => "xxx.alikafka.aliyuncs.com:9092","yyy.alikafka.aliyuncs.com:9092","zzz.alikafka.aliyuncs.com:9092"
        codec => "json"
        type => "_doc"
        topics => "login_out_logs"
    }
}

filter {
          grok {
                match => {"message"=>"%{JAVA_DATE:logdate}\s+%{XHJVM_VALUE:logType}\s.*登录登出日志\s+\[id=(%{FIELD_VALUE:id}?\s+)date=(%{FIELD_VALUE:date}?\s+)osVersion=(%{FIELD_VALUE:osVersion}?)\]"}
  }

# 增加采集时间戳,去掉一些非必要的字段
  date {
       match => ["logdate", "yyyy-MM-dd HH:mm:ss.SSS"]
       target => "@timestamp"
       remove_field => [ "logdate", "logType", "host", "@version", "@timestamp", "path", "message", "beat", "source", "input_type", "offset"]
       }

 }

output{
  elasticsearch{
    # es的地址
    hosts => ["10.xxx.xxx.126:9200"]
    index => "auth_login_out_logs_write"
    codec => line { format => "%{message}"}
    document_type => "_doc"
    # es的用户名
    user => "{username}"
    # es的密码
    password => "{password}"
    document_id => "%{id}"
  }
}

还好无意中找到了logstash所在机器,要不然,要找出logstash还真是麻烦。。。

因为这里把很多“无用”的字段remove掉了,所以在es数据库中也无法得到采集的链路详情。

七、总结

本文试着通过另外一个解决方案来保证高并发接口的高性能,顺便介绍了如何找回filebeat所在机器的过程。同时提醒我们,在采集数据的时候,或者程序开发的时候,特别是当你的链路很长的时候,把每个环节的主体信息记录下来是多么的重要。

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

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

相关文章

【MATLAB源码-第4期】基于MATLAB的1024QAM误码率曲线,以及星座图展示。

1、算法描述 正交幅度调制&#xff08;QAM&#xff0c;Quadrature Amplitude Modulation&#xff09;是一种在两个正交载波上进行幅度调制的调制方式。这两个载波通常是相位差为90度&#xff08;π/2&#xff09;的正弦波&#xff0c;因此被称作正交载波。这种调制方式因此而得…

福建单航次最大批量汽车“出海”

3月12日这一天&#xff0c;在福州海关的严密监管下&#xff0c;共有4000辆上汽名爵品牌的汽车被高效有序地装载到“安吉智慧”号滚装船上&#xff0c;这批车辆即将启程前往荷兰、埃及、英国等多个海外市场。在这批出口汽车中&#xff0c;新能源车型占据了显著的比例&#xff0c…

FFmpeg 框架分析

1 概述 按照DirectShow 对播放器模块的划分&#xff0c;一个完整的播放器应该需要获得以下四个模块支持&#xff1a; Source Filter : 数据源&#xff0c;可以是本地文件fopen, 也可以是网络文件,http,rtp,rtmp 等等 Demux Fliter: 解复用&#xff0c;下载的数据是带容器封装…

Java | Leetcode Java题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> quadruplets new ArrayList<List<Integer>>();if (nums null || nums.length < 4) {return…

循环单链表算法库

学习贺老师数据结构 数据结构之自建算法库——循环单链表_循环单链表 csdn-CSDN博客​​​​​​ 整理总结出的循环单链表算法库 v1.0 : 基本实现功能 v2.0(2024.4.6): 修复Delete_SpecificLocate_CyclicList()删除节点函数bug,添加验证删除节点是否超范围判断 目录 1.主要功能…

CSS设置文本

目录 概述&#xff1a; text-aling: text-decoration: text-transform: text-indent: line-height: letter-spacing: word-spacing: text-shadow: vertical-align: white-space: direction: 概述&#xff1a; 在CSS中我们可以设置文本的属性&#xff0c;就像Word文…

测开面经(Git经典题目,Git入门)

1. GitHub是什么 a. Git是一个分布式版本控制系统&#xff0c;作用是跟踪、管理和协调软件开发项目中的代码更改。 b. 提供了一种有效的方式来管理代码的版本历史&#xff0c;以及多人协作开发的能力。 2. Git的作用有哪些 a. 版本控制&#xff1a;Git可以记录每次代码更改的…

Linux的学习之路:8、Linux调试器-gdb使用

摘要 本章主要是说一下gdb的使用&#xff0c;以及把使用指令放入放个指令手册。 目录 摘要 一、背景 二、使用 1、产生debug文件 2、进入gdb 3、使用指令 三、思维导图 一、背景 Linux调试器gdb的背景主要涉及到Linux程序发布方式和调试需求。 在Linux中&#xff0c…

加速杂交水稻走向世界 政协委员建议在湖南设立一“协会”一“中心”

中新网北京3月8日电 (刘曼)针对中国杂交水稻海外“飘香”的现象&#xff0c;全国政协委员、湖南省政协副主席、民盟湖南省委会主委何寄华建议&#xff0c;在湖南建立杂交水稻国际合作交流协会、设立杂交水稻国际科技合作技术转移中心&#xff0c;支持杂交水稻走向世界。 全国政…

mysql主从复制Slave_SQL_Running: No

1、SHOW SLAVE STATUS \G; Slave_SQL_Running: No 解决方案&#xff1a; 重新同步主库和从库的数据 1、从库先停掉slave stop slave; 2、在主库查看此时的日志文件和位置 show master status; 3、在从库中执行 change master to master_host192.168.2.177,master_userslave…

【MATLAB源码-第187期】基于matlab的人工蜂群优化算法(ABC)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 Artificial Bee Colony&#xff08;ABC&#xff09;算法是一种模仿蜜蜂觅食行为的优化算法&#xff0c;它通过模拟蜜蜂群体的社会结构和行为来解决数学优化问题。本文将详细介绍ABC算法的基本原理、算法流程、以及在实际应用…

C语言进阶课程学习记录 - 字符串与常见问题分析

C语言进阶课程学习记录 - 字符串与字符串问题分析 字符串实验-字符串定义实验-字符串作为字符数组使用实验-字符串长度判断小结 字符串问题分析实验-snprintf实验-字符数组,strlen,sizeof实验-字符串相等比较实验-循环右移 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&…

浅入浅出之nginx

目录 工作流程正向代理概念 反向代理概念 nginx反向代理配置文件介绍解释作用 参考文章Nginx 常用指令和操作启动 Nginx测试配置文件快速关闭 Nginx优雅关闭 Nginx重载配置文件查看版本查看编译时的参数查看进程配置用户访问日志配置错误日志设置 web 根目录配置 server 块配置…

3.反转链表

1.题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&…

matplotlib手动调用默认配色

matplotlib 画图有个默认配色方案&#xff0c;在画不同图时会保持一致。如&#xff1a; import numpy as np import matplotlib.pyplot as plt# 图 1 数据 x np.arange(12).astype(np.float32) 1 y1 np.log(x) y2 1 / x y3 np.sin(x) # 图 2 数据 a np.random.randn(200…

光威神策PRO PCIe 5.0 SSD发布,国产固态硬盘进入10G俱乐部

全球半导体供应链的紧张局势和闪存资源的短缺让许多行业都面临着不小的压力 &#xff0c; 连带的也让消费者难以获取物美价廉的闪存产品 。但是&#xff0c;总有一些企业能够逆流而上&#xff0c; 像是 光威科技这家国产存储品牌&#xff0c; 最近就给国内消费者 带来了一个惊喜…

递归、搜索与回溯算法:⼆叉树中的深搜

⼆叉树中的深搜 深度优先遍历&#xff08;DFS&#xff0c;全称为 Depth First Traversal&#xff09;&#xff0c;是我们树或者图这样的数据结构中常⽤的 ⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分⽀&#xff0c;直到⼀条路径上的所有节点都被遍历 完毕&#xff…

工业数据采集平台:从起源到崛起的辉煌历程

关键词&#xff1a;工业数据采集平台, 工业数据采集, 工业数据采集分析,智能化 在当今数字化的时代&#xff0c;工业领域也在经历着深刻的变革。而工业数据采集平台的发展历程&#xff0c;正是这场变革中的重要篇章。 回首过去&#xff0c;工业数据采集曾是一个繁琐而复杂的过…

C++ AVL树底层实现原理

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;C知识分享⏪   &#x1f69a;代码仓库:C高阶&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C知识   &#x1f51d;&#x1f51d; 目录 前言 AVL 树 1.1 AVL树的概念 1.2 AVL树…

职场成长秘籍:如何利用团队例会提升自己

在职场中&#xff0c;团队例会是一个重要的沟通和协作平台。通过团队例会&#xff0c;我们可以了解项目进展、分享工作经验、解决问题和制定工作计划。那么&#xff0c;如何利用团队例会提升自己&#xff0c;实现职场成长呢&#xff1f;本文将为您揭晓答案。 一、积极发言&…