怒啃 24 小时,终于搞懂linux系统上下文切换!

说白了,服务器系统中的上下文切换就是进程之间切换时的资源切换。
其实很简单。
我们先来说说最重要的事情。
这个切换涉及到保存和加载各种进程状态信息,比如内存、堆栈、寄存器等。
我们去年开发的项目大约大了3 000倍。
我们发现,在高峰时段,上下文切换次数增多,直接影响了系统的响应速度。
还有一点是,不同类型的上下文切换,比如进程间、跨线程、中断等,涉及的资源不同,切换的复杂度也不同。
另一个关键细节是分析工具的选择。
vmstat、pidstat 和 /proc/interrupts 都是好帮手。
一开始我以为上下文切换只是简单的资源切换,后来发现我错了。
它还包括系统的整体性能和响应时间。
等等,另一件事是上下文切换器的数量。
正常情况下应该是每秒几百到万次。
如果生长异常,就要小心了。
因此,我认为合理设置上下文切换的次数并根据实际情况进行适配是优化系统性能的关键。

linux如何切换用户

嘿,你问我如何在 Linux 中更改用户?嗯,我告诉你的都是我经历过的实际操作。

比方说,我上次在上海机房远程调试一位同事时,他的系统需要root权限才能查看日志。
我刚刚使用su,输入root密码,终端突然变成密码了。
但后来我发现有些路径对普通用户可见,但对他们不可见,所以我意识到我必须使用su-。
我记得我必须使用 sudo su- 并输入我的密码,否则它不会起作用。
需要多次尝试才能正确执行此操作。

但说实话,现在我尽量不直接root,没有Su。
上次我在北京的服务器上做一些事情时,我只是使用 sudo apt update 并输入我的密码。
虽然要等几秒钟确认,但至少不用记住root密码,而且当你用exit退出时,仍然可以看到刚才所做的事情。
如果直接使用su成为root,如果忘记更改配置文件,整个系统可能会死机。

最烦人的是切换用户时环境变量不匹配。
上次我在深圳帮一个客户搭建系统,用su切换到另一个用户。
结果我无法识别我配置的路径,系统差点崩溃。
后我意识到 su 直接更改身份,并且 su- 和 su -l (注意两个连字符)是完全复制环境。
你必须记住这一点,否则每次切换时你都必须找到一条新路径。

还有一个sudoers文件,需要提前配置。
去年我在杭州搞自动化部署的时候,因为没有添加sudo权限,所以直接用su root。
结果,客户端获得了错误的权限,不得不再次访问该站点。
现在,我们明确列出了需要在 sudoers 中提升权限的命令。
普通用户只能使用sudo,这样更安全。

无论如何,你可以找到答案。
使用sudo进行日常维护。
如果您确实想要完全控制,请使用 su-。
但请记住,root 权限不是开玩笑。
一旦用完就让他们退休。
不要永远粘着他们。

怒啃 24 小时,终于搞懂linux系统上下文切换!

说实话,当我第一次接触Linux上下文切换时,我觉得这个概念相当混乱。
以我当时调试的服务器为例。
CPU负载突然飙升,最后发现某个进程疯狂等待IO,导致自愿上下文切换次数暴涨。

有趣的是,进程上下文切换最消耗资源的部分是保存和恢复用户模式内存。
我记得老运维哥教了我一个小技巧。
使用vmstat 1 1 0命令每秒捕获数据,查看cs(上下文切换次数)和r(就绪队列长度)的波形。
当时服务器是4 核的机器,r值经常超过2 0,所以我知道CPU肯定是排队的。

线程切换其实还是蛮有趣的。
我尝试过使用taskset来修复同一个Nginx进程中的CPU核心。
你会发现线程切换几乎不增加系统开销。
这与进程切换完全不同,进程切换需要保存整个地址空间,而线程切换只需要切换内核堆栈和寄存器。
有一个项目使用了多个进程但陷入了困境。
后来改成了多线程,性能提升了一倍。

我在中断上下文切换时遇到了陷阱。
某段时间系统突然晃动,vmstat显示in值突然增加到2 00+。
检查/proc/interrupts发现某SATA硬盘IRQ触发过于频繁。
后来发现是固件驱动问题,所以只是更改了BIOS设置就解决了。
这让我明白了,如果中断处理程序写得不好,可能会直接搞垮整个系统。

就分析工具而言,pidstat比vmstat专业得多。
我有一位使用电子商务系统的客户。
他使用 pidstat -w 1 2 0 捕获了闪购活动期间某个进程的 nvcswch(非自愿切换)从 2 00 跃升至 5 000 的时刻。
这直接让他优化了数据库锁机制。

排查问题时,我有一个习惯,就是先看vmstat的b值。
在最后一个系统抖动情况下,b值维持在3 左右,排除了OOM问题。
结合watch -d cat /proc/interrupts动态查看,发现是某个网卡驱动引起的。
这时候在内核文档中查找中断号比单纯看数字有用得多。

最深的体会是理解为什么Java线程比Linux进程轻。
因为JVM可以共享类数据,所以切换线程时不需要像切换进程时那样节省那么多的用户态资源。
这让我想起了我给客户做的性能优化,当时我把同步代码块改成了本地变量缓存,CPU占用率直接降低了3 0%。
因此,只有理论与实践相结合,才能顺利使用这些工具。