news 2026/9/29 15:34:32

Kubernetes持久化存储实战:NFS+PV/PVC搭建与Pod挂载全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes持久化存储实战:NFS+PV/PVC搭建与Pod挂载全攻略

做Kubernetes的人迟早要面对一个灵魂拷问:Pod是出了名的“短命鬼”,它一死里面的数据也跟着没了,这谁受得了?所以持久化存储成了绕不过去的一道坎。在众多存储方案里,NFS+PV/PVC这套组合拳在国内中小团队里出镜率极高——上手快、成本低、够用。这篇博文我打算把从零搭建NFS服务端,到在K8s里创建PV/PVC,再到Pod成功挂载使用的完整链路掰开揉碎讲一遍。不管你是刚接触K8s的新手,还是已经在生产环境里折腾过一阵子的老手,这篇文章里都有你能直接拿去用的东西。

1. 这套方案到底解决什么问题

1.1 先搞明白Pod为什么会丢数据

先问一个问题:为什么K8s里跑应用非得配存储?因为Pod的设计理念就是“用完即弃”。Deployment滚动更新时旧Pod被销毁,节点宕机时Pod被重新调度到别的机器,HPA缩容时多余的副本直接杀掉——在这些场景里,容器文件系统里的数据会跟着容器一起消失。这不是bug,是特性。

有人可能会说:“那我用Docker的volume不就行了?”行,但Docker的volume默认绑定在宿主机本地目录。容器被调度到另一台节点之后,新节点上根本没有那个本地目录,数据照样丢。所以跨节点共享才是K8s环境里真正需要解决的存储问题。NFS天生就是干这个的——它把文件系统通过网络共享出去,任何节点只要装了客户端都能挂载同一块远程目录,数据天然就跨节点了。

1.2 为什么偏偏是NFS+PV/PVC这套组合

K8s里能用的存储方案不少,有本地卷、hostPath、云厂商的云盘、Ceph、GlusterFS等等。但NFS在中小团队里始终有一席之地,原因就三个字:太省事。

云盘虽然稳定,但它是云厂商绑定的,换机房、换云就傻眼,而且一台云盘默认只能挂载到一个节点上,做不了多读多写。Ceph功能强大,但部署一套Ceph集群本身就是个大工程,运维成本直接拉满。hostPath最便宜,但数据绑定宿主机,Pod一旦漂移就找不回来数据。相比之下,NFS只需要一台机器(虚拟机也行)把目录导出,所有K8s节点都挂得上去,支持ReadWriteMany多节点同时读写,性能和稳定性对绝大多数业务来说完全够用。

PV/PVC则是K8s里对存储的一层抽象。有了这层抽象,应用开发者不需要知道存储到底是从NFS来的还是从云盘来的,只需声明“我要10G空间、支持多节点读写”,剩下的匹配工作由K8s完成。这种解耦很适合团队协作:运维管存储资源,开发管应用声明。

1.3 PV和PVC的关系:别把它想复杂了

不少人刚开始学PV/PVC时容易绕晕,我建议用一个生活化的类比来理解:把PV当作仓库里的“库存商品”,PVC当作“采购申请单”。

管理员(运维)先往仓库里入库一批商品,也就是创建PV,每件商品都标好了规格:容量多大、支持几人同时用(访问模式)、属于哪个货架分类(storageClassName)。应用开发者(或者K8s里的工作负载)不需要关心仓库里有什么,只需要提交一份采购申请——创建PVC,写明“我要什么规格的货、需要多少容量”。K8s的调度器会在后台帮你自动匹配一张符合条件的PV,把PVC和PV绑定在一起。绑定成功后,Pod就可以通过PVC直接使用这块存储了。

记住这个思路,后面所有YAML配置都不会把你绕晕。

2. 环境准备与NFS服务端搭建

2.1 实验环境一览

动手之前先把环境说清楚。我这套实验环境是三台Ubuntu 24.04的机器:一台单独做NFS服务端,另外两台是K8s集群的节点。你完全可以用一台机器同时跑NFS服务和单节点K8s练手,不影响理解原理。下面是我用的环境参考:

角色主机名IP地址系统版本软件
NFS服务端nfs-server192.168.1.100Ubuntu 24.04nfs-kernel-server
K8s节点1k8s-node1192.168.1.101Ubuntu 24.04kubeadm集群 + nfs-common
K8s节点2k8s-node2192.168.1.102Ubuntu 24.04kubeadm集群 + nfs-common

