行云无鸣

2011-10-01

Example.com服务器配置

Filed under: 乱语 — 标签:, , , , , , , , , — hellyguo @ 21:15

服务器为Dell PowerEdge 1950
安装Debian6作为操作系统
安装系统时,需要提前准备bnx2/bnx2-mips-06-5.0.0.j3.fw包(为non-free,故需要自行准备),下载路径是:debian.org

邮件服务器配置
1. 安装exim4/courier-pop
sudo apt-get install exim4 exim4-daemon-heavy courier-pop courier-pop-ssl
2. 安装sasl
sudo apt-get install sasl2-bin
3. 配置sasl,使之自启动
sudo vi /etc/default/saslauthd
START=yes #令其自启动
4. 安装SpamAssassin
sudo apt-get install spamassassin
5. 配置SpamAssassin,使之自启动
sudo vi /etc/default/spamassassin
ENABLE=1 #令其自启动
CRON=1 #令其在晚间自动更新过滤规则
6. 启动SpamAssassin
sudo /etc/init.d/spamassassin start
7. 安装ClamAV
sudo apt-get install clamav
8. 安装Greylistd
sudo apt-get install greylistd
9. 配置exim4
sudo dpkg-reconfigure exim4-config
选项提示
1) internet site
2) example.com
3) 留空
4) example.com
5) 留空
6) 留空
7) NO
8) Maildir
9) NO
10. 配置exim4自签证书
sudo /usr/share/doc/exim4/examples/exim-gencert

[*] Creating a self signed SSL certificate for Exim!
This may be sufficient to establish encrypted connections but for
secure identification you need to buy a real certificate!

Please enter the hostname of your MTA at the Common Name (CN) prompt!

Generating a 1024 bit RSA private key
………………………++++++
…………………++++++
writing new private key to ‘/etc/exim4/exim.key’
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Code (2 letters) [US]:CN
State or Province Name (full name) []:Zhejiang
Locality Name (eg, city) []:Hangzhou
Organization Name (eg, company; recommended) []:example.com
Organizational Unit Name (eg, section) []:http://www.example.com
Server name (eg. ssl.domain.tld; required!!!) []:mail.example.com
Email Address []:webmaster@example.com
[*] Done generating self signed certificates for exim!
Refer to the documentation and example configuration files
over at /usr/share/doc/exim4-base/ for an idea on how to enable TLS
support in your mail transfer agent.
生成的证书位于/etc/exim4,名为exim.crt/exim.key。此处为默认位置,在下面步骤中将用到。如果不移动,则下面对证书路径不需要修改;如果进行移动,则需要修改证书路径

11. 配置exim4,使之支持STARTTLS及sasl认证
sudo adduser Debian-exim sasl
sudo /etc/init.d/saslauthd restart
sudo vi /etc/exim4/exim4.conf.template

a) 在.ifdef MAIN_TLS_ENABLE上方添加MAIN_TLS_ENABLE = yes
b) 确认上步的证书路径,已移动则修改
c) 在Authenticate against local passwords using sasl2-bin下方打开plain_saslauthd_server及login_saslauthd_server段的注释
12. 更新exim4的配置文件,并重启exim4
sudo update-exim4.conf
sudo /etc/init.d/exim4 restart

13. 设置每次创建用户时自动产生Maildir
sudo maildirmake /etc/skel/Maildir
sudo chmod 755 /etc/skel/Maildir

14. 测试配置
sudo apt-get install swaks
swaks -a -tls -q HELO -s localhost -au user -ap 'pwd'

=== Trying localhost:25…
=== Connected to localhost.
EHLO localhost
<- 250-localhost Hello localhost [127.0.0.1]
<- 250-SIZE 52428800
<- 250-PIPELINING
<- 250-STARTTLS
STARTTLS
EHLO localhost
<~ 250-localhost Hello localhost [127.0.0.1]
<~ 250-SIZE 52428800
<~ 250-PIPELINING
<~ 250-AUTH PLAIN LOGIN
QUIT
<~ 221 localhost closing connection
=== Connection closed with remote host.

15. 在Exim4中启用Greylistd
sudo greylistd-setup-exim4 add
sudo update-exim4.conf
sudo /etc/init.d/exim4 restart

