MinIO 的 “将事件发布至 Webhook” 功能简介

MinIO 的 “将事件发布至 Webhook” 功能,简单来说就是 对象存储里的事件通知机制。它的作用是让 MinIO 在特定操作发生时,自动通知你的外部系统(例如服务端 API、微服务、自动化流程等)。

MinIO 的 “将事件发布至 Webhook” 功能,简单来说就是 对象存储里的事件通知机制。它的作用是让 MinIO 在特定操作发生时,自动通知你的外部系统(例如服务端 API、微服务、自动化流程等)。


1. 基本概念

  • 事件(Event):对象存储中的操作,如:

    • s3:ObjectCreated:* → 对象创建(上传/复制)
    • s3:ObjectRemoved:* → 对象删除
    • s3:ObjectAccessed:* → 对象被访问(取决于配置)
  • Webhook:HTTP 接口(URL),MinIO 将事件信息以 POST 请求的方式发送给它。

  • 用途:实现 实时响应自动化处理系统联动


2. 作用场景

  1. 自动处理上传文件

    • 用户上传文件到 MinIO → Webhook 收到事件 → 后端服务自动处理文件(如转码、生成缩略图)。
  2. 实时同步

    • 上传/删除对象时,触发 Webhook 将操作信息同步到数据库或其他存储系统。
  3. 告警与监控

    • 对特定操作(如删除敏感文件)触发 Webhook → 通知运维系统或发送 Slack/钉钉告警。
  4. 事件驱动架构(EDA)

    • MinIO 作为事件源,将对象操作事件推送到微服务或消息队列,实现事件驱动设计。

3. 工作流程示例

用户上传文件 myphoto.jpg
      │
      ▼
   MinIO 触发事件 s3:ObjectCreated:Put
      │
      ▼
   POST 请求发送到 Webhook URL
      │
      ▼
   Web 服务收到 JSON payload
      │
      ▼
   自动处理(转码、入库、推送通知等)

Webhook payload 示例

{
    "version": "1",
    "deploymentid": "7e137b2a-f438-44cb-91dc-58148d945542",
    "time": "2026-05-20T03:55:23.858364371Z",
    "event": "",
    "trigger": "incoming",
    "api": {
      "name": "GetObject",
      "bucket": "bucket",
      "object": "repo.go",
      "status": "OK",
      "statusCode": 200,
      "rx": 0,
      "tx": 68,
      "txHeaders": 524,
      "timeToFirstByte": "1443873ns",
      "timeToFirstByteInNS": "1443873",
      "timeToResponse": "1503092ns",
      "timeToResponseInNS": "1503092"
    },
    "remotehost": "222.173.127.34",
    "requestID": "18B129D54B57D454",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 Edg/148.0.0.0",
    "requestPath": "/bucket/e35f6b7b-0661-11f1-85ea-0242ac150003/repo.go",
    "requestHost": "部署域名",
    "requestQuery": {
      "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
      "X-Amz-Credential": "minioadmin/20260520/r/s3/aws4_request",
      "X-Amz-Date": "20260520T035518Z",
      "X-Amz-Expires": "86400",
      "X-Amz-Signature": "640853ac793171f59c002b8bd3052d73016866df484c5c32c0fc1d89b7487d03",
      "X-Amz-SignedHeaders": "host",
      "response-content-disposition": "attachment"
    },
    "requestHeader": {
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
      "Accept-Encoding": "gzip, deflate, br, zstd",
      "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
      "Connection": "keep-alive",
      "Cookie": "Hm_lvt_3f8ed946d171f676297a0",
      "Sec-Ch-Ua": "\"Chromium\";v=\"148\", \"Microsoft Edge\";v=\"148\", \"Not/A)Brand\";v=\"99\"",
      "Sec-Ch-Ua-Mobile": "?0",
      "Sec-Ch-Ua-Platform": "\"Windows\"",
      "Sec-Fetch-Dest": "document",
      "Sec-Fetch-Mode": "navigate",
      "Sec-Fetch-Site": "none",
      "Sec-Fetch-User": "?1",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 Edg/148.0.0.0",
      "X-Amz-Signature-Age": "5858"
    },
    "responseHeader": {
      "Accept-Ranges": "bytes",
      "Content-Disposition": "attachment",
      "Content-Length": "68",
      "Content-Type": "application/octet-stream",
      "ETag": "b338e1f20d5aa78824bb8e53d1cbd8fe",
      "Last-Modified": "Tue, 10 Feb 2026 09:23:12 GMT",
      "Server": "MinIO",
      "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
      "Vary": "Origin,Accept-Encoding",
      "X-Amz-Id-2": "cd12db15ea11a38dd85b2ac1cd0e7672a49d94ae8535078abcb6d6bd756cbab2",
      "X-Amz-Request-Id": "18B129D54B57D454",
      "X-Content-Type-Options": "nosniff",
      "X-Ratelimit-Limit": "26413",
      "X-Ratelimit-Remaining": "26413",
      "X-Xss-Protection": "1; mode=block"
    },
    "tags": {
      "GetObject": "name=repo.go,pool=1,set=1"
    },
    "accessKey": "accessKey"
  }

4. 配置方式

在 MinIO 里,事件通知可通过以下方式配置:控制台 UI

minio 日志配置

在这里插入图片描述

部署接收日志服务

services:
  minio-webhook:
    image: registry.cn-qingdao.aliyuncs.com/lys_ns/app:minio-webhook
    container_name: minio-webhook
    ports:
      - "8080:8080"
    volumes:
      - ./app:/app
      - ./logs:/var/log/minio-webhook
    restart: unless-stopped

app.py

import json
import logging
import os
from datetime import datetime, timezone

from flask import Flask, request

LOG_DIR = os.getenv("WEBHOOK_LOG_DIR", "/var/log/minio-webhook")

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("minio-webhook")

class DailyLogHandler(logging.FileHandler):
    def __init__(self, log_dir):
        self.log_dir = log_dir
        os.makedirs(log_dir, exist_ok=True)
        super().__init__(self._filename())

    def _filename(self):
        return os.path.join(self.log_dir, f"events-{datetime.now():%Y-%m-%d}.log")

    def emit(self, record):
        if self.baseFilename != self._filename():
            self.close()
            self.baseFilename = self._filename()
            self.stream = self._open()
        super().emit(record)

fh = DailyLogHandler(LOG_DIR)
fh.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
logger.addHandler(fh)

app = Flask(__name__)

@app.route("/minio-webhook", methods=["POST"])
def minio_webhook():
    event = request.json
    log_entry = json.dumps({
        "time": datetime.now(timezone.utc).isoformat(),
        "requestPath": event.get("requestPath"),
        "remotehost": event.get("remotehost"),
    })
    logger.info("%s", log_entry)
    return "OK", 200

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