这是我计划本周五在部门内分享的内容,先贴到这里:

Redis是一款最近比较热门的Key-value数据库,它的代码量少,配置简单,与memcache同样轻量级,对于了解NoSQL是一个很好的入口,相信通过介绍之后,无论是前端和后端开发工程师,都会迅速的爱上这款软件!

    * Intro:
          o http://dreamhead.blogbus.com/logs/61443218.html
          o http://labs.alcacoop.it/doku.php?id=articles:redis_land
          o http://code.google.com/p/redis/wiki/ProtocolSpecification
          o http://code.google.com/p/redis/wiki/CommandReference

    * Features:
          o Key-value db
          o Fast: all data are loaded in memory and saved on disk
          o Supporting data types: Strings(<1Gb), Lists, Hashes, Sets, Ordered sets.
          o Interfaces: push/pop、add/remove、sort
          o Replication:
                + 一个master支持多个slave
                + Slave可以接受其他slave的连接来替代他连接master
                + 复制在master是非阻塞的,而在slave是阻塞的
                + 复制被利用来提供可扩展性,在slave端只提供查询功能及数据的冗余

    * Download:
          o http://code.google.com/p/redis/

    * Install:
          o http://blog.chinaunix.net/u3/102568/showart_2339142.html

    * Start Server: ./redis-server
    * Close Server: ./redis-cli shutdown
    * Command Line Client: ./redis-cli
    * Bindings: http://code.google.com/p/redis/#Supported_languages
    * APIs: http://code.google.com/p/redis/wiki/CommandReference
    * Best Practices:
          o Counter
          o message queue
          o user db
          o Autocomplete: http://antirez.com/post/autocomplete-with-redis.html
          o Foursquare.com

  我们每天都接触到大量的信息,必须要有一个沉淀的机制使其转化为知识,否则在重新利用它们的时候,会消耗不必要的时间。下面我将自己管理知识的方法整理出来,供读者参考。

管理要做的事
  最快捷的方式是在桌面上新建记事本;如果你需要用复杂的格式记录它们,建议用onenote;如果你的手机是IPhone、Android、Blackberry系列的,那么恭喜你,还可以使用evernote将你的文件随身携带;不要忘记,小纸条也是很灵活的方式。
管理你的文档
  首先要保证你辛苦编写的文档不丢失,为此,我向你推荐几款工具:如果你有自己的备份空间,如FTP、共享文件夹等等,建议使用syncback,它会将你的文档目录与服务器端进行双向同步,显然也没有空间和网速的制约;你还可以用前面提到的evernote或微软的live mesh来进行同步,它们都为我们提供了若干G的共享存储空间。
  其次要保证你的文档能被随时找到,我强烈向你推荐Google桌面搜索,它通过为你电脑上的文件编制索引,方便你对其进行查找;另外,不建议使用微软自己提供的windows search,我的Thinkpad X201笔记本,只要启动了它的索引服务,CPU温度就会从正常的45度左右,飙升到80度以上,为了节能和CPU长寿,只得卸载之,而Google桌面搜索就没这方面的问题了。
管理下载的文档
  下载的文档特指电影、音乐等尺寸较大大的文件,如果不幸丢失,经济损失尚小,而备份它们的成本却最高。笔者目前也没有想到一劳永逸的办法,毕竟自己花钱购置硬件,总有一个寿命问题。相比较来说,买一块硬盘,加个硬盘盒,是比较经济的存储方式。
