ALG(Alloy+Loki+Grafana)轻量级日志系统

ALG(Alloy+Loki+Grafana)轻量级日志系统

前提要求

  1. Grafana
  2. Minio
  3. Nginx
  4. Prometheus

Grafana日志收集系统旧版是PLG(Protail+Loki+Grafana), Protail收集日志, Loki存储, Grafana展示, 后续的Protail不维护了, Grafana推出了Alloy代替Pritial, 除了收集日志外, 还集成管理Prometheus各种exporter功能, 代替传统模式下需要安装xxxx_exporter插件才能采集指标的情况

ALG适合云原生, 拓展性强, 但是对于传统的日志收集是很支持(后续有Alloy采集本地日志log, gz等格式案例)

读写分离模式部署ALG

初始化文件夹和一些配置文件

初始化文件夹
# log日志存储
mkdir -p /data/alg/flog/logs/log
# 日志压缩文件存储
mkdir -p /data/alg/flog/logs/gz
# minio存储
mkdir -p /data/alg/minio
创建nginx配置文件
vim /data/alg/nginx.conf
user nginx;
worker_processes 5; # worker线程数

events {
    worker_connections 1000; # 单个worker连接数
}

http {
    # 使用Docker内置DNS解析服务名, DNS缓存有效期10秒
    resolver 127.0.0.11 valid=10s;
    # 开启访问日志, 生产中建议关闭
    access_log on;
    
    # 定义上游Loki writer服务器组
    upstream loki_writers {
        server write:3100;
        # 保持长连接池
        keepalive 32;
    }

    # 定义上游Loki reader服务器组
    upstream loki_readers {
        server read:3100;
        keepalive 32;
    }
    
    # 定义上游alloy服务器组
    upstream alloys {
        server alloy:12345;
    }

    # Grafana UI
    server {
        listen 3000;
        
        location / {
            proxy_pass http://grafana:3000;
            
            # 代理设置请求头, 否则Grafana会提示一直登录
            # 并且要设置WebSocket, 否则无法运行实时跟踪
            # 见https://blog.csdn.net/weixin_41287260/article/details/134630447
            # https://www.cnblogs.com/hahaha111122222/p/16407564.html
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $http_host;
        }
    }

    
    # Loki相关日志推送, 存储等配置
    server {
        # 监听容器内 3100 端口(通过 ports 映射到宿主机 3100)启用端口复用提升性能
        listen 3100 reuseport;

         # 定义写入类请求的通用配置块
        location ~ ^/(api/prom/push|loki/api/v1/push) {
            proxy_pass http://loki_writers$request_uri;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
        }

        # 定义实时日志流式传输(tail)请求的通用配置块
        location ~ ^/(api/prom/tail|loki/api/v1/tail) {
            proxy_pass http://loki_readers$request_uri;
            proxy_read_timeout 3600s;
            # 这里必须要配置WebSocket, 否则无法运行实时跟踪
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }

        # 定义所有 Prometheus 格式和 Loki 原生格式查询请求的通用配置块
        location ~ ^/(api/prom/.*|loki/api/.*) {
            proxy_pass http://loki_readers$request_uri;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            # 缓存查询结果10秒
            proxy_cache_valid 200 10s;
        }
    }

    # read 端点, 生产中应该禁外界访问(这里做演示, 所以开放), 容器内部通信即可
    server {
        listen 3101;
        
        location / {
            proxy_pass http://loki_readers/ready;
        }
    }
    
    # write 端点, 生产中禁外界访问(这里做演示, 所以开放), 容器内部通信即可
    server {
        listen 3102;
        
        location / {
            proxy_pass http://loki_writers/ready;
        }
    }

    # Minio UI
    server {
        listen 9001;
        
        location / {
            proxy_pass http://minio:9001;
            
            # 添加websocket支持, 否则Minio会卡主, 页面一直loading
            # 见https://blog.csdn.net/qq_25231683/article/details/128734555
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $http_host;
        }
    }
    
    # Alloy UI
    server {
        listen 12345;
        
        location / {
            proxy_pass http://alloys;
        }
    }    
}
创建alloy配置文件
vim /data/alg/alloy-local-config.yaml
// ========================
// 实时调试
// ========================
livedebugging {
  enabled = true
}

