老婆家的故事

上次说了外公的故事,这次说说我老婆家的故事,确切的说是我老婆爷爷奶奶的故事,我老婆的爷爷家是地主,他们家现在那个村庄的地在解放前都是他们家的,现在还有些邻居是以前给他们家打长工的,不过我老婆的爷爷算是开明地主,后来还加入了共产党,不过也就是这个身份,当时差点丢了性命,据说被国民党抓了,本来都要枪毙了,子弹是个臭子儿,侥幸逃脱,具体啥情况我也没了解清楚,不过确实很惊险。老婆的奶奶是大家闺秀,有钱人家的小姐,陪嫁中有一张大床,据说当时就值几十个大洋,后来日本人来了,老婆爷爷奶奶的家产全被掠夺光了,据说当时拉了好几卡车,所以我对老婆说,和日本人是家仇国恨,要是没有小日本,你奶奶说不定还能给你留些好东西呢。老婆的爷爷在几年前已经去世了,奶奶健在,身体很好,我说奶奶活到100岁肯定没问题,他们都是历史的见证者,真心希望老婆的奶奶身体健康,长命百岁。

—分割线—

今天在写Objective-C时候,解析接口返回的Json数据时出现了类型转换错误,具体就是字符串转整型数字出现错误,我仔细看了一下,是PHP接口返回的Json数据中数字型的数据,被加上了双引号,解决方法是在json_encode后面的参数设置为JSON_NUMERIC_CHECK,比如json_encode($jsonmsg, JSON_NUMERIC_CHECK);

修改之后运行出现错误,我查了一下,原来JSON_NUMERIC_CHECK这个参数是在PHP5.3.3加上的,而我用的Mac版的XAMPP集成环境中,PHP只到5.3.1,看来要升级,后来发现Mac版的XAMPP没有新版了,只能使用另一个集成环境MAMP,它提供了Mac环境下的Apache、Mysql、PHP的集成环境,我已经安装的MAMP里PHP版本为5.3.14,应该没问题,我直接修改MAMP目录下Apache的配置文件,增加虚拟目录(Alias),但修改之后重启MAMP就是不生效,非常奇怪,我搜了半天,也没发现是什么问题,后来发现在MAMP的菜单里,File->Edit Template->Apache->httpd.conf,编辑httpd.conf,之后重启MAMP终于好了。

—分割线—

欢迎订阅我的微信公共帐号:“Laoer杂谈”,搜索微信号:laoertalk,或扫描页面右侧的二维码
新浪微博:@laoer
Twitter:@laoer

云图

电影《云图》是在今年1月底在国内上映的,当时我没去看,前一段时间从同事那里Copy来了完整版的视频,在家里欣赏了这部史诗科幻电影巨作,看过以后就后悔之前没有去电影院贡献票房,不过国内版的有所删节,可能没有完整版的效果好。

《云图》讲述了6个看似不相关,但又环环相扣的故事,真是赞叹编剧和导演的驾驭能力,其中第5个故事《星美451的记录仪》给我的印象非常深刻,这个故事发生在未来的韩国首尔,其中还有中国演员周迅。其实整个《云图》所表达的是自由精神,我们需要不惧强权的向往自由,很多时候是因为你看不见(大家都明白的),当你看见的时候你就知道自由有多么美好,就像星美451看到了克隆人的下场,义无反顾的发表了宣言,最后虽然被处死,但她的努力对后世产生了深远的影响。

“要和人性的九头蛇斗争的人必须以经受巨大的痛苦为代价……你要明白,你生命的价值不过像是无边无垠的海洋里的一滴水!”,“但是如果没有众多的水滴,哪里会有海洋呢?”

我推荐大家看看这部电影,另一个值得关注的地方是,里面很多著名演员比如汤姆·汉克斯,哈利·贝瑞,都是一人扮演多个角色,明年的奥斯卡最佳化妆奖估计非《云图》莫属了。

—分割线—

Linux下删除1天之前修改过的文件的方法

find /tmp -name “session*” -mtime +1|xargs rm -rf //标示查找/tmp目录下,以session开头的,1天之前修改过的文件,并删除

linux 文件的三种时间(以 find 为例):
atime 最后一次访问时间, 如 ls, more 等, 但 chmod, chown, ls, stat 等不会修改些时间, 使用 ls -utl 可以按此时间顺序查看;
ctime 最后一次状态修改时间, 如 chmod, chown 等状态时间改变但修改时间不会改变, 使用 stat file 可以查看;
mtime 最后一次内容修改时间, 如 vi 保存后等, 修改时间发生改变的话, atime 和 ctime 也相应跟着发生改变。

在早版本的SVN,如果在Linux上Check Out工程,里面会包含.svn的隐藏文件夹,有事会给部署造成麻烦,所以还有一个删除.svn目录的方法

