webmin/usermin/virtualmin使用
[| 2012/04/19 23:37]
今天看见有人讨论webmin,这是一个服务器管理面板,用的人比较多。由于我一直都是命令行操作,没有用过面板,有些好奇,于是安装试了一下。
先在一个小内存的vps上试了试,发现内存不足。webmin还是比较重量的。于是找了个内存比较大的装了一下。webmin安装比较快,下载deb包后用dpkg -i安装,解决一些编译依赖后就可以在默认端口10000上使用了。默认是使用root用户密码登陆。
进去以后有点眼花缭乱,左边功能菜单长长的一列,每个点开后都有若干个功能。大概使用了一下,功能非常强大,界面也很不错。基本上覆盖了系统的各项配置,连php、mysql的参数都可以用可视化的方式进行调整,不得不说非常强大。
大概浏览了一下功能列表,cron任务设置、用户管理、自启动程序管理、进程管理、磁盘配额以及各种系统服务的管理,如数据库、ssh、svn、samba、email等等等等等。基本上平时用到的大多数服务都可以以可视化的形式进行配置,并且配置功能很强,页面交互也很友好。
由于是在OpenVZ vps上安装的面板,共享内核的原因,有些功能不能使用,不过已经足够让人眼花了。
在查看可用扩展时,又发现了usermin和virtualmin,在官网上看了下说明,原来分别是普通用户用来管理的面板和虚拟主机管理的面板。
usermin可以直接在webmin里安装,点击安装后自动就装好启动了,默认20000端口,进去后也是一些管理功能,主要是文件、mail等管理,可管理项少了很多,不过也很不错。
然后是virtualmin,这个在官网提供了自动安装脚本,运行了一下,相当复杂,装了半天才装好,装好后还是从10000端口进入,一进去感觉界面很华丽,比webmin好很多。除了有webmin的功能外,主要添加了虚拟主机的操作,主要有增删虚拟主机、设置配额、查看流量、ftp管理等管理项。功能超强。进入usermin后界面也有很大改观,主要增加了一个mail管理界面,可以收发邮件,还有一个邮件列表。
总体使用的感觉非常强大,这应该算是一个比较重量级的管理面板。不过其实平时用的时候根本用不到这么多的功能。也很少有服务器会部署上这么多的服务。个人使用有点太费资源,中小企业用来管理少数几台运行了很多网络基础服务的服务器还是相当不错的。
先在一个小内存的vps上试了试,发现内存不足。webmin还是比较重量的。于是找了个内存比较大的装了一下。webmin安装比较快,下载deb包后用dpkg -i安装,解决一些编译依赖后就可以在默认端口10000上使用了。默认是使用root用户密码登陆。
进去以后有点眼花缭乱,左边功能菜单长长的一列,每个点开后都有若干个功能。大概使用了一下,功能非常强大,界面也很不错。基本上覆盖了系统的各项配置,连php、mysql的参数都可以用可视化的方式进行调整,不得不说非常强大。
大概浏览了一下功能列表,cron任务设置、用户管理、自启动程序管理、进程管理、磁盘配额以及各种系统服务的管理,如数据库、ssh、svn、samba、email等等等等等。基本上平时用到的大多数服务都可以以可视化的形式进行配置,并且配置功能很强,页面交互也很友好。
由于是在OpenVZ vps上安装的面板,共享内核的原因,有些功能不能使用,不过已经足够让人眼花了。
在查看可用扩展时,又发现了usermin和virtualmin,在官网上看了下说明,原来分别是普通用户用来管理的面板和虚拟主机管理的面板。
usermin可以直接在webmin里安装,点击安装后自动就装好启动了,默认20000端口,进去后也是一些管理功能,主要是文件、mail等管理,可管理项少了很多,不过也很不错。
然后是virtualmin,这个在官网提供了自动安装脚本,运行了一下,相当复杂,装了半天才装好,装好后还是从10000端口进入,一进去感觉界面很华丽,比webmin好很多。除了有webmin的功能外,主要添加了虚拟主机的操作,主要有增删虚拟主机、设置配额、查看流量、ftp管理等管理项。功能超强。进入usermin后界面也有很大改观,主要增加了一个mail管理界面,可以收发邮件,还有一个邮件列表。
总体使用的感觉非常强大,这应该算是一个比较重量级的管理面板。不过其实平时用的时候根本用不到这么多的功能。也很少有服务器会部署上这么多的服务。个人使用有点太费资源,中小企业用来管理少数几台运行了很多网络基础服务的服务器还是相当不错的。
一个不错的linux screen配置文件
[| 2012/04/19 00:04]
一个好用的.screenrc配置,f11和f12分别是左右切换tab。很好用,也很简洁。
#termcapinfo rxvt* 'hs:ts=\E]2;:fs=\007:ds=\E]2;\007'
#hardstatus string "screen (%n: %t)"
source /etc/screenrc
altscreen off
hardstatus none
# hardstatus string '%{= kg}[ %H ][%{= kw}%= %?%-Lw%?%{R}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{W} %c %{g}]'
# hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %d/%m %{W}%c %{g}]'
# hardstatus string "%{= bk} %{= wk} %-Lw%{bw}%n+%f %t%{wk}%{wk}%+Lw %=%{kw}%{= R}%{-}"
# hardstatus string "%{= kw} %H %{wk} [%= %-Lw%{r}%n+%f %t%{k}%+Lw %= ] %{kw} %c %{kw}%{= R}%{-}"
# hardstatus string "%{= rw} %H %{wk} %-Lw%{r}%n+%f %t%{wk}%+Lw %= %c%{kw}%{= R}%{-}"
# caption always "%{= rw} %H %{wk} %h %= %-Lw%{r}%n+%f %t%{wk}%+Lw %{kw}%{= R}%{-}"
# caption always "%{= rw} %H %{kw}- %-Lw%{r}%n+%f %t%{kw}%+Lw%=%{= rw}%c %{= R}%{-}"
# caption always "%{= rw} %H %{wk} %-Lw%{r}%n+%f %t%{wk}%+Lw %= %c%{kw}%{= R}%{-}"
# caption always "%{= KW} %l %{KW}%-Lw%{kW} %n+%f %t %{KW}%+Lw %=%c%{KW}%{= R}%{-}"
# caption always "%{= kw} %-Lw%{G}%n+%f %t%{kw}%+Lw %= %c%{kw}%{= R}%{-}"
# caption always "%{= KW} %h %=%{kw}%{= R}%{-}"
# caption always "%{= wk} %{wk}%-Lw%{rw} %n+%f %t %{wk}%+Lw %=%c%{kw}%{= R}%{-}"
caption always "%{= wk}%{wk}%-Lw%{rw} %n+%f %t %{wk}%+Lw %=%c%{= R}%{-}"
# caption always "%{= KW} %{KW}%-Lw%{wk} %n+%f %t %{KW}%+Lw %=%{KW}%c%{KW}%{= R}%{-}"
# caption always "%{= KW} %{KW}%-Lw%{Wk} %n+%f %t %{KW}%+Lw %=%{KW}%c%{KW}%{= R}%{-}"
shelltitle "$ |bash"
defscrollback 50000
startup_message off
# escape ^aA
escape ^aa
termcapinfo xterm|xterms|xs|rxvt ti@:te@ # scroll bar support
term rxvt # mouse support
width 130
height 40
bindkey -k k; screen
bindkey -k F1 prev
bindkey -k F2 next
bindkey -d -k kb stuff ^H
bind x remove
bind j eval "focus down"
bind k eval "focus up"
bind s eval "split" "focus down" "prev"
vbell off
shell -bash
#termcapinfo rxvt* 'hs:ts=\E]2;:fs=\007:ds=\E]2;\007'
#hardstatus string "screen (%n: %t)"
source /etc/screenrc
altscreen off
hardstatus none
# hardstatus string '%{= kg}[ %H ][%{= kw}%= %?%-Lw%?%{R}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{W} %c %{g}]'
# hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %d/%m %{W}%c %{g}]'
# hardstatus string "%{= bk} %{= wk} %-Lw%{bw}%n+%f %t%{wk}%{wk}%+Lw %=%{kw}%{= R}%{-}"
# hardstatus string "%{= kw} %H %{wk} [%= %-Lw%{r}%n+%f %t%{k}%+Lw %= ] %{kw} %c %{kw}%{= R}%{-}"
# hardstatus string "%{= rw} %H %{wk} %-Lw%{r}%n+%f %t%{wk}%+Lw %= %c%{kw}%{= R}%{-}"
# caption always "%{= rw} %H %{wk} %h %= %-Lw%{r}%n+%f %t%{wk}%+Lw %{kw}%{= R}%{-}"
# caption always "%{= rw} %H %{kw}- %-Lw%{r}%n+%f %t%{kw}%+Lw%=%{= rw}%c %{= R}%{-}"
# caption always "%{= rw} %H %{wk} %-Lw%{r}%n+%f %t%{wk}%+Lw %= %c%{kw}%{= R}%{-}"
# caption always "%{= KW} %l %{KW}%-Lw%{kW} %n+%f %t %{KW}%+Lw %=%c%{KW}%{= R}%{-}"
# caption always "%{= kw} %-Lw%{G}%n+%f %t%{kw}%+Lw %= %c%{kw}%{= R}%{-}"
# caption always "%{= KW} %h %=%{kw}%{= R}%{-}"
# caption always "%{= wk} %{wk}%-Lw%{rw} %n+%f %t %{wk}%+Lw %=%c%{kw}%{= R}%{-}"
caption always "%{= wk}%{wk}%-Lw%{rw} %n+%f %t %{wk}%+Lw %=%c%{= R}%{-}"
# caption always "%{= KW} %{KW}%-Lw%{wk} %n+%f %t %{KW}%+Lw %=%{KW}%c%{KW}%{= R}%{-}"
# caption always "%{= KW} %{KW}%-Lw%{Wk} %n+%f %t %{KW}%+Lw %=%{KW}%c%{KW}%{= R}%{-}"
shelltitle "$ |bash"
defscrollback 50000
startup_message off
# escape ^aA
escape ^aa
termcapinfo xterm|xterms|xs|rxvt ti@:te@ # scroll bar support
term rxvt # mouse support
width 130
height 40
bindkey -k k; screen
bindkey -k F1 prev
bindkey -k F2 next
bindkey -d -k kb stuff ^H
bind x remove
bind j eval "focus down"
bind k eval "focus up"
bind s eval "split" "focus down" "prev"
vbell off
shell -bash
linux screen修改会话名字
[| 2012/04/18 15:10]
开了多个screen的话,每次screen -r的时候都有一大串需要选择,默认是用进程号.终端号.主机名来做名字的,无法分辨分别是做什么的,只能一个一个试。
用ctrl+a+A试了下,发现只能改一个tab的名字。问了问高人,原来用:
ctrl+a :sessionname my_screen_name
即可。
当然,最好是在启动screen的时候用screen -S my_screen_name来直接指定名字。
用ctrl+a+A试了下,发现只能改一个tab的名字。问了问高人,原来用:
ctrl+a :sessionname my_screen_name
即可。
当然,最好是在启动screen的时候用screen -S my_screen_name来直接指定名字。
lemon语法分析器模板初探
[| 2012/04/18 00:24]
今天看了一下lighttpd解析http头的过程,之前一直以为是单纯用遍历字符串的形式做的,今天发现除了遍历字符串,还用到了语法分析器来做解析,生成语法分析器模板的就是lemon,语法比较直观,不看文档就能大概看出逻辑,不过深入研究就要借助文档了,文档比较晦涩,需要仔细研究。
大概用法:使用lemon的语法编写一个.y文件,然后调用lemon命令或使用lemon源文件将.y转化成.c和.h,转化后的.c看起来就很晕了,完全看不懂的说。
这个东西还是挺有意思的,lighttpd还用它来解析配置文件。不过配置文件用lua也很不错啊。我准备以后多使用lua作为配置文件,方便灵活。
大概用法:使用lemon的语法编写一个.y文件,然后调用lemon命令或使用lemon源文件将.y转化成.c和.h,转化后的.c看起来就很晕了,完全看不懂的说。
这个东西还是挺有意思的,lighttpd还用它来解析配置文件。不过配置文件用lua也很不错啊。我准备以后多使用lua作为配置文件,方便灵活。
git push中的non-fast-forward问题
[| 2012/04/16 13:50]
今天在回滚一个git操作记录时(使用了git reset --hard)遇到了问题,在push回服务器时提示:
error: failed to push some refs to 'qiuxueda@bb-iis-dev01.vm:code/comlogsvr-proxy'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
看了一下文档:
原文:
NOTE ABOUT FAST-FORWARDS
When an update changes a branch (or more in general, a ref) that used to point at commit A to point at another commit B, it is called a fast-forward update if and only if B is a descendant of A.
In a fast-forward update from A to B, the set of commits that the original commit A built on top of is a subset of the commits the new commit B builds on top of. Hence, it does not lose any
history.
In contrast, a non-fast-forward update will lose history. For example, suppose you and somebody else started at the same commit X, and you built a history leading to commit B while the other
person built a history leading to commit A. The history looks like this:
B
/
---X---A
Further suppose that the other person already pushed changes leading to A back to the original repository you two obtained the original commit X.
The push done by the other person updated the branch that used to point at commit X to point at commit A. It is a fast-forward.
But if you try to push, you will attempt to update the branch (that now points at A) with commit B. This does not fast-forward. If you did so, the changes introduced by commit A will be lost,
because everybody will now start building on top of B.
The command by default does not allow an update that is not a fast-forward to prevent such loss of history.
If you do not want to lose your work (history from X to B) nor the work by the other person (history from X to A), you would need to first fetch the history from the repository, create a history
that contains changes done by both parties, and push the result back.
You can perform "git pull", resolve potential conflicts, and "git push" the result. A "git pull" will create a merge commit C between commits A and B.
B---C
/ /
---X---A
Updating A with the resulting merge commit will fast-forward and your push will be accepted.
Alternatively, you can rebase your change between X and B on top of A, with "git pull --rebase", and push the result back. The rebase will create a new commit D that builds the change between X
and B on top of A.
B D
/ /
---X---A
Again, updating A with this commit will fast-forward and your push will be accepted.
There is another common situation where you may encounter non-fast-forward rejection when you try to push, and it is possible even when you are pushing into a repository nobody else pushes into.
After you push commit A yourself (in the first picture in this section), replace it with "git commit --amend" to produce commit B, and you try to push it out, because forgot that you have pushed
A out already. In such a case, and only if you are certain that nobody in the meantime fetched your earlier commit A (and started building on top of it), you can run "git push --force" to
overwrite it. In other words, "git push --force" is a method reserved for a case where you do mean to lose history.
我的翻译版(不是严格依照原文,按自己理解的意思复述):
关于 FAST-FORWARDS
当修改一个branch(或ref)时,在a是b的直接基线或祖先基线的情况下,将HEAD指针从a移动为b叫做fast-forwards
在这种情况下,因为不会丢失任何历史数据,所以叫做fast-forward
但是,对于non-fast-forward就会丢失历史数据,设想你和另一个人同时以x为基线开发,你开发了一个叫b的commit,而那个人开发了一个叫a的commit:
B
/
---X---A
如果那个人已经将a提交到了服务端,现在服务端的head指向了a,如果你试图去提交b,那么服务端会试图将head从a移动到b上,如此一来,就会丢失a的修改内容,这就是non-fast-forward。
所以默认情况下不允许这种提交,以防止数据丢失
如果你不想丢失你的和别人的工作成果,那么需要先从服务端获取其他人的修改,生成一个包含你的和其他人修改的commit,然后将其提交到服务器。
你可以先运行git pull,然后解决合并冲突,然后git push。git pull会基于a和b生成一个c记录,同时包含两者的修改内容
B---C
/ /
---X---A
这样提交c请求就变成了fast-forward请求,从而被允许。
同样的,你可以在a基础上添加从x到b的这些请求,使用git pull --rebase并push结果到服务器,这样会生成一个commit:d,在a的基础上添加了从x到b的修改
B D
/ /
---X---A
这也是一个fast-forward请求,是被允许的。
(这一段不是特别理解。。像是废话,因为跟上图第一种情况看起来是一回事)还有一种情况,即使没有其他人向版本库推送过数据,你也可能遇到non-fast-forward的情况:
当你推送a到服务端后,又使用了git commit --amend 修改a为b,然后可能忘记已经推送过a,于是试图去推送b到版本库。这样的话,当你确认没有人fetch过a的话,可以使用git push --force去覆盖这个记录。
也就是说,当你确认你确实需要丢失历史数据时,可以使用git push --force来强制推送
在gitolite中,对于每个版本库的授权就有“RW+”字段,其中的“+”权限,就是强制推送的权限,由于可能会导致历史提交丢失,所以是比W更高级的权限,需要单独授予。
error: failed to push some refs to 'qiuxueda@bb-iis-dev01.vm:code/comlogsvr-proxy'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
看了一下文档:
原文:
NOTE ABOUT FAST-FORWARDS
When an update changes a branch (or more in general, a ref) that used to point at commit A to point at another commit B, it is called a fast-forward update if and only if B is a descendant of A.
In a fast-forward update from A to B, the set of commits that the original commit A built on top of is a subset of the commits the new commit B builds on top of. Hence, it does not lose any
history.
In contrast, a non-fast-forward update will lose history. For example, suppose you and somebody else started at the same commit X, and you built a history leading to commit B while the other
person built a history leading to commit A. The history looks like this:
B
/
---X---A
Further suppose that the other person already pushed changes leading to A back to the original repository you two obtained the original commit X.
The push done by the other person updated the branch that used to point at commit X to point at commit A. It is a fast-forward.
But if you try to push, you will attempt to update the branch (that now points at A) with commit B. This does not fast-forward. If you did so, the changes introduced by commit A will be lost,
because everybody will now start building on top of B.
The command by default does not allow an update that is not a fast-forward to prevent such loss of history.
If you do not want to lose your work (history from X to B) nor the work by the other person (history from X to A), you would need to first fetch the history from the repository, create a history
that contains changes done by both parties, and push the result back.
You can perform "git pull", resolve potential conflicts, and "git push" the result. A "git pull" will create a merge commit C between commits A and B.
B---C
/ /
---X---A
Updating A with the resulting merge commit will fast-forward and your push will be accepted.
Alternatively, you can rebase your change between X and B on top of A, with "git pull --rebase", and push the result back. The rebase will create a new commit D that builds the change between X
and B on top of A.
B D
/ /
---X---A
Again, updating A with this commit will fast-forward and your push will be accepted.
There is another common situation where you may encounter non-fast-forward rejection when you try to push, and it is possible even when you are pushing into a repository nobody else pushes into.
After you push commit A yourself (in the first picture in this section), replace it with "git commit --amend" to produce commit B, and you try to push it out, because forgot that you have pushed
A out already. In such a case, and only if you are certain that nobody in the meantime fetched your earlier commit A (and started building on top of it), you can run "git push --force" to
overwrite it. In other words, "git push --force" is a method reserved for a case where you do mean to lose history.
我的翻译版(不是严格依照原文,按自己理解的意思复述):
关于 FAST-FORWARDS
当修改一个branch(或ref)时,在a是b的直接基线或祖先基线的情况下,将HEAD指针从a移动为b叫做fast-forwards
在这种情况下,因为不会丢失任何历史数据,所以叫做fast-forward
但是,对于non-fast-forward就会丢失历史数据,设想你和另一个人同时以x为基线开发,你开发了一个叫b的commit,而那个人开发了一个叫a的commit:
B
/
---X---A
如果那个人已经将a提交到了服务端,现在服务端的head指向了a,如果你试图去提交b,那么服务端会试图将head从a移动到b上,如此一来,就会丢失a的修改内容,这就是non-fast-forward。
所以默认情况下不允许这种提交,以防止数据丢失
如果你不想丢失你的和别人的工作成果,那么需要先从服务端获取其他人的修改,生成一个包含你的和其他人修改的commit,然后将其提交到服务器。
你可以先运行git pull,然后解决合并冲突,然后git push。git pull会基于a和b生成一个c记录,同时包含两者的修改内容
B---C
/ /
---X---A
这样提交c请求就变成了fast-forward请求,从而被允许。
同样的,你可以在a基础上添加从x到b的这些请求,使用git pull --rebase并push结果到服务器,这样会生成一个commit:d,在a的基础上添加了从x到b的修改
B D
/ /
---X---A
这也是一个fast-forward请求,是被允许的。
(这一段不是特别理解。。像是废话,因为跟上图第一种情况看起来是一回事)还有一种情况,即使没有其他人向版本库推送过数据,你也可能遇到non-fast-forward的情况:
当你推送a到服务端后,又使用了git commit --amend 修改a为b,然后可能忘记已经推送过a,于是试图去推送b到版本库。这样的话,当你确认没有人fetch过a的话,可以使用git push --force去覆盖这个记录。
也就是说,当你确认你确实需要丢失历史数据时,可以使用git push --force来强制推送
在gitolite中,对于每个版本库的授权就有“RW+”字段,其中的“+”权限,就是强制推送的权限,由于可能会导致历史提交丢失,所以是比W更高级的权限,需要单独授予。
为blog添加ping插件-自动通知搜索引擎
[| 2012/04/13 22:13]
现在主流搜索引擎都支持ping功能了,每当网站更新时可以主动向搜索引擎发一个xml格式信息,称之为”ping“,通知搜索引擎来抓取,对于收录是非常有好处的。
之前一直懒得搞,今天弄了一下。
参照百度站长工具里提供的格式,搞了一个,试试是否好用呢。
添加了baidu和google的ping地址:
http://ping.baidu.com/ping/RPC2
http://blogsearch.google.com/ping/RPC2
之前一直懒得搞,今天弄了一下。
参照百度站长工具里提供的格式,搞了一个,试试是否好用呢。
添加了baidu和google的ping地址:
http://ping.baidu.com/ping/RPC2
http://blogsearch.google.com/ping/RPC2
OpenVZ VPS内存查看分析工具/超售检查脚本
[| 2012/04/12 02:52]
搞了一个python脚本,用来查看OpenVZ VPS内存情况的,原始数据取自/proc/user_beancounters文件,脚本内做了一个数据简单的分析提取和可视化提高的工作,已经很晚了,先搞几个基本功能出来,增强功能以后再补。
用法: python vz_checker.py /proc/user_beancounters (需要root权限)
输出内容:
filename is:[user_beancounters]
Kernel Mem Info: used:[5.723M] max_used:[35.539M] limit:[2048.000M] fail_count:[0]
Mem already allocated Info: used:[17.621M] max_used:[33.074M] limit:[96.000M] fail_count:[0]
Ram actually used: used:[8.516M] max_used:[67.820M] limit:[96.000M] fail_count:[0]
Mem (Ram + swap) used: used:[9.848M] max_used:[13.219M] limit:[96.000M] fail_count:[0]
Kernel Mem Info:占用的内核内存大小,不可被swap,主要用来存放进程数据等。
Mem already allocated Info:已分配的内存大小,limit即为burst内存大小。
Ram actually used: 实际占用的物理内存大小。
Mem (Ram + swap) used: 占用的物理内存和swap大小。
如果 实际占用的物理内存 == 占用的物理内存和swap大小 那么恭喜你,你的vps里运行的程序都在内存中,主机超售不严重。
如果 实际占用的物理内存 < 占用的物理内存和swap大小 情况不妙,主机已经开始占用swap了,超售比较严重了。
另外我在测试过程中发现有一台vps实际占用物理内存大小显示比物理内存+swap总和还要大,现象很奇怪,查了一些资料没有关于这方面的说明,待后续调查。
脚本功能还比较粗糙,一些数据需要继续打磨,欢迎大家提意见~~
本文地址:http://www.snooda.com/read/263
下载地址:https://github.com/snooda/openvz_checker
用法: python vz_checker.py /proc/user_beancounters (需要root权限)
输出内容:
filename is:[user_beancounters]
Kernel Mem Info: used:[5.723M] max_used:[35.539M] limit:[2048.000M] fail_count:[0]
Mem already allocated Info: used:[17.621M] max_used:[33.074M] limit:[96.000M] fail_count:[0]
Ram actually used: used:[8.516M] max_used:[67.820M] limit:[96.000M] fail_count:[0]
Mem (Ram + swap) used: used:[9.848M] max_used:[13.219M] limit:[96.000M] fail_count:[0]
Kernel Mem Info:占用的内核内存大小,不可被swap,主要用来存放进程数据等。
Mem already allocated Info:已分配的内存大小,limit即为burst内存大小。
Ram actually used: 实际占用的物理内存大小。
Mem (Ram + swap) used: 占用的物理内存和swap大小。
如果 实际占用的物理内存 == 占用的物理内存和swap大小 那么恭喜你,你的vps里运行的程序都在内存中,主机超售不严重。
如果 实际占用的物理内存 < 占用的物理内存和swap大小 情况不妙,主机已经开始占用swap了,超售比较严重了。
另外我在测试过程中发现有一台vps实际占用物理内存大小显示比物理内存+swap总和还要大,现象很奇怪,查了一些资料没有关于这方面的说明,待后续调查。
脚本功能还比较粗糙,一些数据需要继续打磨,欢迎大家提意见~~
本文地址:http://www.snooda.com/read/263
下载地址:https://github.com/snooda/openvz_checker
etag生成规则的配置-lighttpd
[| 2012/04/11 15:20]
最近两天调试一个程序的时候遇到一个问题,发现把一个文件两行对换位置的时候lighttpd不会载入新文件,增加或删除一行就会,考虑到lighttpd有stat cache,怀疑是不是不考虑mtime,只看inode,于是cp了一下,发现还是不行。没办法开gdb调试了一下,囧,原来生成的etag只用到了文件size这一个参数。怪不得。
# 生成ETag的时候是否考虑文件的inode
etag.use-inode = "enable"
# 生成ETag的时候是否考虑文件的mtime
etag.use-mtime = "enable"
# 生成ETag的时候是否考虑文件的size
etag.use-size = "enable"
这是引发困扰的三个参数。平时建议全部开启,或开启后两个。
# 生成ETag的时候是否考虑文件的inode
etag.use-inode = "enable"
# 生成ETag的时候是否考虑文件的mtime
etag.use-mtime = "enable"
# 生成ETag的时候是否考虑文件的size
etag.use-size = "enable"
这是引发困扰的三个参数。平时建议全部开启,或开启后两个。
c程序中变量在循环内部还是外部声明的问题
[| 2012/04/09 15:40]
忘记之前从哪看过的一个文章说不要在for、while等循环内声明变量,因为每次都会重复分配空间,很慢。
今天发现一个模块把变量声明都放到while里面了,看了下代码没有发现必须声明在里面的原因,于是开始怀疑是不是声明在内外是差不多的。
于是测试了一下:
int main() {
int i = 0;
for(;i < 10000000; i++) {
int b;
b++;
}
return 1;
}
使用gcc 编译,把int b放在循环内外试了试,用time ./a.out查看执行时间,发现用时基本相同。
添加-O2优化选项,执行时间均缩减到之前的1/3,内外两种方式时间依然相同。
定义了一个struct实验了下,结果相同
也就是说栈上元素的操作不必纠结于变量声明于何处。
尝试了下堆上元素操作,在预料之内:时间差距巨大,因为重复分配释放内存。
所以对于栈上元素,声明放在循环里和循环外是一样的。堆上元素不同,需注意。
另,仍然需要注意一些计算操作需要放在循环外,比如求大小之类的,避免循环的每个周期重复计算。
原因猜测:1, cpu对栈操作有优化,速度非常快。
2,编译器的基本优化中会优化(gcc没有使用-O参数时仍会优化)
具体原因待深究
今天发现一个模块把变量声明都放到while里面了,看了下代码没有发现必须声明在里面的原因,于是开始怀疑是不是声明在内外是差不多的。
于是测试了一下:
引用
int main() {
int i = 0;
for(;i < 10000000; i++) {
int b;
b++;
}
return 1;
}
使用gcc 编译,把int b放在循环内外试了试,用time ./a.out查看执行时间,发现用时基本相同。
添加-O2优化选项,执行时间均缩减到之前的1/3,内外两种方式时间依然相同。
定义了一个struct实验了下,结果相同
也就是说栈上元素的操作不必纠结于变量声明于何处。
尝试了下堆上元素操作,在预料之内:时间差距巨大,因为重复分配释放内存。
所以对于栈上元素,声明放在循环里和循环外是一样的。堆上元素不同,需注意。
另,仍然需要注意一些计算操作需要放在循环外,比如求大小之类的,避免循环的每个周期重复计算。
原因猜测:1, cpu对栈操作有优化,速度非常快。
2,编译器的基本优化中会优化(gcc没有使用-O参数时仍会优化)
具体原因待深究
静态库和动态库编译链接时的依赖检查
[| 2012/04/05 19:48]
今天编译lua程序时发现总是报缺少dlopen和pow之类的,需要手动加-lm -dl才行。感觉有点奇异,按我的理解来说使用静态库是不需要考虑依赖的。仔细研究了下,发现很多误区。
首先用静态库编译出的可执行文件是不考虑库依赖的,但并不代表用静态库时也不需要考虑。静态库在编译时是不检查函数是否被实现的,也就是说只需要.h即可。
其次,静态库和动态库其实区别很大,静态库只是编译出.o的一个打包的文件,而动态库添加了链接信息。
这样的话静态库还有一个特性,就是在静态库中可以调用一些预留接口,而把这些接口留待以后实现。
首先用静态库编译出的可执行文件是不考虑库依赖的,但并不代表用静态库时也不需要考虑。静态库在编译时是不检查函数是否被实现的,也就是说只需要.h即可。
其次,静态库和动态库其实区别很大,静态库只是编译出.o的一个打包的文件,而动态库添加了链接信息。
这样的话静态库还有一个特性,就是在静态库中可以调用一些预留接口,而把这些接口留待以后实现。