Elastic Stack梳理:Logstash Input插件详解与Codec插件应用指南之文件监控、多行日志处理与Kafka集成

ELK之Logstash(将mysql数据同步到ES6.6.0(全量+增量)) 下载安装包时注意下载到指定文件夹 这里我放在OPT文件夹下 一:安装logstash 进入到opt文件夹打开终端 执行以下命令 wget -c https://artifacts.elastic.co/downloads/logstash/logstash-6.6.0.zip 加上-c支持断点续传 二:解压logstash unzip logstash-6.6.0.zip 三:进入到logstas... 阅读详情

Input插件核心机制与文件监控


Input插件基础功能

Input插件指定数据输入源,单个Pipeline可配置多个插件
Logstash支持丰富的数据源接入(如文件、Kafka、标准输入等)

核心插件包括:

  • stdin:标准输入(无专用配置)
  • file:文件读取(支持日志收集)
  • kafka:消息队列集成

1 ) stdin插件详解

作用:从命令行终端实时读取数据流。
通用配置参数(所有Input插件共享):

  • type:自定义事件类型(字符串),用于后续条件过滤(如 web/mysql)。
  • tags:事件标签(数组),辅助Filter阶段的条件判断。
  • add_field:添加自定义字段(哈希类型)。

配置示例:

input {  
  stdin {  
    codec => "plain"  # 原始文本解码  
    type  => "STD"    # 自定义类型  
    tags  => ["test"]  
    add_field => { "key" => "value" }  
  }  
}  
output { stdout { codec => rubydebug } }  # 调试输出  

执行效果(输入 Hello World):

{  
  "message" => "Hello World",  
  "type"    => "STD",  
  "tags"    => ["test"],  
  "key"     => "value"  
}  
  • 关键作用:type和tags用于后续Filter条件过滤,add_field扩展元数据

2 ) 文件监控(file插件)的核心问题与解决方案

核心问题解决方案:

  • 断点续传:通过 sincedb 文件记录读取位置(路径由 sincedb_path 指定)
  • 实时监控:定时检查文件更新(间隔由 stat_interval 控制,默认1秒)
  • 新增文件发现:定时扫描匹配文件(间隔由 discover_interval 控制,默认15秒)
  • 文件归档处理:基于inode追踪文件,即使重命名仍可完整读取(依赖 logwatch 库)

关键配置参数:

参数类型作用
path数组监听文件路径(支持Glob语法)
exclude数组排除文件规则
start_position枚举beginning(从头读)/end(只读新内容)
ignore_older数值忽略超过设定时长(秒)未更新的文件
close_older数值关闭超过设定时长(秒)无新内容的文件句柄

Glob匹配语法规则:

  • *:匹配任意非隐藏文件
  • ``:递归匹配子目录
  • ?:匹配单个字符
  • [a-z]:匹配字符范围
  • {a,b,c}:匹配多选项
问题Logstash解决方案配置参数
断点续读sincedb位置记录文件sincedb_path
实时读取新增内容定时文件检查机制stat_interval
动态发现新文件目录扫描匹配discover_interval
文件旋转(如logrotate)基于inode追踪(非文件名)ignore_older
文件句柄资源释放自动关闭空闲文件close_older

关键配置详解:

input {
  file {
    path => ["/var/log/*.log", "/var/log//*.log"]  # Glob匹配规则
    exclude => "*.gz"              # 排除压缩文件
    start_position => "beginning"  # 首次读取从文件开头 
    sincedb_path => "/dev/null"    # 调试时禁用sincedb
    ignore_older => 86400          # 忽略24小时未更新文件
    close_older => 3600            # 1小时无新内容关闭句柄
  }
}

注意:start_position 仅在首次读取生效,后续依赖 sincedb 记录。需删除 sincedb 文件才能重新从头读取

3 ) Glob匹配语法规则

path => "/var/log//*.log"  # 递归匹配所有子目录
path => "/var/log/{app1,app2}/*.log"  # 匹配app1/app2目录 
path => "/var/log/??_error.log"       # 匹配两个字符前缀