// ========================
// Docker容器日志发现和采集
// ========================
// Docker 容器发现配置
discovery.docker "flog_scrape" {
    // 连接 Docker daemon 的地址(Unix 套接字)
    host             = "unix:///var/run/docker.sock"  
    // 每5s抓取Docker信息日志
    refresh_interval = "5s"  
}

// 主要用于服务发现阶段对发现的目标(如容器、节点等)的元数据标签进行预处理。当通过服务发现机制(如基于 Docker、Kubernetes 等)发现一系列目标时,这些目标会带有各种元数据标签,这里可以对这些原始标签进行修改、添加、删除等操作,使得标签更加符
discovery.relabel "flog_scrape" {
    // 初始空目标列表(自动从上游发现discovery.docker "flog_scrape"填充)
    targets = []  

    // 提取容器名称
    rule {
        // 原始元数据标签(来自 Docker 的属性)
        source_labels = ["__meta_docker_container_name"]  
        // 正则提取容器名称(去除路径前缀)
        regex         = "/(.*)"  
        // 生成新标签 container 存储处理结果
        target_label  = "container"
    }
    
    // 提取项目名
    rule {
        //
        source_labels = ["__meta_docker_container_label_com_docker_compose_project"]
        regex         = "(.*)"  
        target_label  = "project"     
    }       
}

// Loki Docker 日志采集配置
loki.source.docker "flog_scrape" {
    // Docker 连接配置(需与发现模块一致)
    host             = "unix:///var/run/docker.sock"  
    // 要从中读取日志的容器列表, 关联发现模块获取的目标列表
    targets          = discovery.docker.flog_scrape.targets  
    // 日志转发目的地(指向写入模块)
    forward_to       = [loki.write.default.receiver]  
    // 应用标签重写规则
    relabel_rules    = discovery.relabel.flog_scrape.rules  
    // 目标同步频率(与发现模块同步)
    refresh_interval = "5s"  
}

// ========================
// *.log文件匹配和采集
// ========================
// 本地*.log文件匹配
local.file_match "local_log" {
  path_targets = [
    {__path__ = "/data/alg/flog/logs/log/*.log"},
  ]
}

// ========================
// 本地*.log文件采集
// ========================
loki.source.file "local_log" {
  // 关联发现模块获取的目标列表, 关联到本地机器日志匹配
  targets    = local.file_match.local_log.targets
  // 日志转发目的地(指向写入模块)
  forward_to = [loki.write.default.receiver]
}

// ========================
// *.gz文件匹配和采集
// ========================
// 本地*.gz文件匹配
local.file_match "local_log_gz" {
  path_targets = [
    {__path__ = "/data/alg/flog/logs/gz/*.gz"},
  ]
}

// 本地*.log文件采集
loki.source.file "local_log_gz" {
  // 关联发现模块获取的目标列表, 关联到本地机器日志匹配
  targets    = local.file_match.local_log_gz.targets
  // 日志转发目的地(指向写入模块)
  forward_to = [loki.write.default.receiver]
  // 解压缩
  decompression {
    // 是否启用解压缩
    enabled       = true
    // 开始从新的压缩文件读取之前要等待的时间
    initial_delay = "10s"
    // 使用的压缩格式Gzip
    format        = "gz"
  }
}


