2017-10-23 15:37:57 bdss58 阅读数 459

缘起

周末接到告警,一个线上服务对机器磁盘占用率100%了。马不停蹄地登上线上机器df了一把,果然100%了。赶紧去服务对log目录下删了一批日志文件。然后又df一下确认…,怎么占用率还是100%?!明明刚刚删除了一些大文件,为什么df报告占用率还是满的?赶紧用du看了看各个目录占用情况,发现没有占用到100%啊。经过一番搜索,发现 那些大文件虽然被删除了,但是仍然被某进程打开,所以占用对磁盘空间并没有被释放
使用

lsof +L1
# 或者
lsof | grep deleted

找到删除但仍被进程打开的文件。命令输出的第二列是进程对pid,重启该pid就行了。
这时再df一下,一切正常了。

rm删除文件

通过上面对情景,我意识到,使用rm命令删除文件的时候并没有真正删除文件占用对空间。那么它干了些啥呢?
要回答这个问题,那就要解释一下Linux系统中文件名和文件链接了。
新建一个test.txt

echo "hello world" >> test.txt

ls查看一下

ls -l test.txt
-rw-rw-r-- 1 damon damon 13 Oct 23 14:35 test.txt

注意ls命令输出对第二列,数字1表示文件的链接个数。
下面,给文件新建一个链接,取名为test.txt1

ln test.txt test.txt1

这时再用ls命令查看一下

ls -l

-rw-rw-r-- 2 damon damon  13 Oct 23 14:35 test.txt
-rw-rw-r-- 2 damon damon  13 Oct 23 14:35 test.txt1

此时,文件已经有两个链接了,而文件名字test.txttest.txt1只是链接的名字而已。
顺便提一下软链接,软链接只是文件名的另外一个符号而已(alias)。用ln -s命令新建一个软链接。

ln -s test.txt1 test.txt2
ls -l 

-rw-rw-r-- 2 damon damon  13 Oct 23 14:35 test.txt
-rw-rw-r-- 2 damon damon  13 Oct 23 14:35 test.txt1
lrwxrwxrwx 1 damon damon   9 Oct 23 15:07 test.txt2 -> test.txt1

发现test.txt和test.txt1代表对文件对链接数还是2. 软链接不会增加文件的链接个数。而软链接test.txt2指向文件名test.txt1.
这里写图片描述

好了,做了这么多准备工作,终于可以rm一下做实验了。
先删除test.txt1

rm test.txt1

ls -al

-rw-rw-r-- 1 damon damon  13 Oct 23 14:35 test.txt
lrwxrwxrwx 1 damon damon   9 Oct 23 15:07 test.txt2 -> test.txt1

发现文件的链接个数只剩下1,既·test.txt.由于test.txt1这个链接被删除掉了,指向这个链接的软链接test.txt2也失效了。
总结,rm命令删除的只是文件的链接而已,没有删除磁盘上对应的文件。当一个文件的链接数为0,操作系统会认为该inode对应的磁盘空间被释放出来。

inode 和 文件描述符的关系

Linux里每个进程都有0,1,2三个标准文件描述符,分别对应着输入输出和错误输出。如果进程使用open系统调用打开一个文件tmp.txt,那么进程就会有一个新的文件描述符3,如果再打开其他文件,就会有4,5,6...这样的数字表示的文件描述符。
进程里的文件描述符和 inode 有什么关系呢?Linux内核是如何对应起来的呢?
这里写图片描述

2019-11-25 20:03:00 taoshihan 阅读数 14

在linux中有一个tail命令,tail -f可以实时的监控文件新增加的内容,如果用代码实现这个逻辑,可以下载使用这个包
go get github.com/hpcloud/tail/...

 

测试代码:

package main

import (
    "fmt"

    "github.com/hpcloud/tail"
)

func main() {
    t, _ := tail.TailFile("log.txt", tail.Config{Follow: true})
    for line := range t.Lines {
        fmt.Println(line.Text)
    }
}

 

2018-10-16 23:51:55 shipinsky 阅读数 813

linux设备驱动模型的kobject_uevent向用户态发消息,udev或者mdev监听之后再用户态增加/dev/xxx节点,文件系统监控也是类似的机制。