find . -type d -name “.svn”|xargs rm -rf

—分割线

今日调查继续上次的《打车软件调查》,欢迎各位参与,结果下次公布。

欢迎订阅我的微信公共帐号:“Laoer杂谈”,搜索微信号:laoertalk,或扫描页面右侧的二维码
新浪微博:@laoer
Twitter:@laoer

Nginx下alias支持PHP的问题

这几天在配置Nginx,PHP用FastCGI,想装一个phpMyAdmin管理数据库,phpMyAdmin不想放在网站根目录下,这样不容易和网站应用混在一起,这样phpMyAdmin的目录就放在别处,在Apache里,有alias,比较方便,在Nginx下没有虚拟目录概念的,是用location配合alias使用,我先试了简单的配置方式

location /web/ {
alias  /data/web/;
index  index.html index.htm index.php;
}

location ~ .*\.(php|php5)?$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

我用http://localhost/web/可以访问到/data/web目录下的静态文件,但访问php文件,却报No input file specified.的错误,而且在Nginx的error日志上却什么信息也没有,我在网上搜索了一下,判断应该是php文件并没有被后端的FastCGI运行,我又继续搜索一些文章,试着增加了一段配置

location /web/ {
alias  /data/web/;
index  index.html index.htm index.php;
}

location ~ ^/web/.+\.php$ {
root /data/;
rewrite /web/(.*\.php?) /$1 break;
include fcgi.conf;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
fastcgi_param SCRIPT_FILENAME /data/web$fastcgi_script_name;
}

location ~ .*\.(php|php5)?$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

这下可以了,原理应该是采用rewrite的方法,对于/web/下php类型的的请求交给后端的FastCGI处理,并且指定了php脚本的位置,这样我们就可以配置phpMyAdmin了,配置如下

location /phpmyadmin/ {
alias  /data/phpmyadmin/;
index  index.html index.htm index.php;
}

location ~ ^/phpmyadmin/.+\.php$ {
root /data/;
rewrite /phpmyadmin/(.*\.php?) /$1 break;
include fcgi.conf;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
fastcgi_param SCRIPT_FILENAME /data/phpmyadmin$fastcgi_script_name;
}

location ~ .*\.(php|php5)?$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

要注意的是

location ~ .*\.(php|php5)?$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

这段,要放在phpmyadmin的后面,放在前面就有问题,这是和Nginx的location规则有关,具体看Nginx的文档,另外,phpMyAdmin里要配置一下URI的绝对路径,就可以了。

Linux下Memcached安装事项

在Linux下安装Memcached,先要安装libevent,在http://www.monkey.org/~provos/libevent/下载

Memcache在http://www.danga.com/memcached/download.bml下载

可能是我将libevent安装在/usr/local/libevent目录的缘故,在启动memchached时报一个错误

./memcached: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory

我们先运行下面的命令,将libevent的lib目录加入LD_LIBRARY_PATH里

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/libevent/lib

之后再启动memcached就好了。

ORA-12547: TNS:lost contact问题

今天在Oracle Enterprise Linux上安装Oracle,后面创建数据实例的时候出现了ORA-12547: TNS:lost contact的错误,按理来说,Oracle Enterprise Linux可是就是针对Oracle的,怎么会出现这样的错误,在网上搜索了一下,可能是没有安装libaio包的缘故,我就试试吧。

在安装盘第3张里找到了libaio-0.3.105-2.i386.rpm和libaio-devel-0.3.105-2.i386.rpm,如果身边没有安装盘,可以到http://rpmfind.net上面去搜索一下,安装后,重起电脑,把以前安装过的Oracle卸载掉,重新安装,没有问题了。

以后需要注意,在安装Linux的时候就把这个包选进去。

Linux挂载USB硬盘的方法

先检查Linux是否加载usb模块

lsmod | grep usb

如果没有信息,则执行

modprobe usb-storage

之后把USB的硬盘接上,执行

fdisk -l

可以看到

Disk /dev/sda: 80.0 GB, 80026361856 bytes
255 heads, 63 sectors/track, 9729 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         587     4610655   82  Linux swap
/dev/sda3             588        9729    73433115   83  Linux

Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk /dev/sdb doesn’t contain a valid partition table

可以看到/dev/sda是我们已有的硬盘,/dev/sdb就是USB硬盘了,提示改硬盘还没有分区,接下来我们就对/dev/sdb做分区,执行命令

fdisk /dev/sdb

之后会提示

Command (m for help):

可以输入m看一下help,我们输入n,新创建一个分区,之后出现

Command action
e   extended
p   primary partition (1-4)

输入p,创建主分区,之后

Partition number (1-4):

输入1,会提示

First cylinder (1-121601, default 1):

