现象:1C1G(Ubuntu 22.04)上装了 xfce + TigerVNC,连上去鼠标延迟接近一秒,拖窗口有残影,free -m 可用内存从 512MB 掉到 140MB。卸载之后 240MB 还给业务,卡顿消失。
这篇把这条路上的三个问题拆开:卡在哪一层、参数能救多少、什么时候该彻底换思路。数据是这台机器实测的,硬件不同数字会变,量级和结论成立。
1. 先分层,再动手
VNC 的「卡」是三种现象混在一起,对应三个不同的原因,混着优化只会白折腾。
| 现象 | 验证方法 | 根因 |
|---|---|---|
| 大面积刷新糊成马赛克、滚动拖影 | vnstat -l 或 iftop -n 看突发带宽 | 像素变化量超过上行带宽 |
| 点菜单等半秒、窗口拖动「钝」 | top 看 Xorg / xfwm 的 CPU 占用 | 服务器 CPU 软件渲染桌面帧 |
| 越用越卡、SSH 也变迟钝 | free -m 看 available;vmstat 1 看 si/so | 桌面 + VNC 常驻挤压业务进 swap |
我这台三层全占。下面逐层处理。
1.1 先把「卡」量化,别凭感觉
优化前后各测一次,才知道改的到底是哪一层。方法很简单:在 VNC 会话里的终端跑一个持续输出时间戳的命令,用画面里的时间和本地时间对比:
while true; do echo -ne "\r$(date +%H:%M:%S.%3N)"; sleep 0.1; done
画面里的毫秒数和手机(或本地终端)时间之差,约等于端到端延迟——渲染 + 编码 + 传输 + 解码的总和。我这台实测:
| 配置 | 端到端延迟 | 主观感受 |
|---|---|---|
| 1080p / 24 位 / Raw | 800-1000ms | 点一下等一秒,鼠标像有惯性 |
| 768p / 16 位 / Tight | 180-250ms | 能用,但拖窗口仍能看出残影 |
| 同机 SSH 终端(对照) | < 50ms | 无感 |
这个对照很关键:同一个网络、同一台机器,SSH 是 50ms 而 VNC 是 900ms,差的不是网速,是「渲染 + 传像素」这两步。有了这个数字,后面任何优化是否有效,一次测量就能判断,不用靠「好像快了点」。
2. 带宽层:参数能救一半
VNC 传的是「像素变化量」,不是画面。1080p 桌面滚动一下就是几 MB 的突发,家庭宽带上行 30Mbps 看着够,突发顶不住就糊。
TigerVNC 的参数:
vncserver :1 -geometry 1366x768 -depth 16 -LocalHost yes
| 参数 | 作用 | 代价 |
|---|---|---|
-geometry 1366x768 | 像素量降到 1080p 的 45% | 屏幕变小,双栏 IDE 挤 |
-depth 16 | 数据量再降约三分之一 | 代码高亮颜色发脏 |
| 编码 Tight / ZRLE | 比 Raw 省 80%+ 带宽 | 连续大面积刷新仍吃力 |
实测:滚动拖影明显减轻,菜单弹出延迟从约 500ms 降到 200ms 上下。画质代价是实打实的——16 位色深下 IDE 的高亮颜色是脏的,长时间看眼睛累。所以我的顺序是:先降分辨率,再换编码,色深最后动。
3. 渲染层与内存层:参数救不了
这两层没有可调参数,只有取舍。
| 组件 | 常驻内存(RSS 合计) |
|---|---|
| xfce + xfwm + panel | 约 180MB |
| TigerVNC server | 约 60MB |
| 合计 | 约 240MB |
| GNOME(对照) | 600MB+ |
渲染层的道理更硬:桌面每一帧都是服务器 CPU 算出来的,没有 GPU 加速,1C1G 渲染 1080p 桌面,点菜单延迟半秒是物理结果。软件渲染这件事,参数、编码、协议都改变不了。
结论一句话:1C1G 上装桌面环境,等于把业务的一半内存和一部分 CPU 永久借给一个「偶尔看一眼」的功能。2G 以下机器,我不建议装任何桌面环境。
4. 换思路:渲染位置决定体验上限
卡顿的根因想通之后就一句话:渲染在服务器,传输的是像素。 服务器既要跑业务又要兼职渲染工厂,两头受气。
反过来——渲染放在你自己的电脑上,服务器只传指令和数据——这条路有四条分支,本质区别只有「谁渲染、服务器多装什么」:
| 做法 | 服务器侧开销 | 流畅度 | 适合 |
|---|---|---|---|
| 优化后的 VNC | 240MB 级常驻 | 中 | 偶尔看、需要真桌面会话 |
| xrdp | 桌面 + xrdp 常驻 | 中高 | 习惯 mstsc 的 Windows 用户 |
| SSH + tmux | ≈0 | 高(纯终端) | 命令行熟练者 |
| 本地渲染的桌面型客户端 | ≈0 | 高 | 文件、监控、配置类图形化操作 |
最后一行是近年出现的一类做法:界面在你本地电脑渲染,通过 SSH 通道取数据和下发指令,服务器上不装桌面、不装 VNC,也不需要新开端口。它的收益和 VNC 优化完全不在一个维度——不是「传得更省」,而是「没有像素要传」。
边界同样要说清楚,免得选错:这类方案管的是「操作服务器」(文件、终端、监控、配置),它替代不了「在服务器上跑 GUI 程序本身」——那个场景 VNC / xrdp 仍是唯一解,绕不开。
5. 我最后的做法
1C1G 那台把 xfce 和 TigerVNC 全卸了:
sudo apt purge xfce4* tigervnc* && sudo apt autoremove
systemctl get-default # 应为 multi-user.target
卸完 free -m 对比装机前的记录,差值在 50MB 内算干净。图形化操作改用「本地渲染」那一类方案,服务器侧零新增。真正要跑 GUI 程序的场景我目前没有,所以 VNC 这条路我暂时用不上——这不是 VNC 不行,是我的需求不在它擅长的范围里。
FAQ
Q1:为什么不用向日葵 / ToDesk 连服务器?
它们为「连别人电脑」设计,服务器版要么收费要么砍功能,而且同样要装常驻服务、开通信端口——为了图形界面再引入一个常驻进程,和装 VNC 是同一性质的问题。
Q2:xrdp 比 VNC 好吗?
协议层面 RDP 对带宽友好得多,同网络下确实更流畅。但它同样要求服务器装桌面环境 + xrdp 常驻,内存账一分不少。带宽那层能缓解,渲染和内存两层原地不动。
Q3:画面糊是不是就是带宽不够?
不一定。16 位色深 + Tight 编码下画面本身就会糊,这是压缩的代价。判断方法是:把 -depth 改回 24 位再看,如果延迟没变化只是画质变好,说明瓶颈不在带宽。
Q4:装了桌面之后 SSH 变慢,怎么确认是内存问题?
free -m # available 是否低于 100MB
vmstat 1 5 # si/so 是否长期非零
两个都中就是 swap 在抖,所有进程跟着抖,sshd 也不例外。这是桌面环境在小机器上的连锁反应,不是 sshd 的配置问题。
Q5:卸载桌面后怎么确认真的干净了?
三处检查:systemctl get-default 是 multi-user.target;dpkg -l | grep -E "xfce|vnc" 无残留;ss -lntp 里没有 5901 监听。三项都过,再看 free -m 与装机前的差值。
Q6:768p 会不会不够用?
看你要干什么。改 conf、看日志、翻目录够用;同时开两个纵向分栏的 IDE 就挤了。我的做法是平时 768p,需要宽屏时临时起一个 :2 会话用 1920×1080,用完就关——反正 VNC 会话是按需启动的。