2009年12月25日星期五
emacs distel devel 配置问题
emacs=23.0.0.1
os = xp sp3
.emacs 配置抄用 http://bc.tech.coop/blog/070528.html
—————————–
实际状况
emacs:
error “Can’t handle event closed in state derl-recv-challenge-ack
emacs erlang:
Connection attempt from disallowed node ‘distel_3844@LIWOOOOD-3FD36A’ **
问题:
通常两种问题 1. cookie 不匹配 2. node name 不匹配
排查问题:
首先排查第一个问题:
查看在emacs 中和erlang中是否调用同一个cookie配置文件. 默认情况下是检查
home 目录下的 .erlang.cookie.
1. elrang 中通过 init:get_argument(home). 找到位置 “c:/Document …/Admini..”,
2 emacs 中cookie 可通过变量 derl-cookie 查看. 结果:
Its value is nil
但有这么一句
When NIL, we read ~/.erlang.cookie.
mmd 我想知道问题了,
C:\>env | grep HOME
HOME=d:\emacs
HOMEDRIVE=C:
HOMEPATH=\Documents and Settings\Administrator
问题总结:
在windows下 emacs 调用的home目录是 HOME. 而在erlang所依赖的home 目录是HOMEPATH. 两个调用的 .erlang.cookie 位置不一样
解决:
1. cp “c:/Documents and …/Administ../.erlang.cookie” d:/emacs
2. 在erlang 端 -setcookie cookie ,
在emacs中(setq derl-cookie “cookie”)
参考:
http://osdir.com/ml/lang.erlang.distel.devel/2003-02/msg00001.html
2009年12月15日星期二
转:Erlang开发建议(杂记版)
作者:litaocheng
以下是在erlang项目开发中的一些记录,即包含很多通俗易懂的原则,也包含一些似是而非的建议,比较混乱,还没有积累到一个可以分门别类的地步,各位就将就看吧..
:)
* 确保没有任何编译警告
* Erlang中String采用list实现,32位系统中,其1个字符用8个字节的空间(4个保存value, 4个保存指针)。因此string速度较慢,空间占用较大
* 在Server中,总是尽力书写尾递归(tail-recursive)的函数
* 使用'++'时,left list会被拷贝,然后添加到right list的头部,因此最好把length较短的list放在左侧
* 避免使用regexp,如果需要正则表达式,请使用re
* timer模块的大部分函数实现,依赖于一个process,如果过多使用timer,会导致这个process负载过大,影响效率。
推荐使用erlang:send_after/3及erlang:start_timer/3
* 避免使用list_to_atom/1,因为erlang中atom数量最大为1048576, 且不进行GC控制。因此如果持续性的调用list_to_atom/1
可能很容易达到系统上限,从而导致emulator terminate。请使用list_to_existing_atom/1。
* list内部实现为一个列表,因此length(List), 需要遍历整个list比较耗时
* 对于不同的数据类型,使用不同的size函数:tuple_size/1, byte_size/1, bit_size/1
* 使用binary match来进行binary的分割,而不使用split_binary/2
* 如果两个list都拥有很多数据,那么请不要使用'--',而是将数据转化到ordsets,然后调用ordsets:substract/2.
* 对于binary相关操作可以进行binary优化(bin_opt_info编译选项)代码框架:
* f(<
... % Rest is not used here
f(Rest,...);
f(<
... % Rest is not used here
f(Rest,...);
...
f(<<>>, ...) ->
ReturnValue.
* 调用lists:flatten/1可以将list扁平化,这个操作代价很大,比'++'还要昂贵。下面这些时候我们可以避免:
将数据发送给port时
调用list_bo_binary/1和iolist_to_binary前
* 小的函数可以让您方便的找出错误的函数和代码
* 不要在同一行出现相同的符号
20 some_fun() ->
21 L = [{key1, v1}, {key2, [some_record#v21, v22]}],
22 ...
编译时,会提示line 21 '[' 语法错误, 因为21行有多个 '[' ,所以这个bug不能准确定位,你需要花时间去排查代码。
好的做法是:
20 some_fun() ->
21 L = [{key1, v1},
22 {key2, [some_record#v21, v22]}
23 ],
...
这样,编译其会提示你 line 22 '[' 语法错误,你很开就知道是那个地方错了。
* 使用 CTRL + \ 或 init:stop(), 可以退出Erlang, 使用CTRL + G 及 CTRL + C 弹出菜单选项,可以选择是否退出Erlang。
其中CTRL + G可以用来连接其他的shell, CTRL + C可以查看其他一些系统信息
Ctrl + C abort 是野蛮的退出方式
* use "open_port({fd,0,2}, [out])" make erlang program write standard error to unix system
* If you don't run experiments before you start designing a new system, your entire system will be an experiment!
* standard data structure desc:
Module Description
sets sets, i.e. a collection of unique elements.
gb_sets sets, but based on a general balanced data structure
gb_tree a general balanced tree
dict maps, also called associative arrays
ets hash tables and ordered sets (trees)
dets on-disk hash tables
Suggestion:
elments count: 0 - 100 | 100 - 10000 | 10000 -
our select : list | ets | gb_tree
* 通过code:clash/0 检测代码中是否有module冲突现象(sticky)
* epmd -d -d 启动 epmd 可以查看erlang node之间的通讯
* 将正常的逻辑代码和错误处理代码分离,发生错误时,尽管错误。由另一个错误处理模块进行处理
* 类似于操作系统,我们的程序也可以分为kernel 和 user 两层, 对于kernel绝对不能出现错误, 对于user可以出现错误,进行恢复
* process顶层loop涉及的代码及函数,最好在一个module中实现
* process 的register name和module名称一致, 便于寻找代码
* 每个process具有一个单一的角色,比如:supervisor 用来进行错误恢复, work 工作者,可以出现错误, trusted worker 不会出现错误
* 通过函数调用可以实现的功能,就不要使用sever实现(如gen_server, 及类似的loop 实现)
* 给消息加一个tag,在发生错误的时候,可以定位到消息,同时也有利于程序的稳健
* 在消息循环中,对于unknown的消息,请调用lib:flush_receive/0 将其清除,减轻process msg queue的长度
* server中总是书写尾递归的循环
* 尽量使用record, 而不是原始的tuple来表现数据结构, 在使用record时,使用select match:
#person{name = Name, age = Age} = Person
* 对于返回值,最好也添加一个tag,用来说明返回值类型,或者执行成功与否
* 尽可能少的使用catch和try,在erlang程序中,不推荐主动捕获异常。只有当我们的逻辑特别复杂,我们可以使用throw来返回数据,使用catch来获取返回值。
* 当然程序与外界交互,外界数据不可靠时,需要使用catch和try
* 慎重使用process dictory, 当你使用get/1, put/1时,你的应用会具有很大的slide effect。可以通过加入一个新的参数来保存原本需要存储到process dictory中数据
* 如果不想使自己糊涂,请不要使用import
* 使用export时,将功能类似的接口组合在一起,并添加合理的注视,这样你的接口更清晰,别人使用起来更方便
* 不要书写嵌套太深的代码
* 不要书写太长的module
* 不要书写太长的函数
* 每行代码不能太长
* 避免使用 "_" 匿名变量,请为每个变量选择有意义的名称,如够某个变量暂时不使用,请以下划线 "_" 开始
* {error, enfile} enfile error in socket 是以为内linux系统中 ulimit 限制, 在root下修改:ulimit -n 25000
* {error, enotconn} 表示socket已经关闭
* 在erlang开发时,慎重使用macro,因为erlang的single assign的缘故,同时调用某个marco,而macro又定义了某个变量,可能导致badmatch错误。
比如:
-define(ADDLINEINFO1(F),
(
begin
Str1 = lists:concat(["[Mod:", ?MODULE, " Line:", ?LINE, "]"]),
Str1 ++ F
end
)).
-define(WARN(Log, F, D), log4erl:warn(Log, ?ADDLINEINFO(F), D)).
如果连续使用 WARN, 会出现此错误
* erlang中可以定义很多环境变量:
ERL_MAX_ETS_TABLES 设置最大的ets数目 默认1400
ERL_MAX_PORTS erlang最大的port数目 默认1024
* .app文件中的start_phases, 选项既可以用来作为include applications之间的同步启动,也可以用来对单个application进行分布启动。
顺序如下
包含included app:
application:start(prim_app)
=> prim_app_cb:start(normal, [])
=> prim_app_cb:start_phase(init, normal, [])
=> prim_app_cb:start_phase(go, normal, [])
=> incl_app_cb:start_phase(go, normal, [])
ok
无included app:
application:start(prim_app)
=> prim_app_cb:start(normal, [])
=> prim_app_cb:start_phase(init, normal, [])
=> prim_app_cb:start_phase(go, normal, [])
ok
* 任何时候,都要重视函数的返回值,通过match确保您的预期,如果发生错误,那么就大胆的表达出来。
2009年7月13日星期一
2009年6月25日星期四
ubuntu 网卡安装
1. 找到主板型号945GCT-HM
2. 通过1 找到网卡型号 板载网卡 集成 10/100 Mps Realtek RTL8101E 网卡
3. 到 realtek 官网http://152.104.125.41/ 搜索得到对应的驱动下载页
4. uname -a linux kernel 2.6.28.11-generic
5. 找到对应的linux 驱动
6. 通过驱动自带redme 进行安装
7. 搞定 可乐一杯
2009年6月13日星期六
emacs cedet+ecb+cscope+gdb-ui
cedet: collection of emacs development environment tools
ecb : Emacs Code Browser
配上 php python 调试, 便于开发
http://www.linuxjournal.com/article/7876 emacs+gdb
---------------------
http://downloads.sourceforge.net/mingw/gdb-6.8-mingw-3.tar.bz2?modtime=1208982015&big_mirror=1
解压里面的bin/gdb.exe放到mingw/bin里面,然后就可以用了。
这个是mingw的下载主页,上面的链接就是在这个里面的。
http://sourceforge.net/project/showfiles.php?group_id=2435
2009年6月9日星期二
Repository moved permanently to xxxx please relocate
之前的配置为
DAV svn
SVNParentPath /data/svn/
AuthType Basic
AuthName "Authorization Realm"
AuthUserFile /etc/svnpwdfile
Require valid-user
# SVNListParentPath on
DocumentRoot /data/svn/
ServerName svn.example.cn
貌似正确,可在浏览器里正常 svn checkout时的时候就报Repository moved permanently to xxxx please relocate 错误
原因在faq里明显 就是apache 迷惑了, 可是不设DocumentRoot 就会报错. 解决办法也简单乱设一个有效的路径.... 妈的 居然这样就过了
2009年6月8日星期一
批量svn lock
1.第一次实现
用php实现,原理是应用svn list ,根据传进来的地址进行递归. 将文件lock/unlock
缺点: 不够灵活,每次都要改代码
2.第二次实现
在之前的基础上加入 enable disable filter 参数
优点:相对方便,不用每次都改代码
缺点:无法满足特殊需求, 还是无法避免动代码
3.第三次实现
php脚本只用来通过svn遍历指定目录下的所有文件, 其他的依靠命令来处理就好了
例如:php listsvn.php file:///data/svn/shop/working/b2b1.2/ | grep -e "/ctl\..*\.php" -i | xargs -I % svn unlock %
优点: 足够灵活,足够强大
缺点: 呵呵 每行命令有点长,
总结: 优点远大于缺点
解决vista系统部分CHM打不开,“无法正常显示”的问题
解决vista系统部分CHM打不开,“无法正常显示”的问题
症状:显示左侧目录树,右侧内容提示为“无法显示网页”。
原因:Microsoft系统安全性升级导致。
解法:属性页->解除锁定即可。
不只vista有这个问题,只要是NTFS分区都有这个问题
apache+fcgid+redmine安装心得
如果是还未安装配置,请先看文尾处的参考资料 进行配置.勿阅读本文 免得造成疑惑
安装过程 一波三折,断断续续花了一周时间
1.装fastcgi
2.redmine 安装
首先是在安装ruby上折腾颇多
如果是在freebsd下ruby的包尽量用,可以省力不少.通过 pkg_info | grep ruby 时刻关注所装的包,因为ruby的包之间互为依存. 一定要留意.在调试中出现问题 google 找到原因,大多情况是因为缺包或者包版本不对造成的
关键节点
Test the installation by running WEBrick web server:
ruby script/server webrick -e production
Once WEBrick has started, point your browser to http://localhost:3000/.
You should now see the application welcome page.
如果测试通过表示基本安装已经完成,
3. 整合apache
这时我犯了个致命错误导致文件,用apache fastcgid 模式可以跑起来但是 css js 全部无法加载
解决:
1. 首先还是同过 . redmine/dispatch.fcgi 来测试包是否有问题. 包依赖我是通过这种方式解决掉的, 可当此步骤通过后 依然无法加载css js
2. 排除了ruby的问题,当然怀疑到 httpd.conf 配置问题, 查看/var/log/httpd-error.log经过反复排查 无误, 告失败
3. 这时候想到了.htaccess 的问题,找到 redmine/public/.htaccess 进行调试 不得要领
4. 有些抓狂, 再找到redmine/log/production.log
看到错误
ActionController::RoutingError (No route matches "/stylesheets/jstoolbar.css"
google之 无果,但是想到了 .htaccess 是通过rewrite 将访问转到 dispatch.fcgi上的想到问题应该是出在了rewrite上
打开rewrite log
RewriteLog "/var/log/rewrite.log"
RewriteLogLevel 3
5. 查看结果 rewriteCond %{REQUEST_FILENAME} !-f 失效 js css都通过 dispatch.fcgi 在解析,这当然找不到
可为什么会出现这个问题?依然是个问号 继续google之. 没有答案 为了调试,我把.htaccess 进行了删减 来排查问题
之前的疑问全部浮出水面
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
当我把 mod_fastcgi.c IfModule mod_cgi.c 两段去掉时.一切正常了. 头绪来了 mod_fastcgi mod_fcgid mod_cgi 其中至少跑了两个. 那么问题出在我在配置fcgid 的时候没有将mod_cgi 去掉所导致的问题. 我靠.
把 LoadModule cgi_module libexec/apache22/mod_cgi.so 注释掉,干掉 .htaccess 重新 svn update 重启apache 一切ok!
6.总结
当出现问题时 一定要查看log(各种log 服务的 软件的),通过log问题一块块排查 不能慌乱. 注意思考 依靠网络 但不依赖网络
参考:
1.安装fastcgid
http://www.cyberciti.biz/faq/freebsd-apache22-fastcgi-php-configuration/
(如安此文章出现问题请查看我的另一篇文章 http://leafghost.blogspot.com/2009/06/apache2fastcgi.html )
2.redmine 安装
http://www.redmine.org/wiki/redmine/RedmineInstall
3.整合 apache
http://www.redmine.org/wiki/1/HowTo_configure_Apache_to_run_Redmine
2009年6月1日星期一
apache2配置fastcgi
遇到一个问题
[notice] mod_fcgid: process /usr/local/www/phpPgAdmin/images/themes/default/title.png(2905) exit(communication error), terminated by calling exit(), return code: 255
除了php都无法加载
解决办法, 把 SetHandler fcgid-script 注释掉 换上 AddHandler fcgid-script .php就成了
疑问:
1.FCGIWrapper /usr/local/bin/php-cgi .php 是做什么的
2.[notice] mod_fcgid: call /data/www/shop/shopadmin/index.php with wrapper /usr/local/bin/php-cgi 怎么解决?
没测过, 但是直观感觉是网站快了.. 呵呵
unix jobs
[1]+ Stopped /root/bin/rsync.sh
然后我们可以把程序调度到后台执行:(bg 后面的数字为作业号)
#bg 1
[1]+ /root/bin/rsync.sh &
用 jobs 命令查看正在运行的任务:
#jobs
[1]+ Running /root/bin/rsync.sh &
如果想把它调回到前台运行,可以用
#fg 1
/root/bin/rsync.sh
这样,你在控制台上就只能等待这个任务完成了。
& 将指令丢到后台中去执行
[ctrl]+z 將前台任务丟到后台中暂停
jobs 查看后台的工作状态
fg %jobnumber 将后台的任务拿到前台来处理
bg %jobnumber 将任务放到后台中去处理
kill 管理后台的任务
chrome about:
Like most other browsers, Google Chrome can be fine-tuned by typing "about:command" to show information about version number, memory usage, cached files, plug-ins and more details. Here's the full list:
1. about:cache - A list of all the web pages cached by Google Chrome
2. about:dns - Prefetching DNS records produced benefits
3. about:histograms - A list of histograms for Google Chrome's internal metrics
4. about:internets - Google Chrome's humorous Easter egg
5. about:memory - Measuring memory usage in a multi-process browser
6. about:network - Used for I/O tracking
7. about:plugins - The list of plug-ins that are available in Google Chrome
8. about:stats - A list of internal counters and timers
9. about:version - Shows the version number the browser, WebKit and JavaScript V8 engine
10. view-cache:[URL] - Shows you some under-the-hood cache details
11. view-source:[URL] - Shows the source code.
ports更新方式(cvsup portsnap)
cp /usr/share/examples/cvsup/ports-supfile /root/
修改 ports-supfile 依据位置使用 cvsup1 ~ cvsup13.tw.freebsd.org服务器
也可通过 -h 来指定更新服务器
ports-supfile文件中ports-all 表示我们要更新 /usr/ports 目录下的所有档案。您也可以只更新其中的部份目录,只要将 ports-all 以井字号 "#" 标示起来,并将档案中 ports-base 那一行的 # 移除,接着您就可以依您所要更新的目录来要移除其它的 # 字号。例如,我们只要更新 /usr/ports/www 这个目录,将 ports-all 以 # 标示起来之后,我们还要移除 ports-base 及 ports-www 开头的 #。
2. portsnap fetch update
Portsnap 是一套用以安全地分发 FreeBSD 的系统。 每隔大约一个小时, 就会生成一份 ports 的最新 “快照”, 它会被打包并进行数字签名。 这些文件接下来将通过 HTTP 来分发。
下载压缩的 Ports 套件快照到 /var/db/portsnap。您可以根据需要在这之后关闭 Internet 连接。
# portsnap fetch
假如您是首次运行 Portsnap, 则需要将快照释放到 /usr/ports:
# portsnap extract
如果您已经有装好的 /usr/ports 而您只想更新,则应执行下面的命令:
# portsnap update
因为是下载压缩包,所以速度要比cvs 一个个拉要快很多,
————————————————————-----------------
使用方法:
/etc/portsnap.conf 里面更改
SERVERNAME=portsnap.hshh.org
portsnap简介:
portsnap从freebsd6.0开始引进系统,给与用户方便的更新系统ports
portsnap的命令比较少
fetch 获取数据
extract 释放全部ports
update 更新ports
第一次使用可以 portsnap fetch extract
以后使用可以 portsnap fetch update
如果写在cron可以用 portsnap cron update
3.总结
如果很急只想更新部分ports 可以用cvsup.如果想一劳永逸还是portsnap 更舒适
http://www.twbsd.org/chs/book/index.php?ch=10
参考:http://freebsd.chinaunix.net/doc/2007/01/17/1123592.shtml
大量小文件的实时同步方案
大量小文件的实时同步方案
davies 发表于 2008 年 04 月 24 日
传统的文件同步方案有rsync(单向) 和 unison(双向)等,它们需要扫描所有文件后进行比对,差量传输。如果文件数量达到了百万甚至千万量级,扫描所有文件将非常耗时。而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式。
之前看了Amazon的Dynamo的设计文档,它们每个节点的数据是通过Hash Tree来实现同步,既有通过日志来同步的软实时特点(msyql, bdb等),也可以保证最终数据的一致性(rsync, unison等)。Hash Tree的大体思路是将所有数据存储成树状结构,每个节点的Hash是其所有子节点的Hash的Hash,叶子节点的Hash是其内容的Hash。这样一旦某个节点发生变化,其Hash的变化会迅速传播到根节点。需要同步的系统只需要不断查询跟节点的hash,一旦有变化,顺着树状结构就能够在logN级别的时间找到发生变化的内容,马上同步。
文件系统天然的是树状结构,尽管不是平衡的数。如果文件的修改时间是可靠的,可以表征文件的变化,那就可以用它作为文件的Hash值。另一方面,文件的修改通常是按顺序执行的,后修改的文件比早修改的文件具有更大的修改时间,这样就可以把一个目录内的最大修改时间作为它的修改时间,以实现Hash Tree。这样,一旦某个文件被修改,修改时间的信息就会迅速传播到根目录。
一般的文件系统都不是这样做的,目录的修改时间表示的是目录结构最后发生变化的时间,不包括子目录,否则会不堪重负。因为我们需要自己实现这个功能,利用Linux 2.6内核的新特性inotify获得某个目录内文件发生变化的信息,并把其修改时间传播到它的上级目录(以及再上级目录)。Python 有 pyinotify,watch.py的代码如下:
- #!/usr/bin/python
- from pyinotify import *
- import os, os.path
- flags = IN_CLOSE_WRITE|IN_CREATE|IN_Q_OVERFLOW
- dirs = {}
- base = '/log/lighttpd/cache/images/icon/u241'
- base = 'tmp'
- class UpdateParentDir(ProcessEvent):
- def process_IN_CLOSE_WRITE(self, event):
- print 'modify', event.pathname
- mtime = os.path.getmtime(event.pathname)
- p = event.path
- while p.startswith(base):
- m = os.path.getmtime(p)
- if m <>
- print 'update', p
- os.utime(p, (mtime,mtime))
- elif m > mtime:
- mtime = m
- p = os.path.dirname(p)
- process_IN_MODIFY = process_IN_CLOSE_WRITE
- def process_IN_Q_OVERFLOW(self, event):
- print 'over flow'
- max_queued_events.value *= 2
- def process_default(self, event):
- pass
- wm = WatchManager()
- notifier = Notifier(wm, UpdateParentDir())
- dirs.update(wm.add_watch(base, flags, rec=True, auto_add=True))
- notifier.loop()
在已经有Hash Tree的时候,同步就比较简单了,不停地获取根目录的修改时间并顺着目录结构往下找即可。需要注意的是,在更新完文件后,需要设置修改时间为原文件的修改时间,目录也是,保证Hash Tree的一致性,否则没法同步。mirror.py的代码如下
- #!/usr/bin/python
- import sys,time,re,urllib
- import os,os.path
- from os.path import exists, isdir, getmtime
- src = sys.argv[1]
- dst = sys.argv[2]
- def local_mirror(src, dst):
- if exists(dst) and mtime == getmtime(dst):
- return
- if not isdir(src):
- print 'update:', dst
- open(dst,'wb').write(open(src).read())
- else:
- if not exists(dst):
- os.makedirs(dst)
- for filename in os.listdir(src):
- local_mirror(os.path.join(src,filename), os.path.join(dst,filename))
- os.utime(dst, (mtime,mtime))
- def get_info(path):
- f = urllib.urlopen(path)
- mtime = f.headers.get('Last-Modified')
- if mtime:
- mtime = time.mktime(time.strptime(mtime, '%a, %d %b %Y %H:%M:%S %Z'))
- content = f.read()
- f.close()
- return int(mtime), content
- p = re.compile(r'([\d.]+?) +([\w/]+)')
- def remote_mirror(src, dst):
- mtime, content = get_info(src)
- if exists(dst) and mtime == int(getmtime(dst)):
- return
- print 'update:', dst, src
- if not src.endswith('/'):
- open(dst,'wb').write(content)
- else:
- if not exists(dst):
- os.makedirs(dst)
- for mt,filename in p.findall(content):
- mt = int(float(mt))
- lpath = dst+filename
- if not exists(lpath) or int(getmtime(lpath)) != mt:
- remote_mirror(src+filename, lpath)
- os.utime(dst, (mtime,mtime))
- if src.startswith('http://'):
- mirror = remote_mirror
- else:
- mirror = local_mirror
- while True:
- mirror(src, dst)
- time.sleep(1)
如果源文件不在同一台机器上,可以通过NFS等共享过来。或者可以通过支持列目录的HTTP服务器来访问远程目录,mirror.py 已经支持这种访问方式。server.py 是用webpy做的一个简单的只是列目录的文件服务器。由于瓶颈在IO上,它的性能不是关键。server.py的代码如下:
- #!/usr/bin/python
- import os,os.path
- import web
- import time
- root = 'tmp'
- HTTP_HEADER_TIME = '%a, %d %b %Y %H:%M:%S %Z'
- class FileServer:
- def GET(self, path):
- path = root + path
- if not os.path.exists(path):
- return 404
- mtime = time.localtime(os.path.getmtime(path))
- web.header('Last-Modified', time.strftime(HTTP_HEADER_TIME, mtime))
- if os.path.isdir(path):
- for file in os.listdir(path):
- if file.startswith('.'): continue
- p = os.path.join(path,file)
- m = os.path.getmtime(p)
- if os.path.isdir(p):
- file += '/'
- print m, file
- else:
- print open(path,'rb').read()
- urls = (
- "(/.*)", "FileServer",
- )
- if __name__ == '__main__':
- web.run(urls, globals())
为了获得更好性能,以达到更好的实时性,Hash Tree最好是平衡的,比如BTree。如果一个文件发生变化,同步它需要进行的IO操作为N*M,其中N为数的层数,M为每层的文件数目。现在我们N为2,M最大为10000,适当减少它可以获得更好的性能,比如N为4,M为100。在以后创建目录结构时,最好能够考虑这方面的因素。
之前hongqn推荐过一个利用inotify的文件同步方案,同步方式类似于mysql和bdb等,由于过于复杂导致不可靠而没有采用。上面这个方案只用了一百多行Python代码就基本解决问题了,是不是很帅?:-)
2009年5月30日星期六
FreeBSD笔记┊Ports部署apache2+php5+mysql5+ZendOptimizer(转)
FreeBSD笔记┊Ports部署apache2+php5+mysql5+ZendOptimizer
作者:Sounix 日期:2008-11-17
其实咱学习freebsd的最终目的,也就是LAMP应用。但是我一直不赞成直接就去学习AMP的学习,而是先把L,也就是操作系统先玩懂,在去整服务,就明朗的多了。所以现在接触freebsd半个月,我开始是潜心学习freebsd的相关系统管理,现在基本上算是弄懂了。所以可以开始来学习服务配置了,昨天星期天,花了一天的时间在家里研究,最后忙到另成2点左右,才终于配置成功。其实配置成功后,在回头看看其实原来这么简单。
一、系统准备
什么叫系统准备,前面不是已经学习怎么安装系统了吗?
但是专业的服务器是不需要安装那么多东西的,我们安装的时候就选择minimal安装,然后使用sysinstall安装scr内核,以及ports。
然后编译内核,去掉一些没用的东西。这个我还没学,稍晚一点再学习。
然后升级portstree,可以用portsnap或者cvsup,推荐使用portsnap,这个已经学习过了,可以看前面的笔记。
二、安装apache2.0
升 级ports目录树后,最新版的apache是2.2.9_5。本来我是想安装最新版的,但是公司用的是2.0,为了能够和公司同步,我在这里也安装 apache2.0。但其实2.2和2.0相差不大,而2.2安装的时候会启动make config,也就是一个类图形界面,可以手动选择需要的模块,这样更直观一点;apache 2.0却没有,如果需要设置模块,就要用参数来指定了。
现在来安装apache 2.0:
[root@bsd01 apache20] make install clean
但是安装完之后,竟然无法正常启动,虽然用
apachectl start
/usr/local/etc/rc.d/apache2 start
httpd (no pid file) not running
我们来看看错误在那里:
[Mon Nov 17 13:28:07 2008] [error] [client 10.1.1.20] File does not exist: /usr/local/www/data/favicon.ico
[Mon Nov 17 13:28:08 2008] [error] [client 10.1.1.20] File does not exist: /usr/local/www/data/favicon.ico
[Mon Nov 17 13:28:09 2008] [error] [client 10.1.1.20] File does not exist: /usr/local/www/data/favicon.ico
[Mon Nov 17 13:28:29 2008] [notice] caught SIGTERM, shutting down
[Mon Nov 17 13:28:32 2008] [notice] Apache/2.0.63 (FreeBSD) configured -- resuming normal operations
[Mon Nov 17 13:28:44 2008] [notice] caught SIGTERM, shutting down
[Mon Nov 17 13:28:45 2008] [alert] (EAI 8)hostname nor servname provided, or not known: mod_unique_id: unable to find IPv4 address of "bsd01"
Configuration Failed
[Mon Nov 17 13:28:59 2008] [alert] (EAI 8)hostname nor servname provided, or not known: mod_unique_id: unable to find IPv4 address of "bsd01"
Configuration Failed
貌似是找不到hostname,所以我们编辑/etc/hosts文件:
127.0.0.1 localhost localhost.my.domain
改成下面(也就是后面加上本机计算机名):
127.0.0.1 localhost localhost.my.domain bsd01
现在来启动测试,发现启动成功了:
[root@bsd01 ~]# fetch http://127.0.0.1
127.0.0.1 100% of 1517 B 161 kBps
三、安装php5
[1]. 先来安装php5:
[root@bsd01 php5]# make install clean
然后会出现“make config”的界面,选择你需要的组件就可以,一般如下面所示:
───────────────────────────────────────
[X] CLI Build CLI version
[X] CGI Build CGI version
[X] APACHE Build Apache module
[ ] DEBUG Enable debug
[X] SUHOSIN Enable Suhosin protection system (not for jails)
[X] MULTIBYTE Enable zend multibyte support
[ ] IPV6 Enable ipv6 support
[ ] MAILHEAD Enable mail header patch
[ ] REDIRECT Enable force-cgi-redirect support (CGI only)
[ ] DISCARD Enable discard-path support (CGI only)
[X] FASTCGI Enable fastcgi support (CGI only)
[X] PATHINFO Enable path-info-check support (CGI only)
然后OK开始安装。
[2]. 配置apache以支持php:
加入如下2行:
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
另外看有没有下面这行,没有的话也加上:
LoadModule php5_module libexec/apache2/libphp5.so
然后找到下面这行,在后面加上index.php:
DirectoryIndex index.html index.html.var index.php
[3]. 安装php5扩展
[root@bsd01 php5-extensions]# make install clean
然后会出现“make config”的配置界面,选择需要的组件就可以了,一般如下所示:
───────────────────────────────────────
[X] BCMATH bc style precision math functions
[X] BZ2 bzip2 library support
[X] CALENDAR calendar conversion support
[X] CTYPE ctype functions
[X] CURL CURL support
[ ] DBA dba support
[ ] DBASE dBase library support
[X] DOM DOM support
[X] EXIF EXIF support
[X] FILEINFO fileinfo support
[X] FILTER input filter support
[ ] FRIBIDI FriBidi support
[X] FTP FTP support
[X] GD GD library support
[X] GETTEXT gettext library support
[ ] GMP GNU MP support
[X] HASH HASH Message Digest Framework
[X] ICONV iconv support
[X] IMAP IMAP support
[ ] INTERBASE Interbase 6 database support (Firebird)
[X] JSON JavaScript Object Serialization support
[X] LDAP OpenLDAP support
[X] MBSTRING multibyte string support
[X] MCRYPT Encryption support
[X] MHASH Crypto-hashing support
[ ] MING ming shockwave flash support
[ ] MSSQL MS-SQL database support
[X] MYSQL MySQL database support
[ ] MYSQLI MySQLi database support
[ ] NCURSES ncurses support (CLI only)
[ ] ODBC unixODBC support
[X] OPENSSL OpenSSL support
[ ] PCNTL pcntl support (CLI only)
[X] PCRE Perl Compatible Regular Expression support
[X] PDF PDFlib support (implies GD)
[X] PDO PHP Data Objects Interface (PDO)
[X] PDO_SQLITE PDO sqlite driver
[ ] PGSQL PostgreSQL database support
[X] POSIX POSIX-like functions
[ ] PSPELL pspell support
[ ] READLINE readline support (CLI only)
[ ] RECODE recode support
[X] SESSION session support
[ ] SHMOP shmop support
[X] SIMPLEXML simplexml support
[X] SNMP SNMP support
[ ] SOAP SOAP support
[X] SOCKETS sockets support
[X] SPL Standard PHP Library
[X] SQLITE sqlite support
[ ] SYBASE_CT Sybase database support
[ ] SYSVMSG System V message support
[ ] SYSVSEM System V semaphore support
[ ] SYSVSHM System V shared memory support
[ ] TIDY TIDY support
[X] TOKENIZER tokenizer support
[ ] WDDX WDDX support (implies XML)
[X] XML XML support
[X] XMLREADER XMLReader support
[ ] XMLRPC XMLRPC-EPI support
[X] XMLWRITER XMLWriter support
[X] XSL XSL support (Implies DOM)
[ ] YAZ YAZ support (ANSI/NISO Z39.50)
[X] ZIP ZIP support
[X] ZLIB ZLIB support
这个安装过程比较长,需要耐心等待。
至此,apache+php基本上算是配置成功了。“apachectl restart”重启一下。然后去下载个php探针去测试一下。
四、安装mysql5
[1]. mysql5的安装
安装过程很简单,因为前面我们安装php组件的时候,它自动给我们安装了mysql-client5.0,所以我们server也安装5.0好了:
mysql-client-5.0.67_1 Multithreaded SQL database (client)
php5-mysql-5.2.6_2 The mysql shared extension for php
[root@bsd01 ~]# cd /usr/ports/databases/mysql50-server
[root@bsd01 mysql50-server]# make install clean
* 不过这样安装的mysql不支持gb2312,gbk等编码,查询会出错。可以使用“make WITH_XCHARSET=all install clean” 的安装命令来释放其他的编码支持。如果使用“make WITH_CHARSET=gb2312 WITH_XCHARSET=all install clean”这样的安装命令,则表示把释放所有编码支持并设置gb2312为mysql的默认编码,一般来说是不可取的,除非你真的决定想这么做!
[2]. mysql5配置过程
不要以为上面的安装完之后,mysql-server就可以使用了,其实会出故障的:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
我就是被这个问题搞了我2天都没解决,现在开始配置:
[root@bsd01 ~]# /usr/local/bin/mysql_install_db --user=mysql
[root@bsd01 ~]# /usr/local/bin/mysqld_safe --user=mysql &
[1] 74754
[root@bsd01 ~]# mysqladmin -u root pqssword '123456'
[root@bsd01 ~]# ps -ef | grep mysqld
ps: Process environment requires procfs(5)
74754 p5 I 0:00.08 /bin/sh /usr/local/bin/mysqld_safe --user=mysql
74780 p5 S+ 0:00.02 grep mysqld
[root@bsd01 ~]# kill -9 74754
[1]+ Killed: 9 /usr/local/bin/mysqld_safe --user=mysql
[root@bsd01 ~]# /usr/local/etc/rc.d/mysql-server start
[root@bsd01 ~]# pgrep mysqld
74775
[root@bsd01 ~]# mysql -u root -p
Enter password:123456
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.0.67-log FreeBSD port: mysql-server-5.0.67_1
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
五、为php配置ZendOptimizer
ZendOptimizer可以为php的解析加速,听说可以提高40%-100%的执行速度。所以一般php都会加载这个,现在我们来配置:
[root@bsd01 ports]# make search key=^Zend
Port: ZendOptimizer-3.3.0.a
Path: /usr/ports/devel/ZendOptimizer
Info: An optimizer for PHP code
[root@bsd01 ports]# cd /usr/ports/devel/ZendOptimizer
[root@bsd01 ZendOptimizer]# make install clean
这样就可以安装完成了,然后会有提示,在php.ini加入如下文字:
在最后加入如下文字:
[Zend]
zend_optimizer.optimization_level=15
zend_extension_manager.optimizer="/usr/local/lib/php/20060613/Optimizer"
zend_extension_manager.optimizer_ts="/usr/local/lib/php/20060613/Optimizer_TS"
zend_extension="/usr/local/lib/php/20060613/ZendExtensionManager.so"
zend_extension_ts="/usr/local/lib/php/20060613/ZendExtensionManager_TS.so"
然后重启apache服务:
[root@bsd01 ~]# apachectl start
六、让freebsd自动启动apache+mysql服务
至此,apache+php+mysql已经配置成功了,现在我们配置让freebsd能够在开机的时候自动运行这些服务。
另如果你在手动启动apache的时候,经常提示:
那是因为apache无法开始Accept Filter机制。
则可以在/boot/loader.conf加入“accf_http_load="YES"”即可:
结语:
至此,freebsd7.0下的apache2+php5+mysql5+ZendOptimizer3就已经完满成功了,这里花了我2天多时间的研究。网上很多的教程都是比较不切实际,所以最重要的还是自己实践。
其中最麻烦的就是mysql数据库了,稍微不注意就出现那个/tmp/mysql/sock的错误,很烦,而且网上也找不到具体的解决办法。根据经验,一般是mysql数据库没有启动起来,可以使用“pgrep mysqld”来看看进程有没有启动。
如果没有,可尝试先用“mysql_install_db --user=mysql”,然后再用“mysqld_safe &”来启动,然后重启电脑。
还就是比较烦freebsd的就是我发现如果用“apachectl、mysql-server”这些服务命令执行start|restart命令的时候,经常是服务没启动,但是也不报错,有时候想骂人。所以最好把mysql加在/etc/rc.conf里让它自己启动。
apache 重启的时候,也最好不要用“apachectl restart”,还是依次用“apachectl stop”;"apachectl start"来使用,最后别忘了用“pgrep httpd”来看一下有没有正常启动。没办法,好像freebsd下的apache+mysql有点不保险,所以我们要处处留意。