独家许可与独占许可
独家许可: 被许可方和许可方都可以使用,不能再有其它方使用
独占许可: 只有被许可方可以使用,许可方自己不能使用
文件操作监控
缘起
话说strace是运维的利器,可以跟踪进程的所有的系统调用;有一天,运维小明发现tmp目录下意外产生了大量图片文件,并且在不断增多,但是不知道是哪个进程写的,所以更不知道是哪个应用写的,这时候strace无能为力了(其实可以strace所有可以的进程的,有些麻烦)
曾记否,inotify是可以监控文件(目录)的访问(不仅仅是变化)的,其输出类似:
嗯,没有进程信息,咋办?
还有一个神奇: systemtap
参考文档: https://sourceware.org/systemtap/SystemTap_Beginners_Guide.pdf
这里的iotime.stp 可以用来监控文件的变化,而且包含进程信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#! /usr/bin/env stap /* * Copyright (C) 2006-2007 Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU General Public License v.2. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Print out the amount of time spent in the read and write systemcall * when each file opened by the process is closed. Note that the systemtap * script needs to be running before the open operations occur for * the script to record data. * * This script could be used to to find out which files are slow to load * on a machine. e.g. * * stap iotime.stp -c 'firefox' * * Output format is: * timestamp pid (executabable) info_type path ... * * 200283135 2573 (cupsd) access /etc/printcap read: 0 write: 7063 * 200283143 2573 (cupsd) iotime /etc/printcap time: 69 * */ global start global time_io function timestamp:long() { return gettimeofday_us() - start } function proc:string() { return sprintf("%d (%s)", pid(), execname()) } probe begin { start = gettimeofday_us() } global filehandles, fileread, filewrite probe syscall.open.return { filename = user_string($filename) if ($return != -1) { filehandles[pid(), $return] = filename } else { printf("%d %s access %s fail\n", timestamp(), proc(), filename) } } probe syscall.read.return { p = pid() fd = $fd bytes = $return time = gettimeofday_us() - @entry(gettimeofday_us()) if (bytes > 0) fileread[p, fd] += bytes time_io[p, fd] <<< time } probe syscall.write.return { p = pid() fd = $fd bytes = $return time = gettimeofday_us() - @entry(gettimeofday_us()) if (bytes > 0) filewrite[p, fd] += bytes time_io[p, fd] <<< time } probe syscall.close { if ([pid(), $fd] in filehandles) { printf("%d %s access %s read: %d write: %d\n", timestamp(), proc(), filehandles[pid(), $fd], fileread[pid(), $fd], filewrite[pid(), $fd]) if (@count(time_io[pid(), $fd])) printf("%d %s iotime %s time: %d\n", timestamp(), proc(), filehandles[pid(), $fd], @sum(time_io[pid(), $fd])) } delete fileread[pid(), $fd] delete filewrite[pid(), $fd] delete filehandles[pid(), $fd] delete time_io[pid(),$fd] } |
这个脚本用来干这事儿,逻辑有些多,杀鸡用了牛刀,不过至少可以解决问题
[转载] Linux的capability深入分析 – 舒方小院 – 博客园
Linux 进程状态之 D
题记:
研究啥问题,至少要能重现啥问题
如何制造一个状态为D的进程呢?
如下:
1 2 3 4 5 |
#include <sys/types.h> #include <unistd.h> void main() { if (!vfork()) sleep(100); } |
主机内存查看方式
我们的一个96G内存的机器:
阿里云的一个4G内存的机器:
难道阿里云给的不够?
提工单给阿里云,人家说内存查看方式不对,应该是:
1 |
dmidecode | grep -A 5 "Memory Device" | grep Size | grep -v Range |
工单截屏:
甭说,还真是,如下:
那么,free看不到的那部分内存谁用了去了?
Docker一些知识
- docker容器其实(可以)在同一个父的cgroup下的,可以对这个父的cgroup进行限制,避免总量超限
- 一个机器上可以有多个docker daemon的,截止该文章诞生的时候,该功能还处于试验阶段,至少理论上是可以的: 参考: https://docs.docker.com/engine/reference/commandline/dockerd/#/running-multiple-daemons
- docker daemon可以使用不同的运行时,默认为containnerd,自动启动,并且通过socket通信;· 参考: https://docs.docker.com/engine/reference/commandline/dockerd/#/docker-runtime-execution-options
Docker daemon.json
Docker daemon 启动的时候可以有很多的命令行选项,这些选项也可以写到一个配置文件中,默认位置: /etc/docker/daemon.json ,key、value都和命令行一一对应,基本一样,但就是有些key在daemon.json中是复数形式,如: insecure-registries、storage-opts
1 2 3 4 5 6 |
{ "live-restore": true, "insecure-registries": ["docker-registry.i.bbtfax.com:5000"], "graph":"/data3/docker", "storage-opts":["dm.basesize=50G", "dm.loopdatasize=600G"] } |
docker-1.12 中 dm.basesize 默认10G, docker-1.9.11中默认 100G
storage-opts相关配置: https://docs.docker.com/engine/reference/commandline/dockerd/#/storage-driver-options
dm.fs 容器文件系统类型,目前支持ext4和xfs, 默认xfs
dm.loopdatasize 修改配置后,重启生效,只能改大,不能改小
dm.basesize 每次启动daemon都参考,一旦设置,无法修改,除非把daemon数据都删除重来;如果已经创建了容器了,不管该容器是死了、还是活着的、还是已删除,dm.basesize 都不能修改
有一些docker配置选项可以在不重启daemon的时候修改并生效,直接kill -HUP PID_OF_DAEMON 就可以,这种配置不多:
The list of currently supported options that can be reconfigured is this:
debug
: it changes the daemon to debug mode when set to true.cluster-store
: it reloads the discovery store with the new address.cluster-store-opts
: it uses the new options to reload the discovery store.cluster-advertise
: it modifies the address advertised after reloading.labels
: it replaces the daemon labels with a new set of labels.live-restore
: Enables keeping containers alive during daemon downtime.max-concurrent-downloads
: it updates the max concurrent downloads for each pull.max-concurrent-uploads
: it updates the max concurrent uploads for each push.default-runtime
: it updates the runtime to be used if not is specified at container creation. It defaults to “default” which is the runtime shipped with the official docker packages.runtimes
: it updates the list of available OCI runtimes that can be used to run containers
有些配置重启daemon都不能生效
参考: https://docs.docker.com/engine/reference/commandline/dockerd/#/configuration-reloading
关于wordpress的升级
曾经,我的博客是放在国外的,用过bluehost,用过hostmonster,这两家几乎是一样的。
由于放在国外访问起来不太方便,自己访问都慢,后来忍无可忍,才迁到了国内,当时正在研究docker,为了再次迁移方便,就直接装到了docker里面,这样,迁移的时候只需要迁移容器,省得重新安装了。
但凡“变化”总是会出现一些问题的:
首先,wordpress的升级是非常方便的,点几下鼠标就能轻松搞定,虽说提示升级前要备份,我从来没备份过,总是瞬间就完成了升级; 但是,迁移之后,这种方便的升级没有了,一直很忙,没工夫折腾。终于到现在,忍无可忍,研究了一下,发现wordpress的升级(包括插件的安装和卸载)靠的是博客所在主机提供的ftp服务(我不喜欢这种做法),曾经在bluehost和hostmonster的时候,ftp总是开着的;然而,使用docker之后,我没有开启ftp服务;升级就无法进行。于是,在docker中安装了vsftpd(升级的时候使用,升级完了就关掉),依然不行,猜测是ftp用户的权限的问题,添加权限后,升级便恢复到了曾经的方便。
其二,当今时代,各大网站都在使用https,刚好有些证书提供商可以免费提供https证书,而且自己对http2.0也颇感兴趣,于是,给自己博客添加了https证书,同时开启了http2.0;一切都还算顺利,只是开启https后,网页中一些静态资源(文章中的图片)是写死了http,于是浏览器中就不会出现绿色的锁,这个好办,直接在数据库中批量替换即可(话说替换的时候,由于连接数据库的编码没有指定,导致把数据写坏了,还好我有备份);
其三, 后来无意间发现,自己博客编辑器中本来是可以直接paste那些qq截图的,现在直接ctrl-v不好使了; 这是我非常喜欢的功能,没有这个就太不方便了,该功能是通过插件image paste实现的,重新安装该插件,依然不好使;只好祭出开发调试手段了,首先打开浏览器的“开发者工具”,看看有没有加载失败的资源或者报错的js语句;果然,image paste插件的js文件加载失败,问题比较明显,该文件试图通过http加载,但是chrome是可以容忍https的页面中使用http的图片资源,也禁止使用http的js资源,所以就直接block了;
为什么那么多资源都能很好地通过https加载,偏偏这一个资源非要走http呢?其实不是该插件的过,wordpress管理后台要求配置“站点地址”,这里面是最初配置的http地址,改为https就好了
systemd工具
systemd-cgls
systemd-cgtop