服务器CPU占用过高
前言:在秋招得面试过程中有过几次面试官问我,在服务器端你怎么查负载,碰到了内存啊,cpu啊过高得问题如何解决,一直无法回答,随后慢慢得看了一些资料有了一些答案。
服务器得资源能通常包括 CPU、内存、网络、磁盘等资源。linux系统针对以上负载查询得常用指令有:
使用top或htop命令查看实时负载。使用vmstat查看虚拟内存统计信息。使用iostat查看磁盘I/O统计信息。使用netstat查看网络连接状态。netstat -lnp用于打印当前系统启动了哪些端口,netstat -an用于打印网络连接状况。使用uptime查看系统运行时间和平均负载。使用sar可以监控系统所有资源状态,sar -n DEV查网卡流量历史、sar -q 查看历史负载,最有用的就是查网卡流量,流量过大:rxpck/s大于4000,或者rxKB/s大于5000,则很有可能被攻击了,需要抓包分析。使用free查看当前系统的总内存大小以及使用内存的情况;使用tcpdump抓包工具分析数据包,知道有哪些IP在攻击;可以将内容写入指定文件1.cap中,显示包的内容,不加-w屏幕上显示数据流向。
cpu占用率过高 一般是先top、ps命令查询一下有哪些进程占用资源过高,然后kill掉进程。如果都找不到问题进程,top、ps命令都是遍历/proc/目录下得内容,所有的进程都会在该目录下,他们是通过opendir/readdir这些系统调用函数来遍历的,这些都是os提供的标准接口,除非这些系统调用函数把某些进程给过滤掉了,那样的话top、ps当然无法查询到问题进程,也就是被攻击了,有人潜入系统内部篡改了系统调用。我们就可以通过netstat查看是否有可疑的网络连接,通过排查端口我们可以找到可疑的网络连接,再通过curl命令可以发送请求给目标ip,看看是干嘛的,可能是挖矿病毒之类的。这个时候有一个命令unhide就是专门用来捉拿隐藏进程的。 同时我们知道网络编程实际就是socket编程,再结合linux系统里一切皆文件的思想,我们可以知道,这个连接一定会产生一个fd,我们可以通过这个文件中的信息去确认疑似连接。这个时候就可以通过kill和rm命令杀掉进程和删除文件了。 但是我们不知道这个病毒是如何而来的,因此即使暂时删除了后续也会继续被攻击。 我了解到的问题产生源头就是Redis,罪魁祸首。因为大家基本上不会给redis设置连接密码,redis没有默认的连接密码,一般用户是不会添加,因此容易造成被不法分子利用攻击,因此就要给redis添加密码,或者更改redis默认端口号。 问题产生原因:黑客通过redis连接默认没密码然后数据持久化将远程登录公钥写入服务器。挖矿病毒,利用Redis的未授权访问漏洞进行攻击。Redis 默认配置为6379端口无密码访问,如果redis以root用户启动,攻击者可以通过公网直接链接redis,向root账户写入SSH公钥文件,以此获取服务器权限注入病毒。
CONFIG SET dir /root/.ssh
CONFIG SET dbfilename authorized_keys
SAVE
top、ps和unhide区别:unhide是从进程id最小到最大,挨个访问/proc/Spid目录,一旦发现目录存在但不在ps输出结果中,就找到了隐藏进程。
内存占用过高 在程序运行过程中,函数中的变量应该分配到栈上,但是如果分配到堆上,就造成了内存泄漏。 内存泄漏是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏通常不会直接产生可观察的错误症状,而是逐渐积累,降低系统整体性能,极端的情况下可能使系统崩溃。造成内存泄漏的原因有很多,以下是一些常见的因素:
代码中的错误:程序员的代码中可能存在错误,导致无法正确释放内存。例如,对已经释放的内存进行再次操作,或者没有正确释放不再使用的内存。循环引用:如果两个对象相互引用,而且没有其他对象引用它们,那么这两个对象无法被垃圾回收器回收,导致内存泄漏。静态变量和静态方法:静态变量和静态方法在程序运行期间一直存在,如果它们引用了其他对象,而这些对象又无法被垃圾回收器回收,就会导致内存泄漏。数据库连接和文件句柄等未关闭:长时间打开数据库连接、文件句柄等资源,但没有关闭,也会导致内存泄漏。第三方库或组件的内存泄漏:使用第三方库或组件时,如果这些库或组件存在内存泄漏问题,也会导致应用程序出现内存泄漏。 在Golang中,我们可以通过输入指令 “go build -gcflags=‘-m’ xxx.go”,它的作用是在编译时生成并打印出被GC标记的函数和变量等信息,其中包括哪些变量从栈上跑到堆上。 os给我们提供了一套内存回收机制,主要是俩种:直接内存回收和后台内存回收。后台内存回收(kswapd):在物理内存紧张的时候,会唤醒 kswapd 内核线程来回收内存,这个回收内存的过程异步的,不会阻塞进程的执行。直接内存回收(direct reclaim):如果后台异步回收跟不上进程内存申请的速度,就会开始直接回收,这个回收内存的过程是同步的,会阻塞进程的执行。如果直接内存回收后,空闲的物理内存仍然无法满足此次物理内存的申请,那么内核就会放最后的大招了 ——触发 OOM (Out of Memory)机制。
参考 https://zhuanlan.zhihu.com/p/304998240 轩辕的编程宇宙 小林coding