特殊案例:

  • * 不匹配隐藏文件(需显式指定 .*)
  • `` 跨多级目录递归

4 ) Kafka集成配置

input {
  kafka {
    bootstrap_servers => "kafka1:9092,kafka2:9092"
    group_id => "logstash_consumers"
    topics => ["nginx_logs", "app_logs"]
    consumer_threads => 4  # 并发线程数
  }
}

Codec插件:数据编解码与多行日志处理


1 ) 常用Codec插件对比

插件作用使用场景
plain原始文本输出基础日志
json解析JSON字段API日志
multiline合并多行事件Java异常堆栈
rubydebug友好格式化输出调试模式
dots点状进度指示压力测试

JSON解析示例:

input { stdin { codec => json } }  
output { stdout { codec => rubydebug } }  

输入 {"name":"Alice","age":30} 输出:

{ "name": "Alice", "age": 30 }  # 原始JSON被解析为字段  

2 ) 多行日志处理(multiline codec)

场景1:Java异常堆栈、代码换行字符串

核心参数:

  • pattern:正则表达式匹配行特征(如 ^\s+ 匹配空格开头行)
  • what:previous(归属上一事件)/next(归属下一事件)
  • negate:true(反向匹配,即不符合pattern的行触发合并)
input {
  stdin {
    codec => multiline {
      pattern => "^\[%{TIMESTAMP_ISO8601}\]"    # 匹配时间戳行首
      # pattern => "\\$"                        # 以反斜杠结尾的行
      negate => true                            # 对pattern取反 
      what => "previous"                        # 归属到前一行事件
      # what    => "next"                       # 与下一行合并
    }
  }
}

多行匹配模式:

案例1:Java堆栈日志(空格缩进归并)
pattern => "^\s+"  
what => "previous"
 
案例2:代码换行(反斜杠结尾续行)
pattern => "\\$"  
what => "next"

调试技巧:通过negate反转匹配逻辑,what定义行归属方向

场景2:跨行代码字符串合并

codec => multiline {  
  pattern => "\\$"               # 以反斜杠结尾的行  
  what    => "next"              # 与下一行合并  
}  

输入内容:

Hello \  
World!  

输出效果(单事件):

{ "message" => "Hello World!" }  

工程示例:1


1 ) 基础日志采集管道

// nestjs-logger.service.ts
import { Injectable, Logger } from '@nestjs/common';
import { Client } from '@elastic/elasticsearch';
 
@Injectable()
export class LoggerService {
  private readonly esClient: Client;
 
  constructor() {
    this.esClient = new Client({ node: 'http://localhost:9200' });
  }
 
  async logToES(message: string, context: string) {
    await this.esClient.index({
      index: 'app_logs',
      body: { 
        timestamp: new Date().toISOString(),
        message,
        context 
      }
    });
  }
}

Logstash配置同步ES:

logstash.conf
input {
  file {
    path => "/var/log/nest-app/*.log"
    sincedb_path => "/opt/logstash/sincedb"
  }
}
filter {
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:msg}" }
  }
}
output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "nest-logs-%{+YYYY.MM.dd}"
  }
}

2 ) Kafka缓冲日志中台

// kafka-producer.service.ts
import { Kafka } from 'kafkajs';
 
const kafka = new Kafka({ brokers: ['kafka:9092'] });
const producer = kafka.producer();
 
async function sendLog(topic: string, log: object) {
  await producer.send({
    topic,
    messages: [{ value: JSON.stringify(log) }]
  });
}

Logstash消费Kafka写入ES:

input {
  kafka {
    topics => ["nest_logs"]
    bootstrap_servers => "kafka:9092"
    codec => json  # 自动解析JSON
  }
}
output {
  elasticsearch {
    hosts => ["es01:9200"]
    index => "kafka-logs-%{+yyyy.MM}"
  }
}

3 ) 错误告警联动

Elasticsearch Watcher配置:

PUT _watcher/watch/error_alert
{
  "trigger": { "schedule": { "interval": "1m" } },
  "input": {
    "search": {
      "request": {
        "indices": ["app_logs-*"],
        "body": {
          "query": { "match": { "level": "ERROR" } }
        }
      }
    }
  },
  "actions": {
    "send_email": {
      "email": {
        "to": "admin@example.com",
        "subject": "紧急:发现系统错误日志",
        "body": "检测到{{ctx.payload.hits.total}}条错误日志"
      }
    }
  }
}

工程示例:2


1 )原生Elasticsearch客户端

安装依赖:

npm install @elastic/elasticsearch  

服务封装(es.service.ts):

import { Injectable } from '@nestjs/common';  
import { Client, ClientOptions } from '@elastic/elasticsearch';  
 
@Injectable()  
export class EsService {  
  private client: Client;  
 
  constructor() {  
    this.client = new Client({ node: 'http://localhost:9200' } as ClientOptions);  
  }  
 
  async indexDocument(index: string, body: any) {  
    return this.client.index({ index, body });  
  }  
 
  async search(index: string, query: any) {  
    return this.client.search({ index, body: { query } });  
  }  
}  

2 ) 方案2:NestJS官方Elastic模块

安装依赖:

npm install @nestjs/elasticsearch  

模块注册(app.module.ts):

import { Module } from '@nestjs/common';  
import { ElasticsearchModule } from '@nestjs/elasticsearch';  
 
@Module({  
  imports: [  
    ElasticsearchModule.register({ node: 'http://localhost:9200' }),  
  ],  
})  
export class AppModule {}  

服务调用(log.service.ts):

import { Injectable } from '@nestjs/common';  
import { ElasticsearchService } from '@nestjs/elasticsearch';  
 
@Injectable()  
export class LogService {  
  constructor(private readonly esService: ElasticsearchService) {}  
 
  async createLog(index: string, log: any) {  
    return this.esService.index({ index, body: log });  
  }  
}  

ELK全链路集成(Logstash+Kafka+ES)


架构说明:

  1. Logstash:通过 kafka Input插件消费日志,Filter阶段解析字段
  2. Kafka:作为缓冲队列,解耦日志生产与消费
  3. Elasticsearch:存储结构化日志,NestJS服务通过客户端查询

Logstash配置:

input {  
  kafka {  
    topics => ["nginx_logs"]  
    bootstrap_servers => "kafka:9092"  
  }  
}  
filter {  
  grok { match => { "message" => "%{COMBINEDAPACHELOG}" } } # 解析Nginx日志  
}  
output {  
  elasticsearch {  
    hosts => ["es:9200"]  
    index => "nginx-%{+YYYY.MM.dd}"  
  }  
}  

ES索引生命周期管理(ILM):

PUT _ilm/policy/logs_policy  
{  
  "policy": {  
    "phases": {  
      "hot": { "actions": { "rollover": { "max_size": "50GB" } } },  
      "delete": { "min_age": "30d", "actions": { "delete": {} } }  
    }  
  }  
}  
 
PUT _index_template/logs_template
{
  "index_patterns": ["*-logs*"],
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "index.lifecycle.name": "logs_policy"
    }
  }
}

性能调优参数

# elasticsearch.yml
thread_pool.write.queue_size: 1000  # 增大写入队列
indices.memory.index_buffer_size: 30%  # 内存缓冲区
cluster.routing.allocation.disk.watermark.low: 85%  # 磁盘警戒线

最佳实践:结合_bulk API批量写入,单批次5-15MB数据量

常见问题解决方案


  1. Sincedb失效

    • 删除sincedb_path文件强制从头读取
    • 开发环境可用sincedb_path => "/dev/null"
  2. 多行日志截断

    codec => multiline {
      pattern => "^%{TIMESTAMP_ISO8601} "
      negate => true
      what => "previous"
      auto_flush_interval => 5  # 5秒无新行强制结束事件
    }
    
  3. 文件句柄泄漏

    file {
      close_older => 300   # 5分钟关闭空闲文件
      file_completed_action => "delete"  # 处理完删除归档文件
    }
    