// ========================
// Loki 日志写入配置
// ========================
loki.write "default" {
    // 将日志发送到的位置
    endpoint {
        // 要将日志发送到的完整 URL, Loki 接收端 API 地址
        url       = "http://gateway:3100/loki/api/v1/push"
        // 发送前要累积的最大日志批次大小
        batch_size = "1MiB"
        // 发送批次前要等待的最长时间
        batch_wait = "1s"
        // 多租户标识(生产环境建议动态获取)
        tenant_id = "tenant1"
    }
    // 附加全局标签(当前为空配置)
    external_labels = {}  
}
创建loki配置文件
vim /data/alg/loki-config.yaml
# ========================
# Loki 服务核心配置
# ========================
server:
  http_listen_address: 0.0.0.0    # 监听所有网络接口
  http_listen_port: 3100           # 默认 Loki 服务端口

# ========================
# 集群节点发现与通信配置
# ========================
memberlist:
  join_members: ["read", "write", "backend"]  # 需要连接的初始节点列表(建议使用IP或DNS)
  dead_node_reclaim_time: 30s     # 节点标记为死亡后保留元数据的时间
  gossip_to_dead_nodes_time: 15s  # 停止向死亡节点发送gossip包的时间
  left_ingesters_timeout: 30s     # 离开节点清理超时时间
  bind_addr: ['0.0.0.0']          # 集群通信绑定地址
  bind_port: 7946                 # 集群通信端口
  gossip_interval: 2s             # 节点状态同步间隔

# ========================
# 数据存储架构配置
# ========================
schema_config:
  configs:
    - from: 2023-01-01            # 配置生效起始时间
      store: tsdb                 # 使用 Prometheus TSDB 存储
      object_store: s3            # 对象存储类型
      schema: v13                 # 存储格式版本
      index:
        prefix: index_            # 索引文件前缀
        period: 24h               # 索引文件切割周期

# ========================
# 公共基础配置
# ========================
common:
  path_prefix: /loki             # 存储路径前缀
  replication_factor: 1          # 数据副本数(生产环境建议 >=3)
  compactor_address: http://backend:3100  # 压缩组件地址

  # 对象存储配置
  storage:
    # S3对象存储
    s3:
      endpoint: minio:9000         # S3兼容存储地址
      insecure: true              # 禁用HTTPS(生产环境不推荐)
      bucketnames: loki-data      # 主数据存储桶
      access_key_id: whiteBrocade         # 访问密钥(建议使用环境变量)
      secret_access_key: whiteBrocade  # 密钥(存在安全隐患)
      s3forcepathstyle: true      # 强制路径访问模式
    # 本地文件存储(由于是容器形式启动loki, 这里指的是容器内系统)
    filesystem:
      # 数据保存的地方
      chunks_directory: /tmp/loki/chunks
      # 规则保存的地方
      rules_directory: /tmp/loki/rules
  # 一致性哈希环配置
  ring:
    kvstore:
      store: memberlist           # 使用memberlist实现分布式哈希环

# ========================
# 告警规则配置
# ========================
ruler:
  storage:
    s3:
      bucketnames: loki-ruler     # 独立存储告警规则的桶

# ========================
# 数据压缩配置
# ========================
compactor:
  working_directory: /tmp/compactor  # 临时工作目录(建议使用持久化存储)

docker-compose文件

ALG
  1. loki使用的是读写分离模式部署, 拆分成了read, write, backend三个组件
  2. 存储使用的Minio, 生产中建议对存储日志的桶设置过期策略, 减少存储成本
  3. 使用ng作为网关统一入口, 有些端口生产中不应该开放, 比如说loki的read和write的read访问
version: "3.8"
# ========================
# 自定义网络配置
# ========================
networks:
  loki:  # 创建专用网络确保服务隔离
    driver: bridge

