Tag Archives: php

Phalcon 初体验的安装问题

人是有惰性的,工作时间太久了,就容易忽视技术成长与关注。

这几年,记忆中最早(2010年)团队管理后台项目,用得最多的开发框架是Zend Framework 1.6版本。

前台业务逻辑根据不同的需求,做了不一样的选择。

比如说团队刚开始,就我一个技术的时候,最早为了网站最快上线,就直接用DEDECMS改进业务逻辑,

后面再根据运营需求,找时间去优化CMS逻辑,

当然,在业务改进的过程中,就有内部自己写的一些小型MVC,

后面人员越来越多后,技术团队根据业务要求,陆续有用到ThinkPHP,CodeIgniter,Yii等框架。

其实在这过程中,一个技术团队按不同的业务,更换不一样的开发框架,

有优点,也有的缺点(这个很要命):

优点:

1. 比较能锻炼团队成员学习成长的能力,可以让成员更加全面。

2. 技术上有尝试,团队整体保持对行业的关注度,后期对公司新业务的开展有技术的保障。

缺点:

1. 学习需要时间,时间就是创业团队最重要的成本。

2. 团队人员流失后,项目后期维护成本非常之高,新人进来要学习时间。

无认优缺点,团队在发展过程中,各种问题都会有,这其实就是人或团队成长的过程。

我们的初心,还是希望业务能稳定,效率高,易维护,同时团队成员也可以有更好的成长空间。

这不,咱还是要折腾一下,Phalcon 虽然是2012就出来一个C 扩展编写的框架,听说是高效率。上周就抽时间给尝试了一下。

关于Phalcon介绍,简单百度百科:

Phalcon 是开源、全功能栈、使用 C 扩展编写、针对高性能优化的 PHP 5 框架。 开发者不需要学习和使用 C 语言的功能, 因为所有的功能都以 PHP 类的方式暴露出来,可以直接使用。 Phalcon 也是松耦合的,可以根据项目的需要任意使用其他对象。

 

Phalcon是一套实现MVC架构的高性能PHP应用程序框架。初始版本发布于2012年11月,开放源代码并基于BSD授权条款。与其他大部分的PHP框架不同,Phalcon是以扩展的方式以C语言所编写,因此Phalcon的执行速度高过其他PHP框架,并且消耗更少的资源,根据官方的测试,Phalcon是目前世界上速度最快的PHP框架, 没有之一

文档很完善,安装过程遇到一些小问题,就顺便记录了一下。

主要安装可参考文档: 安装Phalcon点这里

遇到的几个小问题:

第一:php-config is not installed

解决办法,写上php-config的路径就可。

./install –phpize /usr/local/php/bin/phpize –php-config /usr/local/php/bin/php-config

参考:https://segmentfault.com/q/1010000007067920?_ea=1258087

第二:phalcon configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers

解决办法:安装一下re2c。

参考:https://blog.slogra.com/post-421.html

 

最后可以通过phpinfo看到Phalcon框架已安装成功

然后再去Github 下一些实例(https://github.com/phalcon/mvc),就可以开始体验

看到上面例子,说明已是安装成功,接下来就是真正使用了。

计划在后面用这框架做个小的项目,逐步记录在博客上。

2013年7月编程语言排行榜:PHP依然强势

2013年7月9日,Tiobe公司发布新一期编程语言排行榜。从下面的编程语言排行中,我们不难看出PHP这次的上升速度是最为迅速,跟2013 年1月份相比,PHP同比增长了+1.64%,其次就是数据库语言的Transact-SQL(+0.99%)和PL / SQL(+0.34%)。 Tiobe公司认为,PHP上升的背后主要是来自于2012年9月发布最新的PHP Zend Framework。

Zend Framework (ZF) 是用PHP 5来开发web 程序和服务的开源框架。ZF 用100% 面向对象编码实现。 ZF的组件结构独一无二,每个组件几乎不依靠其他组件。这样的松耦合结构可以让开发者独立使用组件。 我们常称此为“use-at-will”设计。

以下是前20名榜单排行榜:

Zend Framework 项目的主要赞助者是 Zend Technologies,但许多其它公司也贡献了组件或重大功能。例如 Google、 Microsoft 和StrikeIron作为伙伴提供了web服务接口和其它希望给 Zend Framework 开发者使用的技术。

没有活跃的ZF社区,Zend Framework 就不能交付和支持所有这些功能。社区成员包括贡献者都可以在这些地方找到:mailing lists, IRC channels 和其它论坛。无论你有什么关于ZF的问题,在社区总能找到答案。

Zend Framework (ZF) 是用 PHP 5 来开发 web 程序和服务的开源框架。ZF用100% 面向对象编码实现。 ZF的组件结构独一无二,每个组件几乎不依靠其他组件。这样的松耦合结构可以让开发者独立使用组件。 我们常称此为use-at-will设计。

虽然它们可以独立使用,但如果组合使用,Zend Framework 标准库理的组件也能形成一个强大而可扩展的web程序。 ZF 提供了强壮而高效的 MVC 实现,易于使用的数据库摘要和实现 HTML 表单解析、校验和过滤的表单组件,这样 开发者可以通过这些易用的、面向对象的接口联合所有这些操作。其它组件如 Zend_Auth 和 Zend_Acl 通过通用 的证书(credential)存储提供用户认证和授权。还有其它实现的客户库来简化访问最流行的可用的 web 服务。 不论你的程序需要什么,你都可能从 Zend Framework 中找到全面测试的组件来极大地减少开发时间。

怎么解决Nginx执行PHP出现的shmget() failed: Invalid argument

最近两天发现,以前可以顺利执行的PHP采集的计划任务出现如下错误。

shmget() failed: Invalid argument
Failed to start up concurrent users module!

所有的程序都 跑不起来。经过查找原因。发现是linux系统参数设置问题,从而导致采集程序执行不了。用命令行查看:

[root@centosggk ~]# sysctl -a | grep shmm
kernel.shmmni = 4096
kernel.shmmax = 0

修改操作:

[root@centosggk ~]# vi /etc/sysctl.conf
kernel.shmmax =1523241824
kernel.shmall =573741
[root@centosggk ~]# sysctl -p
[root@centosggk ~]# sysctl -a | grep shm
kernel.shmmax = 1523241824
kernel.shmmni = 4096

修改后的结果是:

kernel.shmmax 数值说明:
单位:字节。一般建议使用物理内存的一半
以4G内存为例:4096/2*1024*1024=2147483648

kernel.shmall 数值说明:
单位:页。1页=4k,设置数值则为物理内存大小
以4G内存为例:4096*1024*1024/4000=1073742
注:以上两项数值如果填写大于本身物理内存则会不生效。

可参考的文章网址:
http://www.poluoluo.com/server/201306/215354.html
http://www.ablanxue.com/prone_8500_1.html

Sphinx如何实现搜索结果过滤功能

一般网站的搜索功能,用Sphinx做个没什么过滤条件的全文检索功能,基本上能满足网站的部分功能。然而,在很大部分情况下,是需要做检索的结果过滤(需求描述:假如我们要搜索学生档案。a.只需要查找性别为“男”的学生;  b:只要搜索学生年龄在:18至20岁之前的学生档案)。这个时候,我们就需要用到Sphinx的结果集过滤设置功能了。

通过Sphinx PHP API 文档(Sphinx 0.9.8),得到结果集过滤接口有以下几个方法:
  • 5.4.1. SetIDRange
  • 5.4.2. SetFilter
  • 5.4.3. SetFilterRange
  • 5.4.4. SetFilterFloatRange
  • 5.4.5. SetGeoAnchor
篇幅原因这里我不对接口一一做介绍,我只抽取其中两个方法做说明,正好解决上面提到的二个需求:
第一:SetFilter  (解决需求a:只需要查找性别为“男”的学生)
注意:必须是无符号整数属性(sql_attr_uint )
原型: function SetFilter ( $attribute, $values, $exclude=false )
增加整数值过滤器。
此调用在已有的过滤器列表中添加新的过滤器。$attribute是属性名。$values是整数数组。
$exclude是布尔值,它控制是接受匹配的文档(默认模式,即$exclude为假时)还是拒绝它
们。
只有当索引中$attribute列的值与$values中的任一值匹配时文档才会被匹配(或者拒绝,如
果$exclude值为真)
第二:SetFilterRange  (解决需求b:只要搜索学生年龄在:18至20岁之前的学生档案)
注:可以是浮点型属性(sql_attr_float ) 和 无符号整数属性(sql_attr_uint )
原型 : function SetFilterRange ( $attribute, $min, $max, $exclude=false )
添加新的整数范围过滤器。
此调用在已有的过滤器列表中添加新的过滤器。$attribute是属性名, $min、$max定义了
一个整数闭区间,$exclude布尔值,它控制是接受匹配的文档(默认模式,即$exclude为
假时)还是拒绝它们。
只有索引中$attribute列的值落在$min和$max之间(包括$min和$max),文档才会被匹配
(或者拒绝,如果$exclude值为真)。
在搜索的程序要用这几个接口,不是我们想像的那样,直接在程序里直接调用就能用的,如果你在Sphinx数据源配置文件里没有配置置对应的属性,用这个过滤是不生效的(搜索失败,直接报错)。
在使用过滤功能时,需要注意以下两点就行:
1.在sphinx.conf(名称换成您的数据源配置文件)文件里修改如下配置,如:
source main
 {
 type                    = mysql
 sql_host                = 127.0.0.1
 sql_user                = devel
 sql_pass                = oophp.cn
 sql_db                  = oophp
 sql_port                = 3306
 sql_query_pre            = SET NAMES utf8
 # [注:性别,这里要用SetFilter,就必须用sql_attr_uint这属于性。来源:www.oophp.cn]
 sql_attr_uint = gender

 # [注:年龄,SetFilterRange可以用,sql_attr_uint也可以用。来源:www.oophp.cn]
 sql_attr_float = age
}
2.在sphinx.conf的数据源SQL中,把需要过滤的字段相应增加到数据源中,如:
source main
 {
 type                    = mysql
 sql_host                = 127.0.0.1
 sql_user                = devel
 sql_pass                = oophp.cn
 sql_db                  = oophp
 sql_port                = 3306
 sql_query_pre            = SET NAMES utf8
 sql_query =  SELECT id, gender, age, username,
              introduction FROM student  ORDER  BY id  DESC
}
按上面的方式修改数据源配置,重新生成一次全量索引后。直接var_dump检测看是否属性设置是否生效,类似输出这个:
array(9) {
 ["error"]=>
 string(0) ""
 ["warning"]=>
 string(0) ""
 ["status"]=>
 int(0)
 ["fields"]=>
 array(2) {
 [0]=>
 string(5) "username"
 [1]=>
 string(12) "introduction"
 }
 ["attrs"]=>
 array(6) {
 ["id"]=>
 int(1)
 ["gender"]=>
 int(2)
 ["age"]=>
 ["@expr"]=>
 int(5)
 }
 ["matches"]=>
 array(10) {
 [266652]=>
 }
 .......
 }
如果能看到属性区有genderage,就证明修改的配置已生效。这个时候在程序里通过调用相应的接口就能得到正确数据的结果。类似如下:
<?php
$sphinx = new SphinxClient();
$sphinx->SetServer('127.0.0.1','9312');
$sphinx->SetConnectTimeout(1);
$sphinx->SetLimits(0,10);
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED);
$sphinx->SetSortMode (SPH_SORT_EXPR,
            "@weight*50000+age+ln(id)*100000" );