需要强调的是,K8s集群里的每个节点(包括master节点,如果master也可能会调度Pod)都必须安装nfs-common客户端包。光装了NFS服务端、节点缺客户端的话,kubelet在挂载时会直接报错,后面排错的时候会非常痛苦。

2.2 Ubuntu 24.04上搭建NFS服务端

Ubuntu 24.04安装NFS服务端非常简单,三条命令的事:

# 更新软件源 sudo apt update # 安装NFS服务端 sudo apt install -y nfs-kernel-server # 创建要共享的目录 sudo mkdir -p /srv/nfs/k8s # 给目录设置权限,避免后续权限问题 sudo chown nobody:nogroup /srv/nfs/k8s sudo chmod 777 /srv/nfs/k8s

这里把共享目录的属主设为nobody:nogroup、权限设为777,是为了避免后面一堆权限报错。注意这不是什么好习惯,生产环境应该按具体的用户和需求收紧权限,但对于学习环境、前期验证环境,这样的配置能让你躲过最常见的那几个坑。

创建好目录之后,还需要把目录“导出”给客户端。这一步通过修改/etc/exports文件来实现:

sudo vim /etc/exports

在文件末尾追加一行:

/srv/nfs/k8s *(rw,sync,no_subtree_check,no_root_squash)

然后生效配置并确认导出状态:

sudo exportfs -ra sudo exportfs -v

如果看到类似/srv/nfs/k8s <world>的输出,说明导出成功。这里值得一提:Ubuntu 24.04默认的NFS版本是4.x,exportfs -v的输出里能看到NFSv4相关的导出信息,旧版本NFSv3也保持兼容,这对K8s的挂载来说通常不是问题。

2.3 exports配置文件里的门道

/etc/exports里那一行配置不算长,但每个参数都有讲究。我第一次配的时候随手抄了个模板没细想,后面被坑得不轻。这里拆开讲一下:

  • *(rw,sync,no_subtree_check,no_root_squash)里的*表示允许所有网段的客户端访问。生产环境建议改成具体的网段或IP,比如192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash),这样更安全,也能避免外部机器随意挂载。
  • rw表示客户端可读写。如果只配了ro,那K8s的Pod挂载后只能读不能写,很多应用会直接启动失败。
  • sync表示服务端在响应写请求之前,先把数据刷到磁盘上。对应的还有async,性能好但断电丢数据的风险高。数据库这类场景必须用sync,日志这类对丢一点数据不计较的场景可以用async换性能。
  • no_subtree_check主要是减少一些目录权限检查带来的性能开销。对于共享目录嵌套层级较深的场景,建议加上这个参数。
  • no_root_squash是K8s场景下最关键的参数。默认情况下NFS会把客户端的root用户压缩成nobody用户(root_squash),而很多容器的内部进程恰恰是以root身份运行的。如果你不开no_root_squash,容器里往挂载目录写文件时会被强制降权,结果就是各种Permission denied。开了它,root的权限在NFS服务端也能生效,保证容器能正常读写。

2.4 客户端连接前的最后检查

服务端配置完之后,K8s节点的客户端工具要装好。每台节点都执行:

sudo apt update sudo apt install -y nfs-common

然后用手动挂载的方式验证连通性:

# 在K8s节点上执行 sudo mkdir -p /mnt/test-nfs sudo mount -t nfs 192.168.1.100:/srv/nfs/k8s /mnt/test-nfs # 在挂载目录里写个测试文件 echo "nfs ok" | sudo tee /mnt/test-nfs/test.txt # 回到服务端看文件是否出现 ls -l /srv/nfs/k8s/test.txt

如果服务端能看到test.txt,说明网络、NFS服务、权限都没问题。测完记得卸载:

sudo umount /mnt/test-nfs

这一步特别值得做。很多PVC挂载失败的问题,其实在K8s介入之前就已经暴露了——但如果你没有提前手动验证,后面的报错信息会把你带到沟里去。

还有一个小坑:Ubuntu 24.04以及很多现代发行版默认开启了防火墙。如果K8s节点挂载NFS时一直hang住,先检查服务端的防火墙是否放行了NFS相关端口。传统NFS v3需要开放portmapper(111)和mountd等端口,NFSv4通常只需要2049端口。我测试环境为了方便直接让NFS服务走内网,没开防火墙,但生产环境务必把端口开对。