技术总结:

  • Logstash的核心价值在于通过插件化架构实现数据流的灵活编排。Input插件解决数据源适配问题,Codec插件处理数据格式转换,尤其multiline对堆栈日志的归并至关重要
  • 生产环境中需结合Kafka缓冲、ES索引生命周期管理、批量写入策略构建稳健日志管道
logstash+elasticsearch+kibana搭建监控平台  使用logstash+elasticsearch+kibana搭建监控平台  ,也可以使用logstash+influxdb+grafana搭建监控平台   立即下载

相关推荐

从X86到ARM:全面解析服务器CPU架构的演变与未来趋势

本文深入解析了服务器CPU架构从X86到ARM的演变历程与未来趋势。文章从CISC与RISC两种设计哲学切入,分析了X86凭借生态建立的帝国地位及其面临的功耗挑战,并重点阐述了ARM架构凭借其卓越的能效比优势,正从移动端向数据中心市场发起冲击。未来,异构计算、软硬协同与专用芯片将成为服务器CPU发展的核心方向。

gold的博客 1128

logstash

Logstash与Flume对比:     组件比较:         Flume:source    channel        sink         Logstash: input     filter     output          特性比较:         Flume:在高可用方面是优于Logstash             Flume一直看重的是数据传输的安全性,在数...

qq_25460227的博客 585

PHY6252开发实战:从零构建BLE串口透传应用

本文详细介绍了PHY6252开发板在BLE串口透传应用中的实战经验,包括开发环境搭建、BLE串口透传例程解析、AT指令集实现与扩展、数据透传机制优化以及常见问题排查指南。通过智能家居遥控器项目案例,展示了PHY6252在低功耗物联网设备开发中的实际应用。

weixin_29183637的博客 315

Flume防止重复消费——断点续传

Flume防止重复消费基本配置断点续传原理   通常我们使用exec类型的source,通过执行 tail命令来监控采集日志的,但是如果agent进程突然挂了,下次重启采集任务,会导致日志文件内容重复采集。这里可以采用Taildir Source来防止重复消费问题。 基本配置   监听目标文件,当数据被添加到文件后能实时地tail它们。如果正在写入新行,则此source将重试读取它们以等待写入完成...

ThreeAspects的博客 1928

Apollo和autoware规划算法代码ros移植-路径规划可跑工程分享

Apollo6.0规划核心代码移植到Ros工程,可编译移植分享

weixin_39735688的博客 8509

【AI落地】AI生成测试用例,claude or gpt?(提效至少 50%)

gpt生成测试用例?当然好使啦,用好了提效50%+,用不好就让他变好!

青禾tester 1972

Elasticsearch及ELK使用(二):日志数据采集

上一篇结束了Elasticsearch和kibana的安装和基本使用。本文介绍日志数据采集(也叫日志采集),涉及filebeat的软件和logstash软件。 本文分别介绍了从日志文件采集和从数据库(MySQL)中采集。

zyplanke的专栏 6292

论文阅读笔记:Extended Vision Transformer (ExViT) for Land Use and Land Cover Classification

注意力机制驱动的深度模型最近取得了成功,如最具代表性的视觉转换器(ViT),吸引了一波高级研究来探索它们对更广泛领域的适应。然而,遥感(RS)领域中基于Transformer的方法更关注单模态数据,这可能会在充分利用不断增长的多模态地球观测数据时失去可扩展性。为此,我们提出了一种新的多模式深度学习框架,通过在最小修改的情况下扩展传统的ViT,针对土地利用和土地覆盖(LULC)分类任务。

嗑研狗的日常 945

Elastic Stack梳理:Logstash 高级数据处理与监控运维实战指南