//做相应的过滤处理
 //1代表男生
$sphinx->SetFilter('gender',array(1));
//取到18到20岁的学生档案
$sphinx->SetFilterFloatRange('age',18,20);

.......
参考资料:
http://blog.csdn.net/adparking/article/details/6445926
http://www.coreseek.cn/
http://www.wapm.cn/uploads/pdf/sphinx_doc_zhcn_0.9.pdf

[转]如何配置Dell Raid

此文档为自行整理,非官方提供资料,仅供参考。疏漏之处敬请反馈。

对RAID进行操作很可能会导致数据丢失,请在操作之前务必将重要数据妥善备份,以防万一。

名称解释:
Disk Group:磁盘组,这里相当于是阵列,例如配置了一个RAID5,就是一个磁盘组
VD(Virtual Disk): 虚拟磁盘,虚拟磁盘可以不使用阵列的全部容量,也就是说一个磁盘组可以分为多个VD
PD(Physical Disk): 物理磁盘
HS:Hot Spare 热备
Mgmt:管理

【一】,创建逻辑磁盘
1、按照屏幕下方的虚拟磁盘管理器提示,在VD Mgmt菜单(可以通过CTRL+P/CTRL+N切换菜单),按F2展开虚拟磁盘创建菜单

clip_image002

2、在虚拟磁盘创建窗口,按回车键选择”Create New VD”创建新虚拟磁盘

clip_image004

3、在RAID Level选项按回车,可以出现能够支持的RAID级别,RAID卡能够支持的级别有RAID0/1/5/10/50,根据具体配置的硬盘数量不同,这个位置可能出现的选项也会有所区别。
选择不同的级别,选项会有所差别。选择好需要配置的RAID级别(我们这里以RAID5为例),按回车确认。

clip_image006

4、 确认RAID级别以后,按向下方向键,将光标移至Physical Disks列表中,上下移动至需要选择的硬盘位置,按空格键来选择(移除)列表中的硬盘,当选择的硬盘数量达到这个RAID级别所需的要求时,Basic Settings的VD Size中可以显示这个RAID的默认容量信息。有X标志为选中的硬盘。
选择完硬盘后按Tab键,可以将光标移至VD Size栏,VD Size可以手动设定大小,也就是说可以不用将所有的容量配置在一个虚拟磁盘中。如果这个虚拟磁盘没有使用我们所配置的RAID5阵列所有的容量,剩余的 空间可以配置为另外的一个虚拟磁盘,但是配置下一个虚拟磁盘时必须返回VD Mgmt创建(可以参考第13步,会有详细说明)。VD Name根据需要设置,也可为空。
注:各RAID级别最少需要的硬盘数量,RAID0=1  RAID1=2  RAID5=3  RAID10=4  RAID50=6

clip_image007

5、 修改高级设置,选择完VD Size后,可以按向下方向键,或者Tab键,将光标移至Advanced Settings处,按空格键开启(禁用)高级设置。如果开启后(红框处有X标志为开启),可以修改Stripe Element Size大小,以及阵列的Read Policy与Write Policy,Initialize处可以选择是否在阵列配置的同时进行初始化。
高级设置默认为关闭(不可修改),如果没有特殊要求,建议不要修改此处的设置。

clip_image008

6、上述的配置确认完成后,按Tab键,将光标移至OK处,按回车,会出现如下的提示,如果是一个全新的阵列,建议进行初始化操作,如果配置阵列的目的是为了恢复之前的数据,则不要进行初始化。按回车确认即可继续。

clip_image010

7、配置完成后,会返回至VD Mgmt主界面,将光标移至图中Virtual Disk 0处,按回车。

clip_image011

8、可以看到刚才配置成功的虚拟磁盘信息,查看完成后按esc键可以返回主界面

clip_image012

9、在此界面,将光标移至图中Virtual Disk 0处,按F2键可以展开对此虚拟磁盘操作的菜单。
注:左边有+标志的,将光标移至此处,按向右方向键,可以展开子菜单,按向左方向键,可以关闭子菜单

clip_image013

10、如下图红框所示,可以对刚才配置成功的虚拟磁盘(Virtual Disk 0)进行初始化(Initialization),一致性校验(Consistency Check),删除,查看属性等操作。

clip_image014

11、如果我们要对此虚拟磁盘进行初始化,可以将光标移至Initialization处,回车后选择Start Init。此时会弹出提示窗口,初始化将会清除所有数据,如果确认要进行初始化操作,在OK处按回车即可继续。
注:初始化会清除硬盘、阵列中的所有信息,并且无法恢复

clip_image016

12、确认后可以看到初始化的进度,左边红框处为百分比表示,右边红框处表示目前所作的操作。等待初始化进行为100%,虚拟磁盘的配置完成。

clip_image018

13、如果刚才配置虚拟磁盘的时候没有使用阵列的全部容量,剩余的容量可以在这里划分使用。将光标移至Space allocation处,按向右方向键展开此菜单

clip_image020

14、将光标移至*Free Space*处,按F2键,至第15步,或者直接按回车至第16步

clip_image022

15、在弹出的Add New VD处按回车键。

clip_image024

16、再次进入配置虚拟磁盘的界面,此时左边红框处为刚才配置的虚拟磁盘已经选择的物理磁盘信息,右边红框处可以选择这次要划分的容量空间。同样,如果不全部划分,可以再次返回第13步,进行再一个虚拟磁盘的创建。
注:由于虚拟磁盘的建立是基于刚才所创建的阵列,所以RAID Level与刚才所创建的相同,无法更改。

clip_image026

17、每一次创建,都会在Virtual Disks中添加新的虚拟磁盘。这些虚拟磁盘都是在同一个磁盘组(也就是我们刚才所配置的RAID5)上划分的。

clip_image028

【二】,配置热备(Hot spare)
配置Hot Spare有两种模式,一种是全局热备,也就是指这个热备硬盘可以做为这个通道上所有阵列的热备;另一种是独立热备,配置硬盘为某个指定的磁盘组中的所有虚拟磁盘做热备,也就是说这个磁盘组以外的其他阵列即使硬盘掉线,这个热备也不会去自动做rebuild
配置全局热备:
1、首先要已经有存在的磁盘组(阵列),我们这里举例为已经配置了两个阵列,阵列0是由0、1、2三块物理磁盘配置的RAID5,阵列1是由4、5两块物理磁盘配置的RAID1,如图:

clip_image030

2、按CTRL+N 切换至PD Mgmt界面,可以看到4号硬盘的状态是Ready。

clip_image032

3、将光标移至4号硬盘,按F2,在弹出的菜单中,选择Make Global HS,配置全局的热备盘

clip_image034

4、确认后,4号硬盘的状态变为Hotspare

clip_image036

5、配置完成后,可以看到磁盘组0与磁盘组1的热备盘都是同一个。

clip_image038

6、移除热备,进入PD Mgmt菜单,将光标移至热备盘处,按F2,选择Remove Hot Spare,回车移除

clip_image040

配置独立热备:
1、在配置好的虚拟磁盘管理界面下,将光标移至需要配置独立热备的磁盘组上,按F2键,在出现的菜单中选择 Manage Ded. HS

clip_image042

2、将光标移至需要配置为热备的硬盘上,按空格键,看到X标识,说明此硬盘被选择。将光标移至OK处回车,完成配置

clip_image044

3、可以看到磁盘组0已经有了热备盘,并且是Dedicated。而磁盘组1并没有热备盘。

clip_image046

4、移除热备,同第1步,将光标移至需要移除热备的磁盘组上,按F2键,在出现的菜单中选择 Manage Ded. HS

clip_image047

5、将光标移至需要移除的热备硬盘上,按空格键,去掉X标识,说明此硬盘被移除。将光标移至OK处回车,完成热备移除。

clip_image049
【三】删除虚拟磁盘:
1、将光标移至要删除的虚拟磁盘处,按F2,选择Delete VD按回车继续

clip_image051

2、在弹出的确认窗口,OK处按回车确认即可删除。
注:删除的同时会将此虚拟磁盘的数据全部删除。

clip_image053

3、删除磁盘组,将光标移至要删除的磁盘组处,按F2,选择Delete Disk Group按回车继续

clip_image055

4、在弹出的确认窗口,OK处按回车确认,即可删除
注:删除的同时会将此磁盘组的数据全部删除。

clip_image057

2013年最流行的php框架盘点

PHP框架的发展背景

毫无疑问,Web框架技术在近几年已经得到了突飞猛进的发展和普及,在过去几年里,框架技术的普遍经历了比较大的完善过程,很大一部分可以归因于Ruby on Rails,以及在其他编程语言中流露出的MVC框架思想。

如果你是一个PHP忍者,而不是一个铁杆的Ruby追随者,你也许会惊奇市面上已经有这么多的框架,哪一个才是适合你的。当然回答和个问题取决于的诸多因素,今天我们将会回顾一下这个典型的问题,如何为你的下一个应用系统选择适合你的PHP框架。

同时我们也来看一下比较流行的PHP框架,比较一下他们的区别,这样可以帮你自己做出明智的选择,找到最适合你项目的框架。

明确你的需求

在你决定为你的项目选择一个框架之前,你当先理解需要,需求和了解一些开发团队幕后的工作,我们总结出了如下几个问题,在开始下一步之前你可以试着问问自己。

 

你的应用程序主要集中于解决哪些问题?

你的应用可以是一个电子商务平台,一个社交网站,消息共享平台或者活动目录,举例来说,如果你正在构建一个电子商务网站,你也许更希望选用一些具有 用于处理信用卡和交易会话的成熟的扩展函数库的框架。另一方面,如果是一个轻量级的消息平台(比如说微博类系统),则你也许更应该注重快速的扩展和跨服务 器跨数据的支撑访问能力,为了实现负载均衡和快速连接访问。

 

你的主机运行环境将是什么?

有些特殊的框架会需要使用到一些非默认的其它PHP扩展或者软件安装在服务器上,比如,有些框架的数据抽象层必须要求通过PDO来实现访问,而非直 接调用更底层的MySQL或MySQLi,或者有些类似wiki类的程序的图像压缩和处理功能往往需要使用到ImageMagick 或 Graphiviz 这些外部程序。而这些扩展也许并不会被所有的共享主机环境(虚拟主机)支持,此外即便是一个轻量级的小型框架,而且自我集成了所有所需的函数库并且也具有 良好的可移植性和适应性,这样的框架应用在处理数据密集型的操作或者大型数据处理的系统时,性能又会成为它的主要瓶颈。