services:
  # ========================
  # Loki 读取组件(查询节点)
  # ========================
  read:
    image: grafana/loki:latest
    # 容器名
    container_name: loki-read
    # 指定read模式启动
    command: "-config.file=/etc/loki/config.yaml -target=read"  # 指定角色为读取节点
    ports:
      - 3100    # 映射外部访问端口
      - 7946    # memberlist 通信端口
      - 9095    # 指标暴露端口(未映射到宿主机)
    volumes:
      - /data/alg/loki-config.yaml:/etc/loki/config.yaml  # 共享配置文件
    healthcheck:  # 健康检查策略
      test: [
        "CMD-SHELL", # 使用 shell 执行命令
        "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1"
        ]
      interval: 10s # 每10秒检查一次
      timeout: 5s   # 超时时间5秒
      retries: 5    # 最多重试5次
    depends_on: # 依赖Minio
      - minio
    # 定义网络锚点, 后续直接复用
    networks: &loki-dns  # 网络别名锚点
      loki:
        aliases:
          - loki  # 其他服务可通过 loki 域名访问

  # ========================
  # Loki 写入组件(接收节点)
  # ========================
  write:
    image: grafana/loki:latest
    # 容器名
    container_name: loki-write
    # 指定write模式启动
    command: "-config.file=/etc/loki/config.yaml -target=write"
    ports:
      - 3100    # 与读节点区分端口
      - 7946    # memberlist 通信端口
      - 9095    # 指标暴露端口(未映射到宿主机)
    volumes:
      - /data/alg/loki-config.yaml:/etc/loki/config.yaml
    healthcheck: # 健康检查策略
      test: [
        "CMD-SHELL", # 使用 shell 执行命令
        "wget --no-verbose --tries=1 --spider http://localhost:3100/ready || exit 1"
        ]
      interval: 10s # 每10秒检查一次
      timeout: 5s   # 超时时间5秒
      retries: 5    # 最多重试5次
    depends_on: # 依赖Minio
      - minio
    networks:
      <<: *loki-dns  # 复用网络别名配置

  # ========================
  # Loki 后台处理组件
  # ========================
  backend:
    image: grafana/loki:latest
    # 容器名
    container_name: loki-backend
    command: "-config.file=/etc/loki/config.yaml -target=backend -legacy-read-mode=false"
    ports:
      - 3100    # 默认API端口(未映射到宿主机)
      - 7946    # memberlist端口
    volumes:
      - /data/alg/loki-config.yaml:/etc/loki/config.yaml
    networks:
      - loki

  # ========================
  # 日志采集组件(原Grafana Agent)
  # ========================
  alloy:
    image: grafana/alloy:latest
    # 容器名
    container_name: alloy
    command: run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy
    ports:
      - 12345   # Web UI端口
    volumes:
      # 将程序产生的*.log,*.gzd的父目录映射到alloy, 这样才能探测到
      - /data/alg/flog/logs:/data/alg/flog/logs
      - /data/alg/alloy-local-config.yaml:/etc/alloy/config.alloy:ro  # 采集配置
      - /var/run/docker.sock:/var/run/docker.sock  # 挂载docker socket, 如果不挂载这个, 那么没法获取到容器的日志
    networks:
      - loki

  # ========================
  # 对象存储服务(S3兼容)
  # ========================
  minio:
    image: minio/minio:latest
    # 容器名
    container_name: minio
    entrypoint:  # 初始化存储目录
      - sh          
      - -euc        # 执行脚本的参数:e(报错退出) u(未定义变量报错) c(执行后续命令)
      - |           # 多行脚本开始, minio创建目录挂载日志
        mkdir -p /data/loki-data && \
        mkdir -p /data/loki-ruler && \
        minio server /data --console-address :9001
    environment:
      - MINIO_ROOT_USER=whiteBrocade        # 用户名(与Loki配置对应)
      - MINIO_ROOT_PASSWORD=whiteBrocade    # 密码(需加密处理)
      - MINIO_PROMETHEUS_AUTH_TYPE=public   # 开放指标
    volumes:
      - /data/alg/minio:/data  # 持久化存储路径
    ports:
      - 9000    # API端口
      - 9001    # UI端口
    networks:
      - loki

  # ========================
  # 可视化平台
  # ========================
  grafana:
    image: grafana/grafana-enterprise:latest
    # 容器名
    container_name: grafana
    # 数据持久化
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true  # 开启匿名访问(生产环境应关闭)
      # 设置 Grafana 的管理员(admin)账户的初始密码为admin 
      - GF_SECURITY_ADMIN_PASSWORD=admin
      # 设置Grafana的语言为简体中文
      - GF_VIEWER_LANGUAGE=zh-Hans
      # 设置 Grafana 的默认用户界面主题为暗黑模式
      - GF_USERS_DEFAULT_THEME=dark
      - GF_PATHS_PROVISIONING=/etc/grafana/provisioning
    entrypoint:  # 覆盖默认启动命令, 动态创建Loki数据源配置
      - sh
      - -euc         # 执行脚本的参数
      - |            # 多行脚本开始
        mkdir -p /etc/grafana/provisioning/datasources
        cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
        apiVersion: 1
        # 初始化Loki数据源
        datasources:
          - name: Loki     # 显示在UI中的名称
            type: loki     # 数据源类型
            access: proxy  # 通过Grafana服务代理访问
            url: http://gateway:3100  # 通过NG网关访问
            jsonData:
              httpHeaderName1: "X-Scope-OrgID"  # # 多租户头部名称
            secureJsonData:
              httpHeaderValue1: "tenant1"  # 租户ID
        EOF
        /run.sh
    ports:
      - 3000    # Web访问端口
    depends_on: # 依赖网关服务
      - gateway
    networks:
      - loki

  # ========================
  # API网关(流量路由)
  # ========================
  gateway:
    image: nginx:latest
    # 容器名
    container_name: nginx
    volumes:
      - /data/alg/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 3000:3000	# Grafana UI
      - 3100:3100   # Loki统一入口端口
      - 3101:3101   # read 端点
      - 3102:3102   # write 端点
      - 9001:9001   # Minio UI
      - 12345:12345 # Alloy UI
    healthcheck: # 健康检查策略
      test: [
        "CMD", 
        "service", 
        "nginx", 
        "status"]
      interval: 10s
      timeout: 5s
      retries: 5
    depends_on:
      - read
      - write
      - alloy
    networks:
      - loki