# 在NFS服务端上检查防火墙状态 sudo ufw status # 如果开启了,放行2049端口(NFSv4)和111端口(portmapper) sudo ufw allow 2049/tcp sudo ufw allow 111/tcp

3. PV/PVC核心机制解析

3.1 PV的完整生命周期

PV在K8s里是一个集群级别的资源,它独立于任何命名空间而存在。它的一生大致经历四个阶段:Provision(供给)、Bind(绑定)、Reclaim(回收)。

供给有两种方式:静态供给和动态供给。静态供给就是管理员手工创建一批PV,提前准备好容量,等着PVC来领;动态供给则是通过StorageClass和对应的Provisioner插件,在PVC创建的那一刻自动生成PV,不需要管理员操心。资源创建出来之后,PV会处于Available状态,等待被PVC匹配绑定。

绑定是PVC和PV之间的“牵手”动作。当一个PVC被创建后,K8s会扫描集群里所有符合条件的PV,要求是:容量满足、访问模式匹配、storageClassName对得上。绑定成功后PV的状态从Available变成Bound,PVC的spec.volumeName字段会写下对应的PV名称,这个PVC从此就只能使用这一块PV。

回收策略解决的是“PVC删了之后,PV该怎么办”的问题。主要有三种:Retain(保留)、Delete(删除)、Recycle(回收清理后重用,现已废弃)。Retain的意思是PVC删除后PV里面的数据原封不动保留,管理员手动决定是清理还是复用;Delete则是PVC删除后PV连同数据一起删除,常见于云盘这类动态存储的默认行为。对于NFS这种自建存储,我个人强烈建议用Retain,安全,好控制。

3.2 访问模式:别再死记硬背了

K8s里访问模式是存储卷设计里最容易搞混的概念之一。其实就三种常见模式:

访问模式缩写含义适用场景
ReadWriteOnceRWO单节点读写块存储、云盘,比如MySQL单实例
ReadOnlyManyROX多节点只读配置分享、公共文件读取
ReadWriteManyRWX多节点读写共享文件存储,NFS最擅长的场景

NFS天然支持RWX,这是它比云盘强的地方。很多有状态应用(比如多个副本的Web应用、文件上传服务)要求所有副本同时读写同一份数据,用NFS就没问题,用云盘反而做不来。

实际写YAML时要注意,PV里声明的访问模式是它真正支持的能力,PVC里声明的访问模式是应用想用的方式,两者不一定完全相等,但PVC要求的模式必须被PV支持。比如PV声明了RWX和RWO,PVC声明RWO,那这个PVC可以绑定这个PV。如果PVC声明了RWO而PV只声明了RWX,在某些K8s版本里可能会匹配失败,稳妥的写法是PV和PVC保持一致或者PV覆盖更全。

3.3 storageClassName:PV和PVC的“配对暗号”

理解了容量和访问模式之后,storageClassName就是第三个约束条件。它相当于给存储资源分类的标签。比如你的集群里同时有NFS存储和Ceph存储,运维把NFS那批PV标成nfs-storage,把Ceph那批PV标成ceph-storage。应用想用NFS就在PVC里指定storageClassName: nfs-storage,K8s只会去匹配这个类下面的PV,Ceph那批资源再充裕也不理会。

这里有个新手常踩的大坑:如果PVC里不写storageClassName,能不能匹配成功取决于集群是否有默认StorageClass。很多通过云平台或kubeadm搭建的集群默认装了一个云盘类的StorageClass,PVC如果没有显式指定类名,就会走默认的动态供给,跑到云盘上去了,而不是你预期的NFS。反过来,如果你显式指定了storageClassName: "",表示“我不需要StorageClass,只匹配静态PV”,那也不是走动态供给。

所以正确做法是:PV和PVC都显式写上同一个storageClassName。你可以在PV里写storageClassName: nfs,PVC里也写storageClassName: nfs,这样逻辑清晰,后期排错也省心。

3.4 静态供给和动态供给怎么选

静态供给适合存储需求相对稳定、规模不大的场景。运维提前建好几个PV,容量固定,应用按需申领,简单可控。缺点是如果PV容量没规划好,小容量不够、大容量浪费,扩展还要人工介入。

动态供给适合存储需求变化频繁、PV数量多的场景。它的原理是部署一个NFS Provisioner(比如社区常用的nfs-subdir-external-provisioner),它会监听PVC的创建事件,然后自动在NFS服务端建对应子目录、创建PV并完成绑定。应用只需要创建PVC,剩下的全自动化。