16. 在Exim4中启用SpamAssassin
sudo vi /etc/exim4/exim4.conf.template
sudo update-exim4.conf
sudo /etc/init.d/exim4 restart

a) 查找spamd_address = 127.0.0.1,解开此行注释
b) 查找Add headers to a message if it is judged to be spam.,解开下方的warn块
17. 配置Courier证书。默认Courier的证书信息为虚构信息,需要按服务器配置Courier-POP的证书
sudo vi /etc/courier/pop3d.cnf

RANDFILE = /usr/lib/courier/pop3d.rand

[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no

[ req_dn ]
C=CN
ST=Zhejiang
L=Hangzhou
O=example.com
OU=http://www.example.com
CN=mail.example.com
emailAddress=webmaster@example.com

[ cert_type ]
nsCertType = server

18. 生成证书
sudo rm –rf /etc/courier/pop3d.pem
sudo rm –rf /usr/lib/courier/pop3d.pem
sudo mkpop3dcert
sudo mv /usr/lib/courier/pop3d.pem /etc/courier
cd /usr/lib/courier
sudo ln –s /etc/courier/pop3d.pem pop3d.pem

Generating a 1024 bit RSA private key
..++++++
………………………++++++
writing new private key to ‘/usr/lib/courier/pop3d.pem’
—–
1024 semi-random bytes loaded
Generating DH parameters, 512 bit long safe prime, generator 2
This is going to take a long time
…+………+…….+…………..+……….+……………………………..+.+…+…+…………………….+…+……+……….+…………………………………………+……………………..+……………………………………………………………..+………….+…………+…+…..+…..+………….+…………………..+..+……..+………..+….+…..+……………………………..+…………….+………………+……………….+.+……………………………..+………+……..+………………………………+…………………+…….+.+…+……………………….+………………….+………………….+………+………………………..+..+……………………………………………………………+………….+…..++*++*++*++*++*++*
subject= /C=CN/ST=Zhejiang/L=Hangzhou/O=example.com/OU=http://www.example.com/CN=mail.example.com/emailAddress=webmaster@example.com
notBefore=Sep 29 14:35:10 2011 GMT
notAfter=Sep 28 14:35:10 2012 GMT
SHA1 Fingerprint=38:A1:30:3A:3F:F3:5F:B6:25:BF:8C:9E:C9:BF:91:DB:FE:EA:13:5C

19. 配置Courier-POP
sudo vi /etc/courier/pop3d
POP3AUTH=””改为POP3AUTH=”LOGIN PLAIN”
POP3AUTH_TLS=””改为POP3AUTH_TLS=”LOGIN PLAIN”
20. 重启Courier-POP
sudo /etc/init.d/courier-pop restart
sudo /etc/init.d/courier-pop-ssl restart

21. 服务器DNS设置
a) 将域名example.com的MX地址指向mail.example.com
b) 将mail.example.com指向1.2.3.4
22. 客户端设置
POP3
mail.example.com,采用SSL/TLS,普通密码
SMTP
mail.example.com,采用STARTTLS,普通密码
VPN服务器配置
1. 配置步骤:
a) sudo apt-get install pptpd
b) sudo vi /etc/pptpd.conf
将localip和remoteip进行设置
c) sudo vi /etc/ppp/pptpd-options
开启ms-dns
d) sudo vi /etc/ppp/chap-secrets
添加用户名密码
e) sudo vi /etc/sysctl.conf
开启net.ipv4.ip_forward=1
f) sudo sysctl -p
g) sudo /etc/init.d/pptpd restart
2. 客户端设置
XP 网络连接,新建连接,连接工作场所,虚拟专用网络,example,不初始拨号,www.example.com
用户名密码待分配
iptables设置
1. 编写setIptables,位于/home/opuser/bin,如下:

#!/bin/sh

#清除表
sudo iptables -F INPUT
sudo iptables -F OUTPUT
sudo iptables -F FORWARD

#设置默认
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

#允许本地网卡通讯
sudo iptables -A INPUT -i lo -j ACCEPT

#允许已建立连接的连接
sudo iptables -A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT

#允许DNS
sudo iptables -A INPUT -p tcp -m state –state NEW -m tcp –dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp -m state –state NEW -m udp –dport 53 -j ACCEPT

#允许ping
sudo iptables -A INPUT -p icmp -m icmp –icmp-type any -j ACCEPT

#允许telnet
#sudo iptables -A INPUT -p tcp -m tcp –dport 23 -j ACCEPT

#允许ssh
sudo iptables -A INPUT -p tcp -m tcp –dport 22 -j ACCEPT

#允许http
#sudo iptables -A INPUT -p tcp -m tcp –dport 80 -j ACCEPT

#允许mail
sudo iptables -A INPUT -p tcp -m tcp –dport 25 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp –dport 110 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp –dport 143 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp –dport 465 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp –dport 993 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp –dport 995 -j ACCEPT

#启用VPN
sudo iptables -A INPUT -p tcp –dport 1723 -j ACCEPT
sudo iptables -A INPUT -p tcp –dport 47 -j ACCEPT
sudo iptables -A INPUT -p gre -j ACCEPT
# for dynamic ip(ADSL etc.)
#sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE
# for static ip
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j SNAT –to 1.2.3.4
sudo iptables -A FORWARD -p tcp –syn -s 192.168.100.0/24 -j TCPMSS –set-mss 1356

#保存
sudo iptables-save > /tmp/iptables-settings
sudo mv /tmp/iptables-settings /etc/iptables-settings
#启用
sudo iptables-restore < /etc/iptables-settings
2. 在系统启动时自动加载iptables规则
sudo vi /etc/network/if-pre-up.d/iptables
sudo chmod +x /etc/network/if-pre-up.d/iptables

iptabls内容

#!/bin/sh
/sbin/iptables-restore < /etc/iptables-settings

3. 测试

2011-06-05

Debian下采用pptp连接VPN服务器

Filed under: 乱语 — 标签:, , , , , — hellyguo @ 20:25

一般都在Windows或者iPhone下用VPN,这次拜GFW所赐,maven也无法访问,只能在服务器上临时使用VPN来救急救场。
服务器是Debian,预先装好PPTP。

  1. 新建VPN连接
    sudo pptpsetup --create vpn --server vpnserver --username temp --password temp --encrypt
  2. 连接VPN Server
    sudo pon vpn
    sudo ip route del default
    sudo ip route add default via 192.168.111.1 dev ppp0

    如果你还不能上网,譬如我,那就是你的DNS还没有设置对。修改/etc/resolv.conf,新增OpenDNS和Google DNS。
    sudo vi /etc/resolv.conf
    在最前面新增如下内容:

    nameserver 208.67.222.222
    nameserver 208.67.220.220
    nameserver 208.67.222.220
    nameserver 208.67.220.222
    nameserver 8.8.8.8
    nameserver 8.8.8.4

  3. 终止VPN连接
    sudo poff
    sudo ip route add default via 192.168.10.254 dev eth0
  4. 删除VPN连接
    sudo pptpsetup --delete vpn

2011-06-01

在Windows下如何制作Linux启动引导U盘(转)

Filed under: 乱语 — 标签:, , , , , — hellyguo @ 21:39

题注:(做过多次,总是忘记,记于笔头,防止忘记)

1.格式化u盘
在Windows下把u盘格式化为fat(2G以下)或fat32(2G以上)格式(强烈推荐使用hp优盘格式化工具)
2.下载并使用syslinux
在这里下载 syslinux
解压后,在win32目录里面使用以下命令来

syslinux.exe -m -a j: (j:为u盘的盘符)

即可在优盘中创建一个可启动的文件(是隐藏的)。
3.在u盘中建立此文件syslinux.cfg(用记事本编辑) ,并在里面加入
default vmlinuz
append initrd=initrd.gz

4.下载
initrd.gz
vmlinuz
下载你所需的debian的iso文件(只需要CD1可以)。
把这3个文件都放到U盘里面
Over

2010-08-11

在Debian5(sid)下启动spread

Filed under: 乱语 — 标签:, — hellyguo @ 21:47

安装:

$ sudo apt-get install spread

