FreeBSD8.2上部署Lighttpd+MySQL+Redmine
本来不想写这样一篇文章,因为实在只是体力活,没有意外的情况下,反复Configure/make/make install即可以顺利完成,可是生活偏偏这么狗血,就在这样一个简单的任务上,我居然为之整整折腾了一天,颇为郁闷,所以还是记录一下。
先说一下我的环境,硬件是一台自己买零件配的Atom小型机,CPU: Intel(R) Atom(TM) CPU D525 @ 1.80GHz (1810.46-MHz K8-class CPU),内存4G,硬盘是一个从MacBookPro上拆下来的500G硬盘,上面跑着一个FreeBSD8.2(reeBSD dev.0d0f.com 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Thu Feb 17 02:41:51 UTC 2011)系统,采取最简单的安装,外加Lighttpd、PHP、MySQL,组成了我们的测试环境。因为项目接下来的管理的需要,所以打算加一个Redmine。以上是背景。
作为一个曾经读了一个多月Redmine代码的技术宅,安装这个本来是轻车熟驾的。首选当然是直接RVM安装方案。说干就干,装好RVM之后开始 rvm install 1.8.7,gems也自动安装好了,没有报错,貌似挺成功的。但是接下来就开始了噩梦,首先是Gems在装rails的时候,虽然能够安装成功,但是装不了RDoc,提示是找不到iconv库(gem install rails no such file to load -- iconv),当时觉得没什么,大不了不用Doc呗,只要能跑,于是忽略继续,然而在跑代码的时候却发现依然提示找不到iconv,于是明白这是一个关键的包依赖,忽略不了的。前前后仔细查看了一下系统库,Libiconv好好的呆在/usr/local里,不管怎么加参数,都是不行,联想到FreeBSD的各种变态的安全限制,于是决定抛弃RVM,Root到根目录下直接从源代码编译。
手动编译比RVM快多了。然而意外的是,安装Rails时依然是提示找不到iconv,这就不对了,翻了一下Google发现这个包居然是由FreeBSD提供而不是由Ruby自带的,只好祭起万能的Ports。
- [root@dev]#cd /usr/ports/converters/ruby-iconv/
- [root@dev]#make install clean
完了再重新编译Ruby和Gem,还是不行,无奈之下只好不情不愿的编译起FreeBSD的Ports原生包来:
- [root@dev]# echo "RUBY_VERSION=1.8.7" >> /etc/make.conf
- [root@dev]# cd /usr/ports/lang/ruby18
- [root@dev]# make install clean
- [root@dev]# cd /usr/ports/devel/ruby-gems
- [root@dev]# make install clean
- [root@dev]# cd /usr/ports/converters/ruby-iconv
- [root@dev]# make install clean
- [root@dev]# cd /usr/ports/databases/ruby-mysql
- [root@dev]# make install clean
- [root@dev]# gem18 install rails --version=2.3.14
这一编译就折腾了一下午各种依赖的包都要编译,比如一个ruby-rmagick库就安装了63个依赖包。安装好了Ruby rails接下来就安装Redmine吧,从rubyforge上拉最新代码来装:
- [root@dev]# mkdir /usr/local/www/
- [root@dev]# cd /usr/local/www/
- [root@dev]# svn co http://redmine.rubyforge.org/svn/trunk redmine
- [root@dev]# cd redmine
创建Redmine数据库:
- CREATE DATABASE `redmine` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
# 设定Redmine环境
- [root@dev]# cp config/configuration.yml.example config/configuration.yml
- [root@dev]# cp config/database.yml.example config/database.yml
- [root@dev]# vi config/configuration.yml
- [root@dev]# vi config/database.yml
- # 生成session store secret.
- [root@dev]# rake generate_session_store
- # 生成production数据库
- [root@dev]# rake db:migrate RAILS_ENV=production
- [root@dev]# rake redmine:load_default_data RAILS_ENV=production
- # 设置目录权限
- [root@dev]# find /redmine_docroot/ -type f -exec chmod 644 {} \;
- [root@dev]# find /redmine_docroot/ -type d -exec chmod 755 {} \;
- # 设置目录权限
- [root@dev]# mkdir tmp public/plugin_assets
- [root@dev]# sudo chown -R redmine:redmine files log tmp public/plugin_assets
- [root@dev]# sudo chmod -R 755 files log tmp public/plugin_assets
- # 启动Redmine
- [root@dev]# ruby18 script/server webrick -e production
安装thin:
- [root@dev /usr/local]# gem18 install thin
- Fetching: eventmachine-0.12.10.gem (100%)
- Building native extensions. This could take a while...
- Fetching: daemons-1.1.8.gem (100%)
- Fetching: thin-1.3.1.gem (100%)
- Building native extensions. This could take a while...
- Successfully installed eventmachine-0.12.10
- Successfully installed daemons-1.1.8
- Successfully installed thin-1.3.1
- 3 gems installed
- Installing ri documentation for eventmachine-0.12.10...
- Installing ri documentation for daemons-1.1.8...
- Installing ri documentation for thin-1.3.1...
- Installing RDoc documentation for eventmachine-0.12.10...
- Installing RDoc documentation for daemons-1.1.8...
- Installing RDoc documentation for thin-1.3.1...
- 检查thin包是否安装成功:
- [root@dev /usr/local]# gem18 list
- *** LOCAL GEMS ***
- actionmailer (2.3.14)
- actionpack (2.3.14)
- activerecord (2.3.14)
- activeresource (2.3.14)
- activesupport (2.3.14)
- bundler (1.0.22)
- coderay (1.0.5)
- daemons (1.1.8)
- eventmachine (0.12.10)
- i18n (0.4.2)
- mysql2 (0.2.18)
- net-ldap (0.3.1)
- pg (0.9.0)
- rack (1.1.3)
- rails (2.3.14)
- rake (0.9.2.2)
- rmagick (2.13.1)
- ruby-openid (2.1.8)
- sqlite3 (1.3.5)
- thin (1.3.1)
创建thin运行配置文件:
- [root@dev /usr/local]#thin config -C /usr/local/www/redmine/config/redmine.yml -c /usr/local/www/redmine --servers 1 -e production
确认:
- [root@dev]# cat /usr/local/www/redmine/config/redmine.yml
- ---
- chdir: /usr/local/www/redmine
- environment: production
- address: 0.0.0.0
- port: 3000
- timeout: 30
- log: log/thin.log
- pid: tmp/pids/thin.pid
- max_conns: 1024
- max_persistent_conns: 512
- require: []
- wait: 30
- servers: 1
- daemonize: true
启动thin:
- [root@dev]# thin -C /usr/local/www/redmine/config/redmine.yml start
- Starting server on 0.0.0.0:3000 ...
写一个脚本放到/usr/local/etc/rc.d下面去,供启动用:
- [root@dev]#cd /usr/local/etc/rc.d
- [root@dev]#touch thin.rc
- [root@dev]#touch thin_init.rc
- [root@dev]#vi thin.rc
- #!/bin/sh
- function_start_jobs(){
- printf "Starting thin...\n"
- thin -C /usr/local/www/redmine/config/redmine.yml start
- }
- function_stop_jobs(){
- thin -C /usr/local/www/redmine/config/redmine.yml stop
- }
- if [ "$1" = "start" ]; then
- function_start_jobs
- elif [ "$1" = "restart" ]; then
- function_stop_jobs
- function_start_jobs
- elif [ "$1" = "stop" ]; then
- function_stop_jobs
- else
- printf "Usage:/usr/local/etc/rc.d/thin {start|stop|restart}\n"
- fi
- [root@dev]#vi thin_init.rc
- #!/bin/sh
- /usr/local/etc/rc.d/thin start
修改 lighttpd 配置文件 modules.conf,加入mod_proxy模块:
- server.modules = (
- "mod_rewrite",
- "mod_redirect",
- "mod_alias",
- "mod_access",
- "mod_fastcgi",
- "mod_proxy",
- "mod_simple_vhost",
- )
给lighttpd配置加上反向代理:
- [root@dev]# vi /usr/local/etc/lighttpd/lighttpd.conf
- $HTTP["host"] == "redmine.handaoliang.com" {
- $HTTP["url"] =~ "^/((images|stylesheets|javascripts|assets)/(.*)$|(favicon\.ico|robots\.txt))" {
- server.document-root = "/usr/local/www/redmine/public/"
- }
- proxy.balance = "hash"
- proxy.server = (
- "" =>((
- "host" =>"127.0.0.1",
- "port" =>"3000"
- ))
- )
- }
重启Lighttpd和thin,应该就可以了。
附Nginx的反向代理配置:
- upstream redmine_pass {
- server 127.0.0.1:3000;
- }
- server {
- listen 80;
- server_name redmine.handaoliang.com;
- root /usr/local/www/redmine/public;
- location / {
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $http_host;
- proxy_redirect off;
- proxy_read_timeout 30;
- if (-f $request_filename/index.html) {
- rewrite (.*) $1/index.html break;
- }
- if (-f $request_filename.html) {
- rewrite (.*) $1.html break;
- }
- if (-f $request_filename.txt) {
- rewrite (.*) $1.txt break;
- }
- proxy_pass http://redmine_pass/;
- }
- }
开源的压力测试工具PyLot
几天前新开了一个专门介绍国内外优秀开源项目的网站:“秀码趣”(www.showmuch.com),这是写给ShowMuch的稿子。
一、什么是Pylot:
Pylot(www.pylot.org)是一款开源的用以测试Web Service性能和扩展性的工具,它运行HTTP负载测试,这对于制定容量计划、确定基准点、分析系统瓶颈以及系统调优都非常有用。在使用过程中,Pylot会发起并发请求(HTTP Requests),检验服务器响应,以及带有相关指标的报表。它通过GUI或者Shell/Console来执行和监视对被测试网站的测试过程。
Pylot基于Python开发,和著名的Apache压力测试工具ab一样,默认在命令行运行,也可以通过参数触发GUI界面,当然前提是安装了wxPython的。
二、Pylot如何工作:
Pylot的使用方法很简单,你只要在一个XML文件里预定义好测试项目的相关参数即可。Pylot通过对得到的内容进行正则表达式匹配以及通过HTTP状态码来验证服务器响应,在测试开始前,你可以通过图行用户界面或者命令行来调整测试参数(如:Agents数量、请求间隔、时间增量以及测试持续时间等),这些设定使得你可以为各种不同的测试场景建立模型,通过Agents向测试服务器发起并发请求,整个测试过程可以实时地监测运行状态以及错误报告。
三、安装和使用:
1、安装。
Pylot的安装非常简单,首先是必须具备Python2.5以上的环境,然后去它的官网下载发行包(当前是1.26版本),如果你对于图形界面有一定的要求,则必须安装wxPython,另外还有两个可选的安装包是NumPy和Matplotlib,都是用来生成图形报表的。
具体请参考Pylot的官方使用文档:http://www.pylot.org/gettingstarted.html
2、使用。
使用很简单,先解压出来,在解压目录下,会看到有一个:testcases.xml文件,先配置一下:


配置好了之后,运行:python run.py -a 5即可以开始进行压力测试,这里参数“-a 5”的意思是:运行5个Agents。

测试报表会保存在Result目录下。通过访问results.html可以查看网页版报表。

四、简评:
Pylot有着简洁而优雅的源代码,功能强大,有用户图形界面,可生成友好的测试报表,虽然同样开源的压力测试工具有很多,比如Apache自带的大名鼎鼎的压力测试工具AB,但是作为使用Python编写的专业开源压力测试工具,却是值得关注和学习的。
Nginx+PHP+PHPFPM文件类型错误解析漏洞
刚刚接到信息安全部的通知,说是有一台主机存在文件类型错误解析漏洞,吓了一跳。Nginx配置我早就亲自检查了一遍,按说如果有错误类型文件解析会跳转到403才对。但是事实证明还是疏忽大意了。
测试:
curl -I http://www.test.com/images/inbanner_4.jpg/1.php?c=ls
果然得到:
HTTP/1.1 200 OK
Server: nginx/0.8.41
Date: Mon, 21 Feb 2011 07:40:04 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.2.13
这就意味着,黑客可以通过上传图片,在图片中添加可执行代码来获取服务器权限。这对于一个网站来说,是极为可怕的。
解决方法:
修改php.ini将cgi.fix_pathinfo设为0 (注:前面可能有注释符号; 需要删除掉。)
执行php/sbin/php-fpm restart重启。
PHP5.3.3小BUG
编译了一下PHP5.3.3,结果Configure时一切正常,却卡在了Make上,出错信息如下:
- In file included from /Users/handaoliang/MySoft/src/php-5.3.3/ext/mysqli/php_mysqli_structs.h:57,
- from /Users/handaoliang/MySoft/src/php-5.3.3/ext/mysqli/mysqli.c:33:
- /opt/iapps/mysql/include/mysql/my_global.h:1008: error: duplicate ‘unsigned’
- /opt/iapps/mysql/include/mysql/my_global.h:1008: warning: useless type name in empty declaration
根据提示看了一下代码,原来是MySQL为unsigned long这种数据类型定义了一个新名字,而PHP5.3.3没有跟上。
当然也可能是因为我的MySQL版本比较新(mysql-5.1.48),这个我没有去验证过。旧版的MySQL也许没这问题。
vi /opt/iapps/mysql/include/mysql/my_global.h
- typedef unsigned long ulong; /* Short for unsigned long */
修正方法,编辑php_mysqli_structs.h:
vi ext/mysqli/php_mysqli_structs.h
查找:WE_HAD_MBSTATE_T(应该是在第54行,直接跳到第54行也可以)
- 54 #define WE_HAD_MBSTATE_T
- 55 #endif
- 56
- 57 #define HAVE_ULONG 1
- 58 #include <my_global.h>
在#include
或者使用Patch:
- Index: ext/mysqli/php_mysqli_structs.h
- ==========================================
- --- ext/mysqli/php_mysqli_structs.h (revision 301474)
- +++ ext/mysqli/php_mysqli_structs.h (working copy)
- @@ -54,6 +54,7 @@
- #define WE_HAD_MBSTATE_T
- #endif
- +#define HAVE_ULONG 1
- #include <my_global.h>
- #if !defined(HAVE_MBRLEN) && defined(WE_HAD_MBRLEN)
修改之后再make,然后就一切正常了。
让iPhone跑得更快,对iPhone进行系统盘瘦身
iPhone有一个Fonts文件夹,是放在系统盘下的,占据了90多M的磁盘空间。对于像Fonts这种不经常替换的文件,完全可以移到别的磁盘,以节约系统盘有限的空间。下面,我们就通过SSH来连接到iPhone,对iPhone进行一次小小的系统盘瘦身。
先看一下fonts文件夹的大小,94M:
- handaoliang-iphone:/System/Library/Fonts root# du -lh
- 94M .
再看磁盘空间,发现系统盘已经被占用了89%:
- handaoliang-iphone:~ root# df -lh
- Filesystem Size Used Avail Use% Mounted on
- /dev/disk0s1 750M 654M 89M 89% /
- devfs 33K 33K 0 100% /dev
- /dev/disk0s2s1 30G 4.9G 25G 17% /private/var
那么首先,我们把/System/Library/Fonts目录拷贝到 /private/var目录下:
- handaoliang-iphone:~ cp -r /System/Library/Fonts /private/var
然后把/System/Library/Fonts目录重新命名为/System/Library/Fonts.bak:
- handaoliang-iphone:~ mv /System/Library/Fonts /System/Library/Fonts.bak
建立一个软连接,把新的/System/Library/Fonts指向/private/var/Fonts目录:
- ln -s /private/var/Fonts /System/Library/Fonts
重新启动IPHONE,如果工作正常,putty重新登录进入iphone。
删掉备份,删除/System/Library/Fonts.bak目录:
- rm -rf /System/Library/Fonts.bak
再看系统盘空间,可用空间已经增加到了23%:
- handaoliang-iphone:/System/Library root# df -lh
- Filesystem Size Used Avail Use% Mounted on
- /dev/disk0s1 750M 560M 183M 76% /
- devfs 33K 33K 0 100% /dev
- /dev/disk0s2s1 30G 4.9G 25G 17% /private/var