ALG相关访问路径


启动ALG

image-20250306154436045

Grafana UI

  • 访问地址(这里换成你自己的IP): http://192.168.132.10:3000

  • 账号: admin

  • 密码: admin

image-20250306155441031

Minio UI

  • 访问地址(这里换成你自己的IP): http://192.168.132.10:9001
  • 账号: whiteBrocade
  • 密码: whiteBrocade

image-20250306155533136

Grafana Alloy UI

  • 访问地址(这里换成你自己的IP): http://192.168.132.10:12345

image-20250306155931033

Loki Read/Write组件

  • Read访问地址(这里换成你自己的IP): http://192.168.132.10:3101
  • Write访问地址(这里换成你自己的IP): http://192.168.132.10:3102

image-20250306160337569

Flog

使用flog生成日志, 模拟三种情况

  • Docker容器日志
  • 本地*.log日志
  • 本地*.log.gz
version: "3.8"
services:
  # ========================
  # log 是一个由 mingrammer 开发的开源项目,主要用于生成常见的日志格式,如 Apache 通用日志、Apache 错误日志和 RFC3164 系统日志
  # 日志会输出到 容器内部的标准输出(stdout)
  # ========================
  flog-stdout:
    image: mingrammer/flog:latest
    # 容器名
    container_name: flog-stdout
    # -f json:日志格式, 这里指定为json
    # -d 200ms: 日志产生的速度
    # -t stdout: 输出类型为标准输出
    # -l: 无限循环生成日志
    command: -f json -d 200ms -t stdout -l
  # 这里的日志持久化, 用于应用程序产生的*.log日志以及压缩日志
  flog-log:
    image: mingrammer/flog:latest
    # 容器名
    container_name: flog-log
    # -f json:日志格式, 这里指定为json
    # -d 200ms: 日志产生的速度
    # -t log: s输出类型为log日志
    # -l: 无限循环生成日志
    # -w: 覆盖已存在的日志文件
    # -o /data/logs/test.log: 将日志输出到文件中
    # -p 1048576: 当日志文件达到1MB的时候就会分割日志
    # -b 10485760 该路径下/data/logs/*.log最多生成10MB
    command: -f json -d 200ms -l -t log -w -o /data/logs/test.log -p 1048576 -b 10485760
    # 将日志映射到宿主机上, 模拟非容器环境部署程序产生的日志文件
    volumes:
      - /data/alg/flog/logs/log:/data/logs
  flog-gz:
    image: mingrammer/flog:latest
    # 容器名
    container_name: flog-gz
    # -f json:日志格式, 这里指定为json
    # -t gz: 输出类型为gzip文件
    # -l: 无限循环生成日志
    # -w: 覆盖已存在的日志文件
    # -o /data/logs/test.log.gz: 将日志输出到test.log.gz
    # -p 1048576: 当日志文件达到1MB的时候就会分割日志
    # -b 10485760 该路径下/data/logs/*.gz最多生成10MB
    command: -f json -l -t gz -w -o /data/logs/test.log.gz -p 1048576 -b 10485760
    # 将日志映射到宿主机上, 模拟非容器环境部署程序产生的日志文件
    volumes:
      - /data/alg/flog/logs/gz:/data/logs