提示文件夹非spread用户所有,根据提示修改

$ sudo chown spread.spread /var/run/spread

运行:

$ sudo /etc/init.d/spread start

结果,用查看进程没有找到spread

$ ps -ef|grep spread

换方式运行:

$ sudo spread -n localhost

可以运行
猜想是启动脚本有问题
修改/etc/init.d/spread

$ sudo vi /etc/init.d/spread

注释第38行
#test "$ENABLED" != "0" || exit 0
再运行/etc/init.d/spread,有效果了
但是查看进程还是没有
检查日志/var/log/spread.log,发现报错
在spread.org的mailist里面找到修改方法:

$ sudo vi /etc/spread/spread.conf

在第17行后面添加

boron 127.0.1.1

改为:
Spread_Segment 127.0.0.255:4803 {

localhost 127.0.0.1
boron 127.0.1.1
}

同时,顺手打开了第105行和106行的注释

DaemonUser = spread
DaemonGroup = spread

再试,成功!

2010-07-24

coLinux使用记录

Filed under: 乱语 — 标签:, , , — hellyguo @ 21:06

使用coLinux记录,以作备忘
用的是Debian 5.02 lenny,镜像网上下载,48MB
1.网络设置
eth0作为对外连接网卡,采用slirp
后来由于又安装了VMware,导致eth0无法找到。
查看日志后发现,eth0被替换为eth2,而eth2没有在/etc/network/interfaces定义,导致网络无法访问。
在网上查找后,确认需要指定eth0的MAC地址,再重启,就可以解决了
这里的MAC地址,可以通过查看/etc/udev/rules.d/70-persistent-net.rules得到
eth0=slirp,00:ff:10:1d:64:00
eth1作为连入网卡,采用tuntap
这个win32tap,是coLinux安装后出现的那块网卡,MAC地址也是它的
eth1=tuntap,win32tap,00:FF:A1:DB:51:93
2.磁盘扩容
Windows下
创建10G大小usr分区,2G大小home分区,512M大小swap分区
fsutil file createnew usr.ext3 10737418240
fsutil file createnew home.ext3 2147483648
fsutil file createnew swap.dsk 536870912

注:创建好后,建议马上启用NTFS的压缩功能,可以有效减小磁盘占用。包括原有的磁盘文件,也建议压缩。
对速度的影响基本可以忽略
编辑coLinux配置文件,添加加载这几个分区文件的语句
cobd0="D:\coLinuxHD\Debian.root.ext3"
cobd1="D:\coLinuxHD\usr.ext3"
cobd2="D:\coLinuxHD\home.ext3"

进入coLinux后,为新文件创建文件系统
mkfs.ext3 /dev/cobd1
mkfs.ext3 /dev/cobd2
mkswap /dev/cobd3

激活交换分区
swapon
创建挂载点
cd /mnt
mkdir bd1 bd2

临时挂载
mount -t ext3 /mnt/bd1 /dev/cobd1
mount -t ext3 /mnt/bd2 /dev/cobd2

将文件拷贝到新分区中
cp -ax /usr /mnt/bd1
cp -ax /home /mnt/bd2

编辑fstab,添加
/dev/cobd1 /usr ext3 errors=remount-ro 0 2
/dev/cobd2 /home ext3 errors=remount-ro 0 2

重命名原文件夹,防止后期用磁盘挂载后,凭空占据空间,却无法删除
mv /usr /usr1
mv /home /home1

重启
reboot
确认没有问题后,删除原文件夹和临时挂载点
rm -rf /usr1
rm -rf /home1
rm -rf /mnt/bd1 /mnt/bd2

3.Windows分区加载
其实很简单
在coLinux的配置文件中添加:
cofs0=C:\
cofs1=D:\
cofs2=E:\
cofs3=F:\
cofs4=G:\

在coLinux的/mnt中定义好挂载点后
cd /mnt
mkdir winc wind wine winf wing

编辑fstab
cofs0 /mnt/winc cofs defaults 0 0
cofs1 /mnt/wind cofs defaults 0 0
cofs2 /mnt/wine cofs defaults 0 0
cofs3 /mnt/winf cofs defaults 0 0
cofs4 /mnt/wing cofs defaults 0 0

