Trade Off

supercalifragilisticexpialidocious

Orange Has Been Sweet

今天早晨买了一些水果,也买了几个橙子,虽然不便宜,但今晚上吃起来感觉还不错,挺甜的。

怎么总感觉今天有点儿不稳呢,听说ERP的接口搞定了就要去测试了,测试过程不怎么顺利,让别人做事情,而且相隔很远,再加上对方不怎么关心这个有点陈旧的系统,工作就会很难同步,我们一测试就出问题,报告过去后好久才给我改改,再测试,又出问题。目前来看虽然没有完全测试好,但已经暴露出几个问题了,还是比较重要的。

明天需要继续测试剩下的接口,并且要总结问题,发给郑工处理处理,又是漫长的等待,这是必然的,不仅仅是一个周末,估计这块在上线前都会是很紧张的。

这篇文章发表得不容易,generate的时候总出现一个错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/Users/dawncold/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/psych.rb:203:in `parse': (<unknown>): control characters are not allowed at line 1 column 1 (Psych::SyntaxError)
 from /Users/dawncold/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/psych.rb:203:in `parse_stream'
  from /Users/dawncold/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/psych.rb:151:in `parse'
 from /Users/dawncold/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/psych.rb:127:in `load'
  from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/gems/jekyll-0.11.2/lib/jekyll/convertible.rb:33:in `read_yaml'
 from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/gems/jekyll-0.11.2/lib/jekyll/post.rb:39:in `initialize'
  from /Users/dawncold/Documents/Project/work_at_honovation/plugins/preview_unpublished.rb:23:in `new'
 from /Users/dawncold/Documents/Project/work_at_honovation/plugins/preview_unpublished.rb:23:in `block in read_posts'
  from /Users/dawncold/Documents/Project/work_at_honovation/plugins/preview_unpublished.rb:21:in `each'
 from /Users/dawncold/Documents/Project/work_at_honovation/plugins/preview_unpublished.rb:21:in `read_posts'
  from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/gems/jekyll-0.11.2/lib/jekyll/site.rb:128:in `read_directories'
 from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/gems/jekyll-0.11.2/lib/jekyll/site.rb:98:in `read'
  from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/gems/jekyll-0.11.2/lib/jekyll/site.rb:38:in `process'
 from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/gems/jekyll-0.11.2/bin/jekyll:250:in `<top (required)>'
  from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/bin/jekyll:23:in `load'
 from /Users/dawncold/.rvm/gems/ruby-1.9.3-p286/bin/jekyll:23:in `<main>'

这种错误找起来真是蛋疼,最终是在dev这个字符开始的地方找到的,有个奇怪的字符出现了,看不到,也不占空,但确实有个字符在那里占着地方,或许是输入法在切换的时候遗留到那里的吧。。。可恶!

明天还有新工作,测试完ERP后继续做CMS,王总提出了不少新的东西要改进。

Almost Fullfil

昨晚洗完澡后想继续把白天没做完的tag list block做完,没想到阿敏跳出来让我看她最近的摄影作品,看着真不像她拍得东西,整个画面已经不是全都清楚了,该清楚的地方清楚,其余地方模糊。我早就这样和她说过,她还总不相信,现在上了摄影课才知道。

渐渐发现我已经做完tag list的功能了,只是现在给了一个固定的宽高,所以没有匹配到product list这个block,可以加图片或者幻灯片进去,好吧,现在工作似乎简单了不少,马上push了代码准备记录一下,一看已经过了10点。还是想养成早睡早起而不是晚睡早起的习惯,那就睡了吧。

估计今天会和taowen先把昨天没做好的block隐藏功能做好,然后就能继续向着medium、small category开进。

昨天中午看了一个视频,全英文,还是Domain Design,讲了一些在旧系统重构到新系统的技巧,并且如何使用Domain Design,大概能看懂20~30%,英语继续练习吧,实在不行我就把blog改成英文版!!!

New Task

昨天就开始做user center这样一个功能,说简单也简单,至少是从表现上来看很简单,不过也挺重要的,几乎每个电商网站都有一个说得过去的user center,至少要让用户能在这里查询订单什么的。我们这个user center同样参考了不少网站的产品原型,但由于是上线初期,很多功能无法完善,最终呈现给用户的就三四个功能(还有一个是纯粹展示一段文字用的……)

但很可惜,犹豫center的功能性,需要和订单、用户地址、用户信息等功能衔接,有位同事正在搞下单功能,我看到有些地方需要修改,改好后push过去,一会又和那位同事冲突了,这样就很难推进下去了,如果同事在身边还好,可惜不在。

余下一点时间讨论了large category、medium category、small category的效果,明天会先解决ERP下单问题,接着就是按照今天讨论的效果来实现category。大致看了一下diapers.com的实现代码,不那么难,但做到兼容IE的话我还是没底,需要强大前端支持。

Pytz的6分钟时差

项目中有使用pytz这个第三方库来处理datetiem相关的东西。不过最近测试的时候发现,创建了一个时间点后,最终得到的时间点和预想的时间点有6分钟的误差,从网上搜到的资料是这样解决的:详情看http://hi.baidu.com/limodou/item/72da32384b25c7ff97f88df1

创建datetime的时候,特别是带timezone,需要localize一下,否则在使用pytz的时候就会出现这6分钟的差异。代码中首先创建了datetime,然后localize后再replace了timezone为pytz的,最终还astimezone为pytz.utc。我们是使用utc的,你的代码也许不需要:)

NAT实践

昨天用LXC建立了不少container,分别用来做webserver、databaseserver等等,让这些container运行着各自程序启动后如果有外部访问,就会通过iptables把请求发送到各自的地方,这里需要宿主机器做NAT。比如访问80端口,我会把请求转发到内部10.0.3.20这台container来处理,相应的response也会返回过去。这样就做到了服务隔离。