直接回车,即默认1,也就是从1开始,提示

Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-121601, default 121601):

直接回车,因为我把整个硬盘分1个区,所以就用最大值,回车就可以了,提示

Using default value 121601

Command (m for help):

这时候我们可以输入p,看一下分区情况

Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1      121601   976760001   83  Linux

Command (m for help):

这时候输入w,写入分区表,这样就完成了,会提示

The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

我们再执行fdisk -l看一下情况

Disk /dev/sda: 80.0 GB, 80026361856 bytes
255 heads, 63 sectors/track, 9729 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         587     4610655   82  Linux swap
/dev/sda3             588        9729    73433115   83  Linux

Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1      121601   976760001   83  Linux

我们已经看到/dev/sdb1了,现在要对/dev/sdb1做一下格式化,在linux上可以将格式化成多种格式,比如ext3 、reiserfs 、ext2 、fat32 、msdos等,我们还是格式化成ext3的默认格式,执行

mkfs.ext3 /dev/sdb1

mke2fs 1.35 (28-Feb-2004)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
122109952 inodes, 244190000 blocks
12209500 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=247463936
7453 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848

Writing inode tables: done     (在这个地方会等待,直到done)
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information:

直接回车就之后就完成格式化

done

This filesystem will be automatically checked every 30 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

之后我们可以把/dev/sdb1挂载到系统中,比如

mount /dev/sdb1 /u02/oradata1

用df命令看一下

Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda3             72279384   9336512  59271220  14% /
/dev/sda1               101086      8741     87126  10% /boot
none                   1553948         0   1553948   0% /dev/shm
/dev/sdb1            961432072    110656 912483416   1% /u02/oradata1

/dev/sdb1已经mount到/u02/oradata1了。

LVS和Nginx的一些杂记

LVS(Linux Virtual Server)是章文嵩博士创立的开源项目,可以帮助我们建立高可用性和高扩展性的Linux集群,LVS性能非常好,在暂时不能花费巨资购买F5、NetDispatcher之类硬件的时期,LVS还是能够很好的满足需要的。

LVS的Linux组件IPVS在新版本的Linux内核里已经支持,不需要单独再安装,可以通过命令

lsmod |grep ip_vs

检查内核是否支持IPVS。

ipvsadm是LVS的管理软件,在编译安装的时候要注意,先做一个ln连接,类似

ln -s /usr/src/kernels/2.6.9-42.EL-smp-i686 /usr/src/linux

ln -s /usr/src/kernels/2.6.18-8.el5-x86_64 /usr/src/linux

keepalived是一个很方便的LVS管理工具,只要需要配置keepalived的配置文件就可以了,不用一条一条的执行ipvsadm命令了。

将keepalived加为服务的方法(keepalived默认安装在/usr/local/etc下)

cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived
cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/sbin/keepalived /usr/sbin/

关于虚拟IP与真实服务器IP的端口对应问题
在测试中,发现虚拟IP的端口只能和真实服务器IP的端口对应,比如虚拟IP的端口是80,后面对应的真实服务器的端口也只能是80,不能任意配置,真实服务器的端口,让我非常的不解,是我配置错误?还是LVS或keepalived得问题呢?

在Nginx服务器里也可以实现简单的Load Balance,举例

upstream tomcats {
ip_hash;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8280 max_fails=3 fail_timeout=30s;
}
server {
location / {
proxy_pass http://tomcats;
}
}

其中,ip_hash的作用在于很据用IP做hash算法,分配到相应的后端服务上,这样的话,用可以基本上固定的分配到某台机子上,就不用担心Session的问题,fail_timeout和max_fails是指在单位时间重试的次数,如果连接不成功,则不会再向其转发请求。

试用Nginx

Nginx是一款性能非常强劲的Web服务器,也可以用来做反向代理服务器,现在用Nginx做服务器站点越来越多了。

netcraft_chart_with_lighttpd

上图是Nginx和Lighttpd的主机数量比较

最近我试用了一下Nginx,做了一个Nginx+Tomcat的测试,具体步骤如下:

groupadd www
useradd -g www www

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.8.tar.gz
wget http://sysoev.ru/nginx/nginx-0.7.39.tar.gz

tar zxvf pcre-7.8.tar.gz
cd pcre-7.8
./configure
make
make install
cd ..

tar zxvf nginx-0.7.39.tar.gz
cd nginx-0.7.39
./configure –user=www –group=www –prefix=/usr/local/nginx –with-http_stub_status_module –with-http_ssl_module
make
make install

cd /usr/local/nginx/conf/

我们编辑nginx.conf文件,内容如下

user  www www;
worker_processes  3;

error_log  logs/error.log  notice;

pid        logs/nginx.pid;

events {
use epoll;
worker_connections  1024;
}

