2011年6月27日星期一

虚拟主机上的Drupal性能优化


默认情况下,drupal的性能往往为人诟病。就算安装在本地电脑时,你也可以感觉得到它反应的迟钝。不过好在安装了一些模块和进

行相应的设置后,drupal网站的性能会有显著的提升。

在虚拟主机上我们对服务器没有控制权,不能安装APC、memcache之类应用,至多只能配置.htaccess文件。所以这篇文章主要是介绍

一些drupal模块来提升性能。



前端优化

前端优化可以按照yslow或Google Page Speed的建议来进行。

更小的文件尺寸,更少的组件数量,更多的并行通道。

.htaccess

如果你服务器不是Apache或者你没有配置.htaccess的权限,你可以跳过这一部分。通过配置.htaccess文件在服务器级别进行一些优

化是前端优化的理想选择。

添加Expires头(或Cache-control)。drupal根目录下自带的.htaccess文件中已经添加好了Expires头:
view sourceprint?
1 <IfModule mod_expires.c>
2  # Enable expirations.
3  ExpiresActive On
4  # Cache all files for 2 weeks after access (A).
5  ExpiresDefault A1209600 
6 <FilesMatch \.php$>
7    ExpiresActive Off 
8 </FilesMatch>
9 </IfModule>
Gzip各组件。一般需要压缩的是文本文件,如:HTML、CSS、JS、XML和JSON。在.htaccess中加入下面的代码就可以在启用apache的

Gzip或者deflate模块了。
view sourceprint?
01 <ifmodule mod_deflate.c>
02 AddOutputFilter DEFLATE html xml php js css
03 </ifmodule>
04 <ifModule mod_gzip.c>
05 mod_gzip_on Yes
06 mod_gzip_dechunk Yes
07 mod_gzip_item_include file \.(HTML?|txt|CSS|js|PHP|pl)$
08 mod_gzip_item_include handler ^CGI-script$
09 mod_gzip_item_include mime ^text/.*
10 mod_gzip_item_include mime ^application/x-JavaScript.*
11 mod_gzip_item_exclude mime ^image/.*
12 mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
13 </ifModule>
Etag。一般的建议是去掉或者修改etag,但是在普通的虚拟主机上,情况要简单得多,保留默认的etag即可。
核心模块

在admin/settings/performance中启用优化CSS和JS。drupal核心会将众多CSS文件合并一个文件,并且将其压缩(去掉注释、空格等

多余字符);对JS文件,会合文件但不会将其压缩。

如果你没有用.htaccess在服务器级别上启用Gzip,那么可以在admin/settings/performance中启用Gzip page compression(Gzip压

缩页面),这同样会将drupal的输出的HTML页面用Gzip压缩,达到减小页面尺寸的目的。

CSS Gzip和Javascript Aggregator

CSS Gzip和JavaScript Aggregator可以在php级别上用Gzip压缩CSS和JS文件,会极大地减小样式表和脚本文件的尺寸。如果没有

在.htaccess中用 gzip压缩css或js,可以在admin/settings/performance中启用它们。

JavaScript Aggregator另外的一个独特而重要的功能是用JSMIN/JSMIN++压缩JS脚本(去注释空格等多余字符)

parallel

一些较新的浏览器的HTTP并行请求数都超过了4,但网页上各种外挂组件的数量大部分时候都远远超过了这个数量。CDN(Content 

delivery network)可以很好的解决这方面的性能问题。不过这里要说的是parallel模块,parallel并不要求真正的CDN,他可以将

网页上的图片、样式表、脚本改为从子域名下载,从而在效果上与真正的CDN类似。

使用parallel的唯一要求是你可以将你的子域名指向主域名所在的服务器。

CSS SPRITE,进一步减少HTTP请求数

经过上面几步,已经将js和css文件数量减到最少了,剩下的可能就是主题中众多零碎的图片了。将这些图片合成CSS SPRITE是必要

的,SpriteMe是个生成CSS SPRITE不错的工具。当然更多的情况下,是需要自己动手来制作CSS SPRITE的。

各版本浏览中最大http并行请求一览表:

浏览器 HTTP/1.1 HTTP/1.0
IE 6,7 2 4
IE 8 6 6
Firefox 2 2 8
Firefox 3 6 6
Safari 3,4 4 4
Chrome 1,2 6 ?
Chrome 3 4 4
Opera 9.63,10.00alpha 4 4
 

服务器端优化

将缓存进行到底。

Boost

boost将动态的php页面在服务器上生成对应的静态的HTML页面,再有用户访问的时候,就会直接访问这些HTML页面,完全省去了php

执行、数据库查询的步骤,可以极大地提升访问速度。不太完美的是boost只对匿名用户有效,登陆用户总是获得的动态内容。

默认的boost不会对非英文路径的页面生成HTML缓存,使用pathauto模块的需要在admin/settings/performance/boost中禁用Only 

allow ASCII characters in path选项。

Cache Router

cache router提供了整合例如像APC、Memcache、 db、file等缓存技术,在虚拟主机上apc和memcache我们不能随意安装,但是我们

可以用db和file来缓存。db缓存是drupal自带的 功能;而把缓存记录在文件系统上,省去初始化数据库连接过程,可以明显的提高

性能。要启用file缓存,安装并启用cache router后,将以下代码加在setting.php中即可

view sourceprint?
01 $conf['cache_inc'] = './sites/all/modules/cacherouter/cacherouter.inc';
02 $conf['cacherouter'] = array(
03  'default' => array(
04    'engine' => 'file',
05    'servers' => array(),
06    'shared' => TRUE,
07    'prefix' => '',
08    'path' => 'sites/default/files/filecache',
09    'static' => FALSE,
10    'fast_cache' => TRUE,
11  ),
12 );
Authcache

核心的缓存系统和Boost的缓存都是针对匿名用户的,而authcache模块则是针对注册登录用户的缓存模块,并且authcache可以方便

的和cache router结合起来使用。

在setting.php中加上

view sourceprint?
1 $conf['cache_inc'] = './sites/all/modules/authcache/authcache.inc';
然后启用authcache模块,在admin/settings/performance/authcache/config中对相应的角色启用cache即可。另外,如果页面中有

为不同用户定制的内容(如在页面中显示的用户名),你需要在特定的主题页面中进行修改。

authcache可以对匿名用户启用,但是如果你用了boost,在authcache上启用对匿名用户的缓存是没有必要的。

Block Cache Alter

block cache alter为各区块提供了一个缓存选项,可以方便对所有用户缓存区块的内容。

合适的组合

如果网站没什么注册用户,一个Boost模块足够;注册用户访问较多,cache router+authcache是比较合适的;或者你也可以同时启

用Boost+cache router+authcache。

详细的,可以参考drupal.org上关于性能的网页:

Modules for browser performance
Caching: Modules that make Drupal scale
Modules for performance

2011年6月22日星期三

发现drupal button的一个bug

本来想实现一段代码:

$form['export'] = array(
      '#type' => 'button',
      '#value' => t('Export blank dealer'),
      '#attributes' => array('onclick' => 'window.location=\'/admin/build/import-dealer/export-blank-dealer\';'),
  );

发现总是不成功,试过alert('xxx'),可以实现,说明onclick事件成功了。
查看页面源码
<input type="submit" class="form-submit" onclick="window.location='/admin/build/import-dealer/export-blank-dealer';" value="Export blank dealer" id="edit-export" name="op">
明明是'#type' => 'button'怎么打出来的html是type="submit",
找下核心代码在form.inc里1937行找到theme_button函数
原来它把button的也当作submit处理,真不知道drupal的开发人员怎么想的。


原有代码:

/**
 * Theme a form button.
 *
 * @ingroup themeable
 */
function theme_button($element) {
  // Make sure not to overwrite classes.
  if (isset($element['#attributes']['class'])) {
    $element['#attributes']['class'] = 'form-'. $element['#button_type'] .' '. $element['#attributes']['class'];
  }
  else {
    $element['#attributes']['class'] = 'form-'. $element['#button_type'];
  }

  return '<input type="submit" '. (empty($element['#name']) ? '' : 'name="'. $element['#name'] .'" ') .'id="'. $element['#id'] .'" value="'. check_plain($element['#value']) .'" '. drupal_attributes($element['#attributes']) ." />\n";
}

修正代码:

/**
 * Theme a form button.
 *
 * @ingroup themeable
 */
function theme_button($element) {
  // Make sure not to overwrite classes.
  if (isset($element['#attributes']['class'])) {
    $element['#attributes']['class'] = 'form-' . $element['#button_type'] . ' ' . $element['#attributes']['class'];
  } else {
    $element['#attributes']['class'] = 'form-' . $element['#button_type'];
  }
  
  return '<input type="' . $element['#type'] . '" ' . (empty($element['#name']) ? '' : 'name="' . $element['#name'] . '" ') . 'id="' . $element['#id'] . '" value="' . check_plain($element['#value']) . '" ' . drupal_attributes($element['#attributes']) . " />\n";
}

很简单,就是把return部分的type="submit"改成type="' . $element['#type'] . '"
查看页面源码
<input type="button" class="form-submit" onclick="window.location='/admin/build/import-dealer/export-blank-dealer';" value="Export blank dealer" id="edit-export" name="op">

试试onclick,OK成功!

2011年6月17日星期五

其实每个男孩本来都是好男人

  其实每个男孩,本来都是想做一个感情专一的好男人的;  
  
  其实每个男孩,本来看女孩子都是看脸而不是胸部的;  
  
  其实每个男孩,本来都是不会讲黄色笑话的;  
  
  其实每个男孩,本来都是渴望爱一个人直到永远的;  
  
  只是,没有任何女孩喜欢这样的男孩,她们觉得这样的男孩太幼稚,太古板,没有情趣。
  于是男孩开始改变,变成女孩喜欢的那种,嘴角挂着坏坏的笑,玩世不恭或者幽默,开始学会说甜言蜜语而不是心里想说的话,开始学会假装关心,学会给女孩送小饰物讨好她,学会如何追求~;或者看破红尘,游戏情场,成为女人恨恨的那种男人  
  他们可以很容易俘获女孩子的心但是他们也会在黑暗的夜里叼着烟流泪,心里有爱的时候,没有女孩;有了女孩,却永远没有了爱的感觉。
  在听到女人抱怨世上没有一个好男人时候,他们不会再去努力做个好男人,只是微笑着擦肩而过~~~

2011年6月14日星期二

非常爽的screen命令

screen对于不支持SSH的虚拟主机没有作用,但是对于vps来说那可是用处大大的。
不知道朋友们有没有在配置vps环境的时候出现突然中断或者要离开但是还没有配置完成的情况呢?
熠锋遇到很多回,往往已经快配置完成的时候出现短线等情况,那就要从头再安装配置,很是麻烦,有时要连续重新安装好几次系统才可以完成。
现在有了screen命令就不用为此烦恼了。
screen命令是什么?
Screen是一个可以在多个进程之间多路复用一个物理终端的全屏窗口管理器。Screen中有会话的概念,用户可以在一个screen会话中创建多个screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。
如何安装screen命令呢?
除部分精简的系统或者定制的系统大部分都安装了screen命令,如果没有安装,CentOS系统可以执行:
yum install screen
Debian/Ubuntu系统执行:
apt-get install screen
怎么使用screen命令?
1、首先在安装配置环境前创建一个screen会话
screen -S lnmp
lnmp为创建会话的名称
2、创建好以后就可以正常安装和配置vps环境,如怕中途短线或者要离开,马上就可以使用
快捷键Ctrl+a d(即按住Ctrl,依次再按a,d)来保存这个会话窗口
当然程序还在自动进行不会关闭。
3、需要恢复会话的时候就需要执行
screen -r lnmp
lnmp就是你刚开始设置的会话名称
如果在恢复会话的时候忘记了或者没有设定会话名称我们就要执行:
screen -ls
他会列出你所有的会话列表,然后使用:
screen -r 会话名称
来恢复会话窗口。
4、关闭screen的会话
exit
会提示:[screen is terminating],表示已经成功退出screen会话。
5、screen命令常用的一些快捷键:
Ctrl+a c :在当前screen会话中创建窗口
Ctrl+a w :窗口列表
Ctrl+a n :下一个窗口
Ctrl+a p :上一个窗口
Ctrl+a 0-9 :在第0个窗口和第9个窗口之间切换
就这么多了,希望能给大家带来一些帮助!

2011年6月13日星期一

PHP5.3.6编译GD库

昨天重新编译了下gd库,之前的不支持jpeg,在ecshop中出现了问题。过程曲折。
在这简单说下方法吧。
mic的服务器是DEBIAN6 LNMP环境 使用php-fpm及fast-cgi
首先从各官网上下载以下文件:zlib,libpng,freetype,jpeg,libxml2,gd。当然也可以从其他站点下载,但是本着安全且最新的原则,mic是从官网下载的。
~~~~~~~~~~~~~~~~~~~~这部分内容来自http://www.netren.org/index.php/apache2/145-ubuntu-php5gd.htmlhttp://beafroot.blog.163.com/blog/static/1231345332009928105954506/相应的具体参数可能因为版本问题有所不同。mic增加了–prefix参数,这个根据自己需要可以调整~~~~~~~~~~~~
1.安装zlib
tar -zxvf zlib-1.2.5.tar.gz
cd zlib-1.2.5
./configure --prefix="/usr/local/zlib"
make
make install
2.安装libpng
tar -zxvf libpng-1.4.4.tar.gz
cd libpng-1.4.4
./configure --prefix="/usr/local/png"
make
make install
3.安装freetype
tar zxvf freetype-2.1.10.tar.gz
cd freetype-2.1.10
./configure --prefix="/usr/local/freetype"
make
make install
4.安装Jpeg
tar -zxvf jpegsrc.v8b.tar.gz
cd jpeg-8b/
./configure --enable-shared --enable-shared --enable-static --prefix="/usr/local/jpeg"
make
make test
make install
注意,这里configure一定要带–enable-shared参数,不然,不会生成共享库
5:安装 libxml2
tar -zxvf libxml2-2.6.31.tar.gz
cd libxml2-2.6.31
./configure --prefix="/usr/local/libxml"
make
make install
6.安装GD
tar -zxvf gd-2.0.33.tar.gz
cd gd-2.0.33
./configure –prefix="/usr/local/gd" –with-jpeg="/usr/local/jpeg" –with-freetype="/usr/local/freetype" –with-png="/usr/local/png" –with-zlib="/usr/local/zlib"
make
make install
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7.编译php
tar -zxvf php-5.3.6.tar.gz
cd /php-5.3.6
./configure  --prefix="/usr/local/php"  --with-mysql="/usr/local/mysql"  --with-gd --with-ttf  --with-openssl  --enable-mbstring  --enable-fastcgi --with-bz2 --with-zlib --enable-memcache --with-mcrypt --enable-fpm --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-gd-native-ttf --with-fpm-user=www-data --with-fpm-group=www-data
make
make install
到此就已经编译完了。
接下来说下过程中我遇到的问题。
1.编译php时使用–with-gd=”/usr/local/gd”出现gd build test失败的问题
首先要声明一点,就是–with-gd之后一定要加上地址,如果只是–with-gd,那就是用bundled的gd库,也就是php自带的。
如果加上了之后,出现失败的问题,mic的是出现很多个test都是no。mic一开始用php5.3.5编译的,后来换成了5.3.6,同时把所有要安装的gd库软件又都安装了,然后就可以编译了,因此这一点并不是很明确。有了解的哪位麻烦跟mic说下,谢了。
2.编译php时出现gd.h gd.c报错,比如declared及undefined reference等。由于鬼使神差,mic把gd.h复制到了/usr/local/gd/,出现这个问题,删除后就木有问题了。
mic遇到的问题应该就是这两个。。给新手看的。。

2011年6月10日星期五

varnish安装记录

varnish和squid相比最大的优势就是简单快速,简单是安装和配置都简单,快速是运行速度比squid更快,当然,快的前提是varnish比squid占用更多的内存,估计当年设计squid的时候内存还是很贵的东西,所以更多的侧重硬盘,使用内存多,当然还有一个很显而易见的弱点是机器冷启动时候恢复缓存的时间相比squid要长。
wget http://downloads.sourceforge.net/project/varnish/varnish/2.0.6/varnish-2.0.6.tar.gz?use_mirror=ncu
tar zxvf varnish-2.0.6.tar.gz
cd varnish-2.0.6
./configure  –prefix=/srv/varnish
make
make install
启动命令:
/srv/varnish/sbin/varnishd -a :8088 -b localhost:8080
由于我指定了安装目录,所以加上了路径,-a参数表示varnish的监听端口,正常情况下应该监听是80端口,也就是web服务端口,我测试机上被使用掉了,所以用了8088端口, -b 是表示后端(backend)的地址,如果backend在这里指定,那么只能指定一个后端,如果使用的配置文件可以指定多个backend,我的配置文件位置位于/srv/varnish/etc/varnish。
在web服务器的目录中创建一个index.html文件,然后通过varnish进行代理访问.
第一次访问结果如下:
2
第二次访问结果如下:
3
根据请求头,我们看到的确是通过vanish来代理访问后端的,第一次访问age 为0 ,第二次访问age为71,说明这个文件已经在varnish中缓存了,此时可以通过/srv/varnish/bin/varnishstat 来查看一些参数,其中Hitrate 一行应该为1,因为命中了一次。
varnish 配置文件还是很有搞头的一个东西,有点类似与Nginx的语法,虽然不是很像,比如对正则的支持,可以绑定和去除head、Cookie等等功能,有时间的话,翻译一下varnish的introduction
安装编译的时候出现一下错误:
checking for library containing pthread_create... -lpthread
checking for socket in -lsocket... no
checking for getaddrinfo in -lnsl... yes
checking for cos in -lm... yes
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for PCRE... no
configure: error: Package requirements (libpcre) were not met:

No package 'libpcre' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables PCRE_CFLAGS
and PCRE_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

说是缺少 pcre。我安装nginx的时候用到了pcre 安装了的。后又重新安装。错误依旧在。Google  原来是ldconfig 都不行。 后终于找到解决办法:
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
你再编辑 成功!
  good luck!

2011年6月9日星期四

MySQL常用函数

 bin() 十进制转二进制
  ascii() 字符串最左边的字母的ascii
  oct() 十进制变八进制
  hex() 变十六进制
  char() 把每个ASCII值转成对应字母
  char(77,121,83,'81.3','76')
  char_length() 返回字符个数
  length() 返回字符串的字节数
  concat(str1,str2...) 将参数连接成字符串返回,如有任何一个为null,则返回值为null
  locate('bar','foobarbar') 返回bar第一次出现的位置
  instr('foobarbar','bar') 同上,参数位置颠倒
  lpad('hi',4,'?') 左填充
  rpad('hi',4,'?.') 右填充
  left('dfsdfds sdfd',5) 从左截5个字符
  right('dfsdfds sdfd',5) 从右截5个字符
  substring('sdfsdfsda fdsaf sdf',5,6) 从5个字符开始向右截6个,中间可以为负,从左开始数
  mid() 同substring()
  ltrim(' fdsfsd ') 拿掉左边的空格
  rtrim(' fdsfsd ') 拿掉右边的空格
  trim(both 'x' from 'xxfdfxx')自定义拿
  space(6) 得到6个空格的一个串
  repeat('mysql',3) 重复3次mysql
  replace('www.sdfsd.com','w','ww')将文本中w替换成ww
  reverse('abc') 翻转字符串
  lcase() low() 把字符串变成小写
  ucase() upper() 把字符串变成大写
  load_file(file_name) 读入文件
  mod(a,b) 取模 a%b
  ceiling(x) 取大于x的最小整数
  round(x) 将x四舍五入到最近整数
  exp(x)返回值e的x次方
  ln(x)
  log(x,b) x为底
  pi() 常值π
  cos(x)
  sin(x)
  tan(x)
  rand()产生一个在0-1.0之间的随机值 rand(x) x为随机数的种子

上海松善实业有限公司

    上海松善实业有限公司是一家集多品牌销售于一体的电线电缆骨干企业,公司成立于2016年。 公司拥有国内各大品牌:起帆、远东、上上、江南、胜华等。     主要产品有:高低压电力电缆、橡套电缆、控制电缆、架空绝缘电缆、塑胶电缆、电子计算机电缆、通讯电缆、...