Logstash实战调试与数据处理策略摘要 本文系统介绍Logstash核心调试方法与典型数据处理方案。调试方面提出HTTP输入替代STDIN实现热加载,通过metadata字段优化性能,并设计容错机制处理异常数据。实战部分包含Apache日志结构化处理方案(Grok解析、时间戳转换、GeoIP增强)和CSV地震数据导入(坐标处理、ES映射优化)。运维环节详细说明原生API监控指标解读和X-Pack集成配置方法,涵盖吞吐率、延迟等关键指标监控。全文提供可直接落地的配置示例,包括日志解析失败处理、地理坐标优化

Wang的专栏 1050

【基于 CasADi 的欠驱动无人船实时非线性模型预测控制(NMPC)实现 Visual Studio 2022 C++】

本文介绍了基于CasADi和IPOPT在Visual Studio 2022 C++环境下实现的欠驱动无人船实时非线性模型预测控制(NMPC)方案。文章详细阐述了NMPC基本原理、欠驱动无人船动力学模型(包含状态变量和控制变量定义),并给出了C++实现的核心代码框架。该方案通过显式引入系统动力学模型和约束条件,在每个采样周期滚动优化控制序列,有效解决了欠驱动无人船的轨迹跟踪与避碰问题。文中还提供了VS2022配置CasADi环境的详细步骤,包括预编译包下载、工程属性设置等关键环节,为工程实现提供了完整的技术

vor234的博客 654

车辆网络安全ISO/SAE 21434解读(一)概述

ISO/SAE 21434 《道路车辆 网络安全工程》是SAE和ISO共同制定的一项针对道路车辆的网络安全标准,它是一个面向汽车行业全供应链(OEM及各级供应商)的车辆网络安全管理指导文件

xiaoxiabang的博客 8427

如何通过 Logstash 将数据采集到 Elasticsearch

Logstash 是一种广泛使用的 Elastic Stack 工具,用于实时处理大量日志数据。它充当高效的数据管道,将来自各种来源的信息集成到单一结构化流中。其主要功能是可靠地执行数据提取、转换和加载。Logstash 具有多种优势,尤其是其在支持多种类型的输入、过滤器和输出方面的多功能性,可与各种来源和目的地集成。它实时处理数据,捕获和转换信息。它与 Elastic Stack(尤其是 Elasticsearch 和 Kibana)的原生集成有助于数据分析和可视化。

Elastic 中国社区官方博客 3351

OData Request:Create Entity 在 ABAP OData Client Proxy 中的工程化实践

文章摘要 本文针对具备 SAP Gateway 与 ABAP 开发经验的读者,详细讲解如何通过 ABAP OData Client Proxy 实现 OData 服务的 Create 操作。首先对比了 OData V2 与 V4 的 Create 规范差异,强调键、集合 URL 和请求体的标准化要求。随后介绍了 ABAP Client Proxy 的编程模型,包括 Client Proxy、Entity List Resource 和 Create Request/Response 三个核心对象,并提供了完

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 247

ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台

为什么80%的码农都做不了架构师?>>> ...

weixin_34029680的博客 1737

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

logstash的坑

当使用input的file插件时,从文件读取数据, file插件可以设置start_position,logstash会记录读取的偏移量, 当logstash读取文件数据时,如果读到文件末尾了,logstash会把文件读取的偏移量记录到一个实体文件中, 这里要注意的时,logstash开始读取时,只有读取到了文件末尾,才会记录偏移量, 如果文件读取到一半lo

daiyudong2020的博客 7783

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Logstash将日志产生时间替换@timestamp

一、跟着官网学习一下date插件      日期过滤器用于从字段中解析日期,然后使用该日期或时间戳作为事件的logstash时间戳。例如,syslog事件通常具有这样的时间戳:Bash"Apr 17 09:32:01"       你可以使用日期格式MMM dd HH:mm:ss来解析这个。日期过滤器对于排序事件和回填旧数据尤为重要。 如果您在活动中没有找到正确的日期,那么稍后搜索它们可能会排序错...

零度的博客专栏 2万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Logstash安装-源码

Logstash下载有点麻烦,由于国内到elk官网速度很慢,下载过程中容易中断。所以,可以通过有断点续传的工具(迅雷)进行下载好,再进行安装使用。系统环境:[root@test ~]# cat /etc/issueCentOS release 6.7 (Final)Kernel \r on an \m[root@test ~]#安装基础环境# yum install e...

