1. 这不是“装软件清单”,而是SpringCloud项目在Linux上真正跑起来的生存指南
你刚写完一个SpringCloud微服务项目,本地IDE里一切丝滑——Eureka注册中心正常心跳、Gateway路由转发精准、Feign调用毫秒级响应、Sentinel限流面板实时刷新。你信心满满地把jar包扔进测试服务器,敲下java -jar xxx.jar,结果控制台刷出一连串红色异常:Connection refused、UnknownHostException、No route to host……最后卡在Waiting for dependencies to be resolved...,再也没动静。这时候你才意识到:SpringCloud不是单体应用,它是一套协作生态,而Linux服务器不是空白画布,它是有脾气、有依赖、有权限、有时区、有防火墙的真实生产环境。所谓“需要安装的应用”,本质是构建一个能让微服务集群自主发现、可靠通信、稳定运行、可观测、可运维的最小基础设施闭环。我带过6个从零搭建的SpringCloud生产项目,踩过所有坑——比如某次上线前夜,就因为没配NTP时间同步,导致ZooKeeper节点间时钟偏移超30秒,整个集群脑裂;还有一次,因未安装unzip导致Config Server读取Git仓库里的yml文件失败,配置加载为空,服务全部降级。这些都不是代码问题,是环境基建的“隐形债务”。本文不罗列教科书式命令,而是按真实部署流程拆解:哪些应用必须装(为什么)、装到什么版本(依据是什么)、装在哪(路径规范)、怎么验证(不是看进程,是看服务行为)、以及那些看似无关却致命的细节(比如SELinux策略、ulimit限制、时区校准)。适合刚从开发转运维的工程师、独立部署项目的全栈开发者,以及被“环境不一致”折磨到失眠的测试同学。核心关键词贯穿始终:SpringCloud、Linux、服务器、安装、应用——每一个词都对应一个实操决策点,而不是模糊概念。
2. 环境基石:操作系统与基础工具链的硬性要求
2.1 Linux发行版选择:别迷信“最新”,要信“长期支持”
SpringCloud本身是Java应用,理论上能在任何JVM兼容的Linux上运行。但现实远比理论残酷。我见过最典型的翻车案例:某团队为追求“技术先进”,在CentOS 8上部署SpringCloud Gateway,结果因系统自带的glibc版本过低(2.28),导致Netty底层epoll调用异常,高并发下连接数暴涨后直接OOM。后来切到Ubuntu 22.04 LTS(glibc 2.35),问题消失。这不是偶然——SpringCloud依赖的Spring Boot 2.7+、Netty 4.1.90+、Reactor 3.4+等组件,对内核特性(如io_uring)、C库函数、SSL协议栈都有隐性要求。因此,必须选择主流LTS(Long Term Support)发行版:
推荐首选:Ubuntu 22.04 LTS 或 CentOS Stream 8/9
Ubuntu 22.04内核5.15,glibc 2.35,OpenSSL 3.0,完美兼容Spring Boot 3.x及配套生态;CentOS Stream作为RHEL上游,稳定性强,企业环境接受度高。两者均提供5年以上安全更新,避免部署半年后因系统漏洞被迫紧急升级。明确规避:CentOS 7(已EOL)、Debian 10(Buster)、任何滚动更新发行版(如Arch Linux)
CentOS 7已于2024年6月30日终止维护,其glibc 2.17无法支持Spring Boot 3.x的GraalVM native image;Debian 10的OpenSSL 1.1.1d存在已知TLS握手缺陷,影响Config Server从Git拉取加密配置;滚动发行版版本不可控,某次apt upgrade可能升级内核导致驱动不兼容,微服务进程莫名退出。
提示:不要用
cat /etc/os-release只看NAME字段。执行uname -r查内核版本,ldd --version查glibc,openssl version查SSL库——这三个数字决定你的SpringCloud能否“呼吸”。
2.2 Java环境:JDK版本不是越高越好,而是匹配Spring Boot生命周期
SpringCloud版本严格绑定Spring Boot版本,而Spring Boot又对JDK有硬性要求。常见错误是“装了JDK 21,以为很新很稳”,结果启动报错Unsupported class file major version 65。这是因为Spring Boot 3.1.x仅支持JDK 17-21,而Spring Boot 2.7.x最高只支持JDK 17。若你用的是尚硅谷SpringCloud教程(基于Hoxton.SR12,对应Spring Boot 2.3.x),则JDK 8u292或JDK 11.0.15是黄金组合——前者兼容性最广,后者性能更优且长期支持。
安装步骤必须包含验证环节:
# 下载JDK 11(以Adoptium Temurin为例) wget https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.21%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.21_9.tar.gz tar -xzf OpenJDK11U-jdk_x64_linux_hotspot_11.0.21_9.tar.gz -C /opt/java # 配置环境变量(写入/etc/profile.d/java.sh) echo 'export JAVA_HOME=/opt/java/jdk-11.0.21+9' > /etc/profile.d/java.sh echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile.d/java.sh source /etc/profile.d/java.sh # 关键验证:不仅看java -version,更要检查javac和jps java -version # 应输出 openjdk version "11.0.21" 2023-10-17 javac -version # 必须一致,否则编译型配置(如@Value注解)可能失败 jps -l # 能列出Java进程,证明JVM运行时环境完整注意:禁止使用
update-alternatives管理多JDK版本。SpringCloud各服务(Config、Gateway、Auth)可能需不同JDK,统一软链接易引发冲突。正确做法是每个服务启动脚本中显式指定JAVA_HOME,例如JAVA_HOME=/opt/java/jdk-11.0.21+9 java -jar gateway.jar。
2.3 基础工具链:那些被忽略却让部署卡壳的“小工具”
很多团队只关注“大件”(JDK、MySQL),却栽在基础工具上。以下是我在6个项目中必装的5个工具,每个都有血泪教训:
curl:不只是发HTTP请求。Config Server从Git拉取配置时,若
curl缺失或版本过低(<7.68),无法处理Git over HTTPS的SNI扩展,导致git clone超时。安装命令:apt install curl(Ubuntu)或dnf install curl(CentOS Stream)。unzip:SpringCloud Config Server默认从Git仓库拉取zip压缩包(尤其当配置仓库含中文路径时)。若服务器无
unzip,会静默失败,日志只显示Failed to load config。验证命令:unzip -v | head -1,版本应≥6.0。net-tools(ifconfig, netstat):排查端口占用时,
lsof -i :8080虽可用,但某些精简镜像禁用lsof。netstat -tuln | grep :8080是更通用的替代方案。安装:apt install net-tools。vim-enhanced:不是为了编辑美观。SpringCloud服务常需动态修改
application.yml中的spring.cloud.config.uri,若只有vi基础版,不支持语法高亮和行号,极易改错缩进导致YAML解析失败。安装:dnf install vim-enhanced。telnet:诊断服务连通性的终极武器。当Eureka Client注册失败,先
telnet eureka-server 8761——若不通,说明网络或防火墙问题;若通,再查Eureka Server日志。nc -zv eureka-server 8761虽功能类似,但telnet返回码更直观(0=成功,1=失败)。
实操心得:把这些工具写入部署脚本开头。我习惯在
deploy.sh第一行加set -e,然后批量检查:for cmd in java javac curl unzip netstat vim telnet; do if ! command -v $cmd &> /dev/null; then echo "ERROR: $cmd not found. Please install it."; exit 1 fi done
3. 核心中间件:SpringCloud生态运转的“心脏”与“血管”
3.1 注册中心:Eureka vs Nacos,选型背后是运维成本的博弈
SpringCloud默认注册中心是Eureka,但实际生产中,Nacos已成为事实标准。原因不是技术优劣,而是运维现实:Eureka Server自身无持久化,节点宕机即丢失注册信息;而Nacos内置MySQL存储,支持配置持久化、服务健康检查、权重路由,且控制台开箱即用。我曾负责一个金融项目,初期用Eureka,结果因网络抖动导致Eureka Server短暂不可用,所有Client缓存过期后集体失联,业务中断17分钟。切换Nacos后,即使Nacos Server挂掉,Client仍能从本地缓存读取服务列表,降级时间为0。
Nacos安装必须遵循官方生产建议:
- 数据库准备:Nacos 2.2+强制要求外置MySQL 5.7+。执行
/opt/nacos/conf/mysql-schema.sql建表,注意config_info表的content字段类型必须为longtext(非text),否则大配置(如网关路由规则)会截断。 - 端口规划:Nacos默认8848端口,但需额外开放7848(集群通信端口)和9848(gRPC端口)。若用云服务器,安全组必须放行这3个端口。
- 启动参数:禁止用
sh startup.sh -m standalone单机模式。生产必须集群,至少3节点(奇数防脑裂)。每节点配置cluster.conf:192.168.1.101:8848 192.168.1.102:8848 192.168.1.103:8848 - 验证要点:访问
http://nacos-server:8848/nacos,登录后检查“服务列表”是否为空(初始状态),再部署一个测试服务,确认其出现在列表中且健康状态为UP。关键指标:curl -X GET "http://localhost:8848/nacos/v1/ns/operator/metrics?dataId=metrics"返回JSON中serviceCount应≥1。
注意:Nacos客户端版本必须与Server严格匹配。Nacos Server 2.2.3要求Client 2.2.3,混用会导致
com.alibaba.nacos.api.exception.NacosException: failed to req API:/nacos/v1/ns/instance。版本对应表在Nacos官网GitHub Release页有明确标注。
3.2 配置中心:Config Server的“双刃剑”与Git仓库的硬约束
SpringCloud Config Server是把双刃剑:它解耦配置,但也引入单点故障。我见过最惨烈的事故——Config Server因Git仓库URL写错,启动时疯狂重试,耗尽服务器CPU,连SSH都登不上。因此,Config Server必须搭配Git仓库的强约束机制:
Git仓库规范:
- 仓库必须为私有(GitHub Private Repo / GitLab Private Project),禁止用public repo存敏感配置。
- 分支策略:
master分支存生产配置(application-prod.yml),develop分支存测试配置(application-dev.yml)。Config Server通过spring.cloud.config.label=develop指定分支。 - 文件命名:
{application}-{profile}.yml,如auth-service-prod.yml。严禁在application.yml中写spring.profiles.active=prod,这会导致所有服务读取同一份配置,失去Profile隔离意义。
Config Server高可用:
启动时添加--spring.cloud.config.server.git.refreshRate=30(单位秒),避免Git频繁轮询;配置spring.cloud.config.server.git.timeout=10000(10秒超时),防止Git慢响应拖垮服务。更重要的是,必须为Config Server配置健康检查端点:management: endpoint: health: show-details: always endpoints: web: exposure: include: health,info,prometheus这样Nacos或K8s能通过
/actuator/health判断其是否存活,自动剔除故障节点。本地Git缓存陷阱:
Config Server首次启动会克隆Git仓库到/tmp/config-repo-xxx。若服务器重启,/tmp被清空,下次启动需重新克隆,耗时且可能失败。解决方案:在启动脚本中指定缓存目录:java -Dspring.cloud.config.server.git.basedir=/opt/nacos/config-repo \ -jar config-server.jar
实操心得:在Config Server启动后,立即执行
curl http://localhost:8888/auth-service/prod/master。若返回{"name":"auth-service","profiles":["prod"],"label":"master","version":"xxx","state":null,"propertySources":[]},说明Git仓库可读;若返回{"timestamp":"2023-10-01T08:00:00.000+00:00","status":404,"error":"Not Found","message":"No profiles found"},则是application-prod.yml文件名或路径错误。
3.3 网关与熔断:Gateway和Sentinel的协同部署逻辑
SpringCloud Gateway是流量入口,Sentinel是安全阀,二者必须协同部署,而非孤立安装。
Gateway部署要点:
- 线程模型:Gateway基于WebFlux,使用Netty非阻塞IO。必须确保
server.tomcat.max-connections不生效(Tomcat被绕过),而应关注spring.cloud.gateway.httpclient.pool.max-idle-time=5000(连接池空闲时间)。 - 路由配置:
spring.cloud.gateway.routes必须用YAML格式,严禁在Java代码中硬编码路由。我曾见某项目将RouteLocator写成@Bean,导致配置热更新失效。正确方式是在application.yml中定义:spring: cloud: gateway: routes: - id: auth-service uri: lb://auth-service predicates: - Path=/api/auth/** filters: - StripPrefix=2 - SSL卸载:生产环境Gateway前必有Nginx或ALB。Gateway自身不处理HTTPS,
server.ssl.*配置无效。务必在Nginx配置中设置proxy_set_header X-Forwarded-Proto https;,否则Spring Security的isSecure()判断错误。
- 线程模型:Gateway基于WebFlux,使用Netty非阻塞IO。必须确保
Sentinel Dashboard安装:
Sentinel Dashboard是管理控制台,非必需但强烈推荐。下载sentinel-dashboard-1.8.6.jar后,启动命令必须指定参数:java -Dserver.port=8080 \ -Dcsp.sentinel.dashboard.server=localhost:8080 \ -Dproject.name=sentinel-dashboard \ -jar sentinel-dashboard-1.8.6.jar关键参数
-Dcsp.sentinel.dashboard.server定义Dashboard自身地址,用于Client上报心跳。验证方法:访问http://server-ip:8080,登录后查看“机器列表”,应显示sentinel-dashboard自身(若Client未接入,则为空)。Client接入规范:
每个微服务(如user-service)需添加spring-cloud-starter-alibaba-sentinel依赖,并在bootstrap.yml中配置:spring: cloud: sentinel: transport: dashboard: server-ip:8080 # Dashboard地址 port: 8719 # Client与Dashboard通信端口(默认8719) datasource: ds1: nacos: server-addr: nacos-server:8848 dataId: user-service-sentinel groupId: SENTINEL_GROUP rule-type: flow此配置实现:规则存储于Nacos,Dashboard从Nacos读取并推送至Client。避坑点:
port: 8719必须与Dashboard防火墙放行端口一致,且Client服务器需能telnet server-ip 8719。
4. 数据与存储:MySQL、Redis的生产级配置红线
4.1 MySQL:不只是安装,而是字符集与事务隔离的生死线
SpringCloud项目对MySQL的要求远超普通Web应用。Config Server的config_info表存YAML文本,若字符集不匹配,中文配置会变乱码;Auth Service的JWT Token存储需高并发读写,若事务隔离级别不当,会出现Token重复发放。
字符集强制规范:
MySQL 5.7+默认utf8mb4,但安装后必须验证:SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%';正确值应为:
character_set_server=utf8mb4,collation_server=utf8mb4_unicode_ci。若为latin1,在/etc/my.cnf中添加:[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci [client] default-character-set = utf8mb4重启MySQL后,必须为现有数据库执行:
ALTER DATABASE your_db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ALTER TABLE config_info CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;事务隔离级别:
SpringCloud Auth Service常用@Transactional管理Token发放。MySQL默认REPEATABLE READ,但在高并发下可能出现幻读。必须将隔离级别设为READ COMMITTED:SET GLOBAL tx_isolation='READ-COMMITTED';并在Spring Boot配置中显式声明:
spring: datasource: hikari: connection-init-sql: "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"连接池关键参数:
HikariCP是Spring Boot默认连接池,但默认配置不适合微服务:spring: datasource: hikari: maximum-pool-size: 20 # 单服务实例最大连接数,按CPU核数*4估算 minimum-idle: 5 # 最小空闲连接,避免冷启动延迟 connection-timeout: 30000 # 连接超时30秒,防止雪崩 validation-timeout: 3000 # 验证超时3秒,快速失败 idle-timeout: 600000 # 空闲连接最大存活600秒 max-lifetime: 1800000 # 连接最大生命周期30分钟,防长连接泄漏提示:
maximum-pool-size不是越大越好。我曾将此值设为100,结果MySQLmax_connections=151被耗尽,所有服务报Cannot get JDBC Connection。计算公式:总连接数 = 服务实例数 × maximum-pool-size < MySQL max_connections × 0.8。
4.2 Redis:作为分布式锁与缓存的“最后一道防线”
SpringCloud中Redis承担三重角色:Config Server的Git配置缓存、Gateway的限流令牌桶、Auth Service的JWT Token黑名单。因此,单机Redis绝对不可用于生产。
部署模式选择:
- 主从复制(Master-Slave):适用于中小规模,成本低。需配置
redis.conf:# 主节点 bind 0.0.0.0 requirepass your_password # 从节点 slaveof master-ip 6379 masterauth your_password - Redis Cluster:大规模场景必备。至少6节点(3主3从),自动分片。使用
redis-cli --cluster create创建,必须指定--cluster-replicas 1保证每个主节点有1个从节点。
- 主从复制(Master-Slave):适用于中小规模,成本低。需配置
关键配置项:
maxmemory 2gb:设置内存上限,避免OOM。策略选allkeys-lru(LRU淘汰)。timeout 0:客户端空闲超时设为0(永不超时),因微服务连接池会长期复用连接。tcp-keepalive 60:启用TCP保活,每60秒发心跳,防NAT超时断连。
Spring Boot集成验证:
在application.yml中配置:spring: redis: host: redis-cluster-ip port: 6379 password: your_password lettuce: pool: max-active: 20 max-idle: 10 min-idle: 5启动后,执行
redis-cli -h redis-ip -p 6379 -a your_password ping,返回PONG即成功。深度验证:在Auth Service中注入StringRedisTemplate,执行opsForValue().set("test", "ok"),再get("test"),确认值为ok。
注意:Redis密码必须用
-a参数传递,禁止在URL中明文写redis://:password@host:6379,否则密码会暴露在ps aux进程列表中。
5. 运维支撑:时间同步、防火墙、日志归集的隐形护城河
5.1 时间同步:NTP服务是分布式系统的“心跳起搏器”
微服务架构中,时间不同步是幽灵级故障源。Eureka Server与Client的心跳续约基于时间戳,若时钟偏差>30秒,Client会被踢出注册中心;Sentinel的滑动窗口统计若时间跳跃,会导致限流误判。某次线上事故,因一台服务器NTP未开启,时钟快了42秒,导致该节点上所有服务被Eureka标记为DOWN,流量全部切走。
NTP服务安装与校准:
Ubuntu 22.04默认启用systemd-timesyncd,但精度不足。必须切换为chrony:apt remove systemd-timesyncd apt install chrony systemctl enable chrony systemctl start chrony编辑
/etc/chrony/chrony.conf,添加国内可靠NTP源:pool ntp.aliyun.com iburst pool ntp1.aliyun.com iburst driftfile /var/lib/chrony/drift makestep 1 3makestep 1 3表示:若时钟偏差<1秒,平滑调整;若>1秒,在前3次同步时直接跳变。验证与监控:
执行chronyc tracking,关键字段:System clock offset:应<50msRoot dispersion:应<100msLeap status:应为Normal
定期执行timedatectl status,确认System clock synchronized: yes。
提示:云服务器厂商(如阿里云、腾讯云)提供内网NTP服务(如
ntp.tencent.com),优先使用,避免公网NTP丢包。
5.2 防火墙:iptables与firewalld的取舍与规则设计
Linux防火墙是微服务通信的守门员。错误配置会导致服务间调用失败,且难以定位。CentOS Stream默认firewalld,Ubuntu默认ufw,但生产环境必须统一为iptables——因其规则透明、调试简单、社区文档丰富。
iptables规则模板:
创建/root/firewall.sh:#!/bin/bash iptables -F iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # 允许本地回环 iptables -A INPUT -i lo -j ACCEPT # 允许已建立连接 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允许SSH(22端口) iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许Nacos集群通信(8848, 7848, 9848) iptables -A INPUT -p tcp --dport 8848 -j ACCEPT iptables -A INPUT -p tcp --dport 7848 -j ACCEPT iptables -A INPUT -p tcp --dport 9848 -j ACCEPT # 允许MySQL(3306)和Redis(6379)从内网访问 iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 6379 -s 192.168.1.0/24 -j ACCEPT # 保存规则 iptables-save > /etc/iptables/rules.v4执行
bash /root/firewall.sh,并设置开机加载:systemctl enable netfilter-persistent。调试技巧:
当服务调用失败,先执行iptables -L -n -v,查看对应端口的pkts(数据包数)是否增长。若为0,说明请求根本未到达防火墙;若pkts增长但服务无响应,说明防火墙放行,问题在服务自身。
5.3 日志归集:ELK不是“高级功能”,而是故障定位的刚需
SpringCloud服务分散部署,靠tail -f查日志是运维噩梦。必须建立集中日志系统。我坚持用Filebeat + Elasticsearch + Kibana(ELK)轻量栈,而非Logstash(资源消耗大)。
Filebeat部署:
每台服务器安装Filebeat,配置/etc/filebeat/filebeat.yml:filebeat.inputs: - type: log enabled: true paths: - /opt/springcloud/*/logs/*.log # 微服务日志路径 tags: ["springcloud"] output.elasticsearch: hosts: ["es-server:9200"] username: "elastic" password: "your_password"启动:
systemctl enable filebeat && systemctl start filebeat。Elasticsearch索引模板:
为避免日志字段类型混乱,创建模板:PUT _template/springcloud-template { "index_patterns": ["springcloud-*"], "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "properties": { "level": {"type": "keyword"}, "service": {"type": "keyword"}, "traceId": {"type": "keyword"}, "spanId": {"type": "keyword"} } } }Kibana可视化:
在Kibana中创建Index Patternspringcloud-*,然后用Discover查看日志。关键技巧:在搜索栏输入level: "ERROR" and service: "gateway",即可聚焦网关错误;用traceId: "abc123"可追踪一次完整请求链路。
实操心得:Filebeat必须配置
harvester_buffer_size: 16384(默认16KB),否则大日志行(如堆栈跟踪)会被截断。验证方法:在服务中抛出异常,检查Kibana是否显示完整stack trace。
6. 常见问题与排查技巧实录:从“启动失败”到“流量不均”的实战手册
6.1 启动阶段:90%的失败源于环境预检缺失
| 问题现象 | 根本原因 | 排查命令 | 解决方案 |
|---|---|---|---|
java -jar xxx.jar报Error: Could not find or load main class | JDK未正确配置,或jar包损坏 | echo $JAVA_HOME,file xxx.jar | 重新安装JDK,验证java -version;重新构建jar包,jar -tf xxx.jar | head -5检查结构 |
| 服务启动后立即退出,无日志 | systemd服务未配置Type=simple,或Restart=always缺失 | systemctl status service-name,journalctl -u service-name -n 50 | 编辑/etc/systemd/system/service-name.service,添加Type=simple和Restart=always |
Eureka Client注册失败,日志显示Cannot execute request on any known server | Eureka Server地址错误,或网络不通 | ping eureka-server,telnet eureka-server 8761 | 检查application.yml中eureka.client.service-url.defaultZone=http://eureka-server:8761/eureka/,确认DNS解析正确 |
Config Server启动报Could not clone repository | Git仓库URL不可达,或SSH密钥未配置 | git clone git@github.com:user/repo.git手动测试 | 若用SSH,将私钥放入~/.ssh/id_rsa,并chmod 600 ~/.ssh/id_rsa;若用HTTPS,检查spring.cloud.config.server.git.username/password |
注意:所有排查必须按“网络层→系统层→应用层”顺序。先
ping,再telnet,最后看日志。跳过网络检查直接改代码,90%是徒劳。
6.2 运行阶段:流量异常与性能瓶颈的定位链
Gateway路由失效:
现象:访问/api/user/info返回404,但/actuator/gateway/routes显示路由存在。
排查链:curl -X GET "http://gateway:8080/actuator/gateway/routes" \| jq '.[] \| select(.routeId=="user-service")'—— 确认路由ID匹配;curl -I http://gateway:8080/api/user/info—— 查看Location头是否重定向到lb://user-service;curl http://user-service:8080/actuator/health—— 确认下游服务健康;- 若上述均正常,检查
spring.cloud.gateway.discovery.locator.enabled=true是否开启,该配置使Gateway自动发现Nacos注册的服务。
Sentinel限流不生效:
现象:Dashboard配置了QPS=10,但压测时QPS达100仍无拦截。
排查链:curl http://sentinel-dashboard:8080/v1/monitor/pull—— 确认Dashboard能拉取Client规则;curl http://client-service:8080/actuator/sentinel—— 查看rules字段是否包含刚配置的流控规则;- 检查Client依赖是否为
spring-cloud-starter-alibaba-sentinel(非sentinel-core),后者无自动配置。
Nacos服务列表为空:
现象:Client启动日志显示registering service...,但Nacos控制台无服务。
排查链:curl -X POST "http://nacos-server:8848/nacos/v1/ns/instance?serviceName=user-service&ip=192.168.1.101&port=8080"—— 手动注册,若失败则Nacos Server异常;netstat -tuln \| grep :8848—— 确认Nacos监听0.0.0.0:8848,非127.0.0.1:8848;iptables -L -n \| grep 8848—— 确认防火墙放行。
6.3 高级问题:跨服务调用超时与线程池耗尽的根因分析
Feign调用超时:
默认ReadTimeout=60秒,但微服务间调用应≤3秒。在application.yml中精确配置:feign: client: config: default: connectTimeout: 3000 readTimeout: 3000 hystrix: enabled: false # Spring Cloud 2020+默认禁用Hystrix,用Resilience4j线程池耗尽:
现象:服务CPU 100%,jstack pid \| grep "java.lang.Thread.State: RUNNABLE" \| wc -l显示线程数接近maxThreads。
根因:Blocking IO操作(如JDBC查询)阻塞Tomcat线程。解决方案:- 将数据库操作改为异步:`Comple