首页
提效神器
常用运维脚本汇总
电子书阅读
推荐
电子书阅读
事物管理
Search
1
安装docker时报错container-selinux >= 2:2.74
185 阅读
2
rsync命令(可替代rm删除巨量文件)
147 阅读
3
docker 镜像加速器配置,daemon.json文件详解
138 阅读
4
kubernetes集群各组件安装过程汇总
107 阅读
5
使用国内镜像地址拉取k8s安装需要的images
97 阅读
运维
自动化运维
数据库
容器与k8s
环境
云计算
脚本
ai
登录
/
注册
Search
标签搜索
命令
nginx
zabbix
Mingrui
累计撰写
99
篇文章
累计收到
8
条评论
首页
栏目
运维
自动化运维
数据库
容器与k8s
环境
云计算
脚本
ai
页面
提效神器
常用运维脚本汇总
电子书阅读
推荐
电子书阅读
事物管理
搜索到
99
篇与
的结果
2025-12-06
OpenResty
OpenResty系统信息OpenResty在表ngx.conf里提供了六个功能接口,可以获取自身的一些信息:debug:是否算Debug版本prefix:工作目录,即启动时“-p”参数指定的目录nginx_version:大版本号,即内部NGINX的版本号nginx_configure:编译的使用的配置参数subsystem:当前所在的子系统,取值为“http”或“stream”ngx_lua_version:当前所在子系统的版本号注意: prefix和nginx_configure这两个接口是函数的形式。接口的示例代码如下:ngx.say(nginx.config.debug) ngx.say(nginx.config.prefix()) ngx.say(nginx.config.nginx_version) ngx.say(nginx.config.nginx_configure()) ngx.say(nginx.config.subsystem()) ngx.say(nginx.config.ngx_lua_version())OpenResty运行日志函数ngx.log(log_level)记录罗OpenResty的运行日志,用法类似Lua的标准库函数print,可以接受任意多个参数,记录任意信息。print()=ngx.NOTICEngx.log的第一个参数是日志级别。ngx.STDERR:日志直接打印到标准输出,最高级别的日志ngx.EMERG:发生了紧急情况(emergency),需要立即处理ngx.ALERT:发生了严重错误,可能需要报警给运维系统ngx.CRIT:发生了严重错误(critical)ngx.ERR:普通的错误,业务中发生了意外ngx.WARN:警告信息,业务正常,但可能需要检查警告的来源ngx.NOTICE:提醒信息,仅仅算告知,通常可以忽略ngx.INFO:一般的信息ngx.DEBUG:调试可用的信息,只有debug版本才会启用业务逻辑关键点INFO或者WARN,捕获error级别的错误信息OpenResty时间日期对于Web服务来说,能够随时获取正确的时间与日期是非常重要的。OpenResty为此提供罗很多时间日期相关的函数,可以满足绝大多数场景的应用。这些时间日期函数不会引发昂贵的系统调用(ngx.updatetime除外),几乎没有成本。所以在应用程序中应对尽量使用它们操作时间而不是使用Lua标准库里的os。当前时间ngx.say(ngx.today()) #本地时间,格式是“yyyy-mm-dd” ngx.say(ngx.localtime()) #本地时间,格式是“yyyy-mm-dd hh:mm:ss” ngx.say(ngx.utctime()) #utc时间,格式是“yyyy-mm-dd hh:mm:ss”时间戳ngx.time ngx.now时间戳
2025年12月06日
1 阅读
0 评论
0 点赞
2025-12-04
一套脚本标准化所有新服务器
当拿到一台新服务器时,第一件事永远是根据实际业务来对服务器进行标准化设置。脚本特点智能系统识别 自动识别RHEL系(CentOS, RHEL, openEuler等)和Debian系(Ubuntu, Debian等)系统根据不同系统使用对应的包管理器(yum/dnf/apt)全面标准化配置高速软件源配置(阿里云镜像)基础运维工具安装Vim高级配置(语法高亮、Tab设置等)Shell别名与环境变量优化精确时间同步(chrony)内核参数优化(文件描述符、网络参数等)企业级审计系统(history增强+auditd)个性化登录欢迎界面SSH安全加固健壮性与错误处理Root权限检查配置文件备份机制兼容性处理详细的进度提示与状态反馈企业级安全特性操作审计追踪(谁、何时、从哪、做了什么)sudo特权操作监控SSH安全加固系统关键文件监控使用方法将脚本保存为server_init.sh赋予执行权限: chmod +x server_init.sh以root身份运行: sudo ./server_init.sh 警告: 脚本会修改系统关键配置,建议先在测试环境验证。特别是SSH安全加固部分会禁用密码登录,务必先配置好SSH密钥认证。这个脚本已经全面优化,可以适用于企业环境中大部分Linux服务器的标准化初始化需求,让运维工作更加高效、安全、规范。下载地址:{abtn icon="fa-download" color="#ff6800" href="https://www.xiaohetao.xyz/usr/uploads/2025/12/467932042.shh" radius="" content="点击下载"/}1.配置高速软件源使用的https://linuxmirrors.cn/提供的脚本bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ --source mirrors.aliyun.com \ --protocol https \ --use-intranet-source false \ --install-epel true \ --backup true \ --upgrade-software false \ --clean-cache false \ --ignore-backup-tips2.安装运维工具包安装必需工具#centos系统基础工具包 dnf insta1l -y vim-enhanced #增强版Vim(带彩色高亮) dnf instal1 -y wget cur1 #下载工具(必须) dnfinsta11 -y net-tools #网络工具(ifconfig、netstat) dnfinsta11 -y rzsz #文件上传下载(比scp简单) dnf install -y tree # 树状显示目录 dnf install -y bash-completion #命令自动补全(新手神器) dnf install -y git # 代码管理 dnf insta11-y htop iotop iftop #增强版任务/i0/网络管理器Ubuntu系统把dnf换成apt即可。让工具更好用的配置# 1. Vim配置:从“勉强能用”到“得心应手” echo "正在配置Vim:告别默认vi的‘地狱模式’..." cat > /etc/vimrc <<'EOF' " 基础必改项 set number " 显示行号 - 没有行号的编辑器是在猜谜吗? syntax enable " 语法高亮 - 一眼看出字符串、注释、关键字 set tabstop=2 " Tab宽度2空格(根据团队规范调整) set expandtab " Tab转空格 - 保证代码在所有人机器上显示一致 " 搜索增强 set incsearch " 边输入边高亮 set hlsearch " 保持高亮直到下次搜索 " 防止粘贴乱码 if has("mouse") set mouse=a " 启用鼠标(可以拖动、滚轮) endif set paste " 自动识别粘贴模式 EOF # 2. Shell别名:把复杂命令变成“肌肉记忆” echo "正在植入‘命令快捷键’..." cat >> /etc/bashrc <<'EOF' # ==== 安全防护 ==== alias rm='rm -i' # 删除文件时确认 alias cp='cp -i' # 覆盖文件时确认 alias mv='mv -i' # 覆盖文件时确认 # ==== 效率革命 ==== # 经典ls进化史:l → la → ll → llt alias l='ls -CF' alias la='ls -A' alias ll='ls -lhF --color=auto --time-style=long-iso' alias llt='ll -t' # 按时间排序,查日志必备 # ==== 网络诊断快捷键 ==== alias ports='ss -tulanp' # 比netstat更快的现代工具 alias listen='ports | grep LISTEN' # 只看监听端口 alias myip='curl -s icanhazip.com' # 最快获取公网IP # ==== 目录快跳 ==== alias ..='cd ..' alias ...='cd ../..' alias ....='cd ../../..' alias cdlog='cd /var/log' alias cdetc='cd /etc/sysconfig"' EOF 让配置立即生效 source /etc/bashrc 2>/dev/null || true # 定义欢迎脚本路径 WELCOME_SCRIPT="/etc/profile.d/welcome.sh"创建 welcome.sh 内容# 只在交互式 shell 中显示(避免 ssh 执行命令时干扰) if [[ $- != *i* ]]; then return fi # 获取真实用户(支持 sudo/su) get_real_user() { if [[ -n "$SUDO_USER" ]]; then echo "${SUDO_USER}(via sudo)" elif [[ -f /proc/self/loginuid ]] && [[ "$(cat /proc/self/loginuid)" != "4294967295" ]]; then local uid=$(cat /proc/self/loginuid) id -un "$uid" 2>/dev/null || whoami else whoami fi } # 获取源IP get_client_ip() { if [[ -n "$SSH_CLIENT" ]]; then echo "$SSH_CLIENT" | awk '{print $1}' elif [[ -n "$SSH_CONNECTION" ]]; then echo "$SSH_CONNECTION" | awk '{print $3}' else echo "localhost" fi } # 显示欢迎信息(仅首次登录显示一次,避免重复) if [ -z "$WELCOME_SHOWN" ]; then export WELCOME_SHOWN=1 echo "" echo "******************************************************************" echo "* 🌟 欢迎登录企业运维服务器! *" echo "* *" echo "* 🔒 安全审计提示: *" echo "* • 操作用户: $(get_real_user)" echo "* • 登录时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "* • 源 IP 地址: $(get_client_ip)" echo "* *" echo "* ⚠️ 重要声明: *" echo "* 本系统已启用操作审计,所有命令将记录: *" echo "* - 执行者身份(穿透 sudo/su) *" echo "* - 执行时间 *" echo "* - 源 IP 地址 *" echo "* - 工作目录和命令内容 *" echo "* *" echo "* 📊 实时系统状态: *" # 磁盘使用(根分区) # 磁盘使用(根分区) DISK_ROOT=$(df -h / 2>/dev/null | awk 'NR==2 {print $5}') # 内存使用率 MEM_USED=$(free 2>/dev/null | awk 'NR==2 {printf "%.0f%%", $3/$2 * 100}') # CPU 负载 LOAD=$(uptime 2>/dev/null | awk -F'load average:' '{print $2}' | xargs) # 登录用户数 USERS=$(who 2>/dev/null | wc -l) echo "* 💾 根分区使用: ${DISK_ROOT:-N/A}" echo "* 🧠 内存使用率: ${MEM_USED:-N/A}" echo "* ⚡ 系统负载: ${LOAD:-N/A}" echo "* 👥 当前登录: ${USERS} 个会话" echo "* *" echo "* 📞 安全支持: security@gaokun.edu *" echo "******************************************************************" echo "" fi EOF # 设置脚本权限(必须可执行) chmod +x "$WELCOME_SCRIPT" # 验证文件是否存在且可执行 if [[ -f "$WELCOME_SCRIPT" && -x "$WELCOME_SCRIPT" ]]; then echo "✅ 成功部署登录欢迎提示!" echo "📍 文件位置: $WELCOME_SCRIPT" echo "" echo "💡 效果预览(当前用户):" # 手动 source 测试(不退出当前会话) source "$WELCOME_SCRIPT" echo "" echo "📌 说明:" echo "1. 所有新登录用户将自动看到此提示" echo "2. 提示包含实时系统状态(磁盘、内存、负载)" echo "3. 支持 sudo/su 身份穿透识别" echo "4. 不会影响非交互式命令(如 scp、ssh cmd)" else echo "❌ 部署失败!请检查权限和磁盘空间" exit 1 fi echo "🎯 配置已生效!来体验几个‘效率魔法’:" echo "1. 输入 'll' - 看看和普通ls的差别" echo "2. 输入 'cdetc' - 直接跳到配置目录" echo "3. 输入 'listen' - 秒看所有监听端口" 3.配置时间同步chrony -- 传统的NTPd 更适合虚拟化和云环境,启动快,收敛快,抗网络抖动性更强的工具配置时间同步可以解决下面的问题:日志时间错乱证书验证失败分布式系统数据不一致定时任务不执行等等以下配置仅供参考,事实上chrony配置比较简单。# 配置国内时间服务器(替换默认的国外服务器) cat > /etc/chrony.conf <<'EOF' server ntp.aliyun.com iburst server ntp1.aliyun.com iburst server ntp2.aliyun.com iburst # 允许同步的网段(根据实际情况调整) allow 192.168.0.0/16 # 时间误差过大时的处理方式 makestep 1.0 3 # 启用硬件时间同步 rtcsync # 日志配置 logdir /var/log/chrony EOF # 启动并设置开机自启 systemctl enable --now chronyd # 强制立即同步 chronyc -a makestep # 查看同步状态 echo "当前时间:$(date)" echo "时间源状态:" chronyc sources -v 4.内核优化警惕“'To many open files”,部分案例:Elasticsearch官方强制要求调高FD限制Elasticsearch在处理大量索引和分片时,会同时打开成千上万个文件(每个段文件、每个网络连接都占一个FD)。其官方文档明确警告:“The default limit of 1024 open file descriptors is far too low for Elasticsearch.You must increase it to at least 65536.”Elasticsearch官方文档:File Descriptors无数用户在部署ES后遭遇写入失败、节点离群,根因都是未调整此配置。Redis因FD耗尽拒绝新客户端连接Redis为每个客户端连接、主从复制流、AOF文件等分配FD。当 ulimit -n 过低时,即使内存充足,Redis也会报错:1Error accepting client connection: accept: Too many open filesRedis官方FAQ专门列出此问题,并指导用户修改 /etc/security/limits.conf :Redis Optimization Guide – File DescriptorsGitLab 2017年重大事故中,FD限制拖慢恢复在GitLab因误删生产数据库导致全球中断的著名事件中,团队在恢复备份时遇到严重瓶颈。官方复盘报告指出:The restore process was slowed by system limits on open files.”(恢复过程因系统对打开文件数量的限制而变慢)— GitLab Post-Mortem, Feb 2017虽然FD不是主因,但它显著延长了故障恢复时间,凸显了系统级调优的重要性。特别是一些机器没有提前进行调优的时候,到了关键时刻不一定能想得起来。内核优化# 1. 修改进程可打开文件数(解决‘Too many open files’) cat >> /etc/security/limits.conf <<'EOF' # 所有用户的基础限制 * soft nofile 65535 # 软限制(可临时超过) * hard nofile 65535 # 硬限制(最大上限) # 进程数限制(防止fork炸弹) * soft nproc 65535 * hard nproc 65535 # root用户的限制(通常更高) root soft nofile 100000 root hard nofile 100000 EOF # 2. 修改系统级限制(影响所有进程) cat >> /etc/sysctl.conf <<'EOF' # 增加系统最大文件打开数 fs.file-max = 1000000 # 增加TCP连接数(应对高并发) net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535 # 加快TCP回收(应对短连接) net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 # 注意:在内核4.12+已移除,这里仅作演示 # 增加内存分配(应对大量连接) net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 EOF # 3. 立即生效(无需重启) sysctl -p 修改内核是个 危险操作 ,配错了可能导致系统无法启动。一定要做好测试, 灰度上线发布 。5.审计日志与系统安全加固为什么需要操作审计?1、安全合规要求2、故障排查刚需(运维必须会)3、团队管理利器(主管必须懂)怎么做?History增强+Auditd系统审计echo "🔍 [6/6] 正在部署‘企业级运维天眼系统’:谁?在什么时间?从哪来?做了什么?" # ============================================ # 第一部分:增强的History审计(记录命令) # ============================================ cat >> /etc/profile <<'EOF' # ==================== 智能History审计配置 ==================== # 获取登录用户的真实IP(SSH登录记录IP,本地登录记录localhost) USER_IP=$(who -u am i 2>/dev/null | awk '{print $NF}' | sed -e 's/[()]//g') if [[ -z "$USER_IP" ]]; then # 如果是本地登录,尝试获取主机IP USER_IP=$(hostname -i 2>/dev/null || echo "localhost") fi # 核心:判断是否通过sudo切换身份 # $SUDO_USER:如果通过sudo执行命令,这个变量记录原始用户 if [[ -n "$SUDO_USER" ]]; then REAL_USER="$SUDO_USER(as root)" # 记录真实用户+权限提升标记 else REAL_USER=$(whoami) # 记录当前用户 fi # 设置History格式:时间 | 真实用户 | IP地址 | 工作目录 | 执行的命令 export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S | $REAL_USER | $USER_IP | \$(pwd) | " export HISTSIZE=20000 # 内存中保存20000条命令 export HISTFILESIZE=40000 # 历史文件保存40000条命令 # 重要:防止某些命令被忽略(如空格开头) export HISTCONTROL=ignoredups:ignorespace # 设置不想被记录的命令(这些命令太常见,记录会浪费空间) export HISTIGNORE="ls:ll:la:cd:pwd:exit:history:h" # 关键配置:实时同步history到文件(防止终端异常退出丢失记录) shopt -s histappend PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND" # 创建审计日志目录 mkdir -p /var/log/audit chmod 750 /var/log/audit 用户登录/登出审计(每次登录都会记录) echo "$(date '+%Y-%m-%d %H:%M:%S') | $REAL_USER | $USER_IP | 登录系统 | 工作目录: \$(pwd)" >> /var/log/user_audit.log EOF # ============================================ # 第二部分:Sudo操作审计(特权命令记录) # ============================================ echo "配置Sudo操作审计..." # 创建Sudo审计配置 cat > /etc/sudoers.d/audit <<'EOF' # Sudo命令审计配置 Defaults logfile=/var/log/sudo_audit.log # 所有sudo命令记录到这个文件 Defaults log_input # 记录输入内容(如编辑文件的内容) Defaults log_output # 记录命令输出(谨慎开启,可能很大) Defaults iolog_dir=/var/log/sudo-io/%{user} # 每个用户的输入输出分开存放 # 重要:设置命令执行超时(防止命令卡住) Defaults timestamp_timeout=5 # sudo密码5分钟后需要重新输入 Defaults passwd_timeout=1 # 密码输入超时1分钟 EOF chmod 440 /etc/sudoers.d/audit # 必须440权限,保护配置文件 # 创建审计日志文件 touch /var/log/user_audit.log touch /var/log/sudo_audit.log chmod 600 /var/log/user_audit.log chmod 600 /var/log/sudo_audit.log # ============================================ # 第三部分:Auditd系统级审计(内核级监控) # ============================================ echo "安装和配置Auditd系统审计服务..." # 安装auditd if command -v dnf &> /dev/null; then dnf install -y audit audit-libs > /dev/null 2>&1 elif command -v yum &> /dev/null; then yum install -y audit audit-libs > /dev/null 2>&1 fi # 配置auditd规则 cat > /etc/audit/rules.d/99-ops-audit.rules <<'EOF' # ========== 运维操作审计规则 ========== # 1. 监控用户和权限变更 -w /etc/passwd -p wa -k user_changes # 监控用户账户变更 -w /etc/group -p wa -k group_changes # 监控用户组变更 -w /etc/shadow -p wa -k shadow_changes # 监控密码文件变更 -w /etc/sudoers -p wa -k sudoers_changes # 监控sudo权限变更 -w /etc/ssh/sshd_config -p wa -k ssh_changes # 监控SSH配置变更 # 2. 监控系统关键目录(防篡改) -w /etc/ -p wa -k etc_changes # 监控/etc目录所有写操作 -w /usr/bin/ -p wa -k bin_changes # 监控系统命令目录 -w /usr/sbin/ -p wa -k sbin_changes -w /var/log/ -p wa -k log_changes # 监控日志目录(防删日志) -w /root/.ssh/ -p wa -k root_ssh # 监控root的SSH密钥 # 3. 监控特权命令使用(谁提权了?) -w /bin/su -p x -k privilege_escalation # 监控su命令执行 -w /usr/bin/sudo -p x -k privilege_escalation # 监控sudo命令执行 -w /usr/bin/passwd -p x -k password_changes # 监控密码修改 # 4. 监控文件删除操作(谁删了文件?) -a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -k delete_files -a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -k delete_files # 5. 监控网络配置变更 -w /etc/hosts -p wa -k hosts_changes # 监控hosts文件 -w /etc/resolv.conf -p wa -k dns_changes # 监控DNS配置 # 6. 监控防火墙配置变更 -w /etc/sysconfig/iptables -p wa -k firewall_changes -w /etc/firewalld/ -p wa -k firewalld_changes # 7. 监控系统服务变更 -w /usr/lib/systemd/system/ -p wa -k service_changes -w /etc/systemd/system/ -p wa -k service_changes # 8. 监控定时任务变更 -w /etc/crontab -p wa -k cron_changes -w /etc/cron.hourly/ -p wa -k cron_changes -w /etc/cron.daily/ -p wa -k cron_changes -w /etc/cron.weekly/ -p wa -k cron_changes -w /var/spool/cron/ -p wa -k user_cron_changes # 9. 监控内核模块加载(防Rootkit) -w /sbin/insmod -p x -k kernel_modules -w /sbin/rmmod -p x -k kernel_modules -w /sbin/modprobe -p x -k kernel_modules EOF # 启用并启动auditd服务 systemctl enable auditd > /dev/null 2>&1 # 检查auditd是否已在运行,避免冲突 if systemctl is-active auditd &> /dev/null; then echo "auditd服务已在运行,重新加载规则..." auditctl -R /etc/audit/rules.d/99-ops-audit.rules > /dev/null 2>&1 else systemctl start auditd > /dev/null 2>&1 fi echo "✅ 企业级审计系统部署完成!" echo "" 企业里面生产还需做哪些?1、定期备份审计日志 -- 合规化需要,有些企业是每周一次内部审查2、告警的机制,关键操作实时告警(修改密码,删除日志)3、集中化的日志管理,比如ELKvsxsl9g,把所有的服务器日志集中存储,防止日志被纂改4、堡垒机(lumpseryer):统一管理服务器的访问权限、所有的操作视频回放。5、SSH安全加固。6.企业级监控与性能基线企业级监控与性能基线部署完上述的所有环境之后,还需要针对企业内部的一些实际环境进行定制化的软件安装1、安装企业内部工具包CI\CD2、配置sar数据收集3、部署监控告警系统:如:zabki、Prometheus+Gra34、设置性能的基线:了解服务器在正常状态下的表现,当出现异常的时候能够快速识别
2025年12月04日
2 阅读
0 评论
0 点赞
2025-12-04
calibre-web关于报错New db location is invalid, please enter valid path的解决方案
事实证明,AI用多了脑子就会不够用。拿这个报错去问AI,给你的回复是权限不够,比如千问:🔍 问题分析错误信息表明:您尝试将数据库位置设置为 /books但容器无法访问该路径可能原因是:路径不存在、权限不足或挂载配置错误相对来说,豆包给的建议会好很多,它指出了问题的核心: 路径存在,权限合理,文件存在Linux 系统解决该报错的核心是「路径合法 + 权限正确 + 配置重启」:先通过 ls 命令确认路径存在且有 metadata.db;再用 chown/chmod 赋予 Calibre-Web 运行用户权限;后台配置正确路径后重启服务;Docker 用户需确保路径映射正确。问题的解决方案在项目的 GitHub 页面中,按照Quick Start部分给与的提示,即可解决此问题。1.Access Calibre-Web: Open your browser and navigate to: http://localhost:8083 or for the OPDS catalog:http://localhost:8083/opds 2.Log in: Use the default admin credentials: Username: admin Password: admin123 3.Database Setup: If you do not have a Calibre database, download a sample from: https://github.com/janeczku/calibre-web/raw/master/library/metadata.db Move it out of the Calibre-Web folder to avoid overwriting during updates. 4.Configure Calibre Database: In the admin interface, set the Location of Calibre database to the path of the folder containing your Calibre library (where metadata.db is located) and click "Save". 即确认好books目录的权限后,确保books目录下有metadata.db文件存在且有读写权限。
2025年12月04日
2 阅读
0 评论
0 点赞
2025-12-02
kafka常用命令
topic 相关说明:红色的是必需要指定的参数使用bin/kafka-topics.sh 可查看所有的参数信息参数描述--bootstrap-server <String: server connect to> 连接kafka broker主机名称和端口号--topic <String: topic> 操作的topic名称--create创建主题--delete删除主题--alter修改主题--list查看所有主题--describe查看主题详细描述--partitions <Integer: # of partitions>设置分区数--replication-factor <Integer: replication factor>设置分区副本--config <String: name=value>更新系统默认的配置root@kf1:/opt/kafka# bin/kafka-topics.sh --bootstrap-server kf1:9092 --describe --topic first Topic: first TopicId: o4AxZZfwQhG-QR38nHUGxQ PartitionCount: 3 ReplicationFactor: 3 Configs: min.insync.replicas=1,segment.bytes=1073741824 Topic: first Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3 Elr: LastKnownElr: Topic: first Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1 Elr: LastKnownElr: Topic: first Partition: 2 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2 Elr: LastKnownElr: Topic: 主题名称TopicId: 主题IDPartitionCount: 分区数量ReplicationFactor: 副本数量Configs: min.insync.replicas=1,segment.bytes=1073741824Topic:Partition: 分区IDLeader: 副本的leaderReplicas: 副本存储位置Isr: 连接的副本LastKnownElr
2025年12月02日
2 阅读
0 评论
0 点赞
2025-11-27
Kafka——Kafka安装(kafka_2.13-4.1.1)
kafka2.8.0版本引入了基于Raft共识协议的新特性,它允许kafka集群在没有ZooKeeper的情况下运行。为了剥离和去除ZooKeeper,Kafka引入了自己的KRaft(Kafka Raft Metadata Mode)。KRaft是一个新的元数据管理架构,基于Raft一致性算法实现的一种内置元数据管理方式,旨在替代ZooKeeper的元数据管理功能。KRaft的优势有以下几点:简化部署:Kafka 集群不再依赖外部的 ZooKeeper 集群,简化了部署和运维的复杂性。KRaft 将所有协调服务嵌入 Kafka 自身,不再依赖外部系统,这样大大简化了部署和管理,因为管理员只需关注 Kafka 集群。高效的一致性协议:Raft 是一种简洁且易于理解的一致性算法,易于调试和实现。KRaft 利用 Raft 协议实现了强一致性的元数据管理,优化了复制机制。提高性能:由于元数据管理不再依赖 ZooKeeper,Kafka 集群的性能得到了提升,尤其是在元数据读写方面。增强可扩展性:KRaft 模式支持更大的集群规模,可以有效地扩展到数百万个分区。提高元数据操作的扩展性:新的架构允许更多的并发操作,并减少了因为扩展性问题导致的瓶颈,特别是在高负载场景中。更快的控制器故障转移:控制器(Controller)的选举和故障转移速度更快,提高了集群的稳定性。消除 ZooKeeper 作为中间层之后,Kafka 的延迟性能有望得到改善,特别是在涉及选主和元数据更新的场景中。KRaft模式下,kafka集群中的一些节点被指定为控制器(Controller),它们负责集群的元数据管理和共识服务,所有的元数据都存储在kafka内部的主题中,而不是ZooKeeper,控制器通过KRaft协议来确保元数据在集群中的准确复制,这种模式使用了基于时间的存储模型,通过定期快照来保证元数据日志不会无限增长。完全自主:因为是自家产品,所以产品的架构设计,代码开发都可以自己说了算,未来架构走向完全控制在自己手上。控制器(Controller)节点的去中心化:KRaft 模式中,控制器节点由一组 Kafka 服务进程代替,而不是一个独立的 ZooKeeper 集群。这些节点共同负责管理集群的元数据,通过 Raft 实现数据的一致性。日志复制和恢复机制:利用 Raft 的日志复制和状态机应用机制,KRaft 实现了对元数据变更的强一致性支持,这意味着所有控制器节点都能够就集群状态达成共识。动态集群管理:KRaft允许动态地向集群中添加或移除节点,而无需手动去ZooKeeper中更新配置,这使得集群管理更为便捷。下载在 kakfa官网 下载最新的安装包,推荐下载已经编译好的二进制包。wget https://dlcdn.apache.org/kafka/4.1.1/kafka_2.13-4.1.1.tgz tar -xzf kafka_2.13-4.1.1.tgz mv kafka_2.13-4.1.1 /opt/kafka修改配置文件修改位于config目录下的server.properties############################# Server Basics ############################# #定义节点角色。broker,处理消息存储、生产者/消费者请求;controller,管理集群元数据(分区状态、副本分配)。 process.roles=broker,controller # 节点id,要求集群内唯一,每个节点的id都要不同(如 1、2、3)。 node.id=1 #Controller节点启动时发现的初始服务器列表(用于加入集群)。 controller.quorum.bootstrap.servers=kf1:9093,kf2:9093,kf3:9093 #controller集群成员列表,集群内部选举和同步元数据,所有 Controller 节点必须在此列表中,且数量需满足多数派(如 3 节点集群需至少 2 个在线)。 controller.quorum.voters=1@kf1:9093,2@kf2:9093,3@kf3:9093 ############################# Socket Server Settings ##################### #节点绑定的网络接口和端口。PLAINTEXT:Broker服务端口(接收客户端请求),CONTROLLER:Controller间通信端口。 listeners=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 #Broker 之间通信使用的监听器名称 inter.broker.listener.name=PLAINTEXT #客户端实际连接的地址(Broker 会返回此地址给客户端)。 advertised.listeners=PLAINTEXT://192.168.88.51:9092,CONTROLLER://192.168.88.51:9093 #Controller 节点间通信使用的监听器名称 controller.listener.names=CONTROLLER #监听器名称与安全协议的映射关系。 listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL #处理网络请求的线程数(如接收请求、发送响应)。 num.network.threads=3 #处理磁盘 I/O 的线程数(如读写日志文件)。 num.io.threads=8 #Socket 缓冲区 socket.send.buffer.bytes=102400 #发送数据缓冲区大小(100KB)。 socket.receive.buffer.bytes=102400 #接收数据缓冲区大小(100KB)。 socket.request.max.bytes=104857600 #请求最大长度(100MB),防止 OOM。 ############################# Log Basics ############################# #消息日志存储目录(可配置多个路径,逗号分隔)。 log.dirs=/opt/kafka_data # 日志目录(可选) kafka_logs_dir=/var/log/kafka #分区与恢复 num.partitions=3 #新建 Topic 的默认分区数。 num.recovery.threads.per.data.dir=1 #每个日志目录用于崩溃恢复的线程数。 ############################# Internal Topic Settings #################### #副本因子与 ISR offsets.topic.replication.factor=3 # __consumer_offsets 副本数(生产环境建议 ≥3) share.coordinator.state.topic.replication.factor=2 # Share Group 状态主题副本数 share.coordinator.state.topic.min.isr=2 #share.coordinator.state.topic:Kafka Share Group 协调器的状态主题(内部主题)。min.isr:最小同步副本数(Minimum In-Sync Replicas),即写入操作需确认的最小同步副本数量(含 Leader)。配置值 1:表示向 share.coordinator.state.topic写入数据时,只需 Leader 副本确认即可认为成功(无需等待 Follower 副本同步)。逻辑:ISR(In-Sync Replicas,同步副本集)是 Leader 副本及与其保持同步的 Follower 副本的集合。min.isr=1意味着只要 Leader 副本存活且可写,写入就成功(即使没有其他同步副本)。 transaction.state.log.replication.factor=3 #transaction.state.log:Kafka 事务协调器的状态日志主题。事务协调器负责管理分布式事务(如跨分区/主题的事务提交/中止),该主题存储事务元数据(如事务 ID、参与者列表、状态(进行中/已提交/已中止)、超时时间等)。replication.factor:副本因子,即主题每个分区的副本总数(含 Leader 副本)。配置值 1:表示 transaction.state.log的每个分区仅有 1 个副本(仅 Leader 副本,无 Follower 副本)。逻辑:副本因子决定数据冗余度。replication.factor=1意味着数据仅存储在单个 Broker 上,无任何备份。 transaction.state.log.min.isr=3 #transaction.state.log:指定该参数作用于 事务状态日志(而非普通业务 Topic)。min.isr:即“最小同步副本数”,表示事务状态日志的每个分区,必须至少有 N 个副本(包括 Leader 副本)与 Leader 保持同步,否则该分区会进入“不可用”状态(无法写入新事务记录)。当事务状态日志的某个分区进行写入时,Kafka 会确保该分区的 同步副本集(ISR)大小 ≥ 3。只有当至少 3 个副本(Leader + 2 个 Follower)都成功复制了事务日志条目后,才会向生产者返回“事务提交成功”的响应。 default.replication.factor=3 #普通主题默认的副本因子数量 ############################# Log Flush Policy ############################ #日志保留策略 log.retention.hours=168 #日志保留时间(168 小时 = 7 天)。 log.segment.bytes=1073741824 #单个日志分段大小(1GB),达到后滚动生成新文件。 log.retention.check.interval.ms=300000 #检查日志保留的间隔(5 分钟)。在节点2上修改node.id=2 advertised.listeners=PLAINTEXT://192.168.88.52:9092,CONTROLLER://192.168.88.52:9093在节点3上修改node.id=3 advertised.listeners=PLAINTEXT://192.168.88.53:9092,CONTROLLER://192.168.88.53:9093初始化集群并启动首次启动时执行#在任一节点执行,仅执行一次,生成唯一集群ID bin/kafka-storage.sh random-uuid 0jQIB8NvQ3muEJg2vXIRRA #在每个节点执行,格式化存储 bin/kafka-storage.sh format -t 0jQIB8NvQ3muEJg2vXIRRA -c config/server.propertie Formatting metadata directory /opt/kafka_data with metadata.version 4.1-IV1.启动服务配置开机自启创建service文件vim /etc/systemd/system/kafka.service [Unit] Description=Apache Kafka Server Documentation=http://kafka.apache.org/documentation.html Requires=network.target remote-fs.target After=network.target remote-fs.target [Service] Type=simple User=kafka Group=kafka ExecStart=/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties ExecStop=/opt/kafka/bin/kafka-server-stop.sh Restart=on-abnormal RestartSec=10 KillMode=mixed TimeoutStopSec=30 Environment="LOG_DIR=/var/log/kafka" Environment="KAFKA_HEAP_OPTS=-Xmx1G -Xms1G" # 显式设置堆内存 # 日志重定向 StandardOutput=file:/var/log/kafka/service.log StandardError=file:/var/log/kafka/service-error.log [Install] WantedBy=multi-user.target# 重载 systemd 配置 sudo systemctl daemon-reload创建 Kafka 专用用户和目录# 创建系统用户 sudo useradd -r -s /sbin/nologin kafka # 创建数据/日志目录 sudo mkdir -p /opt/kafka_data sudo mkdir -p /var/log/kafka sudo chown -R kafka:kafka /opt/kafka_data /var/log/kafka # 授权 Kafka 安装目录 sudo chown -R kafka:kafka /opt/kafka按顺序启动节点可以使用systemctl命令或者手动的方式启动服务,#systemctl启动 systemctl enable --now kafka #前台启动 bin/kafka-server-start.sh config/server.properties #后台启动 nohup bin/kafka-server-start.sh config/server.properties &查看集群状态bin/kafka-broker-api-versions.sh --bootstrap-server 127.0.0.1:9092 # 192.168.88.51:9092 Broker 对外提供服务的 IP:端口(客户端实际连接的地址)。 #id: 1 Broker 的唯一标识 broker.id(集群中必须唯一,此处为 1、2、3)。 # rack: null 机架信息(未配置,故为 null,用于副本跨机架分布策略)。 #isFenced: false Broker 未被“隔离”(正常工作状态,若为 true则无法处理请求)。 192.168.88.51:9092 (id: 1 rack: null isFenced: false) -> ( Produce(0): 0 to 13 [usable: 13], #Produce(0) API 名称(Produce,消息生产 API),括号内 0是该 API 的 固定 key(Kafka 定义)。 #0 to 13 该 API 支持的 版本范围(从 v0 到 v13,共 14 个版本)。 #usable: 13 客户端与 Broker 协商后 实际使用的版本(取双方都支持的最高版本,性能最优)。 Fetch(1): 4 to 18 [usable: 18], ListOffsets(2): 1 to 10 [usable: 10], Metadata(3): 0 to 13 [usable: 13], OffsetCommit(8): 2 to 9 [usable: 9], OffsetFetch(9): 1 to 9 [usable: 9], FindCoordinator(10): 0 to 6 [usable: 6], JoinGroup(11): 0 to 9 [usable: 9], Heartbeat(12): 0 to 4 [usable: 4], LeaveGroup(13): 0 to 5 [usable: 5], SyncGroup(14): 0 to 5 [usable: 5], DescribeGroups(15): 0 to 6 [usable: 6], ListGroups(16): 0 to 5 [usable: 5], SaslHandshake(17): 0 to 1 [usable: 1], ApiVersions(18): 0 to 4 [usable: 4], CreateTopics(19): 2 to 7 [usable: 7], DeleteTopics(20): 1 to 6 [usable: 6], DeleteRecords(21): 0 to 2 [usable: 2], InitProducerId(22): 0 to 5 [usable: 5], OffsetForLeaderEpoch(23): 2 to 4 [usable: 4], AddPartitionsToTxn(24): 0 to 5 [usable: 5], AddOffsetsToTxn(25): 0 to 4 [usable: 4], EndTxn(26): 0 to 5 [usable: 5], WriteTxnMarkers(27): 1 [usable: 1], TxnOffsetCommit(28): 0 to 5 [usable: 5], DescribeAcls(29): 1 to 3 [usable: 3], CreateAcls(30): 1 to 3 [usable: 3], DeleteAcls(31): 1 to 3 [usable: 3], DescribeConfigs(32): 1 to 4 [usable: 4], AlterConfigs(33): 0 to 2 [usable: 2], AlterReplicaLogDirs(34): 1 to 2 [usable: 2], DescribeLogDirs(35): 1 to 4 [usable: 4], SaslAuthenticate(36): 0 to 2 [usable: 2], CreatePartitions(37): 0 to 3 [usable: 3], CreateDelegationToken(38): 1 to 3 [usable: 3], RenewDelegationToken(39): 1 to 2 [usable: 2], ExpireDelegationToken(40): 1 to 2 [usable: 2], DescribeDelegationToken(41): 1 to 3 [usable: 3], DeleteGroups(42): 0 to 2 [usable: 2], ElectLeaders(43): 0 to 2 [usable: 2], IncrementalAlterConfigs(44): 0 to 1 [usable: 1], AlterPartitionReassignments(45): 0 to 1 [usable: 1], ListPartitionReassignments(46): 0 [usable: 0], OffsetDelete(47): 0 [usable: 0], DescribeClientQuotas(48): 0 to 1 [usable: 1], AlterClientQuotas(49): 0 to 1 [usable: 1], DescribeUserScramCredentials(50): 0 [usable: 0], AlterUserScramCredentials(51): 0 [usable: 0], DescribeQuorum(55): 0 to 2 [usable: 2], UpdateFeatures(57): 0 to 2 [usable: 2], DescribeCluster(60): 0 to 2 [usable: 2], DescribeProducers(61): 0 [usable: 0], UnregisterBroker(64): 0 [usable: 0], DescribeTransactions(65): 0 [usable: 0], ListTransactions(66): 0 to 2 [usable: 2], ConsumerGroupHeartbeat(68): 0 to 1 [usable: 1], ConsumerGroupDescribe(69): 0 to 1 [usable: 1], GetTelemetrySubscriptions(71): UNSUPPORTED, PushTelemetry(72): UNSUPPORTED, ListConfigResources(74): 0 to 1 [usable: 1], DescribeTopicPartitions(75): 0 [usable: 0], ShareGroupHeartbeat(76): 1 [usable: 1], ShareGroupDescribe(77): 1 [usable: 1], ShareFetch(78): 1 [usable: 1], ShareAcknowledge(79): 1 [usable: 1], AddRaftVoter(80): 0 [usable: 0], RemoveRaftVoter(81): 0 [usable: 0], InitializeShareGroupState(83): 0 [usable: 0], ReadShareGroupState(84): 0 [usable: 0], WriteShareGroupState(85): 0 [usable: 0], DeleteShareGroupState(86): 0 [usable: 0], ReadShareGroupStateSummary(87): 0 [usable: 0], StreamsGroupHeartbeat(88): UNSUPPORTED, StreamsGroupDescribe(89): UNSUPPORTED, DescribeShareGroupOffsets(90): 0 [usable: 0], AlterShareGroupOffsets(91): 0 [usable: 0], DeleteShareGroupOffsets(92): 0 [usable: 0] ) 192.168.88.52:9092 (id: 2 rack: null isFenced: false) -> ( …… ) 192.168.88.53:9092 (id: 3 rack: null isFenced: false) -> ( …… )
2025年11月27日
2 阅读
0 评论
0 点赞
1
2
...
20