weixin_34107955的博客 360

flume1.7.0-taildirSource 支持多文件监控和断点续传

flume 1.7.0 推出了 taildirSource 组件。tail 监控 目录下匹配上正则表达式的 的所有文件,实现断点续传。问题但是官方的 taildirSource 组件貌似是支持nginx 日志,对于log4j 日志好像不太管用。 因为log4j 日志会自动切分,log4j 切分日志其实就是新建一个文件,然后把原来的日志文件都改名。但是 taildirSource 组件时不支持文件改

哎幽的成长 1万+

logstash 学习小记

简单的介绍了logstash,给出一些简单实用的examples

iTer的专栏 1万+

关于Flume断点续传(防止重复消费)的解决方案

背景: 前段时间写了个 Flume实时采集日志到 Kafka(极简版),其中我们是使用 exec source执行 tail命令来监控采集日志的,但这样做会存在一些问题:如果agent进程突然挂了,下次重启采集任务,会导致日志文件内容重复采集,虽然进程挂了这种事情不常发生,当我们还是要尽量避免因此带来的负面影响! 一、方案选择 和一些朋友交流过Flume断点续传问题,他们往往是自己修改sourc...

Abysscarry的博客 8983

Logstash处理json根式日志文档的三种方式

假设日志文件中的每一行记录格式为json的,如:{"Method":"JSAPI.JSTicket","Message":"JSTicket:kgt8ON7yVITDhtdwci0qeZg4L-Dj1O5WF42Nog47n_0aGF4WPJDIF2UA9MeS8GzLe6MPjyp2WlzvsL0nlvkohw","CreateTime":"2015/10/13 9:39:59",&am

为一个人走几座城 2151

基于flume+kafka+logstash+es的分布式日志系统

本文将从以下几点讲解的分布式日志系统 1.日志埋点 2.日志收集 3.日志处理分析 4.日志查询展示   先看一下日志数据流程图: flume监听日志文件收集每行日志发到kafka,logstash消费kafka中的消息将日志解析成json插入到es,es提供日志查询 1.日志埋点 由于我们项目结构是网关+dubbo服务实例的分布式系统,埋点主要在http的网关和rpc的服务...

Jews 4168

Kafka 如何实现顺序消费?

Kafka仅保证分区内消息有序,不支持全局有序。实现顺序的关键是:生产端通过相同Key确保消息进入同一分区(配合幂等生产者防重试乱序),消费端保证分区独占且按Key路由至内存队列,由单线程串行处理。吞吐提升可按Key拆分队列并行处理,避免并行导致乱序。核心口诀:同Key同分区,同分区同线程。

223

消费回调固定 return nil:错误传播与 Kafka 位点提交的区别

Mongo 写入失败时处理器记录错误但不 Mark,外层回调仍返回 nil;返回值与 Kafka 位点提交是不同动作。失败消息是否重投或被后续位点越过,需要结合分区水位分析。

2501_92769340的博客 184

第十二篇:《完整实战:订单事件驱动系统(Kafka + 消费者 + 死信队列)》

这篇按一条完整的订单链路来搭:订单服务写库 + 发事件,库存服务消费并扣减,失败走指数退避重试,重试耗尽后进入死信队列,消费端全程幂等去重。Outbox 的 relay 是至少一次,DLQ 的重试也是至少一次。重试消费组的 Lag 速率:order-events.retry 的消费 lag 如果持续增长且不回落,说明重试没有收敛,可能正在走向“重试爆炸”的早期形态。retries=MAX_VALUE 配合幂等生产者,解决的是生产者重试导致的 Broker 端重复,不解决消费端业务重复——后者是下一节的事。

qq_45239623的博客 412
上一篇: Elastic Stack梳理:Logstash线程模型与多实例部署解析
下一篇: Elastic Stack梳理:Logstash Filter 插件深度解析与工程实践指南
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值