1
2
sudo iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.3.20
sudo iptables -t nat -A POSTROUTING -o eth1 -s 10.0.3.20 -j SNAT --to 200.200.200.25

这样就把进入的请求都发到了10.0.3.20这台container上去处理。

nat

只默认开了一个nginx,就这样的效果。

LXC实践

这里的LXC是基于Ubuntu12.04的,在其他系统下可能不太一样。

0.安装lxc

1
sudo apt-get install lxc

1.修改lxc的mirror,不修改的话下载一个ubuntu景象会非常慢!!!

1
2
sudo emacs /etc/default/lxc
第三行的mirror注释去掉,并修改为cn.archive.ubuntu.com,这样就非常快了

2.创建lxc容器,t表示模板中的名字,n表示这个容器的名字(可自定义)

1
sudo lxc-create -t ubuntu -n ubuntu_container

3.启动容器

1
sudo lxc-start -n ubuntu_container

启动后就会出现登录ubuntu的界面,刚刚创建好容器后会给出一个提示,帐号密码都是ubuntu,登录进去就可以使用了。

猜想lxc的用法可能是对于部署的某个进程使用lxc隔离,这并不能做vps用,lxc只是轻量虚拟化,针对进程来的,所以还是单机在使用,如果做vps就得用vmware、xen、openvz这样的东西了。

LVM+RAID实践

两块256Gb SSD,做RAID1,用LVM管理,方便日后动态扩容等。

0.分区,因为是SSD,需要注意4K对齐问题,否则对SSD的寿命和性能有影响:

1
2
fdisk /dev/sda
fdisk /dev/sdb

1.创建PV

1
sudo pvcreate /dev/sd{a1,b1}

2.创建VG

1
sudo vgcreate -s 16M vg0 /dev/sd{a1,b1}

3.创建LV

1
sudo lvcreate -n lv0 vg0 -m 1 -lxxxx --corelog

Python中dict格式化

最近在工作中遇到过写SQL的问题,参数是直接传递进去的,比如这样:

1
db().execute('SELECT * FROM xxx WHERE id = %(id)s', id=get_id())

今天细看Google提供的Python课程发现一个叫DictFormatting的部分,里面就有类似这样的语法,现在才明白。以前用过Python的格式化输出,其实这个dict的格式化和字符串的类似,就是在字符串格式化的基础之上加入了dict的key,%s是表示这里有字符串,而%(xxx)s是表示字符串,而且是以xxx为key的字符串,这个value就是从字典中给出。一半会在这样一个字符串后加“% dictname”表示值从dictname这个字典中给出,这不就是和字符串格式化一样么。

Python中的sort方法

打算从今天开始自习再学学Python的基础,选了Google提供的Python课程,学到list部分,有个练习题目要求针对一组tuples排序,根据tuples的最后一个元素排序,有个hint,可以用key=function这种方法,于是搜索了一番,在Python的wiki中找到这个key方法的描述:

从Python2.4以后list.sort()和sorted()方法都提供了一个key可选参数,传入一个function用来决定排序需要的key。这个key就是所排序元素的权值,最终就是根据权值来排序了。你也可以自己写一个方法,就是那种用def来定义的方法,不过要求接受一个参数,返回一个值,接受的参数就是这个集合(list、dict、tuple)中的某个元素。我是这样写的,it works:

1
2
3
4
def sort_last(tuples):
 # +++your code here+++
 tuples.sort(key = lambda t: t[-1])
 return tuples

根据tuple中最后一个排序。

M4的一点优化(MacOS 10.9)

1.关闭紧急运动传感器

mac系统没有把这些传感器的设置、界面什么的体现到UI里,让我一度以为mbp没有这种设备,实际这也算是mac系统的设计理念吧,把普通用户无须知晓的东西屏蔽掉,让用户看起来、用起来异常简单,不像thinkpad那样,直接把硬盘活动保护啥的做成一个功能给用户展示。。。你看,你看,我们(thinkpad)有保护您硬盘的设备。

这些不让用户看到的功能大多需要相关工具或者命令行来设置:

1
sudo pmset -a sms 0

对于替换了原来硬盘的这种方案就可以关闭紧急运动传感器了,如果加了SSD在光驱位,那就甭管了,继续保护硬盘吧!

2.备份驱动

1
sudo cp /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage.original

3.更新驱动

1
sudo perl -pi -e 's|(\x52\x6F\x74\x61\x74\x69\x6F\x6E\x61\x6C\x00{1,20})[^\x00]{9}(\x00{1,20}\x54)|$1\x00\x00\x00\x00\x00\x00\x00\x00\x00$2|sg' /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

4.开启Trim

1
sudo kextcache -system-prelinked-kernel

5.清除系统内核扩展缓存

1
sudo kextcache -system-caches

6.重启

如果出错就恢复刚刚的备份

1
sudo cp /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage.original /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

3.用noatime方式挂载硬盘,就是少加载一个文件属性参数而已,对于日常使用没啥影响,在/Library/LaunchDaemons里面创建一个noatime.plist,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>noatime</string>
<key>ProgramArguments</key>
<array>
<string>mount</string>
<string>-vuwo</string>
<string>noatime</string>
<string>/</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

修改刚刚创建的文件权限

1
sudo chown root:wheel /Library/LaunchDaemons/noatime.plist

重启

检测结果

1
mount | grep " / "

如果结果里有类似这样的内容(最后的noatime)就表示可以了

1
/dev/disk0s2 on / (hfs, local, journaled, noatime)