你的开发人员或团队的优势和劣势在于什么?

如果你是个项目经理,一个重要的事情是了解清楚你的具体开发人员他们的能力和弱势,因为他们是真的闷头干活儿人,所以也许你可以选择一些更加面向开 发人员友好的容易上手的框架。当然这个问题的也许并不是影响决定是否采用一个框架的决定性因素(不断地要求自己和团队学习新的技术总是好的),但着绝对是 一个会影响到你的时间表、预算和安全等多方面因素的重要考量条件。

如何在高耦合性” 还是 低耦合性” 的框架中做出选择?

如果从框架产品自身的耦合性来将目前主流的php框架产品分为高耦合性和低耦合性两类。低耦合性的框架看起来更像是一个丰富的函数库和逻辑封装的抽 象层,甚至有些好的框架自身就是PHP的一个高级扩展组件,比如PDO,它绝对算得上是一个数据访问的框架也是抽象层。还有一些其他值得一提的低耦合性框 架,比如Zend Framework,CakePHP,以及国内开发的ThinkPHP都属于这个范畴。 如果你将接手的项目历史问题比较多,并且对UI的自定义比较高,你恐怕需要一个低耦合性的框架来满足你灵活的需求。

 

目前主流的开发框架

现在我们已经对你将要开发的应用程序和你的开发团队有了足够的了解和认识,那么接下来让我们来测试几款比较流行的框架和他们所能提供给我们的功能特性吧。

CakePHP 开发框架

官方网址:http://cakephp.org/

下载地址:https://github.com/cakephp/cakephp/archive/2.3.0-RC2.tar.gz

如果你仍然需要编写面向PHP4兼容的代码,CakePHP 将是一个非常不错的选择, 在PHP 4 & 5的MVC式框架列表里面,CakePHP都曾经是最流行的。它还提供了很多种途径的技术支持(讨论组、留言板、IRC等)还有优秀的教程。 CackePHP是个很容易上手的框架,但是你并不容易在短短几周的时间就完全掌握它。

 

Zend Framework框架

官方网址:http://framework.zend.com

下载地址:http://www.zend.com/en/download/633

Zend Framework 是面对一些较有经验的开发者和从底层构建一些企业级应用程序而设计的。(例如:宣称面向企业应用而设计的 Openbiz Cubi 就是基于Zend Framework框架之上而构建的。)该框架是高度模块化的。这意味着你可以按你的实际需要来引用Zend的代码。有些函数库甚至可以很容的被提取出来 单独使用(例如Zend_Gdata,这也是个低耦合性的特点)使用Zend框架,你不必非要遵从它的MVC架构,(虽然你最好能这么做),并且它还提供 了许多内建的高级功能用于完成与现有的web服务整合,多语言化和实现单元测试这些任务。

 

CodeIgniter

官方网址: http://codeigniter.org.cn

下载地址:http://codeigniter.org.cn/download

CodeIgniter 是一个PHP5.2+ 的MVC框架,它体积小巧切具有丰富的文档资源。通常被称为初学者框架,因为它相对容易试用和较短的学习曲线,此外CodeIgniter也是十分灵 活和强大的。该框架拥有一个非常庞大的社区支持。并且在社区里面很容易找到大量的CI函数库,你可以大胆的梦想, 也许你正需要做的事情在社区的某个交流,某个人已经把它实现了。

 

Symfony

官方网址:http://symfony.com/

下载地址:http://symfony.com/download

这是一位老大爷向我推荐应该把它也收录进来。 

Symfony 是最古老的PHP框架之一(相信你从他的网站风格上也发现这一点了),他同样也是转为企业级Web应用程序而设计的。然而,对于他所能提供的所有动力和性 能而言,它只拥有很小的体积并且非常容易配置在大多数php的主机环境中。由于他的年头最长久,你会很容易找到许多关于Symfony的教程、书记等资 料,对于新手来说,这绝对是件好事儿。

Symfony使用命令行代码生成工具来为项目快速生成所需的代码,这种方式也许对于某些开发人员来说是前所未闻的(在那个年头,也许 吧。。。)然后,他可以帮助你在很短的时间里完成代码并是他们可以运行。Symfony的网站上手机了大量的教程和范例代码,来帮助你熟悉掌握他们。

 

Yii Framework

官方网址:http://www.yiiframework.com

下载地址:http://yii.googlecode.com/files/yii-1.1.13.e9e4a0.tar.gz

这也是近几年才出现的一匹黑马。

Yii 是一个高度模块化,高性能的PHP5框架,专门为了Web应用程序而开发。Yii采用了大量的命令行生成工具,让你可以快速的生成一些代码,因此,他最适 合于喜欢在命令行的黑窗口上敲敲打打的人。所有这些代码生成工具意味着你需要记住更多的命令和参数,但是一点你做到了,你会发现,它们将大大减少你所要花 费的时间来设置和配置你的应用程序。

这种开发方式 非常类似于Openbiz Appbuilder所提供的向导式的代码生成方式,最大的不同点是Yii是基于命令行去生成代码,Openbiz Appbuilder是在图形界面上生成代码。

 

最后,一家之见。有不同意见,请留言讨论。

 

分享:PHP怎么样去掉从word直接粘贴过来的没有用的格式

通常我们会遇到直接把word内的内容,直接粘贴到文本编辑器中。这时候会出现在文本编辑器中有一些word内的没用的标签内容。一般处理的方式有二种:1.通过编辑器的JS直接去除。2.提交到后台后,直接用程序去掉无效标签。下面我就分享一个通过PHP的处理方式,成功率可能不是100%。这程序也是在PHP官网上看到的,就顺便粘贴过来了。

function ClearHtml($content,$allowtags='') {
			
			mb_regex_encoding('UTF-8');
			//replace MS special characters first
			$search = array('/&lsquo;/u', '/&rsquo;/u', '/&ldquo;/u', '/&rdquo;/u', '/&mdash;/u');
			$replace = array('\'', '\'', '"', '"', '-');
			$content = preg_replace($search, $replace, $content);
			//make sure _all_ html entities are converted to the plain ascii equivalents - it appears
			//in some MS headers, some html entities are encoded and some aren't
			$content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
			//try to strip out any C style comments first, since these, embedded in html comments, seem to
			//prevent strip_tags from removing html comments (MS Word introduced combination)
			if(mb_stripos($content, '/*') !== FALSE){
				$content = mb_eregi_replace('#/\*.*?\*/#s', '', $content, 'm');
			}
			//introduce a space into any arithmetic expressions that could be caught by strip_tags so that they won't be
			//'<1' becomes '< 1'(note: somewhat application specific)
			$content = preg_replace(array('/<([0-9]+)/'), array('< $1'), $content);
			
			$content = strip_tags($content, $allowtags);
			//eliminate extraneous whitespace from start and end of line, or anywhere there are two or more spaces, convert it to one
			$content = preg_replace(array('/^\s\s+/', '/\s\s+$/', '/\s\s+/u'), array('', '', ' '), $content);
			//strip out inline css and simplify style tags
			$search = array('#<(strong|b)[^>]*>(.*?)</(strong|b)>#isu', '#<(em|i)[^>]*>(.*?)</(em|i)>#isu', '#<u[^>]*>(.*?)</u>#isu');
			$replace = array('<b>$2</b>', '<i>$2</i>', '<u>$1</u>');
			$content = preg_replace($search, $replace, $content);
			
			//on some of the ?newer MS Word exports, where you get conditionals of the form 'if gte mso 9', etc., it appears
			//that whatever is in one of the html comments prevents strip_tags from eradicating the html comment that contains
			//some MS Style Definitions - this last bit gets rid of any leftover comments */
			$num_matches = preg_match_all("/\<!--/u", $content, $matches);
			if($num_matches){
				$content = preg_replace('/\<!--(.)*--\>/isu', '', $content);
			}
			return $content;
}

测试使用结果:

<?php
$content = ' <!--[if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->
    			<p class="p0" style="text-indent: 24.0000pt; margin-bottom: 0pt; margin-top: 0pt;"><span style="mso-spacerun: "yes"; font-size: 12.0000pt; font-family: "宋体";">《优伴户外旅行》&mdash;&mdash;让旅行成为习惯!</span></p>越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!</span></p>';
echo ClearHtml($content,'<p>');

/*
得到的结果:
<p  >《优伴户外旅行》--让旅行成为习惯!</p>越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!</p>
*/
?>

分享:PHP怎么样补齐关闭的HTML标签

很多时候,在我们做文章截取摘要的时候,如果出现HTML的内容,会出现截取的文章没有结束的HTML标签。这样的情况下就会出现页面样式错乱的问题。这 个时候我们需要的就是把缺少的结束标签加批量加上。在www.php.net官网看到一个比较好处理的一个函数,展示如下:

function CloseTags($html)
{
        // strip fraction of open or close tag from end (e.g. if we take first x characters, we might cut off a tag at the end!)
        $html = preg_replace('/<[^>]*$/','',$html); // ending with fraction of open tag
       
        // put open tags into an array
        preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
        $opentags = $result[1];

        // put all closed tags into an array
        preg_match_all('#</([a-z]+)>#iU', $html, $result);
        $closetags = $result[1];

        $len_opened = count($opentags);

        // if all tags are closed, we can return
        if (count($closetags) == $len_opened) {
            return $html;
        }

        // close tags in reverse order that they were opened
        $opentags = array_reverse($opentags);

        // self closing tags
        $sc = array('br','input','img','hr','meta','link');
        // ,'frame','iframe','param','area','base','basefont','col'
        // should not skip tags that can have content inside!

        for ($i=0; $i < $len_opened; $i++)
        {
            $ot = strtolower($opentags[$i]);
            if (!in_array($opentags[$i], $closetags) && !in_array($ot,$sc))
            {
                $html .= '</'.$opentags[$i].'>';
            }
            else
            {
                unset($closetags[array_search($opentags[$i], $closetags)]);
            }
        }
        return $html;
}

测试使用的结果:

<?php
$content = '<div><p><span>越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!';
echo CloseTags($content);

/*
返回的结果是:
<div><p><span>
越发忙碌的你,是否想给自己放个假?专注工作的你,是否还记得上一次锻炼是什么时候?优伴户外旅行,给你不一样的旅行体验:给心自由,便处处都是风景!</span></p></div>
*/
?>

PHP程序下如何取得APK签名以及验证是否一致

        近期的需要取到APK的签名,以此来比对开发者上传的APK软件是否与原创APK的签名一致,以此保护正版APK软件的权益。同时避免像破解,汉化之类的 软件,覆盖在线的正版。所以这个功能需求还是很有必要实现的。

本人对JAVA不太懂,开始想是不是能通过PHP技术来解决这个问题。但是通过查找各方面的 资料,没有找到好的办法。