如果你刚开始学,建议先把静态供给练熟,把PV/PVC的底层逻辑吃透再上动态供给。动态供给虽然方便,但它引入的自动化也意味着出问题时定位更难——你得去查Provisioner的日志,而不是只看PV/PVC的状态。

4. 从YAML书写到Pod挂载的完整实操

4.1 创建PV:一步步写YAML

进入实操环节。我先创建PV,所有YAML我建议都保存成文件,方便后续维护。先创建nfs-pv.yaml:

apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv labels: type: nfs spec: capacity: storage: 10Gi volumeMode: Filesystem accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: nfs nfs: path: /srv/nfs/k8s server: 192.168.1.100

逐字段解释一下:capacity.storage声明了PV的容量为10Gi,这只是一个“可用容量”的声明,K8s并不会去NFS服务端校验这个目录到底有多大,PVC申请容量时以此为判断依据。volumeMode用默认的Filesystem即可,如果写成Block那就是裸设备模式,对NFS场景不适用。accessModes这里用ReadWriteMany,这是NFS的核心优势。persistentVolumeReclaimPolicy用Retain,PVC删除后数据保留,宁可自己手动清理也不能让数据丢。storageClassName填nfs,这是我自己定义的名字,PV和PVC对得上就行。

nfs这一段是核心。server是NFS服务端IP,path是服务端导出的共享目录,这两个必须和/etc/exports里的一致。如果写错路径,挂载的时候会报错或者挂上一个空目录。

应用配置:

kubectl apply -f nfs-pv.yaml kubectl get pv

输出中会看到一个名为nfs-pv、状态为Available的PV,说明它正在等待被PVC认领。

4.2 创建PVC并观察绑定行为

然后创建PVC—nfs-pvc.yaml:

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: nfs

这里是应用开发者写得最多的一段配置。namespace: default表示这个PVC只存在于default命名空间。accessModes和storageClassName必须和PV匹配。resources.requests.storage申请10Gi,要求和PV容量一致或小于等于PV容量都行。

执行:

kubectl apply -f nfs-pvc.yaml kubectl get pvc kubectl get pv

正常情况下PVC的状态会从Pending变成Bound,对应的PV状态也会从Available变成Bound。注意观察两个信息:PVC的VOLUME列会显示绑定的PV名字;PV的CLAIM列会显示被哪个命名空间下的PVC占用了。这说明K8s已经完成了匹配和绑定。

如果PVC一直卡在Pending,别慌,先检查是不是storageClassName写错了、容量是否超过了PV、访问模式是否匹配,后面第5章我会专门讲排错。

4.3 让Pod用上PVC

PV和PVC绑定之后,存储还只是“资源”,必须挂到Pod里才能真正派上用场。创建测试Pod—nfs-test-pod.yaml:

apiVersion: v1 kind: Pod metadata: name: nfs-test-pod spec: containers: - name: nginx image: nginx:alpine ports: - containerPort: 80 volumeMounts: - name: nfs-storage mountPath: /usr/share/nginx/html volumes: - name: nfs-storage persistentVolumeClaim: claimName: nfs-pvc

这里有两个关键字段。volumeMounts声明容器内部哪个目录挂载存储,把NFS共享目录挂载到nginx默认的站点根目录/usr/share/nginx/html,这样写入这个目录的文件就能通过nginx直接访问。volumes定义Pod级别的卷,它引用了前面创建的PVCnfs-pvc。

执行:

kubectl apply -f nfs-test-pod.yaml kubectl get pod nfs-test-pod -o wide

等Pod变成Running状态后,就可以验证挂载是否生效了。

4.4 数据持久化验证:删掉Pod也不怕

挂载是否生效、数据是否持久化,必须用实际测试来验证,不能只看状态。我在Pod里写一个测试文件,然后删掉Pod重建,看看文件还在不在。

# 进入Pod内部,写一个测试文件 kubectl exec -it nfs-test-pod -- /bin/sh echo "hello nfs persistent" > /usr/share/nginx/html/index.html exit # 在K8s节点上直接查看NFS里的文件 cat /srv/nfs/k8s/index.html

上面这一步如果执行成功,说明Pod写入的数据已经落到了NFS服务端。接下来故意销毁这个Pod,再创建一个新Pod使用同一个PVC,验证数据是否还在:

kubectl delete pod nfs-test-pod kubectl apply -f nfs-test-pod.yaml # 等待Pod Running后,再查看文件内容 kubectl exec -it nfs-test-pod -- cat /usr/share/nginx/html/index.html

如果还是输出hello nfs persistent,那恭喜你,整个NFS+PV/PVC链路已经跑通了。这时候你才真正理解“持久化”的含义:Pod可以死无数次,数据只要放在NFS上,就永不消失。

这里有一个细节:由于NFS是网络存储,挂载到Pod里的目录本质上就是服务端目录的映射。你可以直接在NFS服务端创建文件,Pod里立刻就能看到,不需要任何额外操作。这就是网络文件系统最直观的好处。

5. 踩坑记录与排错实战

5.1 最常见的坑:PVC一直Pending

PVC卡在Pending是出现频率最高的报错,基本每个刚上手的人都会撞一次。可能的原因很多,我按排查顺序列一个速查表:

可能原因排查方法解决办法
storageClassName不匹配kubectl get pv -o yaml看PV的storageClassName,和PVC对比统一改成同一个类名
容量不够kubectl get pvc -o yaml看status里的conditions信息扩大PV容量或缩小PVC申请
访问模式不匹配检查PV和PVC的accessModes是否一致统一改成ReadWriteMany
PV已被别的PVC绑定kubectl get pv看PV状态是否Bound新建更多PV或复用已有PV
集群没有匹配的StorageClass检查集群是否存在动态供给或静态PV明确storageClassName并创建对应PV

排查的最快方式是看事件信息:

kubectl describe pvc nfs-pvc

Events字段的末尾通常会直接告诉你卡住的原因,比如waiting for a volume to be created, either by external provisioner or manually created。这句只是说“还没匹配到”,具体原因还要结合PV列表来判断。

5.2 权限问题:Permission denied的真相

Pod能启动,但往里写文件时报Permission denied,这也是高频问题。常见的根因是NFS的root_squash没关闭,容器里的root权限被服务端降级成nobody。此时最简单有效的解决方案是在/etc/exports里加上no_root_squash,然后重新导出:

sudo exportfs -ra

如果已经加了no_root_squash还报权限问题,那就要检查共享目录本身的属主和权限。我之前遇到过一种情况:服务端共享目录是root所有,权限是755,容器内进程以非root用户运行,写文件时没有写权限。解决办法是把目录属主改为容器运行用户的UID,或者放宽目录权限:

sudo chown nobody:nogroup /srv/nfs/k8s sudo chmod 777 /srv/nfs/k8s

用777本身安全性不高,但在内网环境里快速验证链路是没问题的。生产环境建议用更细粒度的权限控制,比如给容器指定fsGroup,让K8s自动调整挂载目录属组。

5.3 挂载hang住与超时排查

Pod一直处于ContainerCreating,kubectl describe pod里看到类似FailedMount的信息,说挂载超时或者无法连接。这种问题的典型原因是网络不通或者NFS服务没起来。

排查顺序是:

  1. 先在节点上手动执行mount -t nfs 192.168.1.100:/srv/nfs/k8s /mnt/test,如果直接hang住,说明节点到服务端的网络或NFS服务有问题。
  2. 检查服务端的systemctl status nfs-kernel-server是否正常,不正常就重启并查看日志。
  3. 检查防火墙端口是否开放,特别是NFSv4的2049端口和portmapper的111端口。
  4. 确认/etc/exports里的共享路径是否写错。如果路径写错,挂载时会报No such file or directory。

NFS挂载超时还有个容易被忽略的原因:客户端和服务端NFS版本不一致。如果你在节点上手动指定了NFSv3挂载成功,但K8s默认走NFSv4却失败,就要检查服务端是否启用了NFSv4支持。Ubuntu 24.04的nfs-kernel-server默认同时支持v3和v4,一般不会出问题,但老版本系统要注意。

5.4 性能调优经验谈

