ubuntu11.10下修改tooltip的颜色
0ubuntu11.10没有了自定义修改主题颜色的界面,导致eclipse里面的弹出框颜色无法直接修改。默认如下一坨黑什么也看不见:
在ubuntu11.10之前可以通过:系统设置-》外观-》修改主题里面的tooltip自定义颜色来实现。但11.10下面没有这个UI了,只能直接修改文件:
找到/usr/share/themes/Ambiance/gtk-2.0/gtkrc,打开编辑,第一行,其中四个属性最关键:
tooltip_fg_color:提示框前景色
tooltip_bg_color:提示框背景色
selected_fg_color:选中前景色
selected_bg_color:选中背景色
修改四个,然后在系统设置里面的外观改换下主题再换回来就可以生效了,如下图:
Mysql的filesort
0网上有不少关于filesort的文章,有更多的文章是关于文档对于filesort翻译的吐槽。
Using filesort
MySQL must do an extra pass to find out how to retrieve the rows in sorted order. The sort is done by going through all rows according to the join type and storing the sort key and pointer to the row for all rows that match the WHERE clause. The keys then are sorted and the rows are retrieved in sorted order.
意思是指mysql要在内存中对符合条件的记录集进行一次额外的排序。
先看表结构:
CREATE TABLE `TimelineEvent` (
`id` bigint(20) NOT NULL DEFAULT ’0′,
`PublishTime` bigint(20) DEFAULT NULL,
`EventType` tinyint(4) NOT NULL DEFAULT ’0′,
`SubType` bigint(20) DEFAULT ’0′,
KEY `PublishTime` (`PublishTime`,`EventType`,`SubType`),
KEY `EventType` (`EventType`,`SubType`,`PublishTime`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk
很多时候我们有这样的查询需求:
mysql> desc select * from TimelineEvent FORCE INDEX(EventType) where EventType in (1,2) and SubType=2 order by PublishTime desc limit 10;
+—-+————-+—————+——-+—————+———–+———+——+——+—————————–+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————+——-+—————+———–+———+——+——+—————————–+
| 1 | SIMPLE | TimelineEvent | range | EventType | EventType | 10 | NULL | 2 | Using where; Using filesort |
+—-+————-+—————+——-+—————+———–+———+——+——+—————————–+
1 row in set (0.00 sec)
mysql> desc select * from TimelineEvent FORCE INDEX(EventType) where EventType>3 and SubType=2 order by PublishTime desc limit 10;
+—-+————-+—————+——-+—————+———–+———+——+——-+—————————–+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————+——-+—————+———–+———+——+——-+—————————–+
| 1 | SIMPLE | TimelineEvent | range | EventType | EventType | 1 | NULL | 65715 | Using where; Using filesort |
+—-+————-+—————+——-+—————+———–+———+——+——-+—————————–+
1 row in set (0.00 sec)
当索引的前缀列(比如这里的EventType)是在做range查询的时候,并不能使用到最后一列索引PublishTime进行排序,desc查看的时候出现filesort。
mysql> desc select * from TimelineEvent FORCE INDEX(EventType) where EventType=3 and SubType=2 order by PublishTime desc limit 10;
+—-+————-+—————+——+—————+———–+———+————-+——+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————+——+—————+———–+———+————-+——+————-+
| 1 | SIMPLE | TimelineEvent | ref | EventType | EventType | 10 | const,const | 1 | Using where |
+—-+————-+—————+——+—————+———–+———+————-+——+————-+
1 row in set (0.00 sec)
使用=查询是非常完美的。
当符合where条件的数据量比较小的时候,filesort排序没有什么问题。但当符合where条件的数据量特别大的时候,使用filesort进行几万甚至几十万的记录排序效率比较低,每个线程都比较占用内存而且容易阻塞,而且结果往往只是取排序后的其中几十条,大数据量排序很浪费。
改进思路就是采用上述表的PublishTime索引:
mysql> desc select * from TimelineEvent FORCE INDEX(PublishTime) where EventType>=3 and SubType=2 order by PublishTime desc limit 10;
+—-+————-+—————+——-+—————+————-+———+——+——+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————+——-+—————+————-+———+——+——+————-+
| 1 | SIMPLE | TimelineEvent | index | NULL | PublishTime | 19 | NULL | 10 | Using where |
+—-+————-+—————+——-+—————+————-+———+——+——+————-+
1 row in set (0.00 sec)
虽然没有了filesort,但我们发现索引的使用情况,type是index。以下是摘自官方文档,对于type是range和index的解释:
Only rows that are in a given range are retrieved, using an index to select the rows. The key column in the output row indicates which index is used. The key_len contains the longest key part that was used. The ref column is NULL for this type.
This join type is the same as ALL, except that only the index tree is scanned. This usually is faster than ALL because the index file usually is smaller than the data file.
MySQL can use this join type when the query uses only columns that are part of a single index.
index这种type按照官方解释接近于all的检索速度,区别在于前者是遍历索引要稍微快一些。而range的话则是返回符合区间条件的记录。这里加入一个无用条件:publishtime>=0(本例中publishtime肯定大于等于0)可以看到变化:
mysql> desc select * from TimelineEvent FORCE INDEX(PublishTime) where EventType>=3 and SubType=2 and publishtime>=0 order by PublishTime desc limit 10;
+—-+————-+—————+——-+—————+————-+———+——+——+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————+——-+—————+————-+———+——+——+————-+
| 1 | SIMPLE | TimelineEvent | range | PublishTime | PublishTime | 19 | NULL | 1 | Using where |
+—-+————-+—————+——-+—————+————-+———+——+——+————-+
1 row in set (0.00 sec)
这个条件的加入对于这个例子检索速度应该是没有影响的,只是告诉desc代码增加了一个检索条件,因为理论上是存在publishTime<0的情况,只是我们的应用不存在而已。
这里还有个问题不知道大家能不能解释,>和>=有区别,表现在key_len上,也就是说>=可以使用到3列索引,而>只用到了EventType一列索引。
mysql> desc select * from TimelineEvent FORCE INDEX(EventType) where EventType>=3 and SubType=2 and publishtime=344 order by PublishTime desc limit 10;
+—-+————-+—————+——-+—————+———–+———+——+——-+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————+——-+—————+———–+———+——+——-+————-+
| 1 | SIMPLE | TimelineEvent | range | EventType | EventType | 19 | NULL | 65715 | Using where |
+—-+————-+—————+——-+—————+———–+———+——+——-+————-+
1 row in set (0.00 sec)
mysql> desc select * from TimelineEvent FORCE INDEX(EventType) where EventType>3 and SubType=2 and publishtime=344 order by PublishTime desc limit 10;
+—-+————-+—————+——-+—————+———–+———+——+——-+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+—————+——-+—————+———–+———+——+——-+————-+
| 1 | SIMPLE | TimelineEvent | range | EventType | EventType | 1 | NULL | 65715 | Using where |
+—-+————-+—————+——-+—————+———–+———+——+——-+————-+
1 row in set (0.00 sec)
sshtunnel+nginx实现android手机翻墙实战
7自己尝试成功了就记录下。
原理是这样的:
android手机上面给网络连接设置本地代理,本地代理服务器收到请求后通过ssh隧道转发到远程服务器,这种ssh本地转发到远程服务器后会请求服务器上的指定远程端口,而这个端口才是真正的代理,它去请求真正的目标服务器,获取到数据后逆着一步步返回。
需要的工具:
1.国外服务器一个ssh账号,并且可以安装nginx等web server(比如还可以用squid)用于代理。
2.sshtunnel,点击这里下载。
3.当然还要一部android手机。
首先在手机上安装sshtunnel,然后运行进行设置:
主机地址,端口,用户名和密码都是ssh设置。
本地端口是指android手机上的应用使用本机的这个端口作为代理,让sshtunnel帮忙转发到远程ssh服务器。
远程端口是指远程ssh服务器收到ssh隧道转发的数据后再使用远程端口那个作为代理进行请求。这里有人可能会有疑问:为什么本机不能直接指定ssh服务器上面的这个远程端口作为代理呢?这里有两个原因:
1.我的ssh服务器上安装的ngnix只能从本地进行连接,所以先通过ssh转发到服务器上再进行请求。
2.通过ssh转发来进行加密。
设置完成后,启动sshtunnel后台服务。然后到设置->无线和网络->代理设置里面设置代理为:127.0.0.1:本地端口。如下图:
接下去在服务器端安装ngnix,在配置文件里面http节点里面加入如下行:
resolver 8.8.8.8;#dns服务器设置
server
{
listen localhost:60000;#监听端口,就是sshtunnel里面设置的远程端口
location /
{
proxy_pass http://$http_host$request_uri;#代理设置
}
}
可惜的是本人服务器不是vps,不支持443端口的绑定,因此无法继续尝试https的转发,有经验的同学欢迎指点。
有关ssh转发的文章可参考:
https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/ 实战ssh端口转发
写代码的意识
0不得不承认,写代码和打dota一样也是需要非常意识,“风骚的走位,淫荡的意识”,引用过来就是讲写代码的时候,需要有一定的前瞻性,意识到这段代码可能存在的潜在问题。因为在你当初写下这段代码的时候,你根本无法预料到在以后的维护过程中会发生怎样的改变,你所能做的就是尽量考虑可能的情况,然后给代码加上防范,我越发觉得这个意识很重要。有以下两个例子为证。
例子1:
- def func_a(self):
- user_info = get_user_by_roleid(roleid)
- if len(user_info) != 0:
- if user_info[0]["status"] != setting.USER_ENABLED:
- self.error_page("对不起,该角色已经被禁用!")
- return None
- elif user_info[0]["urs"].lower() != self._urs.lower():
- self.error_page("该角色暂时不允许登录");
- return None
- else:
- set_last_visit_time(role_id)
- else:
- self.error_page("内部错误,请联系管理员")
- return None
上述代码中使用函数:get_user_by_roleid获取到用户信息后,假如能获取到也就是进入第一个if条件,然后再通过一个if判断是否ok,其中除了判断是否被禁用,elif这句其实看起来有点多余,判断下从数据库里获取到的账户名和当前账户名是否一致,这里就是重点了,也是很容易忽略的地方。因为我们是通过传入roleid来获取到用户信息的,而不是通过传入账户名,在一般情况下这个检查可有可无,因为roleid和账户是一一对应的,都是unique key,但是这句代码的检查却很有意识了阻止了后期维护中可能犯的一个错误:假如有一天账户名需要修改,比如统一加上@163.com这个后缀,而因为一些维护的问题,导致用户传入的账户名是不带后缀的,但是数据库维护后里面的账户名是已经带后缀了(后期维护出现啥问题谁也无法预料),如果没有这句elif判断则这个用户显然可以通过这段代码登录成功,后续操作就不堪设想。而现在在执行到这段代码的时候,加上elif判断就可以有效阻止用户登录成功进行后续操作,从而避免了一系列连锁问题。
这里的len(user_info) != 0这句判断也值得商榷,我们期望返回的数目肯定是1,而不是!=0也不是=2,所以哪天要是roleid不是unique key了,这个判断也是可能会有问题的。
例子2:
在写易推的时候,报错最多的就是NullPointerException,究其原因就是缺少了判断,很多时候想当然的认为这个函数不会返回Null,但实际用户运行环境复杂,总是出乎你意料,程序就这样崩溃了,不友好了,只能怪自己。
所以写代码多检查,准没错。写代码意识很重要;)
for year in (2010,2011): if year == 2010:save elif year == 2011:sail
0拷贝了黄海均同学的年度总结格式,我也来山寨一篇:
年度电子产品:
- htc G3:应该是三月份买的,之后开发了网易微博Android客户端,功不可没。
- ipad:一开始沉迷于游戏,后来完全沦为睡前看优酷新闻的视频播放器,等ipad2出来就没法装13了。
- Teclast TL-C500:一款支持全高清播放的mp4,没有ipad的时候拿来看电影不错,现在用来放床头听歌,因为暂缺mp3。
年度旅游:
- 6月份去了肇庆市鼎湖山游玩,公司组织,我喜欢爬山,喜欢在半山腰山顶上小憩。点这里查看
- 7月份去了西藏,那是一个神圣的,洗涤心灵的地方,和太阳距离最近的高原,一旦过去就会迷恋上那里的一切,此生无悔。点这里查看
- 中秋节骑车往返广州-中山,纯属一时冲动,不过开始慢慢喜欢上了这项运动,全程100公里,历时6个小时。点这里查看
- 国庆节独自一个人游玩桂林阳朔,连绵的山林,别样的西街,到现在我都回味无穷。桂林山水甲天下,阳朔山水甲桂林。点这里查看
- 11月份陪着同学终于游玩了一遍广州市,但凡想的到的能玩的都去了。点这里查看
- 12月31号去深圳和大学室友聚会,在一起的时候我们很开心,一生有你。点这里查看
年度作品:
- 易推:网易微博Android平台下的一个客户端,收获良多,认识了很多朋友,在此非常感谢网易微博,感谢支持这个软件的朋友,感谢郭嘉。传送门
- 微享:一个快速分享网页文字,图片到四大门户微博的firefox插件,写着玩的,点子不错就写了,大家反映也可以。传送门
- 藏宝阁:又是一年的维护,系统的稳定是对我工作的最大肯定。传送门
- 音乐点播:一个你看不到的系统,慢慢也开始给公司带来收益。
年度生活:
- 和恋爱三年多的女友分手,我不想和她结婚,我是流氓。
- 看了N场电影,写了N篇影评,我把影评挪到QQ空间来了,在此对各位想抄影评的小朋友说声抱歉。
- 买了ipad没买过软件,我对不起开发者,对不起正版事业(其实上一条看电影也算支持正版事业了)。
- 有段时间写易推经常写到晚上12点,玩ipad经常玩到晚上2,3点,我对不起自己这张脸,长了好多痘痘都快毁容了,难怪同学都说我老成了。。。
- 好像没丢过东西,倒中了几次奖。
2011年,还是努力提升自己,保持进步,扩大影响力,争取更上一层楼;)
腾讯大讲堂之我见
0《腾讯大讲堂》事件闹得沸沸扬扬,据传是内部员工不甚泄露,导致内部培训文档流传出来,更传该员工已被处理,接下去各大门户纷纷删除,而仅存twitter上讨论火热,本人也是马不停蹄第一时间下到184M版本,听说讲稿还有涉及内部机密,第一时间阅读学习。
184M的《腾讯大讲堂》包含50多篇内部PPT讲稿。首先可以肯定腾讯内部有一种知识积累机制,可能很多公司都有,但是能完整的把每次分享都保存下来并形成一种形式的估计不多(曾也听说某某公司每次分享都会留视频和录音文件)。这种方式的积累好处不言而喻,可以给后来的新人提供快捷完善的学习培训。
50多篇的讲稿涉及的面也比较广,从web前后端到游戏,再到视频再到营销,运维,产品体验以及设计等等,足可以见这种分享制度的内容开放性。分享人也是来自内部各个部门,这里我有点好奇的是:假如分享是面向全公司的,那是如何组织的呢?有这么大会议室以及如何通知有新分享会举办呢,等等类似问题。我们小组50+的人手,我就觉得分享频率和人员参与上刚好合适,再多人组织起来估计很麻烦。
泄露的《腾讯大讲堂》都是比较早之前的分享,最新的也是09年二三月份。从内容上看,分享某个产品架构的居多,而其中又以如何优化占主要部分。主要可以分以下部分(技术方面):
1.内部框架:比如通用table cache,web 框架等等。
2.项目架构:QQ Live架构介绍等。
3.带宽性能优化方向:提高网站效率,节约带宽开销的多种方法。
4.监控运维及工具类:数据采集,运营监控等。
通过阅读,可以发现贵公司很多内部采用的技术以及设计思路,其实在一个公司的一个部门工作意义也就仅在于此了。工作久了,进步的速度自然放慢,这个时候就要学习其他公司的技术,相互交流。交流有很多方式,现在这个大会那个大会铺天盖地,要是公司愿意放你去参加是不错,只可惜不是每个公司每个普通人都有这份待遇,所以跳槽成了另一种选择。
据说泄露该资料的员工已被开除,这显得腾讯不够大气。技术的交流本来是件好事,虽然这次是泄露,但大家从ppt也只能看出个思路和设计,如此做法相当封闭。相比国内有家公司就截然相反,淘宝的开放平台贡献了很多自用工具,这才是影响互联网嘛,自己用的好和大家分享,也让大家帮忙改进。这样大气的公司在国内估计举不出几家来。
分享交流是继读书之后最好的学习进步方式了,希望有一天腾讯作为国产互联网巨头,这只山寨,啥都插一脚的胖企鹅能够首先站出来分享心得,给互联网带来给多的启示。
虚拟机安装mac os x实战
1买不起mac book,很早就想尝试在虚拟机里安装,一直没成功。随着vmware和virtual box版本的提升,网上也越来越多相关的实例来指引。另外有几个月没更新博客了,惭愧之极决定记录下。
首先上verycd下载个iso,我下的是10.6版本,然后最好把virtual box也升级到最新版。按照教程需要先下载一个叫“empireEFI_V1085”来引导,里面有32位和64位版本,只适合intel的cpu。这里详细可以参考这篇文章:http://blog.zhaojie.me/2010/09/how-to-install-mac-os-x-snow-leopard-on-virtualbox.html 。但是悲剧的我就是不成功,启动虚拟机就提示cpu不支持虚拟化技术,本人E5200的cpu(公司机器),一查确实不支持,据说只能到此安装不了。我坚持着点了忽略,但是在加载mac os的iso的时候,虚拟机直接崩溃,还是无果。觉得自己的电脑性能比较强的读者可以参考上面那篇文章安装试试。
我换了个办法,直接去下载了个已安装好mac os x系统的虚拟机文件,链接在这里,是使用VMware安装的。下载完解压,用VMware导入,配置下虚拟机信息,当然内存分配等尽可能多就是,以保证虚拟机运行流畅些。果然一下就进了系统,欣喜。除了系统卡得不行,而且还不能联网,VMware配置上是使用nat方式,我怀疑nat service未启动。果然一打开并设置成自动启动,重启mac os就可以上网了。这个系统的root密码是:memac.cn
只是卡成这样太影响使用心情了,有机会找台系能好的机器再试试,抑或等哪天房价跌了我可能考虑去入手个mac book,昨天发布的mac air真是让人口水。
网站效率优化一点总结
1当一个网站达到一定级别后很容易出现效率问题,各个环节都有可能:比如数据库,前台服务器负载过高,IO吃紧;数据增大缓存不够用或者用来同步数据的网络开销过大等。下面就自己项目遇到的问题和可采取的优化办法进行讨论,欢迎指教。(我们的项目目前日pv在2000w左右)
最开始的时候,我们的项目拥有两台前台服务器,采用dns分流的方法做负载均衡。随着流量增加,前台两台服务器变得异常得卡,访问页面延迟增加,服务器上明显表现就是cpu负载很高,idle几乎保持接近0.登录到服务器操作一些东西反应很慢。这个时候明显服务器不够用了,同时因为前台服务器响应缓慢,造成很多请求拥堵,因为前台和数据库之间是使用长连接,所以间接也影响到了数据库,导致数据库经常超出连接数(我们设置的连接数是800)。当然要增加机器,我们增加了2台服务器,同样做dns分流,这样就有2台电信,2台网通来服务。所以第一条就是增加硬件资源,简单高效。
接下来,随着流量继续攀升,发现数据库连接数一直维持在比较高的水平,很容易就爆了。而且数据库渐渐表现出来IO繁忙,读大概是6-10M/s,因为代码上暂时没有做分库考虑,所以我们准备将用来备份的从数据库用来服务前台读请求。好在代码读写是分离的(也就是每个cgi连到数据库都是2个连接,一个写,一个读),所以很容易就可以把前台的读请求切换到从数据库,这样主数据库一下就清闲了下来,主数据库主要负责写操作,解放了主数据库,主数据库从此悠闲,而从数据库从此肩负了前台大量的读请求。
后来,我们发现从数据库因为读的负担比较重,导致从数据同步主数据库数据出现延迟,这个时候我其实考虑过有没办法修改mysql源码,提高同步线程的优先级来解决。最终没有这么做,因为我们很快加入了新的一台从数据库,现在是两台从数据库来分担前台的大部分读请求,因此情况得到缓解。
再后来,流量继续爬高,导致两台从数据都出现同步延迟了。当然第一反映就是:再加从数据库?再加数据库也许是个解决办法,但是同时也要考虑其他问题,比如:如果都从主数据库同步,会不会增加主数据压力?我们尝试了以下几种办法:
1.静态化页面
我们的项目类似于新闻系统,但是又有区分。所以我们考虑静态化列表页面,每10分钟重新生成一次。结构大致是这样的:每隔10分钟,A机器就刷一次数据库,重新生成列表页面,然后把这些页面同步到B,C等前台机器上,然后前台机器同时设置http expire头来减少浏览器的请求,设置last modify头减少网络传输。这样做是有效果的,一方面减轻了前台压力,同时也减少了数据库请求。但是发现了另一个问题:A机器定期会对数据库造成一个洪峰式的冲击,而且这种主动生成方式非常盲目,另一方面要生成所有的列表页面,在不压缩页面的情况下大概好几G,要在几分钟内生成好几G的页面同时同步到前台各个机器,这对A机器和前台都是很大考验。实际当中我们也发现,只是生成了部分列表页面,A机器已经比较繁忙了。
2.mod_cache
和静态化类似,使用mod_cache可以改主动为被动,使得生成页面不再盲目。结构大致是这样:前台四台服务器都配置mod_cache,缓存5分钟,每当本地没有该页面或者已经过期的时候就去请求A机器拿新的页面并缓存到本地。这种做法代码改动很小,而且作为apache模块,不需要考虑fastcgi或者wsgi建立新进程来服务的开销(指前台机器上)。考虑到有4台服务器都从A机器上拿,实际上A机器上面还可以做一层mod_cache,即前台请求A,A请求自己生成静态页面,然后把静态页面返回给前台,剩下的前台请求A的时候就直接拿已经生成的静态页面就可以了。这种方法很遗憾没有很好地实际测试过,但我觉得是可行的,特别是如果能将生成的静态页面再做gzip压缩,减少A机器和前台的网络传输消耗效率会更高。
3.memcache
memcache和mod_cache其实很像,一个是使用内存,一个是使用磁盘。出乎我们意料的是,相比静态文件好几G的磁盘消耗,使用memcache缓存到内存只占了几百M,这都归功于memcache的压缩。
使用memcache,项目的结构和mod_cache也很像,前台收到请求后去内存拿数据,拿不到则从数据库拿然后再设置到内存。这台memcache机器就像第二点当中那台A机器,但是使用memcache本身有以下几个优势:第一,数据传输已经被压缩,占用内存小,网络传输消耗小;第二,从实际观察发现,memcache这台服务器非常高效,占用cpu极低,和使用mod_cache相比,相当于把A机器的压力分散到了前台机器上(使用memcache仍然都是前台在请求数据库,使用mod_cache则只有A服务器在请求数据库)。这样的话分散压力,提高效率。
实际测试发现,最终上面三种都没用在我们项目中,memcache也没有。原因是我们的项目有点特别,类似于新闻但又不完全相同,类似于游戏分区,每个分区里面有自己的列表,memcache命中率稳定在65%左右,因为尽管总访问量比较大,但是分散到每个区,再到每个区里面每个列表,缓存的命中率并不是很高。
最终我们又回归到了最开始的做法,我们增加了一台比较强悍一点的机器来做从数据库,事实也证明了这样可行。原因是我们发现从数据肩负了主要的读请求,但是之前的从数据库机器都比较烂,4G的机器,2核至强cpu,都是游戏淘汰下来的机器,平时负载在3-4,而且使用了比较多swap,这说明机器内存可能不足了。新机器换用8G内存,4核至强cpu,现在一台机器担当了4台前台服务器的读请求,负载稳定在0.3。
将来,我觉得我们的方向仍然是增加缓存,改变缓存的策略,考虑到memcache这么节约内存,可以把常用的请求对象全部丢到内存里面,相当于内存里保存了数据库部分数据的完整拷贝,这样列表的请求和详细页面的请求都只靠请求memcache就可以完成,不像之前提到的使用memcache,仍存在大量对数据库的请求,同时缓存的内容过期率比较高。这样做相当于mysql的query cache的一个延伸了。
总结下,我觉得一些可行的网站效率优化办法:
1.硬件是硬道理
2.使用从数据库分离读写请求
3.静态化页面
4.使用memcache或者mod_cache(即使用内存或者磁盘来做缓存)
使用vim来改变文件编码
3两条命令:
set enc=xx
set fenc=yy
第一句表示先设置当前文件是采用什么编码的,以告诉vim内部如何获取内容。
第二句表示保存为什么编码。
设置后,wq就可以了。