最后转而去先了解了一下JAVA对包签名原理,再通过JAVA方面去找答案,最终是解决了这个问题。可是这样解决的方法,并不是 我期待的。我很希望会有更加简洁的方法实现,如果有更好解决的方案的朋友,可以留言给我。希望多交流。

下面就讲一下取比对APK签名一致的步骤,总的步骤先归纳如下几点,然后我分别做解释:
1.在服务器上安装JDK,使用keytool命令生效。
2.分别到取到二个APK包的证书指纹。
3.通过指纹信息,对比是否相等,判断是否为同一软件。

现在按上面给出的思路,来执行操作就可以。我们接着往下走:

第一步:在CentOS服务器下安装JDK,让keytool命令生效可以使用。

a.下载适合贵公司服务器的JDK版本。
下载址址:http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u29-download-513648.html

我测试的时候,下载的是:jdk-6u29-linux-x64.bin 。

[root@web-1 home]# wget http://download.oracle.com/otn-pub/java/jdk/6u29-b11/jdk-6u29-linux-x64.bin

b.安装并配置JDK.

[root@web-1 home]# ./jdk-6u29-linux-x64.bin 

[root@web-1 home]# mv jdk1.6*  /usr/local/java

[root@web-1 home]# cat >> /etc/profile  << EFF
########################################
JAVA_HOME=/usr/local/java
JRE_HOME=\$JAVA_HOME/jre
CLASSPATH=:\$JAVA_HOME/lib:\$JRE_HOME/lib
PATH=\$JAVA_HOME/bin:\$JRE_HOME/bin:\$PATH
export JAVA_HOME JRE_HOME CLASSPATH PATH
########################################
EFF

c.测试JAVA环境是否正常。

[root@web-1 home]# java -version

java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)

如果有类似如上输出,证明你的配置成功,恭喜!

注:Windows服务器的安装,我没有做测试,网上教学一堆,所以是Windows服务器的同学可以找找怎么安装JDK。

第二步:通过组合命令取到APK包CERT.RSA证书指纹(MD5或SHA1值)。
注:CERT.RSA文件中保存了公钥、所采用的加密算法等信息。

a.取到第一个包名的证书指纹。

unzip -p mumayidianzishichang_Mumayi_Market_V1.4_mumayi_91db5.apk META-INF/CERT.RSA | keytool -printcert | grep MD5
或者是:
unzip -p mumayidianzishichang_Mumayi_Market_V1.4_mumayi_91db5.apk META-INF/CERT.RSA | keytool -printcert | grep SHA1
输出如下:
[root@web-1 1]# unzip -p mumayidianzishichang_Mumayi_Market_V1.4_mumayi_91db5.apk META-INF/CERT.RSA | keytool -printcert | grep MD5
         MD5:  19:2A:5C:11:3E:72:A0:A1:A1:10:A3:BE:C3:9C:D5:32
[root@web-1 1]# unzip -p mumayidianzishichang_Mumayi_Market_V1.4_mumayi_91db5.apk META-INF/CERT.RSA | keytool -printcert | grep SHA1
         SHA1: 91:83:AF:08:B5:00:88:85:E6:4C:E9:41:4E:3B:06:EC:51:E8:F8:83
         Signature algorithm name: SHA1withRSA

a.取到第二个包名的证书指纹。

unzip -p mumayidianzishichang_Mumayi_Market_V1.5.9_mumayi_9454a.apk META-INF/CERT.RSA | keytool -printcert | grep MD5
或者是:
unzip -p mumayidianzishichang_Mumayi_Market_V1.5.9_mumayi_9454a.apk META-INF/CERT.RSA | keytool -printcert | grep SHA1
输出如下:
[root@web-1 1]# unzip -p mumayidianzishichang_Mumayi_Market_V1.5.9_mumayi_9454a.apk META-INF/CERT.RSA | keytool -printcert | grep MD5
         MD5:  19:2A:5C:11:3E:72:A0:A1:A1:10:A3:BE:C3:9C:D5:32
[root@web-1 1]# unzip -p mumayidianzishichang_Mumayi_Market_V1.5.9_mumayi_9454a.apk META-INF/CERT.RSA | keytool -printcert | grep SHA1
         SHA1: 91:83:AF:08:B5:00:88:85:E6:4C:E9:41:4E:3B:06:EC:51:E8:F8:83
         Signature algorithm name: SHA1withRSA

注意红色框中的MD5与SHA1值,显然后上面二个APK包的版本是一样的,但是他们二个的MD5与SHA1值是相等的。能过这个值,我们就可以
判断出来二个APK中的CERT.RSA文件中保存了公钥、所采用的加密算法等信息是一样的。间接地可以得到,签名信息一致。

最后一步:

通过上面取到的正版的MD5或SHA1值存到数据库中,用于比对新上传的APK软件。如果相等证明APK签名一致,反之说明些APK软件被“污染”。

通过上面的说明,估计大家明白了这其中的原理。只要我们能拿到CERT.RSA证书指纹(MD5或SHA1值)。就可以做APK签名比对的功能了。

最后说一下这种实现方式不足的地下存在二点:
1.在PHP程序方面,需要开启exec,shell_exec等shell命令函数,产生不安全隐患。
2.需要安装JDK,间接地加重了服务器管理与维护的成本。

参考文章与资料:

1.《How can I verify the authenticity of an apk file I downloaded?》这文章写的相当详细,非常感谢此文章作者。

2.《java keytool证书工具使用小结

3.《APK Crack

4.《Android APK 签名比对

[转]Light Table – 新的IDE概念,新的编程环境

虽 然软件界面戏剧性地日益精简,无数的开发工具却依然以不断的新版本、一个接一个的新功能挤占着我们的工作空间。哪怕把它们都放置的井井有条,我们依然被困 在无数文件和指定的目录结构中动弹不得。为什么写代码时我们非得满世界查找需要的东西?为什么只有一动不动的文本文件?

 Bret Victor 指出我们可以做得更好:通过提供即时的反馈,你可以立即看到每一个改动的效果。我发现他是对的。

我们能做得更好,为此,请容我介绍:

 Light Table基于非常简单的理念:写程序需要的是真正的工作台,而不是编辑器和项目浏览器。我们需要把工件挪来挪去,把杂物扔到下面,把有用的材料放在上面最顺手的位置。以下是最基本的模式:

 light table's main screen

 Light Table的基本原则包括:

 你永远不需要查找文档

 文件不是代码最好的表现方式,它们只是比较方便的存储方式而已。

 编辑器无所不在,而且显示的东西无所不包——而非仅限文本。

 鼓励尝试——对代码的改动会立即显示出效果

 我们可以通过“光照模式”仔细查看关联的代码

 让我们在Light Table中看看这些特性吧,首先是随手可得的文档

 阅读新代码时,能立即看到作者留下的文档会很有帮助。通常你必须导航到方法的定义处,但在Light Table中,相关信息会直接显示在边栏中。想要知道这段代码的功能?把光标放到上面就行了。这就保证了你永远无需担心忘记诸如参数次序之类的事情。

 Better than a repl

(译注:翻到这里,我对Light Table的“新特性”开始有所怀疑。几乎所有我用过的IDE都具备就地显示文档的功能,从NetBeans到IDEA无不如此,只要把鼠标指向方法名,就会立即显示诸如参数次序和文档说明之类的信息。我怀疑是作者使用的语言: ClojureScript 的IDE支持太弱的原因。但问题在于,作者既然在VS团队内工作过,还能自如的对编译器进行修改,而且是个Lisper……说明基本上是个大牛,很可能掌握二十几门语言,用过十几个IDE,不可能不知道这些。)

 整天和新代码打交道,我们很容易忘记到底是哪个方法在页面上添加了链接——必须能够就地快速遍历所有的文档并把这个方法找出来。不记得noir.core这个命名空间里有些什么?按下ctrl-f就知道了。

 Better than a repl

(译注:这个也牵强……)

 找到那些你从未见过的方法并立即看到文档是个非常顺手的功能,我们再也无需专门去查找那些外部文档了。

Better than a repl

即时反馈

 在 Inventing on Principle 中,Bret演示了如何写一个即时编写即时改变的游戏(调整代码的同时游戏的界面立即同步变化),也演示了如何在一个二分搜索的例程中实时对代码进行评估 并反馈结果。Lisp程序员习惯用REPL循环(Read-Eval-Print)来进行尝试。但我们可以做得更好——就地尝试、立即反馈。例如,当我输 入代码(+ 3 4)时,立刻可以看到结果7,根本不需要按ctrl-Enter之类的键。

Better than a repl

( 译注:双刃剑:如果遇到一个极耗费资源的表达式会发生什么……如果遇到一个不是那么明显的无限循环会发生什么)

 Light Table并未止步于此,事实上它还会告诉你整个调用过程是如何进行计算的。让我们看看结果是如果在方法中一步步计算出来的。

Better than a repl

( 译注:同样,在这样简单的例程当中看来非常美好的功能,一旦在现实世界使用会怎样?对于层层嵌套的调用会有什么效果?)

 这一级别的实时运算及可视化反馈基本上提供了一个实时调试器,用以快速的尝试不同的参数并观察计算过程,再没有更快的调试方法了。

 Better than a repl

我们提供“绘图台”是有原因的:

在 我为Visual Studio团队工作的最后一段时间里,我开始认为软件窗口并不能很好的对应我们的工作。其他行业的工程师拥有巨大的工作台,可以用来放置图纸、工具和其 它东西。绘图台的概念可以更好的对应我们的工作。我们没必要把自己限制在一个以文件为最小操作单位的世界里。当我们能通过概念层次对代码进行管理时,我们 可以看到更多更复杂的代码之间的交互及影响。

 

 我们看到了气泡提示式的代码块范例,这并没有什么。为什么不尝试下把游戏直接嵌入在工作台中运行呢?这样我们就可以排查每行代码,把问题抛给Light Table,看看它如何回答。

Better than a repl

“光照模式”下的代码

 没有理由认为工具不应帮助我们理解程序是如何组织的。在“光照模式”下,Light Table能让你看到当前处理的部分用到了那些方法,不仅仅是高亮那么简单,它会在边栏显示这些方法的代码实现。

 Better than a repl

(译注:这很有用,但是很显然,对于主流语言的主流IDE而言,做到类似的效果不难。)

 我们不需要四处乱翻以确定一大堆的代码如何交互。

 最后,所有这些特色结合起来让我们不仅能即时的运行输入的代码,而且可以看到数据流是如何在代码中传递的。这里,我发现了一个x变量的赋值错误。输入  (greetings ["chris"])然后立刻看到所有的值传递过程,不仅仅是当前的方法,而是包含了所有用到的方法。undefined

 Better than a repl