启动Flog容器, 如下图

image-20250306154948134

效果

容器日志查看

访问http://192.168.132.10:3000的Grafana面板, 选择Expore, 查看Nginx容器的日志

image-20250306154730631

日志如下

image-20250306154836987

log日志和log.gz日志查看

访问http://192.168.132.10:3000, 通过filename标签(这个标签是alloy内置自动添加的)查看log日志

image-20250306155035916

查看gz格式的压缩日志

image-20250306155154219

Alloy代替Node Exporter方式采集主机信息

alloy除了可以用于收集日志, 还可以采集主机信息, 发送给Prome

参考资料

ALG

博客

Grafana 系列文章(一):基于 Grafana 的全栈可观察性 Demo

Grafana Loki 简要指南:关于标签您需要了解的一切

开源日志监控:Grafana Loki 简要指南

日志之Loki详细讲解

使用读写分离模式扩展 Grafana Loki
Loki部署模式
grafana loki的理解与配置(2.9)
轻量级日志系统docker-compose搭建Loki+Grafana+Promtail,配置、部署,查询全流程
轻量级日志系统-Loki

轻量级日志系统笔记ALG

开源项目推荐:flog
推荐一个小工具:flog
探索Flog:伪装日志流量的神器
gitcode的flog项目

Docker 环境中配置 Grafana:详细教程与常见配置项解析

项目集成grafana,并用非root用户启动

在docker-compose启动grafana,出现权限错误的解决方案

Docker上的Grafana 7.3.0存在权限问题

grafana重启后模板没有数据了 grafana新建dashboard

Docker安装grafana数据持久化+配置SMTP

springboot+Loki+Loki4j+Grafana搭建轻量级日志系统

视频

【IT老齐636】Grafana Loki vs ELK

【IT老齐710】Grafana ALG分布式日志收集架构

【IT老齐711】ALG收集Docker所有实例运行日志

Grafana+Loki+Alloy快速构建企业日志系统

k8s + loki 日志解决方案 (持续更新中)

Loki日志系统-安装、使用、告警

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

捣鼓180天,我写了一个相册小程序

&#x1f64b;为什么要做土著相册这样一个产品&#xff1f; ➡️在高压工作之余&#xff0c;我喜欢浏览B站上的熊猫幼崽视频来放松心情。有天在家族群里看到了大嫂分享的侄女卖萌照片&#xff0c;同样感到非常解压。于是开始翻阅过去的聊天记录&#xff0c;却发现部分图片和视…