这里,我犯了经验主义错误
/dev/cofs0 /mnt/winc cofs defaults 0 0
/dev/cofs1 /mnt/wind cofs defaults 0 0
/dev/cofs2 /mnt/wine cofs defaults 0 0
/dev/cofs3 /mnt/winf cofs defaults 0 0
/dev/cofs4 /mnt/wing cofs defaults 0 0

用了/dev/cofsX这种形式,而不是要求的cofsX,结果,陷在这里很久

2010-07-06

参考网络,将texlive2009配置成支持中文

Filed under: 乱语 — 标签:, , , — hellyguo @ 15:15

sudo mkdir -p /usr/share/texmf/fonts/truetype/chinese
cd /usr/share/texmf/fonts/truetype/chinese/
#创建到~/.fonts目录下字体的联接档
ln -s ~/.fonts/simsun.ttc
ln -s ~/.fonts/simhei.ttf
ln -s ~/.fonts/simfang.ttf
ln -s ~/.fonts/simkai.ttf
cd /usr/share/texmf/
sudo gbkfonts fonts/truetype/chinese/simfang.ttf fs
sudo gbkfonts fonts/truetype/chinese/simsun.ttc song
sudo gbkfonts fonts/truetype/chinese/simkai.ttf kai
sudo gbkfonts fonts/truetype/chinese/simhei.ttf hei
sudo texhash
sudo updmap-sys –enable Map cjk.map

配置完之后,我们来测试一下。
用gedit写如下内容

\documentclass{article}
\usepackage{CJK}
\begin{document}
\begin{CJK}{GBK}{song}
这是latex
\end{CJK}
\end{document}

保存为gbk编码。
安装完成后用latex *.tex来编译cjk的TeX文件,用ctex *.tex来编译cct文件。然后用dvipdfmx *.dvi或者dvipdfm *.dvi(看看结果中哪个没有乱码)来转换成pdf
也可以一条命令出pdf:pdflatex *.tex

基本上,就是把路径给修改了一下
从apt上拿下来的texlive2009,路径需要改为:

/usr/share/texmf/

参考自:URL

2010-06-29

Debian下GNOME自动换桌面壁纸

Filed under: 乱语 — 标签:, , — hellyguo @ 09:50

Debian的默认壁纸中,有一个会自动换的壁纸,星图,很漂亮。
自己研究了下,原来做自动切换很简单。
新建一个文件夹,放一些图片进去,然后,编辑一个xml就可以了。

<background>
<starttime>
<year>2009</year>
<month>08</month>
<day>04</day>
<hour>00</hour>
<minute>00</minute>
<second>00</second>
</starttime>
<!-- This animation will start at midnight. -->
<static>
<duration>1795.0</duration>
<file>/usr/share/backgrounds/autopic/0001.jpg</file>
</static>
<transition>
<duration>5.0</duration>
<from>/usr/share/backgrounds/autopic/0001.jpg</from>
<to>/usr/share/backgrounds/autopic/0002.jpg</to>
</transition>
<static>
<duration>1795.0</duration>
<file>/usr/share/backgrounds/autopic/0002.jpg</file>
</static>
<transition>
<duration>5.0</duration>
<from>/usr/share/backgrounds/autopic/0003.jpg</from>
<to>/usr/share/backgrounds/autopic/0001.jpg</to>
</transition>
</background>

这里,static部分就是静态展示部分,1795表示展示半小时差5秒;transition部分表示切换,5表示在5秒内切换完成。也就是说,半小时内,切换一次。
注意,最后要切换回第一张图片,才能做到循环
使用时,选择到这个新建的文件夹,选中这个XML即可

2010-06-16

3G网卡(CDMA2000)在Linux下拨号

Filed under: 乱语 — 标签:, , , — hellyguo @ 20:26

