适用读者:要在裸机/云主机上把一套中间件装起来并让它真的跑住的人。
前置:S15-B04(进程端口与内存)、B05(磁盘分区与挂载)、B06(时间时区)、J04(Docker 基础)、S02(网络基础)。
覆盖旧文:4438(实战章节:在 Linux 上部署各类软件)→ 1 篇 / 62,275 字符(本系列最大单篇素材)。
扩展点:E-S15-021(部署四处翻车点:版本、权限、内存、时钟)、E-S15-022(集群前置五件事与快照策略)、E-S15-023(监控栈最小落地:Zabbix/Grafana 的分工)。
下一篇:S15-X02 · 环境配置与工具小记登记。
1. 一句话结论
部署失败几乎都落在四个点上:版本对不上、权限不对、内存不够、时钟不同步。 不是"命令记错"。先把这四项做成检查表,再谈装什么。
出处:
A-4438(部署实战章,含 MySQL 5.7/8.0、Tomcat、Nginx、RabbitMQ、Redis、ES、ZK/Kafka/Hadoop/HBase/Spark/Flink、Zabbix/Grafana)。
2. 部署四处翻车点(E-S15-021)
| 翻车点 | 典型表现 | 判据/处置 |
|---|---|---|
| 版本 | MySQL 8 默认 caching_sha2_password,老客户端连不上;JDK 17 跑 Tomcat 9 老版本报 UnsupportedClassVersionError |
先确认"客户端/驱动/JDK"三者版本矩阵,再装服务端 |
| 权限 | ES 不能以 root 启动(can not run elasticsearch as root);Nginx 监听 80 需 CAP_NET_BIND_SERVICE |
专用用户运行;端口 <1024 用 capabilities 或反代 |
| 内存 | ES 默认堆按物理内存推导,容器里会算错 → OOM Killer;Hadoop/Spark 争内存 | 显式 -Xms/-Xmx;容器内设 ES_JAVA_OPTS;给 JVM 设 MaxRAMPercentage |
| 时钟 | 集群节点时间漂移 → Kafka 消息过期、证书校验失败、日志时序错乱 | chrony/systemd-timesyncd 强制同步;虚拟化环境关掉宿主机的时间同步冲突 |
判据:"装完能启动"不等于"装对"——四件事各有一条自检命令(见 §6)。
3. 单机组件:六条安装要点(4438 的提炼)
| 组件 | 关键点 | 常见坑 |
|---|---|---|
| MySQL 5.7 / 8.0 | CentOS 用 yum 源装;Ubuntu/WSL 用 apt;8.0 首次启动生成随机 root 口令(/var/log/mysqld.log 或 mysqld --initialize 输出) |
密码策略(validate_password)导致设不了简单口令;只改 bind-address 忘了 skip-name-resolve 影响连接 |
| Tomcat | 先装 JDK,再解压到 /usr/local,setenv.sh 调堆 |
用 root 跑、CATALINA_HOME 与 CATALINA_BASE 混用 |
| Nginx | 官方源或编译;配置在 /etc/nginx/conf.d/ |
nginx -t 未过就 reload;日志不轮转撑爆磁盘 |
| RabbitMQ | 需 Erlang 版本匹配;rabbitmq-plugins enable rabbitmq_management 开控制台 |
默认 guest/guest 只允许 localhost;内存告警阈值低导致阻塞 |
| Redis | requirepass + bind 127.0.0.1 + protected-mode yes |
公网裸奔 Redis(最常见入侵入口) |
| Elasticsearch | 单节点须 discovery.type=single-node;vm.max_map_count ≥ 262144;bootstrap.memory_lock: true |
用 root 启动;未调 vm.max_map_count 报 max virtual memory areas |
通用顺序:依赖(JDK/Erlang) → 系统参数(ulimit/vm.max_map_count/文件句柄) → 用户与目录 → 安装 → 配置 → 启动 → 自检。跳步的顺序问题,后期排查代价是十倍。
4. 集群前置五件事与快照(E-S15-022)
① 主机名与 hosts 映射:每台设唯一 hostname,/etc/hosts 写全节点 IP↔名字
(Kafka/ZK/Hadoop 都以主机名做 broker/id 标识,改 IP 后必须同步改映射)
② SSH 免密:ssh-keygen → ssh-copy-id 到各节点 → 验证 ssh node2 hostname 不再要密码
③ JDK:统一版本与安装路径,写进 /etc/profile.d/jdk.sh
④ 防火墙与 SELinux:测试环境可关(systemctl disable --now firewalld;SELINUX=disabled),
生产环境改为放行端口(firewall-cmd --add-port),不要图省事关 SELinux
⑤ 内存与磁盘规划:按角色分配(master 小、worker 大),/data 独立挂载
⑥ 装完立刻打快照:集群装好但未灌数据时是"最干净的还原点"
判据:"能 ping 通"不等于"集群能组起来"——ZK/Kafka 依赖主机名解析一致性与时钟一致,两者任一不一致,集群会反复选主或脑裂。
SELinux 那一行的坑:改 /etc/selinux/config 时 disabled 拼错(如 disable)会导致系统起不来——4438 原文专门提醒过这一点,务必逐字符核对,改完先 getenforce 确认。
5. 集群组件共性(ZK / Kafka / Hadoop / HBase / Spark / Flink)
| 共性 | 说明 |
|---|---|
| 配置靠模板 + 分发 | 改一份 xxx-site.xml/server.properties,scp 到各节点;不要逐台手改 |
| id 必须唯一 | ZK 的 myid、Kafka 的 broker.id、DataNode 的目录唯一性 |
| 依赖前置 | Kafka 依赖 ZK(旧版本);HBase 依赖 HDFS+ZK;Spark/Flink 可独立但常与 YARN/K8s 共用 |
| 端口固定 | 2181(ZK)/9092(Kafka)/8020(HDFS)/16010(HBase)/8088(YARN),冲突时统一改并同步所有节点 |
| 验证顺序 | 单节点进程起 → 集群互认(zkServer.sh status 看 leader/follower) → 端到端(建 topic、生产/消费一条消息) |
判据:"集群版先跑通单节点"——单节点不过就上集群,问题会被放大成拓扑问题。
6. 自检命令(只读,安全)
# 版本矩阵
java -version; mysql --version; nginx -v; redis-server --version
# 权限与用户
ps -o user= -p $(pgrep -f elasticsearch | head -1)
# 内存
free -m; sysctl vm.max_map_count; cat /proc/$(pgrep -f java|head -1)/limits | grep -i 'max open files'
# 时钟
timedatectl | grep -E 'System clock|synchronized'; chronyc tracking 2>/dev/null | head -3
# 端口
ss -lntp | grep -E ':(2181|9092|9200|5672|6379|80|443)\b'
# 集群互认
zkServer.sh status; kafka-topics.sh --bootstrap-server node1:9092 --list
7. 监控栈最小落地(E-S15-023)
| 工具 | 分工 | 最小配置 |
|---|---|---|
| Zabbix | 主机/服务可用性、阈值告警(进程、端口、磁盘、自定义脚本) | Server + Agent,MySQL 存数据,Web 前端 |
| Grafana | 时序可视化与看板(常配 Prometheus/ES 数据源) | 一个数据源 + 一个看板模板 |
| 分工判据 | 要"出告警"用 Zabbix;要"看趋势"用 Grafana | 两者不互替 |
最小可用:node_exporter + Prometheus + Grafana 三件套(比 Zabbix 更轻),Zabbix 适合已有 Windows/网络设备混合环境。先有磁盘与内存告警,再谈业务指标。
8. 反例:八种"装完就出事"
| 做法 | 后果 |
|---|---|
| 用 root 跑 ES / 应用 | 一旦被利用即整机失守;ES 直接拒绝启动 |
| Redis 公网裸奔无密码 | 数小时内被写入挖矿/密钥 |
不调 vm.max_map_count |
ES 启动失败,报虚拟内存区域不足 |
| 容器内不设 JVM 堆 | 按宿主机内存推导,OOM Killer 杀进程 |
| 集群节点时间不同步 | 选主抖动、消息过期、证书校验失败 |
| 改 SELinux 拼错 | 系统无法启动 |
| 日志不轮转 | 磁盘写满,服务全挂(4389 就是为此写的脚本) |
| 装完不打快照 | 环境坏了只能从头再来 |
9. 自测
- 部署四处翻车点各举一个真实报错?
- 集群前置六件事?
- 为什么 ZK/Kafka 对"主机名解析"比"IP 连通"更敏感?
- ES 单节点必须加什么参数?两个系统级前提是什么?
- Zabbix 与 Grafana 的分工判据?
答案
- 版本(
UnsupportedClassVersionError)、权限(ES 拒绝 root)、内存(OOM Killer)、时钟(选主抖动)。 - 主机名与 hosts、SSH 免密、统一 JDK、防火墙/SELinux、内存磁盘规划、装完打快照。
- 配置里以主机名标识节点身份,IP 变化后映射不一致会导致节点互不认。
discovery.type=single-node;vm.max_map_count与内存锁定(bootstrap.memory_lock)。- 出告警用 Zabbix,看趋势用 Grafana,不互替。
10. 下一篇
S15-X02 · 环境配置与工具小记登记 —— docker 命令与目录挂载、扩展磁盘、vagrant/Kuboard、Portainer 与 Nginx 环境、nginx 日志自动清理、Linux 基础命令讲义与云服务器选购的处置。
本篇属于系列《S15 · Linux 与运维》。旧文来源:A-4438(实战章节:在 Linux 上部署各类软件,62,275 字符 / 76 点);扩展点 E-S15-021/022/023。组件版本矩阵与具体命令随发行版与版本变化,需按目标环境核对。