JDK ZOOKEEPER KAFKA安装

JDK17下载安装 mkdir -p /usr/local/develop cd /usr/local/develop 将下载的包上传服务器指定路径 解压文件 tar -zxvf jdk-17.0.14_linux-x64_bin.tar.gz -C /usr/local/develop/ 修改文件夹名 mv /usr/local/develop/jdk-17.0.14 /usr/local/develop/java17 配置环境变量…

5c/c++内存管理

1. C/C内存分布 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd";int* ptr1 (int*)malloc(sizeof(int) * 4);i…

Tomcat-web服务器介绍以及安装部署

一、Tomcat简介 Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目&#xff0c;由Apache、Sun和其他一些公司及个人共同开发而成。 Tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用…

国产编辑器EverEdit - 超多样式设置

1 设置-编辑-样式 1.1 设置说明 1.1.1 折叠样式 默认为箭头&#xff0c;折叠样式选项如下&#xff1a; 箭头&#xff1a; 矩形和线条 五边形 圆形图标 1.1.2 光标样式 光标用于指示当前用户输入位置&#xff0c;光标样式选项如下&#xff1a; 默认 纤细 字宽 …

【DeepSeek】5分钟快速实现本地化部署教程

一、快捷部署 &#xff08;1&#xff09;下载ds大模型安装助手&#xff0c;下载后直接点击快速安装即可。 https://file-cdn-deepseek.fanqiesoft.cn/deepseek/deepseek_28348_st.exe &#xff08;2&#xff09;打开软件&#xff0c;点击立即激活 &#xff08;3&#xff09;选…

2025系统架构师(一考就过):(2016-2017)案例+论文历年真题及解析系列二

24、管道-过滤器风格 和 数据仓库风格 对比(2016真题) 比较因素管道-过滤器风格数据仓储风格交互方式顺序结构或有限的循环结构星型数据结构数据流文件或模型控制结构数据流驱动业务功能驱动扩展方法接口适配模型适配25、用例及其关系、类及其关系(2016真题) 用例是对系统…

Artec Leo+Ray II 三维扫描仪成功为VR展数字化30吨重设备-沪敖3D

挑战&#xff1a;在贸易展上展示重达30吨的机械设备&#xff0c;同时克服设备搬运和展示的难题&#xff0c;减轻物流负担。。 解决方案&#xff1a;Artec Leo、Artec Ray II、Artec Studio、Blender、Unity、Microsoft HoloLens、HTC VIVE PRO 效果&#xff1a;在虚拟展厅中&am…

Flink深入浅出之01:应用场景、基本架构、部署模式

Flink 1️⃣ 一 、知识要点 &#x1f4d6; 1. Flink简介 Apache Flink — Stateful Computations over Data StreamsApache Flink 是一个分布式大数据处理引擎&#xff0c;可对有界数据流和无界数据流进行有状态的计算。Flink 能在所有常见集群环境中运行&#xff0c;并能以…

Docker新手入门(持续更新中)

一、定义 快速构建、运行、管理应用的工具。 Docker可以帮助我们下载应用镜像&#xff0c;创建并运行镜像的容器&#xff0c;从而快速部署应用。 所谓镜像&#xff0c;就是将应用所需的函数库、依赖、配置等应用一起打包得到的。 所谓容器&#xff0c;为每个镜像的应用进程创建…

DeepSeek R1学习入门

一、什么是 DeepSeek R1 2025.01.20 DeepSeek-R1 发布&#xff0c;DeepSeek R1 是 DeepSeek AI 开发的第一代推理模型&#xff0c;擅长复杂的推理任务&#xff0c;官方对标OpenAI o1正式版。适用于多种复杂任务&#xff0c;如数学推理、代码生成和逻辑推理等。 根据官方信息D…

