新年快乐暨年终总结

2010年是一个不算很好的年份,从一个忙碌的SNS单位到年中的时候跳到了一个毫无目标的门户单位。之间的落差是显而易见的。

2010年好多时间也没有办成,英文也没学好,婚也还没求,房子也没买,可年龄还是长了一岁。 2010年居然买了很多书。可看完的也就10多本,很多还没完全看完。

《人生十论》应该是今年要看完的最后一本书了,钱穆先生的小时候真是幸福,而他读书也居然有2个顿悟提高的过程。人生三路向对于我这样的实在是太深刻了,对于西方人,中国人,印度人对于人生的三种不同态度。突然想到虽然印度还被殖民地过,但是他们的那种人生态度似乎一直没有改变,而我们似乎也越来越象西方人看齐了。那就是对于外部物质的目标的争取而不是对于内心的自省。

今年对于技术上似乎没有任何长进,也许以后多点分析问题的方法算是一个进步吧。dstat, strace也算是用的较熟练了,可惜这些东西在现在这个地方根本没有用处,对于系统运维来说这些都是多余的。

明年是往mysql还是linux至今也没个定论,我这人的毛病就是贪多,干什么没个定性。经常妄想一口吃成一个胖子。但是如果没有兴趣的事情往往不会坚持下去。钱穆先生小时候就知道看什么书都要彻底的看完。但是其实书不光要彻底的看完,好书得看5遍6遍7遍。

在茫茫银河系中,人类的存在实在是太渺小了,在漫长的人类进化过程中,我们现在只是沧海一粟,在茫茫的人海中,你只是一个不起眼的其中一个。每想到这里,我就觉得很宽慰,没人可以改变整个实际,无论是奥巴马还是霍金以及卡尔萨根都无法改变。所以与其这样,我们还是向着自己的兴趣方向活着吧。

前天参见了海淀堂的圣诞节活动,虽然我不同意神父的一些言论,但是这个世界就是多种多样的。所以我还是很赞同《理想国和哲人王》里的说法。

###########################################

Best regards
Timo Seven
blog: http://www.timoseven.com
twitter: http://twitter.com/zauc
Linux System Admin & MySQL DBA

mysql中group by的排序问题

今日写个小程序,需要用到在mysql中group by 之后排序,但是出现几个问题。数据如下:

但是如果你用group by order by xxx desc发现结果并不是这样的。其实这样只是对group by之后的结果再进行的order by。而mysql还不支持先order by再进行group by

发现group by的结果是根据id进行升序排列的。但是我实际上是需要反序进行排列。

有2个方法我自己找的,一个是通过alter table来解决,另外一个是子查询。 alter table的结果是以后只能进行降序排列了,但是好处是还是可以用到原来的索引,而用子查询基本是全扫描.

 

 

 

 

 

 

###########################################

Best regards
Timo Seven
blog: http://www.timoseven.com
twitter: http://twitter.com/zauc
Linux System Admin & MySQL DBA

jquery的选择器列表

javascript要选择ID还是比较麻烦的。但是最近知道jquery的如此强大,《锋利的jquery》一书算是帮我总结了吧。其实也就是对于jquery的doc一个中文翻译。

但是为了方便以后自己学习,还是摘抄在这里吧。

总结一下 #xxx 表示选择 id="xxx"的元素
.xxx表示选择class="xxx"元素
xxx 表示所有的 xxx 标签元素

1. 基本选择器
$("#test") 选取id="test"的元素
$(".test") 选取class="test"的元素
$("p") 选取所有<p>元素
$("*") 选取所有的元素
$("div,span,p.myClass") 选取所有<div>,<span>和拥有class="myClass"的<p>标签的一组元素