http {
include       mime.types;
default_type  application/octet-stream;

include    /usr/local/nginx/conf/proxy.conf;

log_format  main  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘”$status” $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

#access_log  logs/access.log  main;

sendfile        on;
tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip  on;

server {
listen       80;
server_name  localhost;

#charset koi8-r;

access_log  logs/localhost.access.log  main;

#location / {
#    root   html;
#    index  index.html index.htm;
#}

location / {
proxy_pass http://localhost:8080;
}

#location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
#    expires      30d;
#}

#location ~ .*\.(js|css)?$ {
#   expires      1h;
#}

location /NginxStatus {
stub_status             on;
access_log              on;
auth_basic              “NginxStatus”;
}

#error_page  404              /404.html;

# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}

}

}

同时我们要在/usr/local/nginx/conf下创建proxy.conf文件,内容如下

proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;

保存之后,进入/usr/local/nginx/目录下,执行sbin/nginx,即可启动Nginx。

客户端浏览器输入http://ServerIP,可以看到Tomcat的欢迎页面,证明Ngnix已经转发HTTP请求给后端的Tomcat了,打开http://ServerIP/NginxStatus可以查看Nginx的状态,在Shell下我们还可以查看一下HTTP头

curl -I http://localhost
HTTP/1.1 200 OK
Server: nginx/0.7.39
Date: Thu, 05 Mar 2009 02:08:54 GMT
Content-Type: text/html;charset=ISO-8859-1
Connection: keep-alive
Content-Length: 8132

关于Nginx的配置,还是需要看它的文档http://wiki.nginx.org/Main,国内张宴的《Nginx 0.7.x + PHP 5.2.8(FastCGI)搭建胜过Apache十倍的Web服务器(第4版)[原创]》非常不错,可以参考。

Linux下切分Tomcat的catalina.out日志文件

随着Tomcat的运行,catalina.out文件会越来越大,虽然Tomcat每日会生成一个catalina.ymd.log的文件,但catalina.out主文件仍然不断增加,需要对catalina.out按日切分才好,在网上找了一下,看到一篇《rotating catalina.out in tomcat 5.5 using cronolog》,就用公司的Tomcat配置一下。

cronolog工具已经在服务器上装过,一个对日志切分的小工具,其主页在http://cronolog.org/,我们也用它来切分Apache的日志。

进入Tomcat的bin目录,打开catalina.sh文件,找到tomcat启动的相关行,或者你直接查找catalina.out,一般我们修改下面行中的内容(因为我们一般不会在-security条件下运行),

1
2
3
4
5
6
7
8
9
10
11
12
13
    else$_RUNJAVA$JAVA_OPTS $CATALINA_OPTS \
    -Djava.endorsed.dirs=”$JAVA_ENDORSED_DIRS-classpath$CLASSPATH” \
    -Dcatalina.base=”$CATALINA_BASE” \
    -Dcatalina.home=”$CATALINA_HOME” \
    -Djava.io.tmpdir=”$CATALINA_TMPDIR” \
    org.apache.catalina.startup.Bootstrap “$@” start  \
    >>$CATALINA_BASE/logs/catalina.out 2>&1 &
 
    if [ ! -z "$CATALINA_PID" ]; then
    echo $! > $CATALINA_PID
    fi
    fi

修改
org.apache.catalina.startup.Bootstrap “$@” start  \
>> “$CATALINA_BASE”/logs/catalina.out 2>&1 &

org.apache.catalina.startup.Bootstrap “$@” start 2>&1 \
| /usr/local/sbin/cronolog “$CATALINA_BASE”/logs/catalina.%Y-%m-%d.out >> /dev/null &
同时,上面有一行
touch “$CATALINA_BASE”/logs/catalina.out
可以注释掉,完成之后重起Tomcat就可以了,在logs目录下可以看到catalina.2009-02-18.out的日志,是按日生成的。

Redhat Linux下src rpm的安装方法

方法一:
1. 执行rpm -i your-package.src.rpm
2. cd /usr/src/redhat/SPECS
3. rpmbuild -bp your-package.specs 一个和你的软件包同名的specs文件
4. cd /usr/src/redhat/BUILD/your-package/ 一个和你的软件包同名的目录
5. ./configure 这一步和编译普通的源码软件一样,可以加上参数
6. make
7. make install

方法二:
1. 执行rpm -i you-package.src.rpm
2. cd /usr/src/redhat/SPECS (前两步和方法一相同)
3. rpmbuild -bb your-package.specs 一个和你的软件包同名的specs文件

这时,在/usr/src/redhat/RPM/i386/ (根据具体包的不同,也可能是i686,noarch等等) 在这个目录下,有一个新的rpm包,这个是编译好的二进制文件。执行:

rpm -i new-package.rpm即可安装完成。