Blog今日更新:图片显示

[| 2010/05/30 01:25]
最近几天在搞博客的图片显示,之前去面试的时候面试官就提出过“你的博客只是一些文字的东西,不能显示图片啊”。不能显示图片确实是个硬伤,是博客功能的一大缺失,今天终于搞完了。顺利实现了图片显示功能。


首先就是考虑图片的存储位置和在表示方式。

某些博客程序把图片放到mysql里,这确实很方便,易于管理。但是效率实在不敢恭维,数据库服务器本来就是系统瓶颈,还把图片都扔进去,无疑加大了数据库服务器的负载。并且也不利于分开部署,所以我决定把图片以文件的格式存放。

然后需要考虑图片在文章中的表示方式。最后展示给用户的时候肯定是html了,但是存储到数据库的时候假如存储成html标签的话既不安全,也对兼容性有影响。所以决定使用UBBCode方法,用“[”代替“<”,在显示时再转换。转换过程很简单,正则表达式即可。

这时又出现了一个问题,就是在首页显示的时候,由于要截取文章的前端部分显示,很有可能将img标签截断,这样影响显示。想了好几天,今天终于找到了一个比较好的方法:先用preg_split把文章按“img标签对”作为分隔符分开,这样其他文字就被分成了几大段,通过判断这些段落的起始位置和结束位置可以很简单的判断是否有“img标签对”跨越分界线。若有,则把分界线左移即可。

实践中还发现另外两个问题,一是正则匹配贪婪性问题,若不配置成非贪婪,那么在有多张图片的时候,会匹配第一个img开始标签和最后一个img结束标签。会导致问题,所以要加上问号设置为非贪婪匹配。问题二是img标签对不成对的问题,有可能文章中为了说明[img]而写了一个,这样的话匹配时会从该[img]开始匹配,直到遇到一个【/img】为止,显然会破坏文章,所以匹配img标签对时正则表达式应写成“以[img]开始,中间是非[img]的任意值,以【/img】结束”,这样可以保证匹配的图片url是正确的。



作为一个网站,首页速度非常重要,假如打开首页的时候加载了一大堆巨大的图片,会严重浪费带宽,也会因为页面打开过慢而造成不好的用户体验,所以我决定在首页显示缩略图,在正文中显示原图。这样就遇到了一个问题,就是在用户上传图片的时候可以自动生成缩略图。由于图片处理是比较耗费资源的,所以我决定使用C语言来做这件事。

OpenCV是一个很好用的图形库,很容易就做了个生成缩略图的小程序出来。在用户上传图片后自动调用该程序生成一个缩略图。不过每次生成缩略图都会调用该程序。进程创建和切换的开销太大,稍后会改装成服务来运行。


由于首页上显示缩略图,所以url和正文的不同,需要做相应修改,这里使用了preg_replace_callback,自己写了回调函数,将url进行相应的转化。


至此,图片功能就实现了。下一步要做的就是优化功能,在显示大图时像其他网站一样,先下载缩略图显示一个模糊的图像,再一点一点下载大图替换成清晰图像等功能。


贴个图,呵呵:
点击在新窗口中浏览此图片

左侧钟表做成iframe的好处

[| 2010/05/25 00:50]
本来是为了方便,所以把左侧的那个表搞成iframe包含进来,今天看了下日志,发现这样做还有其他好处。

由于搜索引擎在爬取网页的时候往往不会将iframe的权重算入当前页面,所以搜索引擎对于爬取iframe内的内容并不热心。这样无实际内容并且包含占用流量的图片的表就不会被搜索引擎们抓取太多。节省了双方流量。降低了服务器的负载。
博客有段时间没有更新了,简陋的界面一直为人所诟病,今天决定加点动态的挂件:时钟和消息框。

消息框前两天做好了,今天主要做钟表。

首先是遇到一个问题:时钟单独作为一个页面显示的时候IE,FF,Chrome均正常。但是用require将代码require进主页面后Chrome和FF无法正常工作,IE中表针形状错误。改来改去,不知道问题到底出在哪里。于是直接用iframe包含钟表的方式。解决了。

然后是时钟刷新问题,怎样控制表针每秒移动一个格呢?两种方法:
一,读取服务器时间,使用setInterval隔1000ms刷一次。
二,读取服务器时间,获取脚本载入时间。求时间差,每次刷新时取得当前系统时间并加上时间差。


首先我用了方法二,这种方法的缺点就是在钟表载入后不能修改系统时间,曾经尝试修改了次,IE随着时间的修改表针也移动了,Chrome在修改后表针照旧走,走半分种后就停住再也不动了。。用Chrome里的JavaScript调试器查看了下,系统时间修改后Chrome里Date方式得到的时间并没有随之改变。这可以解释为什么修改了系统时间表针不做相应移动。但走半分种就停住就不知道为什么了。好在一般没有人天天调时间玩,所以这也不是个问题。

然后又试了试方法一,由于setInterval的问题,间隔1000ms并不精确,使用Chrome和IE进行对比,每隔一分钟两者中的钟表要相差1秒。当然不同机器表现不同。总之这种方法计时是相当不准确的,解决方法就是间隔一段时间向服务器请求新的时间,但这样会增加服务器负载。后来研究了下其他网站的一些倒计时,大多是setInterval,这样的准确度是没有方法二高的,好在这些应用对时间精确度要求不高,有些误差也可以接受。这种方法不依赖于客户机时间,避免了一些兼容性问题和出现诡异结果的可能性。

最后选用了方法二。

把代码整理了下,上传。升级成功

右下角弹框的实现

[| 2010/05/19 00:44]
今天想做个在右下角弹框的功能。

首先找了一些成品。发现居然都不能随着页面的滚动而移动。

解决方法:
一,使用window.scroll事件动态调整位置。缺点:快速滚动页面时明显抖动。故不用。
二,css中position:fixed。但顾及IE6的兼容性,需加:
* html #winpop {position: absolute; top: expression(offsetParent.scrollTop+document.documentElement.clientHeight-this.offsetHeight); }

其中* html规则只对IE有效。

我采用了方法二。完美。

准备设计成如下动作:打开页面时,框自下而上移动上来,停留一段时间,隐藏到只剩标题。鼠标移上,挪出;鼠标离开,隐藏。

刚开始就是很简单的的设计,检测到onMouseOver 就调用挪出函数,检测到onMouseOut就调用隐藏函数。挪出函数(show)和隐藏函数(hide)都用setInterval来实现渐渐移出/隐藏的动态效果。达到移动效果后使用clearInterval结束循环。但是很快发现框发生了颤抖,陷入死循环。

去网上查了下资料,发现JavaScript是单线程运行的,所有系统事件触发的回调函数都放到消息队列中依次执行。这样的话在框上升过程中鼠标移开,那么show和hide同时运行,各自不停的向消息队列插入挪出和隐藏消息。结果框始终不能完全隐藏或完全挪出。于是不停上下颤动。陷入死循环。

解决方法:调用hide函数时首先使用clearInterval结束一下show函数的循环,同理,调用show函数时也结束hide函数的循环。这样就不会产生两循环同时运行的结果了。



总结:JavaScript使用单线程模型固然省去了很多同步互斥问题,但是也影响了其实时性,消息队列的使用使函数从被调用到真正运行存在一定延迟,导致设置同样的延时,不同浏览器上实际延迟时间不同,给用户的体验也不同。Chrome中框的运动速度要明显快于IE8。

scp--依赖于openssh-client

[| 2010/05/13 16:59]
今天想用scp往vps上传点东西,结果告诉我vps上没有装scp,yum search scp,没有靠谱的结果,搜了会,发现scp是依赖于ssh的,所以需要安装openssh的客户端,即openssh-client,然后就有scp了。

注:scp传文件的时候需要客户端和服务器都有scp。否则就会失败
刚才发现脚本出问题了,记录的数据有错位现象,测试了下发现crontab自动运行该脚本时,sar输出的第一列时间是24小时制。而自己命令运行脚本时,sar输出的第一列时间是12小时制。

可见crontab中运行的脚本环境变量和用户直接运行稍有不同,还是要小心

博客状态监控脚本1

[| 2010/05/13 01:52]
今天做了个脚本,5分钟运行一次,记录下当前磁盘使用,网络IO,CPU空闲率,进程总数,运行进程数,还有一些其他数据。
主要使用了sar命令,搭配sed和awk,截取出我想要的数据,然后按指定格式放入日志中。

下一步就是做日志分析器,自动画出相应参数的曲线图。还有就是故障报警。

博客迁移至VPS

[| 2010/05/12 01:24]
昨天花时间做了定期备份功能,每天自动把数据库导出发到gmail里,有了备份就能放心的把博客迁过来了。今天着手开始迁移。

首先先清理VPS,由于农场外挂我用的是php写的,想法是在需要的时候可以通过访问URL来手动收菜,平时用一个脚本跑着周期性的去curl那些php。最近经过使用发现手动收菜也没什么必要,所以把php移动到home目录下,脚本直接用php命令来调用外挂,稍事修改,用getopt来获取传入的参数。

然后把刷邮件的脚本也如法炮制,移动到home下。

现在开始迁移博客程序,比较简单,打包上传后tar解压。

遇到第一个问题:rewrite移植。Apache下rewrite是很方便的,直接用.htaccess就可以实现,nginx不支持.htaccess,所以就要在配置文件里写,在网上找了下相应资料,发现全是抄来抄去的,没有一点新意。只好自己摸索。

把Apache下的rewrite规则修改成nginx格式,发现总是报该页无法显示。以为是放的位置不对,来回挪了好几次,不是404就是500。非常郁闷。

决定看看日志,发现错误日志里写着:[error] 18188#0: *1 rewrite or internal redirection cycle while processing"/var/www/html/index.php"
也就是说陷入了循环中。于是猜想nginx在每次rewrite后都会当做一个新请求来再次按配置文件跑一遍,结果index.php就无限rewrite给自己,陷入循环中。不知道为什么nginx这样设计,效率很低啊。应该是为了实现某种功能而做的妥协吧。

幸好nginx的配置文件里支持if语句,于是用正则表达式判断下,假如已经是index.php了,就不rewrite了。

现在页面可以显示出来了,但是css,js都还无法读取,原来我在Apache下对这些文件夹关闭了rewrite,而nginx无此功能。只能在配置文件中再正则匹配一下,假如访问css,js等文件夹就不rewrite。

现在页面已经显示出来了,遇到一个新问题,PHP报warning说filter_var函数找不到。查了下手册发现原来5.2以后的php才有该函数。而VPS用的Cent软件仓库里是5.1.6的PHP,第一想法是编译个5.2,但是由于VPS内存比较小,而且是OpenVZ的,所以很容易爆内存,恰好在filter_var官方介绍页下有人留言,说他用的也是Cent,自己编译了个filter模块加载进去,解决了此问题。这个方法看起来很有吸引力。

先按他说的装了一些必备的库,下载了filter-0.11.0的源码包,下下来一看傻眼了,没有configure文件。也没有Makefile。不知如何下手,回头看那篇文章,里面提到了phpize,原来这是php自带的命令,是编译php模块时进行一些初始化操作的。果然运行后有了configure。然后就是./configure。然后make。这时报错,说找不到php_pcre.h。我找遍整个根目录都没找到有这个文件,搜了下原来在php源码包里,于是又下了个php5.3的源码包,把里面的php_pcre.h揪出来。然后make通过,make install。完成后去php模块目录下就看到一个filter.so出现了。去php.ini里将该模块加载,重启FastCGI php,刷新页面。成功加载模块。


问题源源不绝,紧接着发现从博客迁移过来的数据出现了乱码,奇怪的是评论正常,博文乱码。用set names utf8、set names latin1均无效,数据库数据类型也符合。所以判断是内容乱码了。仔细查看导出的.sql文件,发现博文正文用的是十六进制导出,而评论则是字符导出。应该是十六进制的转换过程有字符集对不上号的情况发生。把博文用字符导出一遍,再导入,正常了。

一切都准备好后,把域名解析转到VPS的IP上,过了半小时的样子,DNS更新,成功迁移了!

又发现两个小问题,一是农场外挂不工作了,而是博客日志不记录。查看了下外挂错误日志,原来是外挂迁移后没有权限写自己日常日志了。修改了下权限。再一看博客日志也是这个问题。很快修复了。

然后又开了个虚拟主机,开在6000端口,把外挂收菜日志页放在上面。结果发现无法访问,chrome提示:ERR_UNSAFE_PORT 。比较疑惑,搜了下,原来很多病毒之类的爱开6000端口,所以浏览器为了安全起见不允许访问6000端口。汗,第一次知道还有这事。把端口修改到别的端口,可以了。

迁移后下一步就是再做一些服务器的监控脚本,监控并统计服务器运行状态。并开始博客新一轮升级。

淘宝充Paypal

[| 2010/04/22 18:56]
今天打电话去建行,告诉我没收入的大学生不能办信用卡,郁闷,没收入不让办信用卡很正常,我办信用卡也不是去欠钱的。我要用Paypal,人家只支持信用卡。。国内怎么就没有像国外一样的虚拟visa卡呢?前端时间办了个建行虚拟卡,只能算个普通银行卡,没法当信用卡用。只能去万能的淘宝。

淘宝代购倒是很多,但是太麻烦,局限性高还不安全。于是看看有没有Paypal充值的。结果发现结果都被人为删除了。。搜了半天,终于找到一家。按6.95的比例换,还是挺不错的,只比汇率高了一点点,买了20$,支付139人民币。哎,虽然现在人民币升值了,还是不值钱啊,三位数只能换两位数。换位思考一下也不难体会美国人花两位数买中国三位数的东西时的心情。”太便宜了!“

人人农场辅助工具--V1.0版

[| 2010/04/20 23:59]
今天经过同学使用,并根据同学提出的宝贵意见,对辅助工具进行如下更新:

1,增加收菜详细日志,可查看收菜所得果实和经验。
2,日志按日期进行分割,便于定位和查看。
3,收菜时间增加不确定因素,避免太过规律被封号。
4,开放用户日志查看功能,用户可在线查看收菜日志。
5,对工具运行参数进行记录,便于监控异常。
6,对工具结构进行修正,便于增添用户。

分页: 15/21 第一页 上页 10 11 12 13 14 15 16 17 18 19 下页 最后页 [ 显示模式: 摘要 | 列表 ]