我的3G无线网卡是电信附送的EC1260,在Windows下和MAC OS X下都能正常运行。在Debian下,通过其自带的华为拨号软件,刚开始非常顺利。某次我更新Debian后,无线网卡无法被拨号器认出,重装拨号器也无效。不得以,只能在VM上的Windows下用3G网卡上网,非常不爽。
知道肯定有命令行命令直接处理,但一直忘记查。这次,记得了,查到了一个比较方便的拨号软件:wvdial。
安装
$ sudo apt-get install wvdial
使用
插上无线网卡后
$ sudo wvdialconf
生成一份基本配置/etc/wvdial.conf
根据自身情况编辑此文件
$ sudo vi /etc/wvdial.conf
这份是我编辑好的:

[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Modem Type = Analog Modem
Baud = 9600
New PPPD = yes
Modem = /dev/ttyUSB0
ISDN = 0
; Phone = <Target Phone Number>
Phone = #777
; Password = <Your Password>
Password = vnet.mobi
; Username = <Your Login Name>
Username = ctnet@mycdma.cn
Dial Prefix =
Dial Attempts = 1
Dial Command = ATM1L3DT
Ask Password = off
Auto Reconnect = on
Abort on Busy = off
Carrier Check = no
Check Def Route = on
Abort on No Dialtone = on
Stupid Mode = on
Idle Seconds = 0
Auto DNS = on

拨号命令:
$ sudo wvdial
退出方式:
在当前窗口上按Ctrl+C

2010-06-14

Debian下停止DB2 Express-C的自动启动

Filed under: 乱语 — 标签:, , — hellyguo @ 19:12

#停止DB2实例的自动启动
db2iauto -off InstName
#InstName可从db2ilist获取
db2ilist

2009-12-10

原来Tomcat的webapp启动顺序是依赖File.list()方法的

Filed under: 乱语 — 标签:, , , , , , — hellyguo @ 20:58

公司开发了一套系统,分多个模块,部署于客户提供WebSphere上,通过设置启动顺序,可以正常运行。现在要搭建模拟演示系统,搭建在公司自己的Linux下。公司没有WebSphere的Linux版(有也不能用,没license),就选择部署在Tomcat下。
本来我们开发也是在Windows下的Tomcat调试的,完全没问题。结果部署到Linux下,问题来了,启动顺序完全不是预期的顺序!
在Windows下,我们是将配置好的xml文件放置于conf/Catalina/localhost,按启动顺序命名为1.xx_a.xml/2.xx_b.xml/3.xx_c.xml/4.xx_d.xml。这样,系统就能正常在Tomcat下运行起来。可是,这样设置,在公司服务器上就是不行!启动顺序一直不是1-2-3-4,而是4-2-3-1。
一开始以为是Tomcat版本问题,虽然Windows下版本和Linux下版本均为5.0.28,我还是为将Linux下的版本升级到了6.0.20。可惜,无济于事。
在网上搜索关于Tomcat启动顺序的文章,都说Tomcat是按字母顺序加载配置文件的。可怎么设置都没有用。在被Tomcat折磨了一天半后,我开始寄希望于有开源的J2EE容器,可以像WebSphere一样,设置启动顺序。在逐一安装了jetty,jonas,jboss,resin,glassfish后,我悲哀地发现,所有这些,都不支持对应用设置启动顺序。
最后尝试了WebLogic。昨天深夜,挂机下载WebLogic 10.3。今天上午安装后发现,WebLogic和WebSphere一样,也能设置启动顺序。很兴奋,想用,但还是打了退堂鼓(也没有license,不能也不敢用)。
最后一条路了,翻看Tomcat的源代码。
下载了Tomcat6.0.20的源代码,在HostConfig.java中找到了那块加载xml的代码。
Line490:

// Deploy XML descriptors from configBase
deployDescriptors(configBase, configBase.list());
// Deploy WARs, and loop if additional descriptors are found
deployWARs(appBase, appBase.list());
// Deploy expanded folders
deployDirectories(appBase, appBase.list());

原来启动顺序就是File.list()的顺序!
又下载Tomcat5.0.28的源代码,查看HostConfig.java,还是如此:
Line426:

String configFiles[] = configBase.list();

Line430:

String files[] = appBase.list();

Line568:

deployDescriptors(configBase(), configBase.list());

Line813:

String files[] = appBase.list();

Line989:

String configFiles[] = configBase.list();

确认了,Tomcat的加载的确是与File.list()有关。
写了个测试代码确认问题:
Test.java

package fileClass_listMethod;

import java.io.File;

public class Test {
public static void main(String args[]) throws Exception {
File file = new File(“.”);
String[] files = file.list();
for (int i = 0; i < files.length; i++) {
System.out.println(files[i]);
}
}
}

这个程序的输出,在大部分操作系统中,是相同的。但的确是存在不同的情况,我,就中奖了。
公司服务器,RHEL4

$ uname -a
Linux xxxweb2008.localdomain 2.6.9-5.ELsmp #1 SMP Wed Jan 5 19:30:39 EST 2005 i686 i686 i386 GNU/Linux
$ java -version
java version “1.5.0_12”
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
Java HotSpot(TM) Server VM (build 1.5.0_12-b04, mixed mode)
$ java Test
Test.java
4.xx_d.xml
2.xx_b.xml
Test.class
1.xx_a.xml
3.xx_c.xml

我的T400,WinXPSP3

2600.xpsp_sp3_gdr.090804-1435 : Service Pack 3
>java –version
java version “1.5.0_07”
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode, sharing)
>java Test
1.xx_a.xml
2.xx_b.xml
3.xx_c.xml
4.xx_d.xml
Test.class
Test.java