NFS用起来方便,但性能确实不如本地盘,这是物理限制。在实践中尽可能从配置和业务层面优化:

  • 优先用async还是sync?数据安全优先就用sync,性能优先且能容忍少量数据丢失才用async。MySQL这类数据库永远别上async。
  • 网络层面,NFS走千兆网和走万兆网体验天差地别。如果业务对I/O有要求,至少让K8s节点和NFS服务端跑在同一二层网络,降低延迟。
  • 调整客户端的挂载参数。在PV的nfs字段里可以加一些选项吗?实际上PV的NFS配置里没有直接暴露mount options的字段,想要调优需要借助StorageClass的mountOptions,动态供给场景下可以用:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-sc provisioner: nfs-subdir-external-provisioner parameters: archiveOnDelete: "true" mountOptions: - hard - nfsvers=4 - rsize=1048576 - wsize=1048576

hard表示NFS请求失败时会持续重试,适合在对数据一致性要求高的场景下使用,防止进程傻等;rsize和wsize调大可以提升大数据块传输效率。不过这些参数对不同内核版本、不同业务模型响应都不一样,建议先在测试环境验证再推生产。

  • 如果你发现NFS在高并发下性能明显下降,可以考虑把共享目录拆成多个子目录、创建多个PV分摊负载,别让所有Pod挤在同一个目录里抢锁。毕竟NFS的锁机制在多写多读场景下是有额外开销的。

我自己在实际项目里的体会有几点。第一,静态供给在中小团队里足够用,别一上来就上动态供给,复杂度完全没必要。第二,权限问题一定要在服务端阶段就处理干净,等到Pod起来再排查Permission denied,排查链路长、浪费的时间也多。第三,生产环境的persistentVolumeReclaimPolicy务必用Retain,哪怕麻烦点手动清理数据,也比PVC误删连带PV里的数据一起消失要强得多。

最后再分享一个小技巧:你可以把NFS服务端的共享目录统一放在一个根路径下,比如/srv/nfs下面按应用建子目录,然后为每个子目录创建独立的PV。这样不同应用的数据互相隔离,后面要备份、迁移、清理都方便。K8s的存储设计本身就是“数据和应用生命周期分离”,这个理念在NFS+PV/PVC的组合里体现得最直接,也最容易让新人理解到底什么才是真正的持久化。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 15:32:58

云服务器从购买到Nginx部署:新手完整实操指南

印象里我第一次买云服务器&#xff0c;在购买页面上来回纠结了快两个小时&#xff0c;生怕点错一个选项就多扣一笔钱。买完之后又陷入下一个问题&#xff1a;怎么连上去&#xff1f;连上去之后装nginx&#xff0c;光一个安装包就折腾了一晚上&#xff0c;搜索引擎开了十几个标签…

作者头像 李华
网站建设 2026/9/29 15:32:43

Redis安全攻防:从未授权访问到主从复制RCE的实战与加固

Redis 又上热搜了。每次有人在安全群里喊"Redis被批量打穿"的时候&#xff0c;评论区总会出现同一个问题&#xff1a;"我就是装了Redis&#xff0c;怎么判断自己中没中招&#xff1f;"说实话&#xff0c;这个问题挺难回答&#xff0c;因为很多人连自己的Re…

作者头像 李华
网站建设 2026/9/29 15:32:13

Spring Boot连接MySQL完整指南:从配置到增删改查实战

Spring Boot 可以说是目前做个人项目、课程设计和中小型业务系统时最常用的 Java 框架&#xff0c;而 MySQL 又几乎成了本地开发的默认数据库。两件事单拎出来都不难&#xff0c;但放到一起&#xff0c;版本、驱动、连接池、字符集、SSL 认证这些环节就像接力赛一样一环扣一环&…

作者头像 李华
网站建设 2026/9/29 15:31:38

AI Overviews冲击内容站:诊断方法、应对策略与实战数据

先说结论&#xff1a;AI Overviews 这个功能从2024年谷歌开始小范围测试&#xff0c;到2025年大规模铺开&#xff0c; 对大量内容站的冲击是实打实的&#xff0c;不是错觉。 如果你的网站内容最近出现“搜索排名还在&#xff0c;但点击量断崖式下跌”的情况&#xff0c;大概率…

作者头像 李华
网站建设 2026/9/29 15:27:36

一篇文章搞懂内存清理:IDEA内存显示与优化释放、自动清理实践

从开始写技术文章到现在&#xff0c;我一直觉得“内存清理”是这个时代最被误解的电脑操作。不少朋友看到任务管理器里内存占用到了 90%&#xff0c;第一反应就是赶紧找个内存清理工具点一下“立即清理”&#xff0c;看着数字掉下来就安心了。可实际上&#xff0c;内存清理工具…

作者头像 李华