Linux
通过URL Rewrite来设置JBoss的301跳转
by Elton on 2010年07月28日, under Java, Linux
Introduction
The rewrite valve implements URL rewrite functionnality in a way that is very similar to mod_rewrite from Apache HTTP Server.
Configuration
The rewrite valve is configured as a regular valve, by adding the following to server.xml as child of an Engine or Host element (or inside a context.xml file):
-
<Valve className="org.jboss.web.rewrite.RewriteValve" />
The valve will then use a rewrite.properties file containing the rewrite directives, located according to the container it is assocaited to:
If associated with an engine, it should be placed in a folder named [engine_name] placed either in the classloader, or in the conf folder of the current JBoss profile
If associated with a host, it should be placed in a folder named [engine_name]/[host_name] placed either in the classloader, or in the conf folder of the current JBoss profile
If associated with a context, it should be placed in the WEB-INF folder of the web application
Directives
The rewrite.properties file contains a list of directives which closely resemble the directives used by mod_rewrite, in particular the central RewriteRule and RewriteCond directives.
Note: This section is a modified version of the mod_rewrite documentation, which is Copyright 1995-2006 The Apache Software Foundation, and licensed under the under the Apache License, Version 2.0.
RewriteCond
Syntax: RewriteCond TestString CondPattern
The RewriteCond directive defines a rule condition. One or more RewriteCond can precede a RewriteRule directive. The following rule is then only used if both the current state of the URI matches its pattern, and if these conditions are met.
TestString is a string which can contain the following expanded constructs in addition to plain text:
RewriteRule backreferences: These are backreferences of the form $N (0 <= N <= 9), which provide access to the grouped parts (in parentheses) of the pattern, from the RewriteRule which is subject to the current set of RewriteCond conditions..
RewriteCond backreferences: These are backreferences of the form %N (1 <= N <= 9), which provide access to the grouped parts (again, in parentheses) of the pattern, from the last matched RewriteCond in the current set of conditions.
RewriteMap expansions: These are expansions of the form ${mapname:key|default}. See the documentation for RewriteMap for more details.
Server-Variables: These are variables of the form %{ NAME_OF_VARIABLE } where NAME_OF_VARIABLE can be a string taken from the following list:
HTTP headers: connection & request:
HTTP_USER_AGENT
HTTP_REFERER
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_ACCEPT
REMOTE_ADDR
REMOTE_HOST
REMOTE_PORT
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
REQUEST_PATH
CONTEXT_PATH
SERVLET_PATH
PATH_INFO
QUERY_STRING
AUTH_TYPE
server internals: date and time: specials:
DOCUMENT_ROOT
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME
THE_REQUEST
REQUEST_URI
REQUEST_FILENAME
HTTPS
These variables all correspond to the similarly named HTTP MIME-headers and Servlet API methods. Most are documented elsewhere in the Manual or in the CGI specification. Those that are special to the rewrite valve include those below.
REQUEST_PATH
Corresponds to the full path that is used for mapping.
CONTEXT_PATH
Corresponds to the path of the mapped context.
SERVLET_PATH
Corresponds to the servlet path.
THE_REQUEST
The full HTTP request line sent by the browser to the server (e.g., "GET /index.html HTTP/1.1"). This does not include any additional headers sent by the browser.
REQUEST_URI
The resource requested in the HTTP request line. (In the example above, this would be "/index.html".)
REQUEST_FILENAME
The full local filesystem path to the file or script matching the request.
HTTPS
Will contain the text "on" if the connection is using SSL/TLS, or "off" otherwise.
Other things you should be aware of:
The variables SCRIPT_FILENAME and REQUEST_FILENAME contain the same value - the value of the filename field of the internal request_rec structure of the Apache server. The first name is the commonly known CGI variable name while the second is the appropriate counterpart of REQUEST_URI (which contains the value of the uri field of request_rec).
%{ENV:variable}, where variable can be any Java system property, is also available.
%{SSL:variable}, where variable is the name of an SSL environment variable, are not implemented yet. Example: %{SSL:SSL_CIPHER_USEKEYSIZE} may expand to 128.
%{HTTP:header}, where header can be any HTTP MIME-header name, can always be used to obtain the value of a header sent in the HTTP request. Example: %{HTTP:Proxy-Connection} is the value of the HTTP header ``Proxy-Connection:''.
CondPattern is the condition pattern, a regular expression which is applied to the current instance of the TestString. TestString is first evaluated, before being matched against CondPattern.
Remember: CondPattern is a perl compatible regular expression with some additions:
You can prefix the pattern string with a '!' character (exclamation mark) to specify a non-matching pattern.
There are some special variants of CondPatterns. Instead of real regular expression strings you can also use one of the following:
'
'>CondPattern’ (lexicographically follows)
Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString lexicographically follows CondPattern.
‘=CondPattern’ (lexicographically equal)
Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString is lexicographically equal to CondPattern (the two strings are exactly equal, character for character). If CondPattern is “” (two quotation marks) this compares TestString to the empty string.
‘-d’ (is directory)
Treats the TestString as a pathname and tests whether or not it exists, and is a directory.
‘-f’ (is regular file)
Treats the TestString as a pathname and tests whether or not it exists, and is a regular file.
‘-s’ (is regular file, with size)
Treats the TestString as a pathname and tests whether or not it exists, and is a regular file with size greater than zero.
. All of these tests can also be prefixed by an exclamation mark (‘!’) to negate their meaning.
You can also set special flags for CondPattern by appending [flags] as the third argument to the RewriteCond directive, where flags is a comma-separated list of any of the following flags:
‘nocase|NC’ (no case)
This makes the test case-insensitive – differences between ‘A-Z’ and ‘a-z’ are ignored, both in the expanded TestString and the CondPattern. This flag is effective only for comparisons between TestString and CondPattern. It has no effect on filesystem and subrequest checks.
‘ornext|OR’ (or next condition)
Use this to combine rule conditions with a local OR instead of the implicit AND. Typical example:
-
-
RewriteCond %{REMOTE_HOST} ^host1.* [OR]
-
RewriteCond %{REMOTE_HOST} ^host2.* [OR]
-
RewriteCond %{REMOTE_HOST} ^host3.*
-
RewriteRule …some special stuff for any of these hosts…
Without this flag you would have to write the condition/rule pair three times.
Example:
To rewrite the Homepage of a site according to the “User-Agent:” header of the request, you can use the following:
-
-
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
-
RewriteRule ^/$ /homepage.max.html [L]
-
-
RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
-
RewriteRule ^/$ /homepage.min.html [L]
-
-
RewriteRule ^/$ /homepage.std.html [L]
-
Explanation: If you use a browser which identifies itself as ‘Mozilla’ (including Netscape Navigator, Mozilla etc), then you get the max homepage (which could include frames, or other special features). If you use the Lynx browser (which is terminal-based), then you get the min homepage (which could be a version designed for easy, text-only browsing). If neither of these conditions apply (you use any other browser, or your browser identifies itself as something non-standard), you get the std (standard) homepage.
RewriteMap
Syntax: RewriteMap name rewriteMapClassName optionalParameters
The maps are implemented using an interface that users must implement. Its class name is org.jboss.web.rewrite.RewriteMap, and its code is:
-
-
package org.jboss.web.rewrite;
-
-
public interface RewriteMap {
-
}
-
RewriteRule
Syntax: RewriteRule Pattern Substitution
The RewriteRule directive is the real rewriting workhorse. The directive can occur more than once, with each instance defining a single rewrite rule. The order in which these rules are defined is important – this is the order in which they will be applied at run-time.
Pattern is a perl compatible regular expression, which is applied to the current URL. “Current” means the value of the URL when this rule is applied. This may not be the originally requested URL, which may already have matched a previous rule, and have been altered.
Some hints on the syntax of regular expressions:
Text:
. Any single character
[chars] Character class: Any character of the class “chars”
[^chars] Character class: Not a character of the class “chars”
text1|text2 Alternative: text1 or text2
Quantifiers:
? 0 or 1 occurrences of the preceding text
* 0 or N occurrences of the preceding text (N > 0)
+ 1 or N occurrences of the preceding text (N > 1)
Grouping:
(text) Grouping of text
(used either to set the borders of an alternative as above, or
to make backreferences, where the Nth group can
be referred to on the RHS of a RewriteRule as $N)
Anchors:
^ Start-of-line anchor
$ End-of-line anchor
Escaping:
\char escape the given char
(for instance, to specify the chars “.[]()” etc.)
For more information about regular expressions, have a look at the perl regular expression manpage (“perldoc perlre”). If you are interested in more detailed information about regular expressions and their variants (POSIX regex etc.) the following book is dedicated to this topic:
Mastering Regular Expressions, 2nd Edition
Jeffrey E.F. Friedl
O’Reilly & Associates, Inc. 2002
ISBN 0-596-00289-0
In the rules, the NOT character (‘!’) is also available as a possible pattern prefix. This enables you to negate a pattern; to say, for instance: “if the current URL does NOT match this pattern”. This can be used for exceptional cases, where it is easier to match the negative pattern, or as a last default rule.
Note: When using the NOT character to negate a pattern, you cannot include grouped wildcard parts in that pattern. This is because, when the pattern does NOT match (ie, the negation matches), there are no contents for the groups. Thus, if negated patterns are used, you cannot use $N in the substitution string!
The substitution of a rewrite rule is the string which is substituted for (or replaces) the original URL which Pattern matched. In addition to plain text, it can include
back-references ($N) to the RewriteRule pattern
back-references (%N) to the last matched RewriteCond pattern
server-variables as in rule condition test-strings (%{VARNAME})
mapping-function calls (${mapname:key|default})
Back-references are identifiers of the form $N (N=0..9), which will be replaced by the contents of the Nth group of the matched Pattern. The server-variables are the same as for the TestString of a RewriteCond directive. The mapping-functions come from the RewriteMap directive and are explained there. These three types of variables are expanded in the order above.
As already mentioned, all rewrite rules are applied to the Substitution (in the order in which they are defined in the config file). The URL is completely replaced by the Substitution and the rewriting process continues until all rules have been applied, or it is explicitly terminated by a flag.
There is a special substitution string named ‘-’ which means: NO substitution! This is useful in providing rewriting rules which only match URLs but do not substitute anything for them. It is commonly used in conjunction with the C (chain) flag, in order to apply more than one pattern before substitution occurs.
Additionally you can set special flags for Substitution by appending [flags] as the third argument to the RewriteRule directive. Flags is a comma-separated list of any of the following flags:
‘chain|C’ (chained with next rule)
This flag chains the current rule with the next rule (which itself can be chained with the following rule, and so on). This has the following effect: if a rule matches, then processing continues as usual – the flag has no effect. If the rule does not match, then all following chained rules are skipped. For instance, it can be used to remove the “.www” part, inside a per-directory rule set, when you let an external redirect happen (where the “.www” part should not occur!).
‘cookie|CO=NAME:VAL:domain[:lifetime[:path]]’ (set cookie)
This sets a cookie in the client’s browser. The cookie’s name is specified by NAME and the value is VAL. The domain field is the domain of the cookie, such as ‘.apache.org’, the optional lifetime is the lifetime of the cookie in minutes, and the optional path is the path of the cookie
‘env|E=VAR:VAL’ (set environment variable)
This forces an environment variable named VAR to be set to the value VAL, where VAL can contain regexp backreferences ($N and %N) which will be expanded. You can use this flag more than once, to set more than one variable. The variables can later be dereferenced in many situations, most commonly from within XSSI (via ) or CGI ($ENV{‘VAR’}). You can also dereference the variable in a later RewriteCond pattern, using %{ENV:VAR}. Use this to strip information from URLs, while maintaining a record of that information.
‘forbidden|F’ (force URL to be forbidden)
This forces the current URL to be forbidden – it immediately sends back a HTTP response of 403 (FORBIDDEN). Use this flag in conjunction with appropriate RewriteConds to conditionally block some URLs.
‘gone|G’ (force URL to be gone)
This forces the current URL to be gone – it immediately sends back a HTTP response of 410 (GONE). Use this flag to mark pages which no longer exist as gone.
‘host|H=Host’ (apply rewriting to host)
Rather that rewrite the URL, the virtual host will be rewritten.
‘last|L’ (last rule)
Stop the rewriting process here and don’t apply any more rewrite rules. This corresponds to the Perl last command or the break command in C. Use this flag to prevent the currently rewritten URL from being rewritten further by following rules. For example, use it to rewrite the root-path URL (‘/’) to a real one, e.g., ‘/e/www/’.
‘next|N’ (next round)
Re-run the rewriting process (starting again with the first rewriting rule). This time, the URL to match is no longer the original URL, but rather the URL returned by the last rewriting rule. This corresponds to the Perl next command or the continue command in C. Use this flag to restart the rewriting process – to immediately go to the top of the loop.
Be careful not to create an infinite loop!
‘nocase|NC’ (no case)
This makes the Pattern case-insensitive, ignoring difference between ‘A-Z’ and ‘a-z’ when Pattern is matched against the current URL.
‘noescape|NE’ (no URI escaping of output)
This flag prevents the rewrite valve from applying the usual URI escaping rules to the result of a rewrite. Ordinarily, special characters (such as ‘%’, ‘$’, ‘;’, and so on) will be escaped into their hexcode equivalents (‘%25′, ‘%24′, and ‘%3B’, respectively); this flag prevents this from happening. This allows percent symbols to appear in the output, as in RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] which would turn ‘/foo/zed’ into a safe request for ‘/bar?arg=P1=zed’.
‘qsappend|QSA’ (query string append)
This flag forces the rewrite engine to append a query string part of the substitution string to the existing string, instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule.
‘redirect|R [=code]‘ (force redirect)
Prefix Substitution with http://thishost[:thisport]/ (which makes the new URL a URI) to force a external redirection. If no code is given, a HTTP response of 302 (MOVED TEMPORARILY) will be returned. If you want to use other response codes in the range 300-400, simply specify the appropriate number or use one of the following symbolic names: temp (default), permanent, seeother. Use this for rules to canonicalize the URL and return it to the client – to translate “/~” into “/u/”, or to always append a slash to /u/user, etc.
Note: When you use this flag, make sure that the substitution field is a valid URL! Otherwise, you will be redirecting to an invalid location. Remember that this flag on its own will only prepend http://thishost[:thisport]/ to the URL, and rewriting will continue. Usually, you will want to stop rewriting at this point, and redirect immediately. To stop rewriting, you should add the ‘L’ flag.
‘skip|S=num’ (skip next rule(s))
This flag forces the rewriting engine to skip the next num rules in sequence, if the current rule matches. Use this to make pseudo if-then-else constructs: The last rule of the then-clause becomes skip=N, where N is the number of rules in the else-clause. (This is not the same as the ‘chain|C’ flag!)
‘type|T=MIME-type’ (force MIME type)
Force the MIME-type of the target file to be MIME-type. This can be used to set up the content-type based on some conditions. For example, the following snippet allows .php files to be displayed by mod_php if they are called with the .phps extension: RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]
参考:http://www.jboss.org/file-access/default/members/jbossweb/freezone/modules/rewrite/index.html
如何使用SHA1或者MD5校验文件完整性
by Elton on 2010年07月4日, under Linux, Mac
有时候当你下载了一个大的文件,但是不知道这个文件是否完整的时候,可以使用提供下载者公布的md5或者sha1码来校验你所下载的文件是否跟下载提供着提供的文件完全一致。
如果你使用的是Mac OSX,UNIX或者Linux,可以使用以下命令来做这个工作:
-
-
/usr/bin/openssl sha1 [full path to file]
-
/usr/bin/openssl md5 [full path to file]
-
第一条命令是使用sha1来校验文件,第二条是使用md5来校验。 校验后会得到类似于如下的结果:
-
-
/usr/bin/openssl md5 sample.iso
-
MD5(sample.iso)= 3be75df53e0cfb3905af0b4f4471c9f3
-
等号后面的就是对应的MD5的值,你可以跟下载提供着公布的MD5值进行比对,如果完全一致,那么恭喜你,你所下载的文件跟下载提供者的文件一模一样。
struct stat
by Elton on 2009年12月3日, under Linux
Unix like的开发如果用stat()函数访问文件的话,会用到struct stat结构体。 其定义如下:
-
-
struct stat {
-
mode_t st_mode; //文件对应的模式,文件,目录等
-
ino_t st_ino; //inode节点号
-
dev_t st_dev; //设备号码
-
dev_t st_rdev; //特殊设备号码
-
nlink_t st_nlink; //文件的连接数
-
uid_t st_uid; //文件所有者
-
gid_t st_gid; //文件所有者对应的组
-
off_t st_size; //普通文件,对应的文件字节数
-
time_t st_atime; //文件最后被访问的时间
-
time_t st_mtime; //文件内容最后被修改的时间
-
time_t st_ctime; //文件状态改变时间
-
blksize_t st_blksize; //文件内容对应的块大小
-
blkcnt_t st_blocks; //伟建内容对应的块数量
-
};
-
Linux文件查找命令find,xargs详述
by Elton on 2009年12月1日, under Linux
前言:关于find命令
由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下。即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只你具有相应的权限。
在运行一个非常消耗资源的find命令时,很多人都倾向于把它放在后台执行,因为遍历一个大的文件系统可能会花费很长的时间(这里是指30G字节以上的文件系统)。
一、find 命令格式
1、find命令的一般形式为;
-
-
find pathname -options [-print -exec -ok …]
-
2、find命令的参数;
-
-
pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。
-
-print: find命令将匹配的文件输出到标准输出。
-
-exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为‘command’ { } \;,注意{ }和\;之间的空格。
-
-ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
-
3、find命令选项
-
-
-name
-
按照文件名查找文件。
-
-
-perm
-
按照文件权限来查找文件。
-
-
-prune
-
使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。
-
-
-user
-
按照文件属主来查找文件。
-
-
-group
-
按照文件所属的组来查找文件。
-
-
-mtime -n +n
-
按照文件的更改时间来查找文件, – n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。
-
-
-nogroup
-
查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
-
-
-nouser
-
查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
-
-newer file1 ! file2
-
-
查找更改时间比文件file1新但比文件file2旧的文件。
-
-type
-
-
查找某一类型的文件,诸如:
-
-
b – 块设备文件。
-
d – 目录。
-
c – 字符设备文件。
-
p – 管道文件。
-
l – 符号链接文件。
-
f – 普通文件。
-
-
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
-
-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-
-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
-
-
-mount:在查找文件时不跨越文件系统mount点。
-
-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
-
-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。
-
另外,下面三个的区别:
-
-
-amin n
-
查找系统中最后N分钟访问的文件
-
-
-atime n
-
查找系统中最后n*24小时访问的文件
-
-
-cmin n
-
查找系统中最后N分钟被改变文件状态的文件
-
-
-ctime n
-
查找系统中最后n*24小时被改变文件状态的文件
-
-
-mmin n
-
查找系统中最后N分钟被改变文件数据的文件
-
-
-mtime n
-
查找系统中最后n*24小时被改变文件数据的文件
-
4、使用exec或ok来执行shell命令
使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便的
在有些操作系统中只允许-exec选项执行诸如l s或ls -l这样的命令。大多数用户使用这一选项是为了查找旧文件并删除它们。建议在真正执行rm命令删除文件之前,最好先用ls命令看一下,确认它们是所要删除的文件。
exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{ },一个空格和一个\,最后是一个分号。为了使用exec选项,必须要同时使用print选项。如果验证一下find命令,会发现该命令只输出从当前路径起的相对路径及文件名。
例如:为了用ls -l命令列出所匹配到的文件,可以把ls -l命令放在find命令的-exec选项中
-
-
# find . -type f -exec ls -l { } \;
-
-rw-r–r– 1 root root 34928 2003-02-25 ./conf/httpd.conf
-
-rw-r–r– 1 root root 12959 2003-02-25 ./conf/magic
-
-rw-r–r– 1 root root 180 2003-02-25 ./conf.d/README
-
上面的例子中,find命令匹配到了当前目录下的所有普通文件,并在-exec选项中使用ls -l命令将它们列出。
在/logs目录中查找更改时间在5日以前的文件并删除它们:
-
-
$ find logs -type f -mtime +5 -exec rm { } \;
-
记住:在shell中用任何方式删除文件之前,应当先查看相应的文件,一定要小心!当使用诸如mv或rm命令时,可以使用-exec选项的安全模式。它将在对每个匹配到的文件进行操作之前提示你。
在下面的例子中, find命令在当前目录中查找所有文件名以.LOG结尾、更改时间在5日以上的文件,并删除它们,只不过在删除之前先给出提示。
-
-
$ find . -name "*.conf" -mtime +5 -ok rm { } \;
-
< rm … ./conf/httpd.conf > ? n
-
按y键删除文件,按n键不删除。
任何形式的命令都可以在-exec选项中使用。
在下面的例子中我们使用grep命令。find命令首先匹配所有文件名为“ passwd*”的文件,例如passwd、passwd.old、passwd.bak,然后执行grep命令看看在这些文件中是否存在一个sam用户。
-
-
# find /etc -name "passwd*" -exec grep "sam" { } \;
-
sam:x:501:501::/usr/sam:/bin/bash
-
二、find命令的例子;
1、查找当前用户主目录下的所有文件:
下面两种方法都可以使用
-
-
$ find $HOME -print
-
$ find ~ -print
-
2、让当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件;
-
-
$ find . -type f -perm 644 -exec ls -l { } \;
-
3、为了查找系统中所有文件长度为0的普通文件,并列出它们的完整路径;
-
-
$ find / -type f -size 0 -exec ls -l { } \;
-
4、查找/var/logs目录中更改时间在7日以前的普通文件,并在删除之前询问它们;
-
-
$ find /var/logs -type f -mtime +7 -ok rm { } \;
-
5、为了查找系统中所有属于root组的文件;
-
-
$find . -group root -exec ls -l { } \;
-
-rw-r–r– 1 root root 595 10月 31 01:09 ./fie1
-
6、find命令将删除当目录中访问时间在7日以来、含有数字后缀的admin.log文件。
该命令只检查三位数字,所以相应文件的后缀不要超过999。先建几个admin.log*的文件 ,才能使用下面这个命令
-
-
$ find . -name "admin.log[0-9][0-9][0-9]" -atime -7 -ok
-
rm { } \;
-
< rm … ./admin.log001 > ? n
-
< rm … ./admin.log002 > ? n
-
< rm … ./admin.log042 > ? n
-
< rm … ./admin.log942 > ? n
-
7、为了查找当前文件系统中的所有目录并排序;
-
-
$ find . -type d | sort
-
8、为了查找系统中所有的rmt磁带设备;
-
-
$ find /dev/rmt -print
-
三、xargs
-
-
xargs – build and execute command lines from standard input
-
在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;
而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
来看看xargs命令是如何同find命令一起使用的,并给出一些例子。
下面的例子查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件
-
-
#find . -type f -print | xargs file
-
./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text
-
./.kde/Autostart/.directory: ISO-8859 text\
-
……
-
在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中:
-
-
$ find / -name "core" -print | xargs echo "" >/tmp/core.log
-
上面这个执行太慢,我改成在当前目录下查找
-
-
#find . -name "file*" -print | xargs echo "" > /temp/core.log
-
# cat /temp/core.log
-
./file6
-
在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:
-
-
# ls -l
-
drwxrwxrwx 2 sam adm 4096 10月 30 20:14 file6
-
-rwxrwxrwx 2 sam adm 0 10月 31 01:01 http3.conf
-
-rwxrwxrwx 2 sam adm 0 10月 31 01:01 httpd.conf
-
-
# find . -perm -7 -print | xargs chmod o-w
-
# ls -l
-
drwxrwxr-x 2 sam adm 4096 10月 30 20:14 file6
-
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf
-
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
-
用grep命令在所有的普通文件中搜索hostname这个词:
-
-
# find . -type f -print | xargs grep "hostname"
-
./httpd1.conf:# different IP addresses or hostnames and have them handled by the
-
./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames
-
on your
-
用grep命令在当前目录下的所有普通文件中搜索hostnames这个词:
-
-
# find . -name \* -type f -print | xargs grep "hostnames"
-
./httpd1.conf:# different IP addresses or hostnames and have them handled by the
-
./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames
-
on your
-
注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。
find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。
四、find 命令的参数
下面是find一些常用参数的例子,有用到的时候查查就行了,像上面前几个贴子,都用到了其中的的一些参数,也可以用man或查看论坛里其它贴子有find的命令手册
1、使用name选项
文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用。
可以使用某种文件名模式来匹配文件,记住要用引号将文件名模式引起来。
不管当前路径是什么,如果想要在自己的根目录$HOME中查找文件名符合*.txt的文件,使用~作为 ‘pathname’参数,波浪号~代表了你的$HOME目录。
-
-
$ find ~ -name "*.txt" -print
-
想要在当前目录及子目录中查找所有的‘ *.txt’文件,可以用:
-
-
$ find . -name "*.txt" -print
-
想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,可以用:
-
-
$ find . -name "[A-Z]*" -print
-
想要在/etc目录中查找文件名以host开头的文件,可以用:
-
-
$ find /etc -name "host*" -print
-
想要查找$HOME目录中的文件,可以用:
-
-
$ find ~ -name "*" -print 或find . -print
-
要想让系统高负荷运行,就从根目录开始查找所有的文件。
-
-
$ find / -name "*" -print
-
如果想在当前目录查找文件名以两个小写字母开头,跟着是两个数字,最后是.txt的文件,下面的命令就能够返回名为ax37.txt的文件:
-
-
$find . -name "[a-z][a-z][0--9][0--9].txt" -print
-
2、用perm选项
按照文件权限模式用-perm选项,按文件权限模式来查找文件的话。最好使用八进制的权限表示法。
如在当前目录下查找文件权限位为755的文件,即文件属主可以读、写、执行,其他用户可以读、执行的文件,可以用:
-
-
$ find . -perm 755 -print
-
还有一种表达方法:在八进制数字前面要加一个横杠-,表示都匹配,如-007就相当于777,-006相当于666
-
-
# ls -l
-
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf
-
-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf
-
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
-
drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam
-
-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp
-
-
# find . -perm 006
-
# find . -perm -006
-
./sam
-
./httpd1.conf
-
./temp
-
-perm mode:文件许可正好符合mode
-
-
-perm +mode:文件许可部分符合mode
-
-
-perm -mode: 文件许可完全符合mode
-
-
3、忽略某个目录
如果在查找文件时希望忽略某个目录,因为你知道那个目录中没有你所要查找的文件,那么可以使用-prune选项来指出需要忽略的目录。在使用-prune选项时要当心,因为如果你同时使用了-depth选项,那么-prune选项就会被find命令忽略。
如果希望在/apps目录下查找文件,但不希望在/apps/bin目录下查找,可以用:
-
-
$ find /apps -path "/apps/bin" -prune -o -print
-
4、使用find查找文件的时候怎么避开某个文件目录
比如要在/usr/sam目录下查找不在dir1子目录之内的所有文件
-
-
find /usr/sam -path "/usr/sam/dir1" -prune -o -print
-
find [-path ..] [expression] 在路径列表的后面的是表达式
-path “/usr/sam” -prune -o -print 是 -path “/usr/sam” -a -prune -o
-print 的简写表达式按顺序求值, -a 和 -o 都是短路求值,与 shell 的 && 和 || 类似如果 -path “/usr/sam” 为真,则求值 -prune , -prune 返回真,与逻辑表达式为真;否则不求值 -prune,与逻辑表达式为假。如果 -path “/usr/sam” -a -prune 为假,则求值 -print ,-print返回真,或逻辑表达式为真;否则不求值 -print,或逻辑表达式为真。
这个表达式组合特例可以用伪码写为
-
-
if -path "/usr/sam" then
-
-prune
-
else
-
-print
-
避开多个文件夹
-
-
find /usr/sam \( -path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -print
-
圆括号表示表达式的结合。
\ 表示引用,即指示 shell 不对后面的字符作特殊解释,而留给 find 命令去解释其意义。
查找某一确定文件,-name等选项加在-o 之后
-
-
#find /usr/sam \(-path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -name "temp" -print
-
5、使用user和nouser选项
按文件属主查找文件,如在$HOME目录中查找文件属主为sam的文件,可以用:
-
-
$ find ~ -user sam -print
-
在/etc目录下查找文件属主为uucp的文件:
-
-
$ find /etc -user uucp -print
-
为了查找属主帐户已经被删除的文件,可以使用-nouser选项。这样就能够找到那些属主在/etc/passwd文件中没有有效帐户的文件。在使用-nouser选项时,不必给出用户名; find命令能够为你完成相应的工作。
例如,希望在/home目录下查找所有的这类文件,可以用:
-
-
$ find /home -nouser -print
-
6、使用group和nogroup选项
就像user和nouser选项一样,针对文件所属于的用户组, find命令也具有同样的选项,为了在/apps目录下查找属于gem用户组的文件,可以用:
-
-
$ find /apps -group gem -print
-
要查找没有有效所属用户组的所有文件,可以使用nogroup选项。下面的find命令从文件系统的根目录处查找这样的文件
-
-
$ find / -nogroup-print
-
7、按照更改时间或访问时间等查找文件
如果希望按照更改时间来查找文件,可以使用mtime,atime或ctime选项。如果系统突然没有可用空间了,很有可能某一个文件的长度在此期间增长迅速,这时就可以用mtime选项来查找这样的文件。
用减号-来限定更改时间在距今n日以内的文件,而用加号+来限定更改时间在距今n日以前的文件。
希望在系统根目录下查找更改时间在5日以内的文件,可以用:
-
-
$ find / -mtime -5 -print
-
为了在/var/adm目录下查找更改时间在3日以前的文件,可以用:
-
-
$ find /var/adm -mtime +3 -print
-
8、查找比某个文件新或旧的文件
如果希望查找更改时间比某个文件新但比另一个文件旧的所有文件,可以使用-newer选项。它的一般形式为:
newest_file_name ! oldest_file_name
其中,!是逻辑非符号。
查找更改时间比文件sam新但比文件temp旧的文件:
例:有两个文件
-
-
-rw-r–r– 1 sam adm 0 10月 31 01:07 fiel
-
-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf
-
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
-
drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam
-
-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp
-
-
# find -newer httpd1.conf ! -newer temp -ls
-
1077669 0 -rwxrwxr-x 2 sam adm 0 10月 31 01:01 ./httpd.conf
-
1077671 4 -rw-rw-rw- 1 root root 2792 10月 31 20:19 ./temp
-
1077673 0 -rw-r–r– 1 sam adm 0 10月 31 01:07 ./fiel
-
查找更改时间在比temp文件新的文件:
-
-
$ find . -newer temp -print
-
9、使用type选项
在/etc目录下查找所有的目录,可以用:
-
-
$ find /etc -type d -print
-
在当前目录下查找除目录以外的所有类型的文件,可以用:
-
-
$ find . ! -type d -print
-
在/etc目录下查找所有的符号链接文件,可以用
-
-
$ find /etc -type l -print
-
10、使用size选项
可以按照文件长度来查找文件,这里所指的文件长度既可以用块(block)来计量,也可以用字节来计量。以字节计量文件长度的表达形式为N c;以块计量文件长度只用数字表示即可。
在按照文件长度查找文件时,一般使用这种以字节表示的文件长度,在查看文件系统的大小,因为这时使用块来计量更容易转换。
在当前目录下查找文件长度大于1 M字节的文件:
-
-
$ find . -size +1000000c -print
-
在/home/apache目录下查找文件长度恰好为100字节的文件:
-
-
$ find /home/apache -size 100c -print
-
在当前目录下查找长度超过10块的文件(一块等于512字节):
-
-
$ find . -size +10 -print
-
11、使用depth选项
在使用find命令时,可能希望先匹配所有的文件,再在子目录中查找。使用depth选项就可以使find命令这样做。这样做的一个原因就是,当在使用find命令向磁带上备份文件系统时,希望首先备份所有的文件,其次再备份子目录中的文件。
在下面的例子中, find命令从文件系统的根目录开始,查找一个名为CON.FILE的文件。
它将首先匹配所有的文件然后再进入子目录中查找。
-
-
$ find / -name "CON.FILE" -depth -print
-
12、使用mount选项
在当前的文件系统中查找文件(不进入其他文件系统),可以使用find命令的mount选项。
从当前目录开始查找位于本文件系统中文件名以XC结尾的文件:
-
-
$ find . -name "*.XC" -mount -print
-
五、关于本文
本文是find 命令的详细说明,可贵的是针对参数举了很多的实例,大量的例证,让初学者更为容易理解;本文是zhy2111314兄贴在论坛中;我对本文进行了再次整理,为方便大家阅读; ── 北南南北
小组级git服务器搭建
by Elton on 2009年11月26日, under Linux
如果使用git的人数较少,可以使用下面的步骤快速部署一个git服务器环境。
1. 生成 SSH 公钥
每个需要使用git服务器的工程师,自己需要生成一个ssh公钥
进入自己的~/.ssh目录,看有没有用 文件名 和 文件名.pub 来命名的一对文件,这个 文件名 通常是 id_dsa 或者 id_rsa。 .pub 文件是公钥,另一个文件是密钥。假如没有这些文件(或者干脆连 .ssh 目录都没有),你可以用 ssh-keygen 的程序来建立它们,该程序在 Linux/Mac 系统由 SSH 包提供, 在 Windows 上则包含在 MSysGit 包里:
-
-
$ ssh-keygen
-
Generating public/private rsa key pair.
-
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
-
Enter passphrase (empty for no passphrase):
-
Enter same passphrase again:
-
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
-
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
-
The key fingerprint is:
-
43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local
-
它先要求你确认保存公钥的位置(.ssh/id_rsa),然后它会让你重复一个密码两次,如果不想在使用公钥的时候输入密码,可以留空。
现在,所有做过这一步的用户都得把它们的公钥给你或者 Git 服务器的管理者(假设 SSH 服务被设定为使用公钥机制)。他们只需要复制 .pub 文件的内容然后 e-email 之。公钥的样子大致如下:
-
-
$ cat ~/.ssh/id_rsa.pub
-
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
-
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
-
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
-
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
-
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
-
NrRFi9wrf+M7Q== schacon@agadorlaptop.local
-
2. 架设服务器
首先,创建一个 ‘git’ 用户并为其创建一个 .ssh 目录,在用户主目录下:
-
-
$ sudo adduser git
-
$ su git
-
$ cd
-
$ mkdir .ssh
-
接下来,把开发者的 SSH 公钥添加到这个用户的 authorized_keys 文件中。假设你通过 e-mail 收到了几个公钥并存到了临时文件里。只要把它们加入 authorized_keys 文件
-
-
$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
-
$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
-
$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys
-
现在可以使用 –bare 选项运行 git init 来设定一个空仓库,这会初始化一个不包含工作目录的仓库。
-
-
$ cd /opt/git
-
$ mkdir project.git
-
$ cd project.git
-
$ git –bare init
-
这时,开发人员就可以把它加为远程仓库,推送一个分支,从而把第一个版本的工程上传到仓库里了。值得注意的是,每次添加一个新项目都需要通过 shell 登入主机并创建一个纯仓库。我们不妨以 gitserver 作为 git 用户和仓库所在的主机名。如果你在网络内部运行该主机,并且在 DNS 中设定 gitserver 指向该主机,那么以下这些命令都是可用的:
-
-
# 在一个工程师的电脑上
-
$ cd myproject
-
$ git init
-
$ git add .
-
$ git commit -m ‘initial commit’
-
$ git remote add origin git@gitserver:/opt/git/project.git
-
$ git push origin master
-
这样,其他人的克隆和推送也一样变得很简单:
-
-
$ git clone git@gitserver:/opt/git/project.git
-
$ vim README
-
$ git commit -am ‘fix for the README file’
-
$ git push origin master
-
用这个方法可以很快捷的为少数几个开发者架设一个可读写的 Git 服务。
作为一个额外的防范措施,你可以用 Git 自带的 git-shell 简单工具来把 git 用户的活动限制在仅与 Git 相关。把它设为 git 用户登入的 shell,那么该用户就不能拥有主机正常的 shell 访问权。为了实现这一点,需要指明用户的登入shell 是 git-shell ,而不是 bash 或者 csh。你可能得编辑 /etc/passwd 文件
-
-
$ sudo vim /etc/passwd
-
在文件末尾,你应该能找到类似这样的行:
-
-
git:x:1000:1000::/home/git:/bin/sh
-
把 bin/sh 改为 /usr/bin/git-shell (或者用 which git-shell 查看它的位置)。该行修改后的样子如下:
-
-
git:x:1000:1000::/home/git:/usr/bin/git-shell
-
现在 git 用户只能用 SSH 连接来推送和获取 Git 仓库,而不能直接使用主机 shell。尝试登录的话,你会看到下面这样的拒绝信息:
-
-
$ ssh git@gitserver
-
fatal: What do you think I am? A shell? (你以为我是个啥?shell吗?)
-
Connection to gitserver closed. (gitserver 连接已断开。)
-
CentOS 5.3 OpenVZ安装指南
by Elton on 2009年10月27日, under Linux
1. 安装宿主系统CentOS 5.3,分区的时候,要分一个/vz的ext3分区用来存放OpenVZ的template和Virtual Private Servers。 官方的建议是:
/ 2-4G
/swap 2倍物理内存
/vz 剩余的磁盘空间
2. 关掉FIrewall和SELinux
3. 安装OpenVZ
a) 从http://wiki.openvz.org/Download/kernel下载你操作系统对应的内核版本。 我这里用的是ovzkernel-2.6.18-128.2.1.el5.028stab064.7.i686.rpm
-
-
rpm -ihv ovzkernel-2.6.18-128.2.1.el5.028stab064.7.i686.rpm
-
b) 编辑GRUB Loader
/boot/grub/grub.conf
确保grub.conf文件的内容为:
-
-
title OpenVZ (2.6.18-128.2.1.el5.028stab064.7)
-
root (hd0,0)
-
kernel /boot/vmlinuz-2.6.18-128.2.1.el5.028stab064.7 ro root=LABEL=/
-
initrd /boot/initrd-2.6.18-128.2.1.el5.028stab064.7.img
-
c) 设置sysctl参数
/etc/sysctl.conf
-
-
# On Hardware Node we generally need
-
# packet forwarding enabled and proxy arp disabled
-
net.ipv4.ip_forward = 1
-
net.ipv4.conf.default.proxy_arp = 0
-
# Enables source route verification
-
net.ipv4.conf.all.rp_filter = 1
-
# Enables the magic-sysrq key
-
kernel.sysrq = 1
-
# TCP Explict Congestion Notification
-
#net.ipv4.tcp_ecn = 0
-
# we do not want all our interfaces to send redirects
-
net.ipv4.conf.default.send_redirects = 1
-
net.ipv4.conf.all.send_redirects = 0
-
使用下面的命令,使设置生效,之后重启系统。
-
-
# sysctl -p
-
c) 安装客户端工具
- vzctl: 这个工具是用来操作VPS的,如创建,销毁,开始,关闭和设置参数
- vzquota: 用于设定VPS的 quota
- vzpkg:这个工具用来管理 OpenVZ的 templates.
-
-
rpm -Uhv vzyum-2.4.0-11.noarch.rpm
-
rpm -Uhv vzquota-3.0.12-1.i386.rpm
-
rpm -Uhv vzctl-3.0.23-1.i386.rpm
-
rpm -Uhv vzpkg-2.7.0-18.noarch.rpm
-
然后你就可以启动OpenVZ了
-
-
/etc/init.d/vz start
-
3.安装OpenVZ template
在这里下载你所需要的模板http://openvz.org/download/template/
先安装模板metadata,再使用vzpkgcache生成cache
或者直接在http://openvz.org/download/template/cache/下载已经cache过的模板,比如centos-5-x86_64.tar.gz ,不用解压,直接把它放到/vz/template/cache中。 然后使用下面的命令来生成虚机
-
-
vzctl create 101 –ostemplate centos-5-x86 –config vps.basic
-
create后面的数字是这个VPS的ID,每个VPS都要有一个唯一的ID来做标示。 可以使用ip的最后一位来做标示, 这样方便记忆。
VPS创建后,会在/vz/root/vpsid/生成一个目录作为它的私有空间.
为了便于设置,不必每个VPS都指定参数,创建的时候跟上了一个–config参数用于指定VPS的设置参数。 这些配置文件在/etc/sysconfig/vz-script中。 上面使用的就是/etc/sysconfig/vz-scripts/ve-vps.basic.conf-sample这个文件
你可以通过编辑/etc/sysconfig/vz文件的内容,来预先指定模板和配置文件,如:
-
-
DEF_OSTEMPLATE="centos-5-x86"
-
CONFIGFILE="vps.basic"
-
这样就可以通过下面的命令快速建立VPS
-
-
# vzctl create 101
-
Creating VPS private area: /vz/private/101
-
VPS is mounted
-
Postcreate action done
-
VPS is unmounted
-
VPS private area was created
-
4. 设置VPS
创建虚机后,使用下面命令来设置虚机的参数
-
-
vzctl set 101 –hostname test101.my.org –save #设置主机名
-
vzctl set 101 –nameserver 202.96.209.5 –save #设置DNS
-
vzctl set 101 –ipadd 172.1.1.101 –save #设置IP
-
vzctl set 101 –userpasswd username:password #设置帐号
-
5. 启动和终止
a) 启动
-
-
vzctl start 101
-
b)终止
-
-
vzctl stop 101
-
c)查看状态
-
-
vzctl status 101
-
d)查看所有虚机的资源占用情况
-
-
cat /proc/vz/veinfo
-
e) 查看所有虚机的状态
-
-
vzlist -a
-
6. 删除VPS
-
-
vzctl destroy 101
-
升级内核后spawn-fcgi无法启动
by Elton on 2009年09月17日, under Linux, PHP
今天升级Linux内核到2.6.30-r5。但是升级重启后,发现blog打不开了。Nginx报502的Gateway错误。
第一反应就是起到php解析作用的spawn-fcgi没有启动起来。于是尝试再次手动启动。 但是发现怎么也启动不起来。
开始以为是因为升级内核引起的,于是退回以前的内核版本,结果一样。始终无法启动spawn-fcgi的fastcgi服务。说明不是内核的问题。 检查Nginx日志和系统日志都没有什么有价值的信息。
在一筹莫展的时候,突然注意到启动spawn-fcgi的命令中包含了php-cgi这个命令。 会不会是php的问题呢。 后来手工直接执行,发现确实php有问题。 重新使用emerge -av php编译安装php后,终于可以启动spawn-fcgi了。 网站也一切正常了。
出现问题的原因应该是以前使用emerge升级过系统,部分升级影响了php所需要调用的文件,当时没有重新启动,升级后的影响没有马上生效。 这次升级内核重启后,那些升级都生效了,结果问题就暴露出来了。
以后出现问题还是不要着急,任何环节都有可能出现问题。 而且有时候可能被问题的表象所蒙蔽,比如这次升级就误认为是因为内核的问题,但是其实后来证明根本跟内核没有关系。 出现问题还是要不放过任何可能出现问题的地方,即使你觉得不可能出现问题的地方也要去测试一下,逐一排查,最终肯定可以找到问题的原因的。
Gentoo下安装PHP和Nginx请参考之前发表的帖子
使用rsync同步文件
by Elton on 2009年09月4日, under Linux
什么是 rsync?
rsync 应用程序是在 Linux® 和 UNIX® 上广泛使用的文件传输和同步程序,而且它已经移植到了 Windows® 上。它的关键特性是一个非常快的算法,它只通过数据链路发送文件差异,因此把机器之间传输的数据总量降低到最低限度。(如果使用 File Transfer Protocol [FTP] 或 rcp 和 scp 等实用程序,那么即使只修改了一个字节,也会发送完整的文件)。当然,rsync 并非只能处理现有的文件:它还可以处理只在链路一端存在的文件和目录。最后,通过压缩数据来优化通信,因此可以通过非宽带连接使用这个工具。
使用 rsync
我们使用 rsync 把本地文件直接同步到一个远程服务器。还可以把远程服务器同步到本地,或者同步两个本地目录,但是不能同步两个远程服务器。
效果相同但格式不同的两个rsync命令
-
-
rsync –compress –recursive –delete –links \
-
–times –perms –owner –group \
-
–verbose –progress –stats \
-
–rsh="ssh" \
-
–exclude "*bak" –exclude "*~" \
-
/my/path/at/the/laptop/* myserver:/some/path/at/the/server
-
-
rsync -zrltpogve "ssh" –progress –stats –delete \
-
–exclude "*bak" –exclude "*~" \
-
/my/path/at/the/laptop/* myserver:/some/path/at/the/server
-
注意,上面命令中选项的次序是任意的,而且大多数选项有短格式。首先,–compress(或 -z)指定将压缩数据,这可以节省带宽。应该总是使用这个选项。(在非常高速的数据链路上,不进行压缩可能也可以,但是对于大多数远程连接,压缩都是有帮助的)。可以使用补充选项 –compress-level=level 指定压缩的级别;但是,通常可以接受标准的压缩级别。
–recursive (-r) 选项让 rsync 递归地复制所有目录。这会复制目录中的所有文件,包括其中的子目录及其内容。如果不需要这个功能,可以使用 –dirs 选项 (-d) 产生相反的效果:跳过子目录及其内容。
在默认情况下,rsync 把需要的文件复制到目标计算机,但是并不删除额外文件。通过使用 –delete 选项,目标目录会与原目录保持完全一致。但是要注意:如果把一个空目录同步到远程目录,就会删除远程目录中的所有内容!
如果原目录中有符号链接,–links 选项(或 -l)会在目标目录中重新创建这些符号链接。另一种方法是使用 –copy-links(或 -L)复制符号链接指向的文件或目录,而不是复制符号链接本身。如果有符号链接指向复制的树之外的文件或目录(这是一种安全风险),可以使用 –copy-unsafe-links。–safe-links 选项忽略这样的链接,这更安全。
后面四个选项(–times、–perms、–owner 和 –group 或 -tpog)分别让 rsync 保持原来的更新时间戳、权限、所有者和组信息。同时指定所有这些选项的简便方法是使用 –archive(或 -a),这还会设置 –recursive 和 –links 选项。
后面三个选项(–verbose、–progress 和 –stats)提供关于 rsync 正在执行的操作的大量信息。如果对这些信息不感兴趣,只需跳过它们,除非出现错误,rsync 会悄悄地运行。
尽管当前的 rsync 版本默认使用 ssh,但是可以使用 –rsh(或 -e)选项强制使用 ssh。如果需要使用额外的 ssh 参数(例如希望让 ssh 使用非标准端口),可以添加这些参数,例如 –rsh “ssh -p 12345″。
可以使用 –exclude 选项(和对应的 –include)选择要同步的文件。在这个示例中,排除了常见的备份文件。应该根据需要排除和包含文件,从而优化发送的内容。
最后,指定源路径和目标路径。不要忘记最后的 /*,否则结果可能不符合期望。可以通过查看文档了解 some/path、some/path/ 和 some/path/* 之间的差异。但是,使用 /* 是最保险的方法。
可以使用 -a 选项 (–archive) 简化清单 1 中的命令,见 清单 2。(如果作为根在服务器上运行 rsync,-a 选项可能会复制一些额外的内容 — 请查阅文档 — 这不是一种安全的做法)。rsync 还有许多选项;可以通过 rsync –help 和 man rsync 了解所有选项。
F5负载均衡配置手册
by Elton on 2009年08月27日, under Linux
负载均衡器通常称为四层交换机或七层交换机。四层交换机主要分析IP层及TCP/UDP层,实现四层流量负载均衡。七层交换机除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息。
一、F5配置步骤:
1、F5组网规划
(1)组网拓朴图(具体到网络设备物理端口的分配和连接,服务器网卡的分配与连接)
(2)IP地址的分配(具体到网络设备和服务器网卡的IP地址的分配)
(3)F5上业务的VIP、成员池、节点、负载均衡算法、策略保持方法的确定
2、F5配置前的准备工作
(1)版本检查
f5-portal-1:~# b version
Kernel:
BIG-IP Kernel 4.5PTF-07 Build18
(2)时间检查--如不正确,请到单用户模式下进行修改
f5-portal-1:~# date
Thu May 20 15:05:10 CST 2004
(3)申请license--现场用的F5都需要自己到F5网站上申请license
3、F5 的通用配置
(1)在安全要求允许的情况下,在setup菜单中可以打开telnet及ftp功能,便于以后方便维护
(2)配置vlan unique_mac选项,此选项是保证F5上不同的vlan 的MAC地址不一样。在缺省情况下,F5的各个vlan的MAC地址是一样的,建议在配置时,把此项统一选择上。可用命令ifconfig –a来较验
具体是system/Advanced Properties/vlan unique_mac
(3)配置snat any_ip选项选项,此选项为了保证内网的机器做了snat后,可以对ping的数据流作转换。Ping是第三层的数据包,缺省情况下F5是不对 ping的数据包作转换,也就是internal vlan的主机无法ping external vlan的机器。(注意:还可以采用telnet来验证。)
具体是system/Advanced Properties/snat any_ip
4、F5 的初始化配置
建议在对F5进行初始时都用命令行方式来进行初始化(用Web页面初始化的方式有时会有问题)。登录到命令行上,运行config或setup命令可以进行初始化配置。初次运行时会提示一些license的信息。
default:~# config
5、F5双机切换监控配置(有F5双机时需要)
(1)在web页面中选择相应的vlan,在arm failsafe选择则可。Timeout为从F5收不到包的时间起,经过多长时间就发生切换。此配置不能同步,需要在F5的主备机上同时配置。每个vlan都可以配置vlan arm failsafe。
具体在Network下
(2)在web页面中选择system,在redundant properties中把gateway failsafe选择则可。Router是需要监控的地址。此配置不能同步,需要在F5的主备机上同时配置。一套F5上只能配置一个gateway failsafe
具体在system/redundant properties/gateway failsafe
6、F5 MAC masquerade配置
Mac Masquerading是F5的Shared IP Address (Floating)的MAC地址,F5如果不配置此项,则shared IP Address的MAC地址与每台F5的vlan self IP Address的MAC地址是一样的。
一般服务器是以shared IP Address为网关,在两台F5上都配置了Mac Masquerade(相同的MAC地址),这样当F5发生切换后,服务器上shared IP address的MAC不变,保证了业务的不中断
具体在Network下
7、F5的pool配置
(1)在配置工具Web页面的导航面板中选择“Pools”中的“Pools”标签,点击“ADD”按钮添加服务器池(Pool)。
(2)在池属性(Pool Properties)中的“Load Balancing Method”表格中选择负载均衡策略,通常采用默认策略:“Round Robin”
(3)在“Resouces”表格中的“Member Address”文本框输入成员IP地址,在“Service”文本框中输入服务端口,点击“>>”添加到“Current Members”当前成员列表中。
(4)添加所有组成员,点击“Done”完成配置。
(5)在“Pools”中的“Pool Name”列选中特定池,然后池属性页面中选择“Persistence”标签。
(6)在“Persistence Type”表格中选定会话保持类型。点击“Apply”应用配置。
8、F5的virtual server配置
(1)在配置工具Web页面的导航面板中选择“Virtual Servers”中的“Virtual Servers”标签,点击“ADD”按钮添加虚拟服务器。
(2)在“Add Virtual Server”窗口的“Address”文本框中输入虚拟服务器IP地址,并在“Service”文本框中输入服务端口号或在下拉框中选择现有的服务名称,点击“Next”执行下一步。
(3)在“Add Virtual Server”窗口的“Configure Basic Properties”页面中点击“Next”执行下一步。 在“Add Virtual Server”窗口的“Select Physical Resources”页面中点击单选按钮“Pool”,并在下拉框中选择虚拟服务器对应的负载均衡池。
(4)按“Done”完成创建虚拟服务器。
9、F5的monitor的配置
(1)在配置工具Web页面的导航面板中选择“Monitor”中的“Monitors”标签,点击“ADD”按钮添加监控
(2)根据需要选择相关关联类型:“Node Associations”标签、Node Address Associations”标签、Service Associations”标签。
(3)被选关联标签中,在“Choose Monitor”表格中选择监控名称,点击“>>”按钮添加到“Monitor Rule”监控规格文本框中。监控规则可以为一条或多条。
(4)选择监控规则后,在对应节点的“Associate Current Monitor Rule”复选框中选中。如果欲删除监控关联,则选中对应节点的“Delete Existing Assocation”复选框。
(5)点击“Apply”关联监控
10、F5的SNAT配置
(1)在配置工具Web页面的导航面板中选择“NATs”中的“SNATs”标签,点击“ADD”按钮添加SNAT地址。
(2)在“Add SNAT”窗口中“Translation Address”的“IP”文本框中输入SNAT IP地址,并在“Origin List”的“Origin Address”文本框中输入节点IP地址或在“Origin VLAN”下拉框中选择VLAN名称,点击“>>”加入“Current List”列表。
(3)按“Done”完成添加SNAT IP地址。
11、F5主备机同步及切换校验
具体在system/Redundant Properties/synchonize Config…
12、业务的校验
F5主备机切换的校验
F5主备机业务运行的校验
其中1~6是基本配置,7~10业务配置,11~12校验
二、F5负载均衡器的维护
1、F5节点及应用的检查
通过“System -> Network Map”页面查看节点及应用状态
绿色:节点或虚拟服务器为“UP”
红色:节点或虚拟服务器状态为“Down”
灰色:节点或虚拟服务器被禁用
2、日志的检查
(1)当天日志:从web上查看logs中的system log、bigip log、monitor log,看日志中是否有异常。
(2)7天内的日志
系统日志文件 – /var/log/messages消息, 系统消息
BIG-IP 日志文件 – /var/log/bigip
“External” BIG-IP events
Monitor 日志文件 – /var/log/bigd
“Internal” BIG-IP Events
3DNS 日志文件 – /var/log/3dns
3DNS Information
用gzcat、more、vi命令打开
3、F5流量的检查
(1)业务上的基本维护主要是在F5上查看F5分发到各节点的connect是否负载均衡,一般不应有数量级的差别
(2)通过WEB->pool-> pool statistics中查看connection项中的total和current项,不应有明显的数量级的差别
(3)F5 qkview命令
执行qkview,执行完成后将输出信息保存在文件“/var/tmp/-tech.out”中,供高级技术支持用
(4)F5 tcpdump命令
TCPDUMP是Unix系统常用的报文分析工具,TCPDUMP经常用于故障定位,如会话保持失效、SNAT通信问题等
tcpdump [ -adeflnNOpqRStvxX ] [ -c count ] [ -F file ]
[ -i interface ] [ -m module ] [ -r file ]
[ -s snaplen ] [ -T type ] [ -w file ]
[ -E algo:secret ] [ expression ]
使用ETag和Expires调优web服务器性能
by Elton on 2009年08月4日, under Linux
正确使用Etag和Expires标识处理,可以使得页面更加有效被Cache。
在客户端通过浏览器发出第一次请求某一个URL时,根据 HTTP 协议的规定,浏览器会向服务器传送报头(Http Request Header),服务器端响应同时记录相关属性标记(Http Reponse Header),服务器端的返回状态会是200,格式类似如下:
-
-
HTTP/1.1 200 OK
-
Date: Tue, 03 Mar 2009 04:58:40 GMT
-
Content-Type: image/jpeg
-
Content-Length: 83185
-
Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
-
Cache-Control: max-age=2592000
-
-
Expires: Thu, 02 Apr 2009 05:14:08 GMT
-
Etag: “5d8c72a5edda8d6a:3239″
-
客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送报头(Http Request Header),服务器端响应并记录相关记录属性标记文件没有发生改动,服务器端返回304,直接从缓存中读取:
-
-
HTTP/1.x 304 Not Modified
-
Date: Tue, 03 Mar 2009 05:03:56 GMT
-
Content-Type: image/jpeg
-
Content-Length: 83185
-
Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
-
Cache-Control: max-age=2592000
-
Expires: Thu, 02 Apr 2009 05:14:08 GMT
-
Etag: “5d8c72a5edda8d6a:3239″
-
其中Last-Modified、Expires和Etag是标记页面缓存标识
一、Last-Modified、Expires和Etag相关工作原理
1、Last-Modified
在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记(Http Reponse Header)此文件在服务期端最后被修改的时间,格式类似这样:
Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头(Http Request Header),询问该时间之后文件是否有被修改过:
If-Modified-Since: Tue, 24 Feb 2009 08:01:04 GMT
如果服务器端的资源没有变化,则自动返回 HTTP 304 (NotChanged.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。
注:如果If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求
2、Etag工作原理
HTTP 协议规格说明定义ETag为“被请求变量的实体标记” (参见14.19)。简单点即服务器响应时给请求URL标记,并在HTTP响应头中将其传送到客户端,类似服务器端返回的格式:
Etag: “5d8c72a5edda8d6a:3239″
客户端的查询更新格式是这样的:
If-None-Match: “5d8c72a5edda8d6a:3239″
如果ETag没改变,则返回状态304。
即:在客户端发出请求后,Http Reponse Header中包含 Etag: “5d8c72a5edda8d6a:3239″
标识,等于告诉Client端,你拿到的这个的资源有表示ID:5d8c72a5edda8d6a:3239。当下次需要发Request索要同一个 URI的时候,浏览器同时发出一个If-None-Match报头( Http RequestHeader)此时包头中信息包含上次访问得到的Etag: “5d8c72a5edda8d6a:3239″标识。
If-None-Match: “5d8c72a5edda8d6a:3239“
,这样,Client端等于Cache了两份,服务器端就会比对2者的etag。如果If-None-Match为False,不返回200,返回304 (Not Modified) Response。
3、Expires
给出的日期/时间后,被响应认为是过时。如Expires: Thu, 02 Apr 2009 05:14:08 GMT
需和Last-Modified结合使用。用于控制请求文件的有效时间,当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端. 当缓存中数据失效或过期,才决定从服务器更新数据。
4、Last-Modified和Expires
Last-Modified标识能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而且要和Expires一起用。而Expires标识却使得浏览器干脆连HTTP请求都不用发,比如当用户F5或者点击Refresh按钮的时候就算对于有Expires的URI,一样也会发一个HTTP请求出去,所以,Last-Modified还是要用的,而 且要和Expires一起用。
5、Etag和Expires
如果服务器端同时设置了Etag和Expires时,Etag原理同样,即与Last-Modified/Etag对应的HttpRequest Header:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和WebServer发出的 Last-Modified,Etag值完全一样;在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和 Etag之后,服务器才能返回304.
6、Last-Modified和Etag
Last-Modified 和ETags请求的http报头一起使用,服务器首先产生 Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改,来决定文件是否继续缓存
过程如下:
1. 客户端请求一个页面(A)。
2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3. 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。
注:
1、Last-Modified和Etag头都是由Web Server发出的Http Reponse Header,Web Server应该同时支持这两种头。
2、Web Server发送完Last-Modified/Etag头给客户端后,客户端会缓存这些头;
3、客户端再次发起相同页面的请求时,将分别发送与Last-Modified/Etag对应的Http RequestHeader:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和 WebServer发出的Last-Modified,Etag值完全一样;
4、通过上述值到服务器端检查,判断文件是否继续缓存;
二、Apache、Lighttpd和Nginx中针配置Etag和Expires,有效缓存纯静态如css/js/pic/页面/流媒体等文件。
A、Expires
A.1、Apache Etag
使用Apache的mod_expires 模块来设置,这包括控制应答时的Expires头内容和Cache-Control头的max-age指令
-
-
ExpiresActive On
-
ExpiresByType image/gif “access plus 1 month”
-
ExpiresByType image/jpg “access plus 1 month”
-
ExpiresByType image/jpeg “access plus 1 month”
-
ExpiresByType image/x-icon “access plus 1 month”
-
ExpiresByType image/bmp “access plus 1 month”
-
ExpiresByType image/png “access plus 1 month”
-
ExpiresByType text/html “access plus 30 minutes”
-
ExpiresByType text/css “access plus 30 minutes”
-
ExpiresByType text/txt “access plus 30 minutes”
-
ExpiresByType text/js ”access plus 30 minutes”
-
ExpiresByType application/x-javascript ”access plus 30 minutes”
-
ExpiresByType application/x-shockwave-flash ”access plus 30 minutes”
-
或
-
<ifmodule mod_expires.c>
-
<filesmatch “\.(jpg|gif|png|css|js)$”>
-
ExpiresActive on
-
ExpiresDefault “access plus 1 year”
-
</filesmatch>
-
</ifmodule>
-
当设置了expires后,会自动输出Cache-Control 的max-age 信息
具体关于 Expires 详细内容可以查看Apache官方文档。
在这个时间段里,该文件的请求都将直接通过缓存服务器获取,
当然如果需要忽略浏览器的刷新请求(F5),缓存服务器squid还需要使用 refresh_pattern 选项来忽略该请求
-
-
refresh_pattern -i \.gif$ 1440 100% 28800 ignore-reload
-
refresh_pattern -i \.jpg$ 1440 100% 28800 ignore-reload
-
refresh_pattern -i \.jpeg$ 1440 100% 28800 ignore-reload
-
refresh_pattern -i \.png$ 1440 100% 28800 ignore-reload
-
refresh_pattern -i \.bmp$ 1440 100% 28800 ignore-reload
-
refresh_pattern -i \.htm$ 60 100% 100 ignore-reload
-
refresh_pattern -i \.html$ 1440 50% 28800 ignore-reload
-
refresh_pattern -i \.xml$ 1440 50% 28800 ignore-reload
-
refresh_pattern -i \.txt$ 1440 50% 28800 ignore-reload
-
refresh_pattern -i \.css$ 1440 50% 28800 reload-into-ims
-
refresh_pattern -i \.js$ 60 50% 100 reload-into-ims
-
refresh_pattern . 10 50% 60
-
有关Squid中Expires的说明,请参考Squid官方中refresh_pattern介绍。
A.2、Lighttpd Expires
和Apache一样Lighttpd设置expire也要先查看是否支持了mod_expire模块,
下面的设置是让URI中所有images目录下的文件1小时后过期;
-
-
expire.url = ( “/images/” => “access 1 hours” )
-
下面是让作用于images目录及其子目录的文件;
-
-
$HTTP["url"] =~ “^/images/” {
-
expire.url = ( “” => “access 1 hours” )
-
}
-
也可以指定文件的类型;
-
-
$HTTP["url"] =~ “\.(jpg|gif|png|css|js)$” {
-
expire.url = ( “” => “access 1 hours” )
-
}
-
具体参考Lighttpd官方Expires解释
A.3、Nginx中Expires
-
-
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
-
{
-
expires 30d;
-
}
-
location ~ .*\.(js|css)?$
-
{
-
expires 1h;
-
}
-
这类文件并不常修改,通过 expires 指令来控制其在浏览器的缓存,以减少不必要的请求。 expires 指令可以控制 HTTP 应答中的“ Expires ”和“ Cache-Control ”的头标(起到控制页面缓存的作用)。其他请参考Nginx中Expires
B.1、Apache中Etag设置
在Apache中设置Etag的支持比较简单,只用在含有静态文件的目录中建立一个文件.htaccess, 里面加入:
-
-
FileETag MTime Size
-
这样就行了,详细的可以参考Apache的FileEtag文档页
B.2、Lighttpd Etag
在Lighttpd中设置Etag支持:
etag.use-inode: 是否使用inode作为Etag
etag.use-mtime: 是否使用文件修改时间作为Etag
etag.use-size: 是否使用文件大小作为Etag
static-file.etags: 是否启用Etag的功能
第四个参数肯定是要enable的, 前面三个就看实际的需要来选吧,推荐使用修改时间
B.3、 Nginx Etag
Nginx中默认没有添加对Etag标识.Igor Sysoev的观点”在对静态文件处理上看不出如何Etag好于Last-Modified标识。”
Note:
Yes, it’s addition,and it’s easy to add, however, I do not see howETag is better than Last-Modified for static files. -Igor Sysoev
A nice short description is here:
http://www.mnot.net/cache_docs/#WORK
It looks to me that it makes some caches out there to cache theresponse from the origin server more reliable as in rfc2616(ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt) is written.
3.11 Entity Tags 13.3.2 Entity Tag Cache Validators 14.19 ETag
当然也有第三方nginx-static-etags 模块了,请参考
http://mikewest.org/2008/11/generating-etags-for-static-content-using-nginx
三、对于非实时交互动态页面中Expires和Etag处理
对数据更新并不频繁、如tag分类归档等等,可以考虑对其cache。简单点就是在非实时交互的动态程序中输出expires和etag标识,让其缓存。但需要注意关闭session,防止http response时http header包含session id标识;
3.1、Expires
如expires.php
-
-
<?php
-
?>
-
以上信息表示该文件自请求后24小时后过期。
其他需要处理的动态页面直接调用即可。
3.2、Etag
根据Http返回状态来处理。当返回304直接从缓存中读取
如etag.php
-
-
<?php
-
cache();
-
function cache()
-
{
-
$etag = “http://longrujun.name”;
-
if ($_SERVER[‘HTTP_IF_NONE_MATCH’] == $etag)
-
{
-
exit;
-
}
-
}
-
?>
-
来自: http://longrujun.name/index.php/2009/03/04/etag%E5%92%8Cexpires/