文件系统改变发起事件的机制
http://book.51cto.com/art/200712/62884.htm

inotify -- Linux 2.6 内核中的文件系统变化通知机制
https://www.ibm.com/developerworks/cn/linux/l-inotifynew/

Linux File System Change Monitoring Technology、Notifier Technology
https://www.cnblogs.com/LittleHann/p/4500160.html

2016-09-13 11:55:46 qq_27078095 阅读数 772

目前,每天中午cpu的负载都会突然增加,通过htop命令查看到此时的vbox的cpu占用率一致蛮高的,便计划对vbox的cpu使用率进行计划性监控,最开始的想法很简单就是通过调用top命令来进行cpu使用率的监控,但监控了好几天,发现值一直为0,而htop中值是一直有变化的,正常的结果也不应该为0,可惜,我没法对htop进行重定向,便计划通过/proc/<pid>/stat文件中的数据进行监控。可是当读取/proc/<pid>/stat文件内容后发现第14,15,16,17列的值完全没有变化(用于计算cpu使用率),预估top的值没有变化也和此有关,但htop的值一直有变化,而且显示的不止一个进程,故猜想htop读取的是线程值,所以开始读取/proc/<pid>/task/<tid>/stat文件内容,发现所需列的值有发生变化,而且一秒内变化的值和htop显示的值类似(此段内容,个人没法确定正确与否),故此,读取线程cpu使用率,代码如下:

import subprocess
import time
import psutil
import os

NAME = 'vbox_cpu_info'
VERBOSE = True
#通过psutil读取VBoxHeadless进程pid
def usePsutil():
    pidList = psutil.pids()
    processToTest = "VBoxHeadless"
    for eachPid in pidList:
        try:
            eachProcess = psutil.Process(eachPid)
            processName = eachProcess.name()  
            if(processName == processToTest):
                return eachPid
        except psutil.NoSuchProcess,pid:
            print "no process found with pid=%s"%(pid)
#得到线程的cpu占用时间
def get_cpu_time():
    vboxPid = tryPsutil()
    currentDirs = os.listdir("/proc/%d/task/"%vboxPid)
    allDirs = []
    timeOfCPU = []
    for i in currentDirs:
        allDirs.append(i)
    for i in allDirs:
        fileName = "/proc/%d/task/%d/stat"%(vboxPid,int(i))
        with open(fileName, 'r') as f:
            line = f.readlines()
            line_str = ''.join(line)
            line_split = line_str.split()
            timeOfCPU.append(int(line_split[13]) + int(line_split[14]) + int(line_split[15]) + int(line_split[16]))
    return timeOfCPU
#得到线程id
def get_tid():
    vboxPid = tryPsutil()
    currentDirs = os.listdir("/proc/%d/task/"%vboxPid)
    allDirs = []
    for i in currentDirs:
        allDirs.append(i)
    return allDirs
#得到tid和cpu used
def get_stats():
    firstTime = []
    lastTime =[]
    firstTime = get_cpu_time()
    time.sleep(1)
    lastTime = get_cpu_time()
    CPUofUsed = list(map(lambda x: x[0]-x[1], zip(lastTime, firstTime)))
    tid = get_tid()
    print zip(tid,CPUofUsed)
get_stats()

若需在nagios中监控,只需修改少量代码即可,在此忽略,若想在collectd中监控,可参考:https://github.com/anryko/cpu-collectd-plugin

2018-08-16 16:26:52 Keith003 阅读数 7468

下载软件jprofiler 8.0.1

https://download.csdn.net/download/keith003/10608384

服务配置过程

Jprofiler服务端软件上传至liunx目录(liunx目录自己指定)

修改tomcat启动文件(startup.sh),增加如下内容

JAVA_OPTS='-Xms256m -Xmx1024mm'  
CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS -agentpath:/opt/jprofiler8/bin/linux-x64/libjprofilerti.so=port=8849,nowait"  
export CATALINA_OPTS  

启动tomcat容器(查看日志)

客户端连接过程

安装成功后

输入服务器ip地址

linux 存放路径

把服务器中startup.sh 拷贝到本地tomcat 目录中

服务器配置端口号

 

没有更多推荐了,返回首页