管理你的电脑
  如果电脑某天不幸需要重装,你便需要手忙脚乱的备份一大堆存放在C盘中的数据,如果平时就将你的数据打理的井井有条,就可以避免这一麻烦。现有几个小办法向读者提供:使用驱动备份专家之类的软件将你的驱动程序备份到别处,如果先前购置的硬件中有驱动光盘,建议将整张光盘做成ISO镜像存放在硬盘上;打开“我的文档”的属性窗口,修改文档路径为C盘以外的某个目录并转移;使用类似Firefox Sync的工具同步或备份你的浏览器书签等数据。

  相信大家也有许多自己的经验,欢迎到新浪微博(@房如华bluetent)上与我交流,谢谢。

  在linux环境下,使用ssh客户端进行开发的朋友们可能经常会被不稳定的网络环境所困扰:在掉线后,很多中断的脚本要重跑,目录要重进;vi会自动生成一些swap文件,甚至在recover后仍然存在,给操作带来了不便;若同时打开多个终端,损失就更大了。
  这里推荐一个简单的解决办法:

  1. 在linux服务器上安装一个叫screen的软件。
  2. 使用ssh客户端,用正常的方式远程连上服务器。
  3. 输入screen,此时你看到的终端画面已经被screen接管了。它同时保存了终端现场,从而使恢复现场成为可能。
  4. 此后进行正常的操作,终端界面的状态会被screen实时保存。在任何时候按Ctrl+a+d,都会从screen模式退回(Detach)到伪终端。输入screen -ls,可以看到被挂起的screen列表。再输入screen -r ,即可回到刚才的screen窗口。当然即使异常掉线了,重新登陆后,还是可以使用screen -r恢复现场的,这就是我们使用它的意义所在。
  5. 可以在.bash_profile里加一行
    alias r='screen -d `screen -ls |grep Attached|cut -f2|cut -f1 -d"."`;screen -r `screen -ls |grep Detached|cut -f2|cut -f1 -d"."`'
    能够方便的切回screen窗口(假设只开了一个screen)。

  日历是很多软件和在线产品中都具有的功能,通过对日历中事件和任务的管理,可以有效的组织工作和生活中的各项活动。由于人们的活动地点会不断迁移(如公司到家),管理日历的媒介会不断变化(Outlook、Sunbird、手机),那么日历数据就会分散到不同的媒介中,不方便管理。针对上述问题,本文提供了一套解决方案,将不同媒介中的日历数据,以符合iCanlendar标准的格式与google calendar进行数据同步,使得每种媒介上都保持最新的信息。 Read the rest of this entry »

  当javascript语句向服务器端发起ajax请求后,如果一切顺利,会从服务器端收到响应数据,浏览器会把这个响应字符串转交给回调函数处理。按我的经验,响应字符串有两种比较好的形式,一种是json,一种是html。下面以php5+smarty服务端开发模式为例作简要介绍:

  1. json方式:
    服务端对请求数据作如下处理:

    $param1 = $_POST["param1"];
    $result_array = foo($param1);
    $json_array = json_encode($result_array);
    echo($json_array);
    

    那么函数foo的返回值就以json数组的形式返回给客户端,这时直接用eval的方法将返回值赋给某个javascript变量就可以使用了。

  2. html方式:
    服务端对请求数据作如下处理:

    $param1 = $_POST["param1"];
    $result_array = foo($param1);
    $tpl = new Smarty();
    $tpl->assign("result", $result_array);
    $html = $tpl->fetch("foo1.html");
    echo($html);
    

    那么函数foo的返回值会被assign到一个smarty模板里,通过smarty的fetch方法,获得一段html代码,这时直接把html代码赋给某个div的innerHTML属性就可以了。

  第一种方式遵循了清晰的MVC结构。由于javascript还需处理返回的数组,所以适合响应数组比较简单的情况,不适合大段html代码的渲染。第二种方式将模板和JS、PHP进行了良好的分离,便于维护。由于html变化后,页面的dom结构也发生变化,所以适合大段html代码的渲染,不适合交互复杂的类C/S页面。

  最近打算在产品中使用extjs。考虑到这是一个线上环境,对javascript的要求比较高,因而计划对它进行裁剪和压缩,分以下几步进行:

  1. 使用extjs提供的在线裁剪工具(Build your own Ext)对庞大的extjs库进行定制。我定制了三种不同量级的版本,基本可以满足日常各种需要了。
  2. 使用JSA对裁剪后的代码进行语法压缩和文本压缩,其语法压缩具有极高的可靠性,文本压缩的比率也较高。
  3. 激活apache 2的mod_deflate模块,并启用对javascript的压缩。

  经过以上三步优化后,extjs的尺寸被缩减到了一个可以接受的数值了。具体效果参见下表:

支持的模块 原始版本尺寸 被JSA处理后版本尺寸 原始版本经deflate压缩后尺寸 JSA版本经deflate压缩后尺寸
jQuery
Ext Core
Core-Utilities
Data
Views
140369 77957 (55.5%) 41233 (29.4%) 36225 (25.8%)
在前一个基础上增加:
Core-Layers
Dialog
Form
QuickTips-Tooltip Widget
Loading Mask Widget
303172 164433 (54.2%) 85097 (28.1%) 73920 (24.4%)
在前一个基础上增加:
Core-Drag and Drop
DateMenu
ColorMenu
Resizable
Button Widget
Tabs Widget
SplitBar Widget
Menu Widget
Border Layout Widget
Toolbar Widget
Grid
Tree
Form-HtmlEditor
499490 261616 (52.4%) 133973 (26.8%) 114157 (22.9%)

可以看出:JSA的压缩比率接近一半;不过,无论代码是否被JSA压缩过,经mod_deflate模块处理后的大小都是比较接近的,也就是说,在服务器端开启gzip/deflate特性是非常必要的。

  在Drupal4.5中有一个非常有用的功能--“分类列表”,它会显示站点的所有分类,以及分类中node的个数和上次更新时间。但不知何故,4.6中去掉了这一特性,我们在设置block的时候找不到分类这个条目了。
  解决方法是这样:找到Drupal 4.5版本modules/taxonomy.module文件中的taxonomy_block函数,拷贝至4.6版本的同一位置下即可。这时block设置界面就会自动多出一个分类的条目,激活便能使用了。

  上班迟到要扣钱,一个简单的分段函数是无法达到很强的约束力的。于是我设计了一个略微复杂的函数,供地球上的HR参考。
  S = S0 + dTA1+ρn/N
  各参数代表的意义如下:
  S0:金额基数,即最低罚款额。
  d:比例系数。
  n:在该人到达公司前,当天公司已经迟到的总人数(人)。
  N:当天公司共需签到的总人数(人)。
  A:金额基数(元),可以为一个与T相关的函数。
  T:该人当天迟到的时间(分钟)。
  ρ:比例系数,用于调整N对S的影响。
  简述:某个人迟到需缴纳的罚款,跟当天迟到的分钟数线性相关。随着迟到人数占公司总人数的比例不断增加,罚款数额也会增加。
  这个函数将会起到如下作用:T对S的约束会促使员工无论迟到了多久,都要尽快到达公司,否则罚款是随时间不断上涨的。n对S的约束会促使员工尽量早到公司,否则总会比前一位同事多交罚款,并且客观上会降低迟到员工的总数。

  1. 在浏览器输入www.passport.com,然后点击登录链接。
    进入这个页面:

    https://login.passport.com/ppsecure/secure.srf?…

    页面的form中只有一个叫做mspppostint的参数,长度745字节,怀疑为服务器生成的base64格式的密钥,用于验证login.passport.com跳到login.passport.net的合法性。如果是这样的话,那么这两台服务器应该共同约定一个双向加密算法,分别对mspppostint进行加密解密。

  2. 上述页面自动发送post请求到这个页面:

    https://login.passport.net/ppsecure/uisecure.srf?…

    好了,用户可以输入用户名和密码登录。
    在这个页面的form的action里,我看到url的domain是login.passport.com,另有两个参数是rn = IHL*ZsXU 和 tpf = b903d408b520d9c7914a4d39d46e948a,怀疑也是用于验证login.passport.net到login.passport.com的合法性。

  3. 登录成功后,页面跳转到https://accountservices.msn.com/default.srf?…
    从login.passport.net是如何跳到accountservices.msn.com的,我还没有弄明白,这关键一步请大家帮忙指点。
function x()
{
	var a=null;
	try
	{
		a=new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch(c)
	{
		try
		{
			a=new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(b)
		{
			a=null;
		}
	}
	if(!a&&typeof XMLHttpRequest!="undefined")
	{
		a=new XMLHttpRequest();
	}
	return a;
}

  这个实例化方法至少支持IE、Firefox、Opera和Safari,它的一大特色是用了try…catch…,而不是经常用的if…else…,这种方式是比较稳妥和有效的。

  最近在同事的带动下,决定把工作时的操作系统换成Linux。
  我原先之所以不用Linux,是对Gnome的桌面缺乏足够的信心,对KDE又极度不爽。但自从看了cxa大师装上slackware + dropline X后,对dropline基于Gnome的X界面惊叹不已,便把自己20G的笔记本硬盘掰下一小块,装上了Slackware Linux。
  安装过程时而晴空万里,时而倾盆大雨,Linux就是在成功和失败的交织中让人学会玩味生活,所以才获得了全世界电脑爱好者的追捧,再次证实很多人是在自虐中寻求快感的。
  好了言归正传,先做些准备工作,比如用PQMagic分区,下载slackware安装包等等。随后装Grub for dos,修改boot.ini,重启后用Grub引导安装即可。
  Dropline的确很强大,它能够帮你妥善管理包括Firefox和Thunderbird在内的很多软件包,并在有软件更新的时候向你发出提示信息。我挑选了跟我平时工作紧密相关的软件包,放在开始菜单的toolbar里,基本可以完成平日所有的工作了,他们是:网页浏览器Mozilla Firefox,字处理软件Open Office,邮件客户端Mozilla Thunderbird,支持Jabber协议的聊天工具Gaim,SSH终端Teminal(打算换成putty),Web开发工具Bluefish,以及一个RSS阅读器Liferea。
  安装过程并不是一帆风顺,比如装USB的外接鼠标就出现了很多麻烦,现在工作起来也不很正常,再慢慢研究。SCIM装上了很久才能成功的使用,问题出在没有更新gtk的module列表,以及LOCALE设置有误。连安装zhcon的时候,系统也给我惹了不少麻烦,最后在同事的大力帮助下,在src/debug.h里加上一行#include<assert .h>才算了事。我白用g++ 3.3.5来伺候它了,或许2.9.5更爽些?
  虽然Dropline的后续开发脚步骤然停止,Slackware也宣称今后将更多支持KDE的桌面环境,但我还是很喜欢现在的样子,因为它很适合我的需求,多一分则乱,少一分则空。在我PIII 800的本子上跑的比较流畅,能够更便利的与其它UNIX/Linux服务器进行交互。我不确定它是不是最好的发行版之一,但我还是决定把它留下来当我的助手。

  首先我们做个测试:
  写一段JS提交一个表单:

theForm.action=”test.php?id=1″;
theForm.submit();

  在test.php里打印来路页面:

die($_SERVER["HTTP_REFERER"]);

  然后分别在Firefox和IE里面查看test.php页面,发现均显示test.php。
  接下来,将上述JS更换为:

location.href=”test.php?id=1″;

  即改用GET方式提交表单。然后再次查看test.php页面,会发现Firefox仍然显示test.php,而IE显示空白。
  这说明IE并不将location.href属性的更改视为一次点击链接的过程。

  一台操作系统为fedora的服务器,在安装时设定的时区是EST,为了便于awstats的日志统计,现欲将系统时区调整为CST(中国标准时间),并使apache服务应用该设置。
  第一步是修改系统时区。方法是多种多样的,比如tzselect,比如ln -s /etc/localtime /usr/share/zoneinfo/yourregion/yourcity,等等。
  第二步是使apache使用新的时区。通常的思路是/path/to/apache/sbin/apachectl restart,但是我尝试了几次都失败了,我便以为系统的硬件时钟也需要调整,于是又走了许多弯路。后来我突然想到一个例子,就是当我们未正确设置servername时,restart不显示任何信息,而start会提示”Could not determine the server’s fully
qualified domain name…”之类的提示信息,我于是推断restart并不等于stop+start。为了证实这个思路,我stop了apache服务,然后start,从日志记录中看到,新的时区设置已被应用到apache中。

  通常,我们需要在Linux环境下手写iptables/ipchains规则,并设置为每次启动时运行。由于技术水平等因素制约,规则的内容并不全面,效率也不够高。
  现在有了Easy Firewall Generator,事情就变得简单多了。它是一个用PHP语言编写的程序,用户向其提交一些参数,就可以获得一套防火墙规则,拷贝下来就可以使用了。
  我们可以从EFG提供的方案中学到很多东西,例如:每条链最末一条规则的action都是RETURN,这样当数据包不符合先前规则时,就可以提前退出,而不再试图匹配后面的规则,提高了整体性能。
  关于Easy Firewall Generator使用的几点技巧:我们配置防火墙,通常是先关掉所有端口,再开放一系列端口,但在EFG的参数设置里,只能输入一个端口,怎么办呢?我们可以这样做:选中“Allow Inbound Services”并提交,然后输入一个端口,例如110,再提交,在获取的规则中查找110字符串,按照所在行的规则续写就可以了。另外,如果想使用我们稍后提到的fireparse工具,还需要将“Log entries in a Fireparse format”选中。
  接下来我们开始使用fireparse。fireparse是一个用perl语言编写的日志解析程序,更确切的讲,它是ADMLogger的一个重要的插件;它还会将分析结果寄至管理员的邮箱,便于快速反应和维护。
  fireparse的安装方法如下:
  首先到aaron.marasco.com下载ADMLogger(已经内含parser插件)。
  然后仔细阅读doc/README.ADMLogger。尤其是搞懂第三步:mailfirst一定要加上;如果parse日志已经设置为按日期保存(强烈推荐),则不必拷贝那个轮转文件了。最后执行一下 /var/adm/logger/logger.pl,在确认无误后,即可放入cron文件自动运行。

  今天分别在异域桃源BBS和我公司的网站渤海易网上安装了Awstats。它是一个Perl编写的,基于Web服务器日志的异常强大的网站访问统计系统,使用它可以非常准确的得到各个时段的访问量及汇总,横向、纵向的数据比较,来路页面,对搜索引擎的友好程度,用户地理来源,甚至死链接。
  先折腾异域桃源。异域桃源BBS的服务器是Linux系统的,默认安装了Perl,我到http://sourceforge.net/projects/awstats/ 上下载了Awstats的最新版本,解压,然后将里面的wwwroot/cgi-bin拷贝到apache的cgi目录下,再将wwwroot/icon目录拷贝到www页根目录下。接下来是对配置文件的改动了。将awstats.model.conf保存为awstats.yyty.conf,修改LogFile和SiteName的值,执行awstats.pl -update -config=yyty 即可对日志进行分析(不妨将这句加入crontab定时运行)。在浏览器地址栏内输入http://yyty.org/awstats/awstats.pl?config=yyty 就能够看到截至日志分析时刻的统计结果了。awstats的配置文件很长,尤其在中后部分有一些细节的配置,以及插件的选择,不妨尝试一下,很多遇到的问题可以在配置里找到解决办法。
  有了第一次架设经验,在公司网站服务器上做就很踏实了。渤海易网的服务是架设在IIS上的,基本安装过程与Linux下是相似的。首先,到http://activestate.com/Products/ActivePerl/ 去下载ActivePerl用于解释Perl。其次,我们需要自行设定一个方便Awstats解析的日志格式:打开IIS配置窗口,选择“W3C扩充扩展日志文件格式”,仅仅选中以下各项:date,time,c-ip,cs-username,cs-method,cs-uri-stem,cs-uri-query,sc-status,sc-bytes,cs-version,cs(User-Agent),cs(Referer),保存设置,关闭IIS服务,将服务器上已有日志妥善转移到别处,然后启动IIS服务。接下来配置Awstats的配置文件,将LogFormat设定为”date time c-ip cs-username cs-method cs-uri-stem cs-uri-query
sc-status sc-bytes cs-version cs(User-Agent) cs(Referer)”。此后步骤同Linux部分。如果查看统计结果时发现数据时间统一向后错位了8个小时怎么办?不要着急,仔细在配置文件里找答案,有个叫做timezone的插件可以解决这个问题。加上timezone +8即可。但加载此模块会降低Awstats40%的性能,需三思,更高级改动方法详见 http://www.chedong.com/tech/awstats.html 。
  观看统计结果是件非常有成就感的事情,尤其是观看渤海易网的各项指标时。通过对网站关键字的分析,以及各类搜索爬虫路过的痕迹,我们能够在网站优化和安全控制方面更有的放矢的开展工作;观察错误日志,我们甚至发现了几处死链接。总之,统计的目的就是让人们对一件事物有宏观的把握,并能发现和改善微观矛盾,促进其进一步发展。