提高Zend Framework 2 性能

公司的新站选用了Zend Framework 2,一切都进行得很顺利,但在线上测试的时候,用xdebug profile一下,发现生产首页用了500毫秒,而无cache情况下产品页得生成也接近800毫秒。于是上网搜索,找到几个提高ZF2性能的几个tips。

Autoloader Classmap

使用classmap,就可以在初始化的时间返回一个‘类-文件’对应的array,从而加速加载类的速度。默认的类加载是使用StandardAutoloader,正则表达式来将类名字转换成文件名再加载,试想一下每次加载都要跑一下性能不高的正则匹配,速度能有多快呢

这是默认的自动加载配置src/module/<app>/Module.php

public function getAutoloaderConfig()
{
    return array(
        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
            ),
        ),
        'Zend\Loader\ClassMapAutoloader' => array(
            __DIR__ . '/config/autoload_classmap.php',
       ),
    );
}

将其修改成

public function getAutoloaderConfig()
{
    return array(
        'Zend\Loader\ClassMapAutoloader' => array(
            __DIR__ . '/config/autoload_classmap.php',
        ),

        'Zend\Loader\StandardAutoloader' => array(
            'namespaces' => array(
                __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
            ),
        ),
    );
}

然后使用ZF2自带的命令行工具生成classmap文件

$ php zf2/bin/classmap_generator.php -l <your-zf2-app-location> -o <your-zf2-app-location>/config

之后就会在app/config目录下生成autoload_classmap.php文件。

Template Map

和classmap类似,这个会将‘模板-文件’的对应关系变成一个array并返回,免去了转换的过程。

同理,运行如下命令

$ php zf2/bin/templatemap_generator.php -l -l <your-zf2-app-location> -o <your-zf2-app-location>/config

这样,template_map.php就会在app/config下生成。然后,在app/config/module.config.phpview_manager下加上以下那句话

'view_manager' => array(
    'template_map' => include __DIR__  .'/template_map.php',
),

参考:ZF2 Performance QuickTipp #2 – Classmap Autoloading

再见2013, 你好2014

2013

就在2周前,我达成了过去四年一直奋斗的目标,那一刻我不敢相信这是事实,事情是来的这么的意外,又那么的顺其自然。

在收到这份圣诞大礼之后,总算要在2013年的日历上画上句号。这一年有很多回忆,多得不敢再去回想。曾经,我以为我再无机会留下来的时候,是家人和身边的朋友给予了我希望;在那个灰暗的八月份,是我的另一半一直陪伴着我,支持着我;在那段不堪回首的日子,是家人和朋友不断地给我提供意见和协助。终于,在迟到的四个月后,我的目标终于到来了。

2013年,除了经历这长达四个月由悲到喜得经历外,工作上我还是转型了。以前,我是个不入流得程序猿,现在,我想是个不入流的程序猿。从之前的文章可以看出,我现在更专注于系统方面的工作,职位也变成“System Integrator”。无所谓的好坏,只是看着自己这缓慢的进步,就恨不得每天有大量的时间学习。

2014

展望2014,除了俗套的多赚钱、快买房外,我还是希望在工作,应该说是技术上有更大的突破。同时,也希望此blog不再凋零,4个月不更新的时期应该要过去了。另外,我不再希望我的GitHub账号里面没有一个自己的代码库。

站在新的起点,希望能以新的角度去生活。

MySQL主从复制下改变主服务器IP

公司所有服务器终于放到同一个机房,开通了内网访问。这样,就必须更改某几台MySQL从服务器的配置,变成内网访问。

备份

首先是关闭MySQL服务器(slave端)以及备份配置信息

service mysqld stop

#进入到mysql目录
cd /var/lib/mysql
#备份配置
cp master.info master.info.bak
#查看行数
wc -l < master.info

wc是为了确保修改后master.info的行数保持一样

修改

之后,修改master.info里的IP为新的主服务器的IP地址。

然后,不启动replication的情况下启动MySQL服务器

service mysql start --skip-slave-start

验证

登录到MySQL并运行SHOW slave status \G

如果看到的IP为新的地址,那么恭喜,修改成功,接着可以启动replication了

START SLAVE;
SHOW SLAVE STATUS\G

    *************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: xx.xx.xx.xx
                  Master_User: slave_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.xxxx
          Read_Master_Log_Pos: xxxxxxxx
               Relay_Log_File: slave-relay-bin.xxxx
                Relay_Log_Pos: xxxxxxxx
        Relay_Master_Log_File: master-bin.xxxx
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: mysql,test,information_schema
           Replicate_Do_Table:
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: xxxxxxxxx
              Relay_Log_Space: xxxxxxxxx
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:

在Openfiler上启用Fibre Channel

由于服务器的IO开始略显不足,需要安装一张Qlogic的FC卡来增加服务器和存储的性能。本文将介绍如何在Openfiler 2.99 下启用FC和创建Target。(注意:请自行替换<>中的字符)

  1. unmap某个volume,此步骤可通过openfiler的web界面完成。

  2. 在web界面的Service里启用FC target

  3. 运行以下命令来启用vdisk_fileiovdisk_blockio

    modprobe scst_disk
    modprobe scst_vdisk
    modprobe qla2x00tgt
    modprobe scst_vdisk
    modprobe scst_user
    modprobe scst_modisk
    modprobe scst_processor
    modprobe scst_raid
    modprobe scst_tape
    modprobe scst_cdrom
    modprobe scst_changer
    modprobe ib_srpt
    
  4. 创建一个scst设备

    scstadmin -open_dev <device-name> -handler <vdisk_fileio or vdisk_blockio> -attributes filename=<path of logical volume>
    
  5. 为服务器创建安全组

    # add group
    scstadmin -add_group <group-name> -driver qla2x00t -target <onboard fc card wwn>
    
    # assign server fc to security group
    scstadmin -add_init <server wwn> -driver qla2x00t -target <onboard fc card wwn> -group <group-name>
    
  6. 分配虚拟盘到安全组和Lun

    scstadmin  -add_lun 0 -driver qla2x00t -target <onboard fc card wwn> -group <group-name> -device <device-name>
    
  7. 将刚才的动作都保存到config文件中

    scstadmin -write_config /etc/scst.conf
    

保存后,scst.conf 里应保存以下信息:

HANDLER vdisk_fileio {
        DEVICE <device-name> {
                t10_dev_id "fc_vol 3d61d0df"
                usn 3d61d0df

                filename /dev/group_1/logical_volumn_1
        }
}

TARGET_DRIVER qla2x00t {
        TARGET <onboard fc wwn 1> {
                rel_tgt_id 1
                enabled 0

        }

        TARGET <onboard fc wwn 2> {
                rel_tgt_id 2
                enabled 1

                GROUP <group-name> {
                        LUN 0 <device-name>

                        INITIATOR <server fc wwn>

                }
        }
}

其实此配置文件可以随意修改,根据需要修改完后可以运行以下命令使其生效

scstadmin -config /etc/scst.conf

参考:

http://www.tomlecluse.be/blog/20110619/openfiler-299-fiber-channel-setup

从Linode迁移到Amazon云

突然才发现已经快2个月没有更新博客,再不整理就真的要长草了。

在Linode宣布推出NextGen计划的时候,我反潮流而行,将博客迁移到Amazon的云服务。不在迷恋Linode那强大的配置,以及那诱人的速度,我决定向现实屈服,转向了有一年免费的AWS。$20一个月的VPS用来放这样一个流量少得可怜的博客,实在有『土豪』的感觉,而博客上的Google Adsense,也由于自己当时的糊涂拿不到广告费,零收入的博客,还是放到免费的地方吧。何况每月15G的流量,已经足够这个博客生存了。

以前用Linode时将博客放在日本节点,访问速度是建博以来最快的。现在此博放到了AWS的新加坡节点上,当连上SSH的时候就明显感觉到收费和免费服务的差别了,事实上AWS的免费和收费服务是没有区别的。去年上半年的时候就体验过EC2上的石头硬盘,昨晚再次编译PHP时,我明智地选择了一小时后再查看结果。果然,还在编译中。

==============================我是分割线==============================

以前概念不清楚,使用AWS的时候忽略了VPC这个好东西,所以每次EC2重启的时候,内部IP地址都会换一遍。

这次的迁移,我使用了一个VPC,将一个EC2实例和RDS实例放到里面,EC2上的程序使用内部IP连接到RDS上的数据库。建立RDS实例的时候,因为选择了可连接到公共网络,所以会自动创建一个网络接口(Network Interface),其私有和公共IP都是不可控的。而EC2的实例就可以随意增减网络接口了。EC2使用了EBS,传说中IOPS只有5的石头硬盘,将为访问速度的下降奉献了一分力。

最后,希望各位朋友帮忙测试下速度,看看这新加坡节点的速度如何。