那么它会如何运行?

 

 如 同你在视频中看到的原型系统。那是一个用Noir、很多ClojureScript类库、CodeMirror组成的网页程序。我稍微对Clojure编 译器进行了修改好获得表单的元数据(比如列的位置和其它位置参数)。除此之外,就只是过一遍语法分析树和少许魔法的问题了:) (这是关于编程语言的事情了)

 无需掩饰,我真的很喜欢 Clojure这种Lisp方言,对我来说这是最简单的原型开发语言。但是其它语言只要具备动态运行时的支持,都可以实现前述的特性,只需要做非常简单的 AST(抽象语法树)分析和一些聪明的调整而已。那么,Light Table可以支持JavaScript吗?当然,而且越快越好,机不可失!

 我 一直很沉迷开发工具——创造那些用于创造的工具。改变我们构建软件的方式并以此向世界回馈巨大的价值,我们面临着无可估量的机遇,当我在Visual Studio工作时,我就看到了一点曙光。这只是开始,只是播种。是时候跳出条条框框并重新思考那些让我们创造一切的工具了。undefined

 

【本译文仅用于学习和交流目的。非商业转载请注明译者、出处,并保留文章在译言的完整链接】

博客加上了Sphinx全文搜索功能


很久之前就想把博客搜索功能给加上,但一直没有去做。今天抽时间把这个功能给实现了。用的全文搜索引擎为Sphinx。为了支持中文的搜索,所以选择了经过改进的Coreseek,它支持全中文的分词。关于它的安装,可以参才我的这篇文章《如何使用Sphinx来实现全文检索(搜索)功能》.

下面是搜索展示,您可以通过博客右侧试用一下搜索功能:


搜索的结果展示如下:

现在只是用来搜索文章标题,全文的搜索没有加到搜索行列中。这个功能只是在生成索引的时候,把内容字段加入就可以。如有必要,以后会加上。

[转]Redis.conf 中文配置详解

其实redis.conf文件中,对每一个配置项都有非常详细的注释,本文只是将其进行翻译,同时加了点小料。本文档所对应的redis版本为2.0.4。

  1. 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写):

    		1k  => 1000      bytes
     1kb => 1024      bytes
     1m  => 1000000   bytes
     1mb => 1024*1024 bytes
  2. daemonize no 默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
  3. pidfile /var/run/redis.pid 当redis在后台运行的时候,Redis默认会把pid文件放在/var/run/redis.pid,你可以配置到其他地址。当运行多个redis服务时,需要指定不同的pid文件和端口
  4. port 6379 指定redis运行的端口
  5. bind 127.0.0.1 指定redis只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求,在生产环境中最好设置该项
  6. timeout 300 设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接
  7. loglevel debug log等级分为4级,debug, verbose, notice, 和warning。生产环境下一般开启notice
  8. logfile stdout 配置log文件地址,默认使用标准输出,即打印在命令行终端的窗口上
  9. databases 16 设置数据库的个数,可以使用SELECT <dbid>命令来切换数据库。默认使用的数据库是 DB 0
  10. save 900 1 设置Redis进行数据库镜像的频率。

    		#   after 900 sec (15 min) if at least 1 key changed
    #   after 300 sec (5 min) if at least 10 keys changed
    #   after 60 sec if at least 10000 keys changed

    在给定的例子中,我们可以倒过来理解:

    		if(在60秒之内有10000个keys发生变化时){
        进行镜像备份
    }else if(在300秒之内有10个keys发生了变化){
        进行镜像备份
    }else if(在900秒之内有1个keys发生了变化){
        进行镜像备份
    }

    所以,按照这里的配置,每隔60秒,redis会检查现在发生了多少变化,是不是应该进行镜像备份了。但是当数据库比较大时,在我的测试中,镜像备份的速度非常慢,并由此导致redis内存暴涨直至crash。

  11. rdbcompression yes 在进行镜像备份时,是否进行压缩
  12. dbfilename dump.rdb 镜像备份文件的文件名
  13. dir /opt/local/var/db/redis/ 数据库镜像备份的文件放置的路径。这里的路径跟文件名要分开配置是因为redis在进行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成 时,再把该该临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放在这个指定的路径当中。
  14. slaveof <masterip> <masterport> 设置该数据库为其他数据库的从数据库
  15. masterauth <master-password> 当主数据库连接需要密码验证时,在这里指定
  16. requirepass foobared 设置客户端连接后进行任何其他指定前需要使用的密码。警告:因为redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150K次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解。
  17. maxclients 128 限制同时连接的客户数量。当连接数超过这个值时,redis将不再接收其他连接请求,客户端尝试连接时将收到error信息。
  18. maxmemory <bytes> 设置redis能够使用的最大内存。当内存满了的时候,如果还接收到set命令,redis将先尝试剔除设置过expire信息的key,而不管该key 的过期时间还没有到达。在删除时,将按照过期时间进行删除,最早将要被过期的key将最先被删除。如果带有expire信息的key都删光了,那么将返回 错误。这样,redis将不再接收写请求,只接收get请求。maxmemory的设置比较适合于把redis当作于类似memcached的缓存来使 用。
  19. appendonly no 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那 么将造成比较大范围的数据丢失。所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之 前的状态。但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。所以我认为推荐生产环境下的做法为关闭镜像,开启appendonly.aof,同时可以选择在访问较少的时间每天对 appendonly.aof进行重写一次。
  20. appendfsync everysec 设置对appendonly.aof文件进行同步的频率。always表示每次有写操作都进行同步,everysec表示对写操作进行累积,每秒同步一次。这个需要根据实际业务场景进行配置
  21. vm-enabled no 是否开启虚拟内存支持。因为redis是一个内存数据库,而且当内存满的时候,无法接收新的写请求,所以在redis 2.0中,提供了虚拟内存的支持。但是需要注意的是,redis中,所有的key都会放在内存中,在内存不够时,只会把value值放入交换区。这样保证 了虽然使用虚拟内存,但性能基本不受影响,同时,你需要注意的是你要把vm-max-memory设置到足够来放下你的所有的key
  22. vm-swap-file /tmp/redis.swap 设置虚拟内存的交换文件路径
  23. vm-max-memory 0 这里设置开启虚拟内存之后,redis将使用的最大物理内存的大小。默认为0,redis将把他所有的能放到交换文件的都放到交换文件中,以尽量少的使用物理内存。在生产环境下,需要根据实际情况设置该值,最好不要使用默认的0
  24. vm-page-size 32 设置虚拟内存的页大小,如果你的value值比较大,比如说你要在value中放置博客、新闻之类的所有文章内容,就设大一点,如果要放置的都是很小的内容,那就设小一点。
  25. vm-pages 134217728 设置交换文件的总的page数量,需要注意的是,page table信息会放在物理内存中,每8个page就会占据RAM中的1个byte。总的虚拟内存大小 = vm-page-size * vm-pages
  26. vm-max-threads 4 设置VM IO同时使用的线程数量。因为在进行内存交换时,对数据有编码和解码的过程,所以尽管IO设备在硬件上本上不能支持很多的并发读写,但是还是如果你所保存的vlaue值比较大,将该值设大一些,还是能够提升性能的
  27. glueoutputbuf yes 把小的输出缓存放在一起,以便能够在一个TCP packet中为客户端发送多个响应,具体原理和真实效果我不是很清楚。所以根据注释,你不是很确定的时候就设置成yes
  28. hash-max-zipmap-entries 在redis 2.0中引入了hash数据结构。当hash中包含超过指定元素个数并且最大的元素没有超过临界时,hash将以一种特殊的编码方式(大大减少内存使用)来存储,这里可以设置这两个临界值
  29. activerehashing yes 开启之后,redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用。当你的使用场景中,有 非常严格的实时性需要,不能够接受Redis时不时的对请求有2毫秒的延迟的话,把这项配置为no。如果没有这么严格的实时性要求,可以设置为yes,以 便能够尽可能快的释放内存

初步安装key-list类型内存数据引擎-Memlink

在这两天在为选用哪个Key/Value数据库烦恼。Redis,还是Memlink? 在网络上查找与对比了一下,相对来说Redis的名气会大很多,学习并投入并使用到项目还是很多案例的。而对于Memlink,了解的人并没有多少。它只是天涯社区开发人员开发出来的一款数据引擎。

看了一下关于Memlink的介绍,按我个人的理解,发现它是在借鉴Redis优点的前提下,再进行了实际的改进。当然对于谁好谁坏,我目前还没有去测试,对于初学者的我,在没有好的选择下,最好的做法就是分别安装二个。再进行相应的测试与对比。

现在我把对于Memlink安装步骤给写出来,不过发现Memlink的安装相比于Redis安装要复杂的太多。环境要求也是要高一些。

先看一下编译环境要求(Memlink手册要求).

    * 依赖python http://www.python.org/ 版本2.6
    * 依赖scons http://www.scons.org/ 版本为2.0.1
    * 库依赖libevent http://monkey.org/~provos/libevent/ 版本1.4.14b
    * 依赖swig http://sourceforge.net/projects/swig/files/ 版本 swig-1.3.40,注意不是 swigwin-1.3.40

    scons是个python模块。安装方法为,解压缩后,进入该目录,运行:
    
    python setup.py install
    
    注意python的版本。
    scons相当于make。它依赖于python。它基本命令和make对比:
    scons => make
    scons -c => make clean
    scons 安装路径 => make install

A.分别下载依赖的包

下载python2.7.1的包

下载页面地址:http://www.python.org/getit/
#wget http://www.python.org/ftp/python/2.7.1/Python-2.7.1.tar.bz2

下载scons 包

下载页面地址:http://www.scons.org/download.php
#wget http://prdownloads.sourceforge.net/scons/scons-2.0.1.tar.gz

下载libevent包

下载页面地址:http://monkey.org/~provos/libevent/
#wget http://monkey.org/~provos/libevent-1.4.1-beta.tar.gz

下载swig-1.3.40

下载页面地址:http://sourceforge.net/projects/swig/files/swig/swig-1.3.40/
#wget http://sourceforge.net/projects/swig/files/swig/swig-1.3.40/swig-1.3.40.tar.gz/download

B.编译并安装相应的环境
 

#tar jxvf  Python-2.7.1.tar.bz2
#cd Python-2.7.1
#./configure
#make && make install

#tar zxvf  scons-2.0.1.tar.gz
#cd scons-2.0.1
#python setup.py install

#tar zxvf  libevent-1.4.1-beta.tar.gz
#cd libevent-1.4.1-beta
#./configure
#make && make install

#tar zxvf  swig-1.3.40.tar.gz
#cd  swig-1.3.40
#./configure
#make && make install

C.下载,编译并安装Memlink

#wget http://memlink.googlecode.com/files/memlink-0.3.4.tar.gz
#tar  zxvf memlink-0.3.4.tar.gz
#cd   memlink-0.3.4
#scons


经过2分钟左右,就会在该目录下面会出现可执行文件memlink。

安装Memlink
memlink安装需要执行 "scons 安装路径" 这个命令。其中的安装路径在SConstruct文件中有配置,必须和里面的install_dir一致。这里默认是/opt/memlink,可以根据情况修改。
 

#vim SConstruct  //找到install_dir,把/opt/memlink改成你需要安装memlink路径  例如:/usr/local/memlink
#scons /usr/local/memlink   //这个是我自己的设定的目录


此时查看 /usr/local/memlink目录下会多出二个文件夹bin和etc.到此,证明你已成功安装完成memlink

D.编译安装PHP客户端模块
进入到上步memlink文件目录

#cd memlink-0.3.4/client/php
#vim SConstruct   //直接运行scons.该目录下面有一个叫SConstruct的文件, 里面有个配置选项叫php_config的,这个是您PHP环境下php-config文件的路径。
编译生成的memlink.so拷贝到php扩展模块目录中。

 编辑PHP.ini 加入extension=memlink.so 模块。
 重启Apache或是Nginx服务器,并查看phpinfo,如果能在phpinfo页面看到类似如下图片,则说明PHP客户端模块安装成功。


 
 参考网址:
 http://www.infoq.com/cn/news/2010/11/tianya-memlink
 http://code.google.com/p/memlink/wiki/DesignDocument#%E4%BF%AE%E6%94%B9%E4%B8%80%E4%B8%AA%E6%95%B0%E6%8D%AE%E7%9A%84mask
 http://liluo.org/2010/08/centos-5-5-%E4%B8%AD-python-%E5%8D%87%E7%BA%A7%E5%88%B0-2-6-5/
 http://code.google.com/p/memlink/wiki/Install
 http://code.google.com/p/memlink/wiki/ClientAPI
 

初步学习怎么安装Redis与phpredis

Redis是什么?Redis本质上一个Key/Value数据库,与Memcached类似的NoSQL型数据库,但是他的数据可以持久化的保存在磁盘上,解决了服务重启后数据不丢失的问题,他的值可以是string(字符串)、list(列表)、sets(集合)或者是ordered  sets(被排序的集合),所有的数据类型都具有push/pop、add/remove、执行服务端的并集、交集、两个sets集中的差别等等操作,这些操作都是具有原子性的,Redis还支持各种不同的排序能力
Redis 2.0更是增加了很多新特性,如:提升了性能、增加了新的数据类型、更少的利用内存(AOF和VM)
Redis支持绝大部分主流的开发语言,如:C、Java、C#、PHP、Perl、Python、Lua、Erlang、Ruby等等。
Redis的功能:
1、Redis的Sharding:Redis支持客户端的Sharding功能,通过一致性hash算法实现,当前Redis不支持故障冗余,在集群中不能在线增加或删除Redis
2、Redis的master/slave复制:
1. 一个master支持多个slave
2.  Slave可以接受其他slave的连接来替代他连接master
3.  复制在master是非阻塞的,而在slave是阻塞的
4.   复制被利用来提供可扩展性,在slave端只提供查询功能及数据的冗余
3、Redis的Virtual Memory功能:vm是Redis2.0新增的一个非常稳定和可靠的功能,
vm的引入是为了提高Redis的性能,也就是把很少使用的value保存到disk,而key保存在内存中。实际上就是如果你有10w的keys在内存中,而只有仅仅10%左右的key经常使用,那么Redis可以通过开启VM尝试将不经常使用的Value转换到disk上保存
4、Redis的附加档案(AOF)功能:Redis通过配置的策略将数据集保存到aof中,当Redis挂掉后能够通过aof恢复到挂掉前的状态。

A.快速安装Redis
1.去Redis官网下载Redis源码

wget http://redis.googlecode.com/files/redis-2.2.8.tar.gz


2.解压并执行make安装

# tar zxvf redis-2.2.8.tar.gz
#cd redis-2.2.8.tar.gz
#make
#src/redis-server     //注意不要关掉Server

3.测试是否成功安装
 

#src/redis-cli
redis>set blogname  kylingood
OK
redis>get blogname
"kylingood"

B.安装PHP的phpredis模块
1.下载phpredis扩展模块

#wget  --no-check-certificate  https://github.com/owlient/phpredis


2.增加phpredis模块

#tar zxvf owlient-phpredis-2.1.1-1-g90ecd17.tar.gz
#cd  owlient-phpredis-2.1.1-1-g90ecd17
# /usr/local/php/bin/phpize   //这个phpize是安装php模块的
# ./configure –with-php-config=/usr/local/php/bin/php-config
# make
# make install


接下来在php.ini中添加:
extension=redis.so
extension_dir=/usr/local/lib/php/extensions/no-debug-non-zts-20060613/

重启apache或者nginx

3.查看php.ini配置,看是否有如下Redis模块
如图:

4.测试PHP操作Redis服务器.

<?php
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->set('test','Hello redis world!');
echo $redis->get('test');
exit;
?>


如果你能成功看到页面输出:Hellow redis world!  那恭喜您,我们Redis初级配置已大功告成。

最后,安装中遇到的问题:
a.启动redis-server出现:
Warning: no config file specified, using the default config.
In order to specify a config file use 'redis-server /path/to/redis.conf'
这个只需要在执行启动时加上,redis.conf的配置路径:
#src/redis-server  /usr/local/redis-2.2.8/redis.conf

b.启动redis-server出现:
WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.
To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

警告:过量使用内存设置为0!在低内存环境下,后台保存可能失败。为了修正这个问题,请在/etc/sysctl.conf 添加一项 'vm.overcommit_memory = 1' ,然后重启(或者运行命令'sysctl vm.overcommit_memory=1' )使其生效。

这个警告的处理就很简单了,按照他说的,改一下,重启。发现依旧报警告。然后只好再运行一下命令令'sysctl vm.overcommit_memory=1' 。

c.wget  https://github.com/owlient/phpredis 出现:
–2011-05-29 15:26:31–  https://github.com/owlient/phpredis/tarball/master
Resolving github.com… 207.97.227.239
Connecting to github.com|207.97.227.239|:443… connected.
ERROR: certificate common name `*.github.com' doesn't match requested host name `github.com'.
To connect to github.com insecurely, use `–no-check-certificate'.
Unable to establish SSL connection.

解决方案:在wget 后面加上 “–no-check-certificate” 。原因是:Unable to establish SSL connection,有时间再找找,可能和系统设置有关。

相关软件下载和文章参考列表:
http://redis.io/download
https://github.com/owlient/phpredis
http://blog.csdn.net/chenggong2dm/archive/2010/12/28/6102162.aspx
http://my.oschina.net/zhaocx/blog/14133
http://blog.sina.com.cn/s/blog_620ad6170100ocqr.html

[转]怎样在linux下查看内核版本、系统版本、系统位数(32or64)

1. 查看内核版本命令:

1) [root@q1test01 ~]# cat /proc/version
  Linux version 2.6.18-194.el5 (mockbuild@builder10.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)) #1 SMP Fri Apr 2 14:58:14 EDT 2010

3.4.4-2)) #1 SMP Mon Sep 19 18:00:54 EDT 2005

2) [root@q1test01 ~]# uname -a
   Linux q1test01 2.6.9-22.ELsmp #1 SMP Mon Sep 19 18:00:54 EDT 2005 x86_64 x86_64 x86_64 GNU/Linux

3) [root@q1test01 ~]# uname -r
   2.6.9-22.ELsmp

 

2. 查看linux版本:

1) 登录到服务器执行 lsb_release -a ,即可列出所有版本信息,例如:

   [root@3.5.5Biz-46 ~]# [root@q1test01 ~]# lsb_release -a
   LSB Version:    :core-3.0-amd64:core-3.0-ia32:core-3.0-noarch:graphics-3.0-amd64:graphics-3.0-

   ia32:graphics-3.0-noarch
   Distributor ID: RedHatEnterpriseAS
   Description:    Red Hat Enterprise Linux AS release 4 (Nahant Update 2)
   Release:        4
   Codename:       NahantUpdate2
   注:这个命令适用于所有的linux,包括Redhat、SuSE、Debian等发行版。


2) 登录到linux执行cat /etc/issue,例如如下:

   [root@q1test01 ~]# cat /etc/issue
   Red Hat Enterprise Linux AS release 4 (Nahant Update 2)
   Kernel \r on an \m

3) 登录到linux执行cat /etc/redhat-release ,例如如下:

   [root@q1test01 ~]# cat /etc/redhat-release
   Red Hat Enterprise Linux AS release 4 (Nahant Update 2)
   注:这种方式下可以直接看到具体的版本号,比如 AS4 Update 1

4) 登录到linux执行rpm -q redhat-release ,例如如下:

   [root@q1test01 ~]# rpm -q redhat-release
   redhat-release-4AS-3
   注:这种方式下可看到一个所谓的release号,比如上边的例子是3
   这个release号和实际的版本之间存在一定的对应关系,如下:
   redhat-release-3AS-1 -> Redhat Enterprise Linux AS 3
   redhat-release-3AS-7.4 -> Redhat Enterprise Linux AS 3 Update 4
   redhat-release-4AS-2 -> Redhat Enterprise Linux AS 4
   redhat-release-4AS-2.4 -> Redhat Enterprise Linux AS 4 Update 1
   redhat-release-4AS-3 -> Redhat Enterprise Linux AS 4 Update 2
   redhat-release-4AS-4.1 -> Redhat Enterprise Linux AS 4 Update 3
   redhat-release-4AS-5.5 -> Redhat Enterprise Linux AS 4 Update 4
   另:第3)、4)两种方法只对Redhat Linux有效.


查看系统是64位还是32位:

1、getconf LONG_BIT or getconf WORD_BIT

2、file /bin/ls

3、lsb_release -a

 

转载文章:http://hi.baidu.com/qinyougen/blog/item/ae2b5fcff4cefa31f8dc6148.html

利用MySQL的MASTER SLAVE异步功能来实现数据库主从同步

很久之前就听过MySQL主从同步功能,一直都没有花时间去做这方面的尝试。最近公司有需求做MySQL主从同步功能,就花时间在网上找了找这方面配置的资料,了解到主从备份的大致优点:
MySQL的主从同步是一个很成熟的架构,优点为:
①在从服务器可以执行查询工作(即我们常说的读功 能),降低主服 务器压力;
②在从主服务器进行备份,避免备份期间影响主服务器服务;
③当主服务器出现问题时,可以切换到从服务器。

MySQL异步复制基本原理

从MySQL3.23.15以后,MySQL支持单向的异步复制。也就是说,1台MySQL服务器充当Master(主库),1台或多台 MySQL服务器充当Slaves(从库),数据从Master向Slaves进行异步复制。注意,这种复制是异步的,有别于MySQL的同步复制实现(这种实现称做MySQL集群,MySQL Cluster)。

当主库有更新的时候,主库会把更新操作的SQL写入二进制日志(Bin log),并维护一个二进制日志文件的索引,以便于日志文件轮回(Rotate)。在从库启动异步复制的时候,从库会开启两个I/O线程,其中一个线程连接主库,要求主库把二进制日志的变化部分传给从库,并把传回的日志写入本地磁盘。另一个线程则负责读取本地写入的二进制日志,并在本地执行,以反映出这种变化。较老的版本在复制的时候只启用一个I/O线程,实现这两部分的功能。

有几个关键性的地方需要注意:

– 主库必须启用Bin log,主库和从库必须有唯一的Server Id
– 从库必须清楚了解从主库的哪一个Bin log文件的哪一个偏移位置起开始复制
– 从库可以从主库只复制指定的数据库,或者数据库的某些数据表
– 主库和从库的数据库名称可以不一样,不过还是推荐使用一样的名称
– 主库和从库的MySQL版本需保持一致

尝试测试的开发的生产环境为:
主数据库:IP:192.168.1.191   MySQL版本:Ver 14.14 Distrib 5.1.53
从数据库:IP:192.168.1.192   MySQL版本:Ver 14.12 Distrib 5.0.91
从数据库:IP:192.168.1.193   MySQL版本:Ver 14.12 Distrib 5.0.91

服务器操作系统都是:Centos 5.6

A:配置主数据库:

1.修改主库(IP:192.168.1.191) my.cnf配置文件
#vim /etc/my.cnf
在[mysqld]区域段内加入以下配置:
server-id =1                   #设置主机ID标识,注意此ID不要同其他主机相同,保证唯一性
log-bin=mysql-bin           #记录mysql日志
binlog-do-db=database1  #设置需要同步的数据库,如果有多个数据库,每个数据库一行
binlog-do-db=database2  #再增加一个需要同步的数据库
binlog-ignore-db=mysql   #设置不需要同步的数据库,如果有多个数据库,每个数据库一行

2.重启主库(IP:192.168.1.191)MySQL服务器,使配置生效
#service mysqld restart

3.增加一个数据库用户,给予此用户可远程连接到主库数据,且要有对需要备份数据库操作所有权限。
增加用户语句:grant all privileges on *.* to '用户名'@'%' identified by '密码';  
#mysql -uroot -p        //登陆数据库
mysql>grant all privileges on *.* to 'kylingood'@'%' identified by '123456';    //建立数据库kylingood用户

4.选其中一台从库(IP:192.168.1.192或IP:192.168.1.193)验证,新增加的数据库用户是否有权限登陆主服务器,且是否具有对备份数据进行想关操作权限。
从库:IP:192.168.1.192
#mysql -h  192.168.1.191 -u kylingood  -p
如果可以连接成功,且能对需要备份数据进行操作,证明用户权限这块已没有问题。
这点很重要,大部分原因同步配置不成功,很可能是用户没有权限造成。

5.把主库表给锁住,并把需要备份的数据分别导入到对应的二个从库.

为了避免风险,新主库mysql现在最好不要对外提供服.同时主库中复制数据到两个从库. 可以直接压缩数据库文件包,并上传到二个从服务器上。
mysql> flush tables with read lock;

6.查看并记录同步的位置,记住File和position的值,在下面同步时会运用到这二个数据。
mysql>show master status;

mysql> show master status;    
+——————+———-+————–+——————+    
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |    
+——————+———-+————–+——————+    
| mysql-bin.000001 98   |              |                  |     
+——————+———-+————–+——————+    
1 row in set (0.00 sec)

B:修改二个从库(IP:192.168.1.192)和(IP:192.168.1.193)配置文件my.cnf

1.分别修改对应的数据库配置文件

#vim /etc/my.cnf
在[mysqld]区域段内加入以下配置:
IP:192.168.1.192
server-id=2        #请注意这个ID唯一性
log-bin=mysql-bin           #记录mysql日志
binlog-do-db=database1  #设置需要同步的数据库,如果有多个数据库,每个数据库一行
binlog-do-db=database2  #再增加一个需要同步的数据库
binlog-ignore-db=mysql   #设置不需要同步的数据库,如果有多个数据库,每个数据库一行

IP:192.168.1.193
server-id=3        #请注意这个ID唯一性
log-bin=mysql-bin           #记录mysql日志
binlog-do-db=database1  #设置需要同步的数据库,如果有多个数据库,每个数据库一行
binlog-do-db=database2  #再增加一个需要同步的数据库
binlog-ignore-db=mysql   #设置不需要同步的数据库,如果有多个数据库,每个数据库一行

此二个配置基本和主库一样,是为了以后如果同步出错,或是主服务器出问题,可以做主从切换,这样网站就可以在短时间内恢复。

2.把主库数据分别导入到对应从服务器的数据库中

3.解锁主库表(IP:192.168.1.191).
mysql>unlock tables;

4.开始设置同步
 设置连接MASTER MASTER_LOG_FILE为主库的File,MASTER_LOG_POS为主库的Position

mysql>slave stop;
mysql> change master to master_host='192.168.1.191',master_user='kylingood', master_password='123456',    
master_log_file=mysql-bin.000001', master_log_pos=98;    
mysql> slave start;  

解释一下:
master_host='主服务器IPod'
master_user='允许连接主库的用户名',
master_password='用户密码',    
master_log_file='主库的File',
master_log_pos='主库的Position';

5.查看主从同步是否配置成功.
下面输出的信息参考说明可以参考观方文档:
http://dev.mysql.com/doc/refman/5.1/zh/replication.html

mysql> show slave status\G;
Slave_IO_Running: Yes(网络正常);
Slave_SQL_Running: Yes(表结构正常),
进一步验证了以上过程的正确性,截图如下(一定要保证这二项参数为YES).

在主MySQL上可输入mysql> show full processlist;
观察其状态,正确结果也应该如截图所示:

6.测试从主数据插入,删除数据操作,再去二个从库查看是否有同步到。如果可以同步,则恭喜您配置主从同步成功。

MySQL主从架构投入生产前后应该注意的事项:

一、配置前,master和slave的hostname一定要取个不同的,免得配置时发生问题;另外,强烈建议ntpdate二台服务器的时间,不然来个未来(feature)时间就麻烦了。

二、由于MySQL数据库走的都是内网,所以二台机器的iptables可以关闭,在配置过程中由于没关iptables发生了错误,直接导致admin在slave数据库上连不上主数据库,这个特指出来给大家借荐 下;

三、主MySQL的binlog功能一定要打开,我们的线上服务器有次由于PHP程序误操作,可以用binlog恢复过来了;但开启此功能要注意binlog的大小。
  
附参考资料:
http://dev.mysql.com/doc/refman/4.1/en/replication.html
http://blog.sina.com.cn/s/blog_4b0710d8010007eo.html
http://www.javaeye.com/topic/153875
http://www.php100.com/html/webkaifa/database/Mysql/2010/1103/6744.html
http://blogold.chinaunix.net/u/27383/showart_542565.html
http://www.blogjava.net/lzj520/archive/2008/02/27/182485.html
 

如何解决Nginx+PHP出现The page you are looking for is temporarily unavailable问题

nginx出现下面错误:

The page you are looking for is temporarily unavailable.
Please try again later.

1.先检查PHP FastCGI进程数是否够用:
netstat -anpo|grep "php-cgi"|wc -l
如果输出为0的话,则表示FastCGI 进程数够大,

2.此时则修改scgi_params文件,找到:
scgi_param SCGI    1;
把它改为:
scgi_param SCGI    5;

3.PHP程序如果的执行时间超过了Nginx的等待时间,就可适当地增加nginx.conf配置文件中FastCGI的timeout时间,例如:
http
{
    ……
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k
    fastcgi_buffers 4 64k
    ……
}

4.重启FastCGI
先杀掉进程:# pkill -9  php-cgi
然后重启:# /usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www -g www -f /usr/local/bin/php-cgi

5.重启Nginx
先杀掉进程:# killall -9 nginx
然后重启:# /usr/local/sbin/nginx

改正我的错误:其实出现上面的错误,并不是FastCGI进程数是否够用问题,而是可能下面这篇文章所提到的原因

原文章:http://zhiwei.li/text/2008/11/nginx%E4%B8%8D%E8%83%BD%E5%A4%84%E7%90%86php%E7%9A%84%E9%97%AE%E9%A2%98/

1)访问任意PHP文件,出现
The page you are looking for is temporarily unavailable.
Please try again later.

2)访问html页面,正常

原因:
nginx 不能正常通过FastCGI结果访问 PHP

1)如果是以tcp socket形式,可能是 进程用户权限设置得不对
spawn-fcgi -a 127.0.0.1 -p 9000 -C 2 -u www-data -g www-data -f /usr/bin/php-cgi
可以改为 www-data 或者 nobody, 重启php-cgi进程

2)如果是unix socket,可能 socket文件权限没有写入能力
srwxrwxr-x  1 gavin gavin    0 11-12 10:18 php-fcgi.sock
为其他用户添加写入能力
chmod o+w php-fcgi.sock

参考文章:
http://wubolu.javaeye.com/blog/514466
http://blog.s135.com/post/361/
https://wiki.archlinux.org/index.php/Nginx
http://www.tetx.com/program/htm/tetx/blog/view/blog_id/1209961017/index.htm

如何使用Sphinx来实现全文检索(搜索)功能

前年(2009)在参与开发CMSTOP系统时,就知道此CMS使用Sphinx实现进行全文检索功能。但那时候自己并没有这功能的开发。不过了解了Sphinx的全文搜索的强大功能。这次,在新的公司,也要做一个全文搜索功能。第一时间就想到了Sphinx来进行功能的实现。

当然在实际上,Sphinx对中文的分词功能并不好。可是很庆幸地是,Coreseek很好地帮我们解决了这一个问题。在这里很感谢此团队为开源事业做出的贡献。Sphinx能得到很多人的认同与用使用,很大一部分功劳和这团队关系。关于此团队更多信息可查看Coreseek首页

下面我就基本地简介一下如何使用Sphinx来实现全文检索功能,当然大部分安装信息都是在Coreseek主站上直接copy下来,因为他们写的实在太详细了。让我没有任何可发挥的地方。

1.下载Sphinx 支持中文分词Coreseek  http://www.coreseek.cn/news/11/52/

2.进行安装:参考http://www.coreseek.cn/products-install/install_on_bsd_linux/
##下载coreseek:coreseek 3.2.14:点击下载、coreseek 4.0.1:点击下载
 

$ wget http://www.coreseek.cn/uploads/csft/3.2/coreseek-3.2.14.tar.gz
$ 或者 http://www.coreseek.cn/uploads/csft/4.0/coreseek-4.0.1-beta.tar.gz
$ tar xzvf coreseek-3.2.14.tar.gz 或者 coreseek-4.0.1-beta.tar.gz
$ cd coreseek-3.2.14 或者 coreseek-4.0.1-beta

##安装mmseg

$ cd mmseg-3.2.14
$ ./bootstrap    #提示中如无error可以不用理会
$ ./configure --prefix=/usr/local/mmseg3
$ make && make install
$ cd ..

##安装coreseek,需提前安装mysql依赖库及操作系统基础开发库以支持mysql数据源和xml数据源

$ cd csft-3.2.14 或者 cd csft-4.0.1
$ sh buildconf.sh    #提示中如无error可以不用理会
$ ./configure --prefix=/usr/local/coreseek  --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/mmseg3/include/mmseg/ 
--with-mmseg-libs=/usr/local/mmseg3/lib/ --with-mysql    ##如果提示mysql问题,可以查看MySQL数据源安装说明
$ make && make install
$ cd ..

##测试mmseg分词,coreseek搜索(需要预先设置好字符集为zh_CN.UTF-8,确保正确显示中文)

$ cd testpack
$ cat var/test/test.xml    #此时应该正确显示中文
$ /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc var/test/test.xml
$ /usr/local/coreseek/bin/indexer -c etc/csft.conf --all

 

3.增加Sphinx增量索引
   
   a.先建立一个计数表

CREATE TABLE sph_counter(
  		counter_id INTEGER PRIMARY KEY NOT NULL,
  		max_doc_id INTEGER NOT NULL
     );

   b.修改sphinx.conf

#主要数据源
      source main
	{
    	type                    = mysql

    	sql_host                = localhost
    	sql_user                = oophp
    	sql_pass                = oophp.cn
    	sql_db                    = oophp
    	sql_port                = 3306
    	sql_query_pre            = SET NAMES utf8
    	sql_query_pre	    =REPLACE INTO sph_counter SELECT 1, MAX(id) FROM dede_archives
    	sql_query                = Select  *  From article where channel=3 AND id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )
                                                              	#sql_query第一列id需为整数
                                                              	#title、content作为字符串/文本字段,被全文索引
    	#sql_attr_uint            =id           #从SQL读取到的值必须为整数
    	#sql_attr_timestamp        =pubdata_attr #从SQL读取到的值必须为整数,作为时间属性

    	sql_query_info_pre      = SET NAMES utf8                                        #命令行查询时,设置正确的字符集
    	sql_query_info = Select * From article WHERE channel=3  AND id=$id
	}

       #增量数据源
	source delta : main
	{
		sql_query_pre =SET NAMES utf8 
        	sql_query = Select * From article  where  channel=3 AND \
	id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )  
	}
    
	#主索引生成
	index main
	{
    	source            = main             #对应的source名称
    	path            = /usr/local/coreseek/data/main/ #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    	docinfo            = extern
    	mlock            = 0
    	morphology        = none
    	min_word_len        = 1
    	html_strip                = 0
    	ngram_len=0
    	#中文分词配置,详情请查看:http://www.coreseek.cn/products-install/coreseek_mmseg/
    	charset_dictpath = /usr/local/mmseg3/etc/   #BSD、Linux环境下设置,/符号结尾
    	#charset_dictpath = etc/                             #Windows环境下设置,/符号结尾,最好给出绝对路径,例如:C:/usr/local/coreseek/etc/...
    	charset_type        = zh_cn.utf-8
    	#charset_type        = utf-8
    	#charset_table        = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
    	#ngram_chars        = U+3000..U+2FA1F

	}
        
       #增量索引
	index delta : main
	{
    		source            = delta             #对应的source名称
    		path            = /usr/local/coreseek/data/delta/ #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
	}
	#全局index定义
	indexer
	{
    		mem_limit            = 128M
	}

	#searchd服务定义
	searchd
	{
    		listen                  =   9312
    		read_timeout        = 5
    		max_children        = 30
    		max_matches            = 1000
    		seamless_rotate        = 0
    		preopen_indexes        = 0
    		unlink_old            = 1
    		pid_file = /var/log/searchd.pid  #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    		log = /var/log/searchd_mysql.log        #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    		query_log = /var/log/query_mysql.log #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    		binlog_path =                                #关闭binlog日志
	}

 

c.启动sphinx服务,并生成主索引

#/usr/local/coreseek/bin/searchd
 # /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf main --rotate

d.建立生成主索引和增量索引shell脚本

build_main_index.sh脚本:
		#!/bin/sh
		#/usr/local/coreseek/bin/searchd --stop
		/usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf main --rotate 
		
build_delta_index.sh脚本:
		#!/bin/sh
		#/usr/local/coreseek/bin/searchd --stop
		/usr/local/coreseek/bin/indexer  -c /usr/local/coreseek/etc/sphinx.conf  delta --rotate
		/usr/local/coreseek/bin/indexer  -c /usr/local/coreseek/etc/sphinx.conf --merge main delta --merge-dst-range deleted 0 0 --rotate 
		#/usr/local/coreseek/bin/searchd

    e.写入cron计划任务中,生成增量索引,并重新建立主索引

//每10分钟生成一次索引
*/10 * * * *  /bin/sh /usr/local/coreseek/build_delta_index.sh >/dev/null 2>&1  
	
//每天凌晨3点过5分,重新建立一次主索引
5 3 * * *  /bin/sh /usr/local/coreseek/build_main_index.sh > /dev/null 2>&1

参考网站:

http://sphinxsearch.com/

http://www.coreseek.cn/

http://www.sphinxsearch.org/archives/category/sphinx

Sphinx增量索引

[转]命令行修改mysql的root密码方法

  开发中,可能会忘记mysql的root密码或是需要修改其密码的情,下面参考看到一篇文章,就把他给转过来了:
方法一:
在/usr/local/mysql/bin/下:
./mysqladmin -u root password ‘new_password’
一般安装时或是忘记root密码的时候,可以用此方法设置。

方法二:
在mysql状态下:
mysql>UPDATE user SET password=PASSWORD(‘new_password’) WHERE user=’root’;
mysql>FLUSH PRIVILEGES;

方法三:
mysql>SET PASSWORD FOR root=PASSWORD(‘new_password’);

初步使用rsync实现网站的镜像备份功能

RSYNC是Linux,UNIX系统下的数据镜像及备份工具,具有可使本地和远程两台主机的文件,目录之间,快速同步镜像,远程数据备份等功能.在同步过程中,可根据远程服务器上的数据变动,相应的删除或者更新本地机的数据,同步数据不用全部传送,大大提高同步及备份文件的速度.同时在网络安全方面,也可以设置为SSH传输模式. 远程主机(Rsync Server)可为RSYNC daemon模式,开启之后将开放tcp4 873 port,等待本地主机(Rsync client)的连接,连接时远程主机会进行认证,确认合法用户进入,便开始进行资料传输,在第一次传输时会把整个资料都备份同步到本地主机上,在下一次传输时,添加相应参数则可根据远程主机的数据变动来相应调整同步操作.
此工具可以在各种系统下运用,并且在功能和效率上都有不错的表现。

1.下载http://rsync.samba.org/  rsync
2.分别安装在对应的服务器上,A主服务器(192.168.1.22),B备份服务器192.168.1.11和C备份服务器192.168.1.38

3.A主服务器安装与配置:
  linux[Centos]: a.#  ./configure   b.#make  c.#make install clean
  FreeBSD:a.#cd /usr/ports/net/rsync   b.#make install clean
 
  a.配置rsyncd.conf
  #vim /etc/rsyncd.conf  加入下面内容
 
    uid = nobody(也可换成root)
    gid = nobody(也可换成root)
    hosts allow = 192.168.1.11,192.168.1.38  (允许进行备份的IP)
    hosts deny = 0.0.0.0/32
    use chroot = no
    max connections = 4  (最大连接数)
    pid file = /var/run/rsyncd.pid 
    lock file = /var/run/rsync.lock 
    log file = /var/log/rsyncd.log  (服务器日志文件)
       
       #其中一个备份目录,可以增加任意个
    [www]
    path = /usr/local/www  (要备份的目录文件)
    ignore errors
    read only = yes
    list = no
    auth users = user_backup    (用于备份的用户名字)
    secrets file = /etc/rsyncd.secrets  (用户名和对应的密码) 

b. 编辑rsyncd.conf
    设定用户和认证密码:user_backup:98765
    更改rsyncd.conf权限:chmod 600  /etc/rsyncd.conf
    
c.设定rsyncd随机启动:
   Linux[CentOS]:  
       编辑/etc/rc.d/rc.local,在最后添加:
       /usr/local/bin/rsync –daemon
       
    FreeBSD:编辑/etc/rc.conf     在最后添加: rsyncd_enable=”YES”

e.启动Rsync daemon模式

    Linux[CentOS]:  /usr/local/bin/rsync –daemon –config=/etc/rsyncd.conf
       
    FreeBSD: /usr/local/bin/rsync –daemon –config=/etc/rsyncd.conf

B与C备份服务器安装客户端

  a.安装:
    linux[Centos]: a.#  ./configure   b.#make  c.#make install clean
    FreeBSD:a.#cd /usr/ports/net/rsync   b.#make install clean
    
  b.配置rsyncd.secrets
     编辑并加入: 98765  //主服务器,设定的认证密码。这里就不需要加用户名了
     更改rsyncd.secrets 权限:chmod 600 rsyncd.secrets
     
   c.测试备份情况:
   输入:# /usr/local/bin/rsync -avzrtopg –delete –exclude "logs/" –exclude "conf/ssl.*/" –progress user_backup@192.168.1.22::www /home/public_html/ –password-file=/etc/rsyncd.secrets
   
   上面语句参数说明:
     这个命令行中-avzrtopg里的a是归档模式,表示以递归方式传输文件,并保持所有文件属性,v是verbose,z是压缩,r是recursive,topg都是保持文件原有属性如属主、时间的参数。– progress是指显示出详细的进度情况,–delete是指如果服务器端删除了这一文件,那么客户端也相应把文件删除,保持真正的一致。– exclude "logs/" 表示不对/www/logs目录下的文件进行备份。–exclude "conf/ssl.*/"表示不对/www/conf/ssl.*/目录下的文件进行备份。
 
      192.168.1.22::www 表示对该命令是对服务器192.168.1.22中的www模块进行备份,user_backup表示使用user_backup用户来对该模块进行备份。

    –password-file=/etc/rsync.pass来指定密码文件,这样就可以在脚本中使用而无需交互式地输入验证密码了,这里需要注意的是这份密码文件权限属性要设得只有root可读。

  这里将备份的内容存放在备份机的 /home/public_html/目录下。
    
  通过计划任务实现定时每周三1:05启动备份功能:
  5 1 * * 3  root  /usr/local/bin/rsync -avzrtopg –delete –exclude "logs/" –exclude "conf/ssl.*/" –progress user_backup@192.168.1.22::www /home/public_html/ –password-file=/etc/rsyncd.secrets
  > /dev/null 2>&1


重启rsyncd.conf
/usr/local/bin/rsync –daemon –config=/etc/rsyncd.conf

//查看进程
ps auxf|grep 'rsync'

参考网址:http://future.blog.51cto.com/26959/83651
http://blogold.chinaunix.net/u/31839/showart_2106203.html
http://blog.chinaunix.net/space.php?uid=20733428&do=blog&cuid=1091174
http://www.twvbb.com/vbb/post/10884/32/