2. 层次选择器
$("div span") 选取<div>里的所有的<span>元素
$("div > span") 选取<div>元素下元素名是<span>的子元素
$(‘.one + div’) 选取class="one"的下一个<div>的兄弟元素
$(‘#two~div’) 选取id="two"的元素后面的所有<div>兄弟元素

3. 基本过滤选择器
$("div:first") 选取所有<div>元素中第一个<div>元素
$("div:last") 选取所有<div>元素中最后一个<div>元素
$("input:not(.myClass)") 选取所有class不等于myClass的<input>元素
$("input:even") 选取索引是偶数的<input>元素

$("input:odd") 选取索引是奇数的<input>元素
$("input:eq(1)") 选取索引等于1的<input>元素
$("input:gt(1)") 选取索引大于1的<input>元素,但是不包括1
$("input:lt(1)") 选取索引小于1的<input>元素,但是不包括1

$(":header") 选取网页中所有的<h1>,<h2>,<h3>…..
$("div:animated") 选取正在执行动画的<div>元素

4. 内容过滤选择器
$("div:contain(‘我’)") 选取含有文本"我"的<div>元素

$("div:empty") 选取不包含子元素(包括文本元素)的<div>空元素
$("div:has(p)") 选取含有<p>元素的<div>元素
$("div:parent") 选取拥有子元素(包括文本元素)的<div>元素

5. 可见性过滤选择器
$(":hidden") 选取所有不可见的元素。包括<input type="hidden"/>, <div style="display:none;"> ……

$("div:visible") 选取所有可见的<div>元素

6. 属性过滤选择器
$("div[id]") 选取拥有属性id的元素
$("div") 选取属性title="test"的<div>元素
$("div") 选取属性title不等于"test"的<div>元素(注意:没有属性title的<div>元素也会被选取)

$("div") 选取属性title以"test"开始的<div>元素
$("div") 选取属性title以"test"结束的<div>元素
$("div") 选取属性title含有"test"的<div>元素

$("div[id]") 选取拥有属性id,并且属性title以"test"结束的<div>元素

7. 子元素过滤选择器
$(":nth-child(index/even/odd/equation)") 为每一个父元素匹配子元素,并且:nth-child(index)的index是从1开始的
$("ul li:first-child") 选取每个<ul>中第一个<li>元素

$("ul li:last-child") 选取每个<ul>中最后一个<li>元素
$("ul li:only-child") 在<ul>中选取是唯一子元素的<li>元素

8. 表单对象属性过滤选择器
$("#form1:enabled") 选取id为"form1"的表单内的所有可用元素

$("#form2:disabled") 选取id为"form2"的表单内所有不可用的元素
$("input:checked") 选取所有被选中的<input>元素
$("select:selected") 选取所有被选中的选项元素

9. 表单对象属性过滤示例
$(":input") 选取所有<input>,<textarea>,<select>和<button>元素

$(":text") 选取所有的单行文本框
$(":password") 选取所有的密码框
$(":radio") 选取所有的单选框
$(":checkbox") 选取所有的复选框
$(":submit") 选取所有的提交按钮
$(":image") 选取所有的图像按钮
$(":reset") 选取所有的重置按钮

$(":button") 选取所有的按钮
$(":file") 选取所有的上传域
$(":hidden") 选取所有不可建元素

###########################################

Best regards
Timo Seven
blog: http://www.timoseven.com
twitter: http://twitter.com/zauc
Linux System Admin & MySQL DBA

闲聊网站

过去快6个月了,也应该可以说了,毕竟你们也没有给我保密费用。

之前在一个SNS网站的时候,领导高瞻远瞩说要开发日本市场,于是我就发现我们项目组内很多人都是有留学日本经历的,并且还建立了日本办事处,他们主要负责商务和产品设计。

但是到了今年,这个项目组突然就出问题了。主要来自以下几个方面。

首先日本商务开发不成功,虽然日本的头是以前yahoo日本的副总裁,但是我们跟yahoo的合作却不是很顺利,没有导入太多yahoo日本的用户,造成用户数增长缓慢,本来预计的250W用户量迟迟到不了。虽然我们公司和yahoo日本都是老孙投的,但是不知道为什么跟yahoo日本的合作会那么难。

其次是日本的产品设计人员,日本是一个崇尚终身制的国家,所以我们很难招到非常有经验的产品设计人员,虽然有很多有经验的产品设计人员,但是实际上是很难从其它公司挖过来的。因为日本人一般都把自己的公司当家。而我们国内的设计人员根本无法了解日本人的习惯,所以设计的东西也就那样了。

最后一个是领导是否重视,记得项目组刚成立的时候,沉一船同志几乎是每天都来看一下,那时候虽然大家都非常忙,很少有哪天不加班的,但是大家都感觉都过的特充实,特有干劲,也来了一批很有实力的同事。可一年多过去了,这个项目也不温不火下去,注册人数一直没有很好的提高。

根据后台的数据统计,发现日本人的行为习惯还真是太奇怪了。注册流程中居然是在须知部分停留大部分的时间,看来是真够谨慎的。而日本网站也不允许在网站中输入其它网站的密码,所以根本不能象kaixin001这种直接导入msn帐号啥的。而且我们发现日本用户的忠诚度非常高,一旦他注册了你们网站,有20%–30%的人会后面每天都来。但是他们并不喜欢推荐自己的朋友来。而我们网站的对象居然来了很多小朋友,这实在是太出人意外了。

另外一个情况是日本人对于手机非常重视,非常注重网站在手机上的体验。另外不反对为服务支付。这个应该对于国内网站的站长真是太羡慕了。但是日本人也是非常苛刻的,对于网站一个任何小问题都会给你提出要求,而一旦你没有调整的话,那他就会跟好多人说不要来了。并且会投诉到日本通信省。并且日本人对于隐私非常重视,所以我们在一开始的时候犯了很多错误。

虽然我们是2个靠的很近的国家,但是差别太大了。现在的中国到底还有多少人会把公司当成自己的家吗?而且我们很少会为服务付费。免费一直是我们的原则。于是除了电子商务网站,其它网站几乎都是靠网络广告而存活。

不过在移动互联网浪潮即将到来,同时手机支付也在越来越流行的情况下,我想我们也是会为服务付费的。比如现在买windows和office正版的人越来越多了,还有apple store这样的存在,更是促进了这种浪潮的来临。现在国内在手机应用的公司越来越多了。

###########################################

Best regards
Timo Seven
blog: http://www.timoseven.com
twitter: http://twitter.com/zauc

Linux System Admin & MySQL DBA

初用addslashes

最近一直忙一个php版本的nginx平台管理系统,需要将很多不同的nginx配置文件存入到mysql中。

但是nginx配置文件中单引号,双引号,斜杠这些符号比较多,一直没法存入到数据库中。于是找了下看看php有什么通过转义的方式存入mysql。发现居然还是有的。在php.ini文件中进行如下设置就好了。

magic_quotes_gpc = On (Get/Post/Cookie)
magic_quotes_runtime = Off
magic_quotes_sybase = On

经过如上设置就很容易的将Nginx配置文件存入到数据库中,但是会把'(单引号)存为”(2个单引号)。这种就会让我每次还得把2个单引号转为1个单引号再进行发布。看了上面3个方法的官方文档,居然从5.3后是被默认关闭的,并且在6中就被废弃掉了。那看来只能找其它的代替。还好文档中提到了用addslaashes()方法来代替。用了下还真是比较好用。

使用如下:

addslashes()
$str=addslashes($str);

这样存入mysql中的是没有斜杠,也不会变成2个单引号。看来这就是为什么上面3个参数会在5.3以后被默认关闭了。

很多方法都是到需要的再查资料吧,我还是不喜欢一上手就系统化学习,那样经常会由于收益曲线不高而最终放弃。

###########################################

Best regards
Timo Seven
blog: http://www.timoseven.com
twitter: http://twitter.com/zauc
Linux System Admin & MySQL DBA

应用运维和系统运维

运维工作对于很多人来说其实就是看一个看说明书的工作。从man page到各种软件的readme,install file都要看。理论上看着挺简单的。但是接触多了这就分了应用运维和系统运维。

我这2个都做过。老实说系统运维是更轻松的,毕竟系统级别的改变一般是比较少的,比如碰到系统内核升级,centos版本升级,数据库版本升级,CDN改造这些不是一直要做的事情。这是一个长期过程。系统级别的更改往往是非常慎重的,得经过非常多的测试,比较和优化才可以进行上线。

系统运维首先需要保证的就是系统的稳定性,毕竟所有应用都是架设在系统平台上的。所以系统运维既是一个基础的工作,又是一个非常重要的工作。说基础是因为它是一切应用的基础的,说重要是因为要是系统不稳定,那何谈应用的稳定性呢?系统稳定性,这个基本是由于驱动导致的,有些驱动问题在一般情况是看不到的,但是一旦在高并发的情况下,比如AS5对于某些品牌的网卡在大流量下网卡会崩溃掉。还好linux的驱动开发者还是非常热心的,一般很快有patch会出来。但是还是由于我们测试不够仔细才会有这样的问题产生。

系统的优化也是非常重要的,曾经有个以前同事说他们的游戏服务器压力很大,主要的压力是在io上,其实就是磁盘上。vmstat看到io部分值非常高。这个有应用导致的,也有系统平台和系统软件导致的。比如这个问题就是由于使用sendfile读写大文件,而改成使用普通的read方法就立刻降下来了。但是有时候还有缓存读写等等原因。另外一个优化是对于系统参数和网络参数的优化。其实这些都是要根据这个服务器具体跑什么应用来决定的。

下面说下当初做应用运维的日子。在那个SNS网站的日子,我就彻底经历过了。应用运维是要保证应用层的稳定性。但是对于大型SNS网站,网站更新是一个常态的过程。于是你就会发现发布成为一个天天进行的东西。但是发布和到底怎么发?发了后的预期结果是什么?到底会对现有应用有什么副作用?这次发布是代码的发布还是一个新的应用组件的发布?

于是应用运维首先要建立一个严格化的发布和测试流程。但是有时候开发会用点非常新的软件为了实现产品需求,但是应用运维如果不知道这个东西,那一旦出了问题你就没法一下子确定问题的症结就麻烦了,特别是对应用的稳定性造成影响后,那你身上的压力就特别大了。

这次velocity会议上淘宝运维的九峰同学的PPT还是非常不错的。基本上对于应用运维做了一个很好的总结。一个好的应用运维基本要在产品设计阶段就要加入进去,这个时候加入进去对于你理解业务逻辑是非常有好处的,同时你可以发现某些肯定会对系统稳定性产生问题的设计提出自己的修改意见,毕竟产品一般都是不怎么懂得技术的。当然我们更关注的是产品的稳定性,至于产品要达到什么效果那是产品仔细考虑的东西。

而在开发阶段,那需要跟开发商量通过哪些现有的开源程序可以达到产品需求,这个时候尽量使用那些你了解的,稳定的,最好版本已经超过0.5的那些软件。而不要使用那些你都不知道它的工作机制的软件。这个过程通常比较容易,毕竟开发也想这是一个稳定的应用,但是有些激进的开发者往往会自己造轮子,那你得明白这个轮子是怎么工作的。曾经在的那个视频公司就有这样的问题,很多东西都是开发自己造的轮子,连数据同步这些都是自己造的,但是由于不够稳定,给我工作造成了极大的麻烦。

测试阶段,分为功能测试和压力测试。大部分公司都是这样分为2种,如果只有功能测试的公司,那你得注意了,应用的稳定性跟压力有时候是成正比的。

发布阶段,这个比较简单,备份备份备份,可回滚可回滚可回滚。

前面这些其实都是应用运维的先期工作,应用运维真正的工作现在才开始呢。通过各种工具查看系统和应用状态。基础的有:cpu使用率,内存使用率,io情况,网络连接数,网络流量等等。业务方面的可以看下现在的pv,uv以及你自己定制的各种事务流程。而这些数据不光是看应用是否有问题的,而且还是以后扩展这个应用还是砍掉这个应用的核心数据。

应用运维的报警工作,比如pop3服务是否正确,应用的内部调用是否正常,有阻塞没? 这些要是能做到预警机制那对你非常有利,在运营还没发现问题的时候你就解决了问题,那不是很好阿。当然这些你需要对这个应用的内部逻辑非常清楚才会方便的建立好。

通过上面你可以发现应用运维包含了部分系统运维的工作。系统运维对于系统软件的工作机制和文档和各种操作系统发行版的文档要非常熟悉。而应用运维有时候更象是一个架构师和应用说明书。

具体的troubshooting就不说了。

###########################################

Best regards
Timo Seven
blog: http://www.timoseven.com
twitter: http://twitter.com/zauc

Linux System Admin & MySQL DBA

一个expect自动登录问题解决

批量改配置的时候发现有些机器的密码第一位是 ‘-‘ 这样在expect的send 方法中会转为方法,这样造成了无法自动登录。出现的错误如下:

spawn ssh root@10.xx.xxx.xxx
&amp;amp;quot;: must be -i, -h, -s, -null, -0, -raw, -break, or —
while executing

&amp;amp;quot;send_user &amp;amp;quot;$PASSWORDr&amp;amp;quot;&amp;amp;quot;
(file &amp;amp;quot;./ssh_login&amp;amp;quot; line 20)

google搜索下也没什么答案,只好看下man page,发现有这样一段

The — flag forces the next argument to be interpreted as a string rather than a flag. Any string can be preceded by "–"

whether or not it actually looks like a flag. This provides a reliable mechanism to specify variable strings without being
tripped up by those that accidentally look like flags. (All strings starting with "-" are reserved for future options.)

于是改成 send — "$PASSWORDr"; 就解决了。

###########################################

Best regards
Timo Seven
blog: http://www.timoseven.com
twitter: http://twitter.com/zauc
Linux System Admin & MySQL DBA