我的虚拟机Linux,Debian 5.02

$ uname -a
Linux debian.vmware 2.6.26-2-686 #1 SMP Wed Aug 19 06:06:52 UTC 2009 i686 GNU/Linux
$ java -version
java version “1.6.0_12”
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode)
$ java Test
1.xml
2.xml
3.xml
Test.class
Test.java

由此可见,网上说的Tomcat启动顺序是基于字母顺序,并不准确。严格说,是基于操作系统的底层实现。基于字母顺序,只是大多数系统的情况。查看JavaDoc,明确说明了此点:
list
public String[] list()
返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组。
如果此抽象路径名并不表示一个目录,则此方法将返回 null。否则,为目录中的每个文件或目录返回一个字符串数组。表示目录本身及其父目录的名称不包括在结果中。每个字符串是一个文件名,而不是一条完整路径。
不保证所得数组中的相同字符串将以特定顺序出现,特别是不保证它们按字母顺序出现。
返回:
由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组。如果目录为空,则数组也将为空。如果抽象路径名不表示一个目录,或者发生 I/O 错误,则返回 null。
抛出:
SecurityException – 如果存在安全管理器,且其 SecurityManager.checkRead(java.lang.String) 方法拒绝对目录进行读取访问
直接修改Tomcat5.0.28的HostConfig.java
Line427:

String configFiles[] = configBase.list();
Arrays.sort(configFiles, 0, configFiles.length);
deployDescriptors(configBase, configFiles);

Line432:

String files[] = appBase.list();
Arrays.sort(files, 0, files.length);
deployWARs(appBase, files);

Line571:

String[] cfgFiles = configBase.list();
Arrays.sort(cfgFiles, 0, cfgFiles.length);
deployDescriptors(configBase(), cfgFiles);

Line818:

String files[] = appBase.list();

if (files != null) {
Arrays.sort(files, 0, files.length);

Line995:

String configFiles[] = configBase.list();
Arrays.sort(configFiles, 0, configFiles.length);
deployDescriptors(configBase, configFiles);

重新更新了catalina.jar后,启动Tomcat5.0.28,应用按排定顺序正常启动。
也修改了Tomcat6.0.28的HostConfig.java:
Line491:

// Deploy XML descriptors from configBase
String[] configFiles = configBase.list();
Arrays.sort(configFiles, 0, configFiles.length);
deployDescriptors(configBase, configFiles);
// Deploy WARs, and loop if additional descriptors are found
String[] appFiles = appBase.list();
Arrays.sort(appFiles, 0, appFiles.length);
deployWARs(appBase, appFiles);
// Deploy expanded folders
deployDirectories(appBase, appFiles);

update:我将这点作为增强点提交到Tomcat的bugzilla了,URL
update:提交被否决了,认为Web程序都是独立的,不应该依赖于加载顺序。

Older Posts »

%d 博主赞过: