别人的浪漫

睡到中午,起来准备发给硕求婚现场观众的卡片文字,追他敲定中英文。捋顺行进流程,解决疑点。最后设计好卡片团,下厂印制,总共大半个下午搞定。

看来只要我想做的话,执行力还是不错的,不过这仅仅是开始,要点是明天的最终环境变量结果,之后就随机应变吧。

对了,这里的零星观众们,此事件暂时还属于一个秘密,不论怎样不要透露哦~嘘~~

刘丽娜的生日礼物,高宝的转账,一些看似不大的事情经常也会消耗很多时间,不过好歹都做完了,总体看来今天效率还满高。

 

9号决战上海了,首席伴郎压力大啊~~

悲催的延续

也许写技术博客不应该带太多情绪。。。好吧以后注意。

悲剧在延续,继安装好各个软件后,开始调试。PDO连接数据库直接给502错误。

你要是报个500吧,我还能理解,502是什么态度呢?

命令行下运行,就仨字——“段错误”(Segment fault)

搜索给出是内存访问错误,登时有点抓狂,莫非要我追源码不成。

研究一阵子无果,问了下大家意见,志强说见过类似错误,赶快邀来帮忙。展示了一下由于完全没有其他信息,也比较没辙,志强提出使用connect方式连接一下mysql看看,果然,出现信息了 “Headers and client library minor version mismatch. Headers:50045 Library:50517”

终于有所发现,50517是新的数据库版本,50045是原有的老的数据库版本,看来是php编译的时候使用的mysql源文件还是老版本的,也就是说原有的mysql并没有清除干净,于是马上开始着手清除原有的mysql的文件,然后一遍一遍的编译php。

话说志强是一位好同志,个高人帅又安静,爱好点乐器,天平的东北爷们,而且貌似还单身,有靠谱的可以给介绍一个嗯嗯,咳,跑题了。。。

当删掉了最后一部分我认为有可能是原mysql的文件并再次编译未果之后,我开始怀疑是不是文件的问题了。。。有点迟钝了。。。这时想到了缓存,于是重启服务器。

终于!开机后的再次编译之后运行成功,原来我被这个幽灵缓存坑了一整天。。。

最后总结一下,时间耽误在思维的局限上,更早之前就应该想想更多的问题点。崩溃没有意义,应该冷静的跳出圈子转换思维。另外耐心和迅捷操作也很重要。

接上 编译安装Memcache

Memcache的安装比较顺利了,不过也有一些小问题需要注意

Memcached据说需用到libevent这个库 https://github.com/downloads/libevent/libevent/libevent-2.0.15-stable.tar.gz,但是不装好像也没有什么问题。

Install Libevent
1
2
3
4
5
6
tar zxvf libevent-2.0.12-stable.tar.gz
cd libevent-2.0.12-stable
./confiugre --prefix=/usr
make
make install

安装Memcached

Install memcached
1
2
3
4
5
6
7
wget http://memcached.googlecode.com/files/memcached-1.4.9.tar.gz
tar zxvf memcached-1.4.9.tar.gz
cd memcached-1.4.9
./confiugre --prefix=/opt/modules/memcached --with-libevent-dir=/usr
make
make install

安装 php memcache扩展

Install php-memcache
1
2
3
4
5
6
7
8
wget http://pecl.php.net/get/memcache-3.0.6.tgz
tar xvf memcache-3.0.6.tgz
cd memcache-3.0.6
/opt/modules/php/bin/phpize
./configure --enable-memcache --with-php-conf=/usr/local/php/bin/php-config
make
make install

安装完成后,提示
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626

配置php.ini文件,在文件最后添加
extension_dir="/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626"
extension=memcache.so

查看php是否成功加载memcache.so
/opt/modules/php/bin/php -m

启动memcached服务端程序
memcached -d -m 64 -u www-data -l localhost -p 11211 -c 640 -P /tmp/Memcached.pid

各个参数的意义
-d选项是启动一个守护进程,
-m是分配给Memcached使用的内存数量,单位是MB,
-u是运行Memcache的用户,我这里是root,
-l是监听的服务器IP地址,
-p是设置Memcache监听的端口,最好是1024以上的端口,
-c选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定,
-P是设置保存Memcache的pid文件

配置memcached开机启动

init memcache
1
2
3
cp memcached.txt /etc/init.d/memcached
chmod + x /etc/init.d/memcached
chkconfig memcached on

svn比较简单不再纪录

悲催之LNMP环境编译安装

最近负责一台实验机的部署,需要搭建LNMP环境,由于并不太熟悉安装细节,决定尝试指定目录编译安装,方便以后的管理控制。

之后便开始了为期3天的痛苦折磨,各种诡异的错误,加上本身心情不好,无以言表烦闷挫败之感,今天跟其死磕到底,终于拨云见日,小出一口气。

Linux环境的搭建本身应该是很基础的知识,由于以前并未实际操作过,算是一个缺口,这次也正好是个机会恶补一下吧,如冯鑫所说,停止自欺欺人,从基础开始巩固自己,不失为一件好事。

先叙述一段前奏:整体配置之前,下载了各个软件的源码包,不小心毁了原来的Apache+php系统导致报警系统实效,临时熬夜搭建了最新的nginx+php-fpm的环境配用,中间踩雷无数,主要关于nginx的配置。由于还没有安装mysql,php编译时没有带上mysql的相关参数,只是临时使用,当第二天真正搭建时才开始了mysql+php编译的噩梦。。。

失败的地方就不说了,主要叙述安装过程及注意要点,以备后用。

php必须在mysql后面安装,nginx随意

1,先安装nginx可以用来测试php,nginx编译安装也最简单注意附带上prefix参数确定路径。其他教程也有nginx附带zlib和openssl组件的,如果附带可以按如下方式安装。

a.安装zlib,openssl等组件

Install zlib & openssl
1
2
3
4
5
6
7
8
9
10
unzip -x zlib125.zip
cd zlib-1.2.5
./configure --prefix=/usr
make
make install
tar zxvf openssl-0.9.8r.tar.gz
cd openssl-0.9.8r
make
make install

b.安装 nginx

Install Nginx & pcre
1
2
3
4
5
6
7
tar zxvf pcre-8.13.tar.gz
tar zxvf nginx-1.0.8.tar.gz
cd nginx-1.0.8
./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin --with-http_ssl_module --with-http_sub_module --with-http_flv_module --with-http_stub_status_module --with-zlib=../zlib-1.2.5 --with-openssl=../openssl-0.9.8r --with-pcre=../pcre-8.13
make
make install

2,安装mysql,长话短说

mysql5.5.17需要安装CMake

Install CMake
1
2
3
4
5
tar zxvf cmake-2.8.5.tar.gz
cd cmake-2.8.5
./configure
make
make install

在安装最后一步时可能会出错,解决办法是指定安装位置make install DESTDIR=/usr/local.

最后可用的参数设置:

Install Mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
groupadd mysql
useradd -d /opt/modules/mysql -g mysql -s /usr/sbin/nologin mysql
chown -R mysql:mysql /opt/modules/mysql
chmod -R 755 /opt/modules/mysql
cmake -DCMAKE_INSTALL_PREFIX=/opt/modules/mysql \
-DMYSQL_DATADIR=/opt/modules/mysql/data \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DMYSQL_UNIX_ADDR=/tmp/mysqld.sock \
-DMYSQL_TCP_PORT=3306 \
-DENABLED_LOCAL_INFILE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DMYSQL_USER=mysql
make
make install

复制配置文件my.cnf

Install Mysql
1
2
3
cp /opt/modules/mysql/support-files/my-medium.cnf /etc/my.cnf
chown mysql.mysql /etc/my.cnf
chmod 755 /etc/my.cnf

配置开机启动

Install Mysql
1
2
3
cp /opt/modules/mysql/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chkconfig mysqld on

在这之前,需要初始化mysql信息表。记得非默认路径安装的要带上mysql和data的路径。
mysql_path/scripts/mysql_install_db --user=mysql --basedir=/opt/modules/mysql --datadir=/path_to_mysql_data_dir

另外补充开放root外网访问命令,备忘:
GRANT ALL PRIVILEGES ON *.* TO 'monitor'@'%' IDENTIFIED BY 'admin'WITH GRANT OPTION;
FLUSH PRIVILEGES;

启动mysql并设置密码

Install Mysql
1
2
/etc/init.d/mysqld start
/usr/local/mysql/bin/mysqladmin -u root password '新密码'

3,php安装,最悲催的就是这个,configure各种报错,最后又神奇可用,无以言表。。。

最后可用的设置,注:新版本的php都自带fpm了,所以不用安装。

Install PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
./configure --prefix=/opt/modules/php \
--with-config-file-path=/opt/modules/php/etc \
--with-iconv-dir \
--with-freetype-dir \
--with-jpeg-dir \
--with-png-dir \
--with-zlib \
--with-libxml-dir=/usr \
--enable-xml \
--disable-rpath \
--enable-magic-quotes \
--enable-safe-mode \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--with-curl \
--with-curlwrappers \
--enable-mbregex \
--enable-fpm \
--enable-mbstring \
--with-mcrypt \
--enable-ftp \
--with-gd \
--enable-gd-native-ttf \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-zip \
--enable-soap \
--without-pear \
--with-gettext \
--enable-fpm \
--with-fpm-user=www \
--with-fpm-group=www \
--with-pdo-mysql=/opt/modules/mysql \
--with-mysql=/opt/modules/mysql \
--with-mysqli=/opt/modules/mysql/bin/mysql_config
make
make install

make时曾出现 /usr/bin/ld: cannot find -lltdl 解决很简单,库在,只是没编译

Install PHP
1
2
3
4
cd /usr/share/libtool/libltdl
./configure --prefix=/usr
make
make install

复制php.ini到配置文件目录及php-fpm 开机启动

Install PHP
1
2
3
cp php.ini-production /opt/modules/php/etc/php.ini
cp /opt/modules/php/sbin/php-fpm /etc/init.d/php-fpm
chmod +x /etc/init.d/php-fpm

这时候还不能使用/etc/init.d/php-fpm start启动,需修改一下php-fpm配置文件才可以,配置文件位置php安装目录 etc 目录下,默认有个参考文件.

Install PHP
1
2
3
4
5
cp php-fpm.conf.default /opt/modules/php/etc/php-fpm.conf
vim php-fpm.conf
,pm.start_servers = 20
,pm.min_spare_servers = 5
,pm.max_spare_servers = 35

去掉以上三项前面的逗号,这时再使用/etc/init.d/php-fpm start 即可启动。

最后配置nginx.conf最坑爹的就在这。。。

Install PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name localhost;
    root /var/www/html;
    location ~ .*\.(php|php5)?$
  {
   #fastcgi_pass unix:/tmp/php-cgi.sock;
   fastcgi_pass 127.0.0.1:9000;
   fastcgi_index index.php;
   include fastcgi.conf;
  }
}

默认情况下,最后一行fastcgi.conf是fastcgi_params,这是无论如何过不去的,看看内容,只差一行。。。

补充一句,有问题可以去LNMP.org找灵感,不过很多问题都是未提到的。。。

暂时到这儿。。。要死了。。。明天继续磕memcached和svn...

段落

似乎所有的事情都告一段落了,是好事情。

感受到内心的平静和兴奋。

平静因为感恩和包容,生活的目的和态度都很重要,找到一个永恒的目的很难却很持久,态度决定你能走多远。

兴奋因为一些预感,生命也许即将开始另一个阶段,虽然过程可能很多挫折打击,抱着感恩和奉献的心去做则无悔无惧,至少目前有资源有渠道,拼的是想象力和执行力。

某贴说,这辈子要做的两件事情:一见钟情轰轰烈烈的爱一场,说走就走的豪迈旅行。第一件事太没谱,第二件可以有。

Stay hungry, stay foolish, until the last of your day.

我的假期

至此为止,已经不关乎于假期,而关乎于需要记住的事情。

最重要的朋友们,一个都不要失去。

身体是自己的,保持锻炼。

无意义的等待,没必要继续,无悔即可。更重要的是,以后不要再错过值得珍惜的人。

我已经27了,时间越来越少了,今年的计划要搁浅一些,那么其他的一些需要补上了。

猫是种讨人喜欢的宠物,虽然它没有像狗一样的忠心和对你的归属感,但是自律,毕竟你没打算要求你的宠物看家护院或者帮你挡子弹什么的不是么。

Stay hungry, Stay foolish, 乔帮主与世长辞,留下无尽财富。今生要好好做人,积德行善,我要去看看天堂被乔帮主改造成什么样了。

抓住假期的尾巴,至此它还是充实的,因此更需要一个happy ending。

 

装饰WordPress

终于把空间里面几点遗留问题解决了,不是不报时候未到啊,曾经寻了千百度今天都轻松找到渠道。

1,Tag Cloud选用了wp-cumulus,解决了放大和Logo的问题,就势寻找到帖子完美的解决了中文Tag的问题。 http://www.lostleon.com/blog/2009/12/hacked-wp-cumulus-to-support-chinese/

2,代码高亮选择了Crayon,比较满意黑色底色的模版。

PHPUnit深入实践

近日在暴风成功推行了PHPUnit,这里记录一下实践的过程和心得。

安装

网上说的安装方法大致有两种,pear安装和自行下载压缩包安装,但是单独使用都不靠谱,两种结合一下就好了。

首先使用pear安装phpunit,具体操作步骤参考http://pear.phpunit.de/ 这是最便捷的取得最新版本并增加好所有依赖的方式。

然后取出runner文件夹中的PHPUnit.php,修改代码执行器目录到php的目录,并改名为PHPUnit,放在/usr/bin/文件夹下。(window用户可以设定path让它可以在环境中被找到)

基类整理

PHPUnit提供框架和数据库测试集成代码,但是封装了的工具并不完全够用,可以根据自己的需求增加一些更加实用的方法和类到基类中,如:

1,phpunit原生并不提供可以使用php数组进行数据库初始化的方式,所以需要一个额外的类去封装phpunit的Dataset方法,做到可以使用数组的方式组织初始数据,毕竟直接写在代码里的数组比额外的xml文件管理起来要方便的多,如:

Array DataSet
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* 使用数组初始化数据库内容扩展类
* @author wangkepan
*
*/
class StromTest_DbUnit_ArrayDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
{
/**
* @var array
*/
protected $tables = array();
/**
* @param array $data
*/
public function __construct(array $data)
{
foreach ($data AS $tableName => $rows) {
$columns = array();
if (isset($rows[0])) {
$columns = array_keys($rows[0]);
}
$metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
$table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);
foreach ($rows AS $row) {
$table->addRow($row);
}
$this->tables[$tableName] = $table;
}
}
protected function createIterator($reverse = FALSE)
{
return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
}
public function getTable($tableName)
{
if (!isset($this->tables[$tableName])) {
throw new InvalidArgumentException("$tableName is not a table in the current database.");
}
return $this->tables[$tableName];
}
}

2,对于一些protected 和 private 的方法,需要用反射类修改方法的可读性来对方法进行测试,实现方法参看http://stackoverflow.com/questions/249664/best-practices-to-test-protected-methods-with-phpunit

Reflection
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 取得私有对象方法。需要php版本大于5.3.2
* @param string $className
* @param string $methodName
* @return Ambiguous
*/
protected static function getMethod($className, $methodName)
{
$class = new ReflectionClass($className);
$method = $class->getMethod($methodName);
$method->setAccessible(true);
return $method;
}

3,对框架的初始化类,此处见仁见智,不一定要用类实现,只要达到目的。

框架整合

刚才提到对框架的整合,这里再补充一下对框架测试的心得。

选用框架ZF1.10,Zend的类库中已经对phpunit有了封装支持,这是非常方便的,不过对于版本上的兼容好像有一些问题,所以在DB的pdo初始化部分遇到了一些麻烦,由于Zend_Test_Phpunit_db并没有提供什么额外的功能,而且对于Model的测试DB_Unit已经足矣,故舍弃了集成Zend_Test的DB部分扩展,直接使用DB_Unit。这样做的唯一缺点是无法使用ZF的配置文件取得数据库参数,不过只要稍加修改手动引入各个变量就能达到目的。

框架测试部分择直接集成Zend封装之后的类,增加了对于Zend分发,路由,跳转,返回值路径等各方面页面等级的测试,相当强大,唯一的缺点是不具备数据库测试的功能,所以对于一些web接口类型的测试,显得有点力不从心。

终极整合:分析了一下类库源码,发现DB_Unit的主类和Zend的框架测试类继承的是同一父类,而且双方作为扩展都对通用性进行了处理,两方面也做的是完全不相干的事情,但是php不支持多继承,故用了一个下三滥的方法:拷贝出DB _Unit的主类,修改其父类为Zend框架测试类,自己封装的基类再继承拷贝出来的类,其代码不用做任何修改,则新的基类拥有了DB_Unit和Zend框架测试类的所有功能,可以同时对controller的分发和数据库反应进行测试,而且测试代码可以统一继承同一个基类,功能大大加强。

遗憾

必须拷贝出DB_Unit源码是非常不优雅的,而且可能会给后面的升级带来麻烦,但还未找到很合适的解决方法,也许反射可以做到这样的事情,研究了一下暂时未果。

另外一个比较难受的状态是无法(或未找到方法)对每个测试用例进行单独的数据初始化(虽然每个用例前都会做一次初始化),这就对新加入的测试造成一定的不便,因为需要去判断新加入的一些基础数据会不会对以前的测试造成影响。

第三点就是对controller的实例化比较麻烦(这个应该能解决,需要再深入研究一下zend框架),导致对Action的行为能够掌控,却无法对controller中的一些私有方法进行掌控,测试粒度比较大。

总结

总体来说当前的功能已经完全能够达到单元测试的目的了,虽然依旧存在一些问题,以后也一定会遇到更多问题,只要了解得足够详细,所有都会迎刃而解,钻研、想象力和追求完美的精神都不可缺少。

向往的地方

南美玻利维亚乌尤尼

除了北欧极光,想去的地方又多了一个。

下一步攒钱搞单反了,工作,旅游,创业。

极致

冯鑫说:得不到成功是因为成功的欲望还不够强烈。

冯鑫说:大多数选择问题,其实是排序问题。

冯鑫说:计划,总结,进步。

冯鑫说:事情做到极致,一定成功。

欲望,排序,进步,成功。

一部分关乎于人心的事情是不可套用的,只有顺其自然。

做任何事情加快10%是个值得实践的主意。

莫忘2014年10月的约定。

——这两天学到的和想起的,就用这个突然很有好感的词做标题吧。