[数据库笔记(二)]表的增删改查(基础)

目录 前言 CRUD 新增 单行数据全列插入 ​编辑 多行数据指定列插入 查询 全列查询 指定列查询 查询字段为表达式 别名&#xff1a;AS 别名去重&#xff1a;distinct 排序&#xff1a;order by 条件查询&#xff1a;where 运算符 和 <>的区别 between...…

Redis——缓存穿透、击穿、雪崩

缓存穿透 什么是缓存穿透 缓存穿透说简单点就是大量请求的 key 根本不存在于缓存中&#xff0c;导致请求直接到了数据库上&#xff0c;根本没有经过缓存这一层。举个例子&#xff1a;某个黑客故意制造我们缓存中不存在的 key 发起大量请求&#xff0c;导致大量请求落到数据库…

网络安全ctf试题 ctf网络安全大赛真题

MISC 1 签到 难度 签到 复制给出的flag输入即可 2 range_download 难度 中等 flag{6095B134-5437-4B21-BE52-EDC46A276297} 0x01 分析dns流量&#xff0c;发现dns && ip.addr1.1.1.1存在dns隧道数据&#xff0c;整理后得到base64: cGFzc3dvcmQ6IG5zc195eWRzIQ 解…

蓝桥备赛(11)- 数据结构、算法与STL

一、数据结构 1.1 什么是数据结构&#xff1f; 在计算机科学中&#xff0c;数据结构是一种 数据组织、管理和存储的格式。它是相互之间存在一种 或多种特定关系的数据元素的集合。 ---> 通俗点&#xff0c;数据结构就是数据的组织形式 &#xff0c; 研究数据是用什么方…

VsCode + EIDE + OpenOCD + STM32(野火DAP) 开发环境配置

VsCode EIDE OpenOCD STM32(野火DAP) 开发环境配置 接受了新时代编辑器的我&#xff0c;实在受不了Keil的上古编辑页面&#xff0c;周树人说过&#xff1a;由奢入俭难&#xff0c;下面我们一起折腾一下开源软件Vscode&#xff0c; 用以开发51和STM32&#xff0c;有错误之处&…

esp32驱动带字库芯片TFT屏幕

前言 学习esp32单片机开发&#xff0c;前段时间在网上买了一块2.0寸TFT屏幕。 长这个样子&#xff0c;这个屏幕带汉字字库的硬件模块。我仔细看了一下这个字库模块上面写的字是25Q32FVSIG 1336 文档 卖家也发来了开发文档&#xff0c;是个doc文档&#xff0c;张这个样子。 开…

短分享-Flink图构建

一、背景 通过简单的书写map、union、keyby等代码&#xff0c;Flink便能构建起一个庞大的分布式计算任务&#xff0c;Flink如何实现的这个酷炫功能呢&#xff1f;我们本次分享Flink做的第一步&#xff0c;将代码解析构建成图 源码基于Flink 2.10&#xff0c;书籍参考《Flink核…

在 ASP.NET Core 中启用 Brotli 和 Gzip 响应压缩

在本文中&#xff0c;我们将探讨如何在 ASP.NET Core 应用程序中启用响应压缩&#xff0c;重点介绍 Brotli 和 Gzip 算法以及如何验证压缩是否有效。 什么是响应压缩&#xff1f; 响应压缩通过使用Brotli 或 Gzip等算法来最小化 HTTP 响应的大小。这些算法在传输文本资产&#…

调研:如何实现智能分析助手(Agent)(AutoCoder、FastGPT、AutoGen、DataCopilot)

文章目录 调研&#xff1a;如何实现智能分析助手&#xff08;Agent&#xff09;&#xff08;AutoCoder、FastGPT、AutoGen、DataCopilot&#xff09;一、交互流程二、数据流程三、架构分类四、开源产品4.1 AutoCoder&#xff08;知识库变体&#xff09;4.2 FastGPT&#xff08;…