Year: 2013

BuyVM VPS 安装优化记

BuyVM 的 VPS

早两周忘了是谁提醒了下, 说 buyvm 家 15$/yr 的 VPS 有货, 非常值得去抢, 当时估算了下这个价格确实算良心价, 虽然只有 128M 内存, 但作为一台自己的 vps 折腾点东西完全都够了的, 果断下手一台

这台机器打算拿来放一些自己玩的小程序, 同时把个人的空间和 blog 迁过来, 本还想拿这个机器做自己私有的翻墙中继, 不过试了下到本地的速度最高也没超过 30KB/s 过, 遂放弃, 等啥时候有烧包需要时去买 linode 在日本的节点好了

系统选择和基本设置

之前自己用 debian-server 做纯服务端的东西感觉很爽, 占资源少文档丰富, 出点问题也能很容易在 Google 帮助下搞定, 所以系统也选的 debian, 然后因为只有 128M 内存, 上 64bit 没意义, 而且会更耗内存一点, 所以选了 32bit 的版本

debian 有几个比较坑爹的地方, 首先就是新建用户默认不建 home 目录, 非要在 useradd 的时候强加 -m 参数指定, 不然还要人肉新建 home 目录兵把 /etc/skel/ 下的几个隐藏文件拷过来做初始化

然后就是如果不是 root 用户, /sbin 和 /usr/sbin 默认是不在 PATH 里的, 需要手动将这些路径打开, 不然连 ifconfig 什么的都用不了. 修改 /etc/profile 里, 将 PATH 设成全用户一致 (此处参考: http://techpoet.blogspot.jp/2010/01/add-sbin-to-user-path-in-debian.html)

自己有一堆常用的配置库放在 github 上, 直接 git 取下来放到 home 目录, 把一堆 rc 结尾的文件前面加点让对应的程序能读到. 特别的是 vimrc, 最好还是放到 /etc/vim/vimrc.local 下, 不然 sudo 的时候碰上的还是没配过的 vim, 挺不爽的

系统自带应用内存优化

因为只有 128M 的内存, 要做很多勒紧腰带过日子的准备, 先就是卸载一堆自带的服务, 释放宝贵的内存, 此处参考了 http://www.yyphs.com/post/475.html, 不过我只去掉了会启动的组件, 即如下操作

# 系统升级
apt-get update && apt-get upgrade

# 去除多余软件
apt-get -y purge apache2-* bind9-* xinetd samba-* nscd-* portmap sendmail-* sasl2-bin

# 清理软件包
apt-get autoremove && apt-get clean

LEMP 环境安装

Web 应用从早两年的 LAMP 现在都在转 LEMP, 主要还是把 Apache 这个巨无霸换成了相对小巧又耐操的 nginx, 自己之前用 nginx 感觉也相当好, 这次也把系统默认的 Apache 干掉换这个

一开始参考的 http://www.howtoforge.com/installing-nginx-with-php5-and-mysql-support-on-debian-squeeze, 安装 mysql, nginx, php 都很正常, 但是这里面提到 debian 没有 php-fpm, 所以用 lighttpd, 不过我装 lighttpd 后内存爆掉, 随便搜了下优化方案都搞不定, 卸掉, 还是用习惯的 php-fpm 方式跑 fastcgi

http://www.webhostingtalk.com/showthread.php?t=1025286 这个提示装上 php5-fpm, 从装 nginx 开始就用不上了, 后面的优化也先不用管, 一会一起处理 (wordpress 似乎还依赖一个叫 php5-apc 的包, 装的时候一起带上)

内存优化

上面那一堆装好后如果不做优化, 坨坨的爆内存, 所以该关的功能要关, 该调的参要调. mysql 的一个优化关键是要关 innodb, 然后 nginx/php-fpm/mysql 都要做的事就是降低同时运行的实例数, 减少连接数, 同时严格控制各处内存大小. 具体怎么配的也忘了, 主要参考的是搜到的这两篇里关于参数的配置

http://blog.log4d.com/2011/11/vps-lnmp-setup-config/ (主要参考其参数配置)

http://keithscode.com/blog/23-running-mysql-on-a-small-128mb-vps.html (主要参考其参数配置)

最后的内存占用如下 (目前运行状态, 装了 wordpress)

$ free
             total       used       free     shared    buffers     cached
Mem:        262144      88972     173172          0          0          0
-/+ buffers/cache:      88972     173172
Swap:            0          0          0

安装迁移 wordpress

先在 mysql 里建对应的数据库, 这个随便都能搜到, 自己碰到个坑是 mysql 分配数据库权限时用已有用户无法登陆, 最后还是删掉用户在分配权限时再新建用户, 用 identify 来设置密码

mysql> create database wp;
mysql> grant all privileges on wp.* to wp_user@localhost identified by 'wp_pass';

装 wordpress, 一切正常, 用老的文件, 改名备份 wp-config.php 直接访问 wp-admin/install.php
用导出的文件再导入 (大于 2M 的话需要修改 php 的上传限制: 修改 /etc/php5/fpm/php.ini 文件修改 upload_max_filesize 项)

之前用的是多说的评论系统, 把插件重新启用, 并绑定原来注册过的站点就能将评论恢复, 一切搞定

奇怪的问题

上面写的好像很容易, 实际上对一个新手 OP 来说还是非常磕磕碰碰的, 最后在 OP 之外还有些奇怪的问题

先是多说, 绑定站点时临时性卡死, 然后再导数据时有延迟, 再后面就有重复的评论出现, 但是又不是所有的评论都被重复一遍, 研究了半天没弄明白, 自己手动删掉了重复的

然后删重复数据时发现有一条奇葩的回复显示在了另一篇文章下, 还是一条二级评论, 但是在后台看对应的又是正确的文章, 而且文章下的评论数是对的, 就是不显示, 自己折腾半天都没弄好, 无奈去联系多说的技术客服, 周末不在线, 留言后觉得不放心, 又去 dev.duoshuo.com/wordpress-plugin 报了一遍才安心

今天终于找上人, 帮着看了下, 先让我把评论模式从嵌套改成盖楼, 发现果然显示在正确的文章下了, 但是错误的引用了一条另一篇文章下的评论, 而且引用的那条评论还在此评论后好几个月才发出来, 顺手看了下 HTML 源码, 发现多说也是按 评论(post-id), 文章(thread-id), 引用(root-id) 来组织的数据 (这跟 BBS 上的 pid, gid, rid 一样一样啊), 然后这条出错的评论应该是两边哪里没同步好, 导致其 root-id 出错, 而 root-id 对应的评论在另一篇文章下, 所以嵌套模式时就显示到那边去了, 而正确的文章下因为找不到对应的父评论所以也没显示, 而盖楼模式下不判断父评论所以能显示, 但是存在错误引用关系, 最后让帮忙手动将出错评论的 root-id 置零, 总算搞定

第二件事是一个陈年老问题还在, 一年多前就写过一篇爆流量记, 里面提到有人抓 win7.iso, 但是当时找不到证据说是谁, 迁到新站后还在被抓, 期间 404/302/416 轮着报了一年多错居然还抓, 怒了去看看到底都哪来的请求, 意外发现有很多标识 QQDownload 的请求, 从 momodi 那联系上 QQ 旋风的人, 跟他们 blabla 说了一堆, 结果估计他们也从来没碰到过这样的事, 说要不你先自己屏蔽掉? 我哭笑不得说现在对我倒没啥影响了, 反正就算屏蔽也耗系统资源, 而且现在每次给个 416 也费不了我多少流量, 只是觉得很不爽而已. 不过后来自己去找了下迅雷和旋风离线下载的 IP 段, 这几个好像又都不在里面, 贴下原始日志, 大家看看有啥想法没:

$ awk '/QQDownload/{cnt[$1]++};END{for(ip in cnt){print ip, cnt[ip]}}' access.log
101.226.68.137 196
140.207.54.139 195
183.195.232.138 196
$ awk '/cn_windows_7/{cnt[$1]++};END{for(ip in cnt){print ip, cnt[ip]}}' access.log
122.141.67.50 329
123.185.52.73 54
14.114.226.18 150
14.114.226.194 14677
14.115.129.55 4040
180.117.68.185 361
59.33.63.137 1476

抽几条完整日志如下:

101.226.68.137 – – [21/Apr/2013:19:44:18 +0800] “HEAD / HTTP/1.1” 200 0 “-” “Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; QQDownload 713; .NET CLR 2.0.50727; InfoPath.2)”
14.115.129.55 – – [21/Apr/2013:19:44:18 +0800] “GET /ftp/Win7_rtm_with_loader/cn_windows_7_professional_x86_dvd_x15-65790.iso HTTP/1.1” 416 615 “http://yewen.us/” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)”
14.115.129.55 – – [21/Apr/2013:19:44:22 +0800] “GET /ftp/Win7_rtm_with_loader/cn_windows_7_professional_x86_dvd_x15-65790.iso HTTP/1.1” 416 615 “http://yewen.us/” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)”
14.115.129.55 – – [21/Apr/2013:19:44:25 +0800] “GET /ftp/Win7_rtm_with_loader/cn_windows_7_professional_x86_dvd_x15-65790.iso HTTP/1.1” 416 615 “http://yewen.us/” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)”

SNS 背后的技术: 消息流的推拉模式选择

上一篇扯到 SNS 本质上还是要满足沟通需要, 既然有沟通就涉及到信息本体的传播, 曾经的各种传播方式多半采用把信息从消息源推送到接收者, 由接收者用收件箱保存并查看的方式实现, 比如短信, 比如电子邮件等等

这种推送模式在传统信息沟通中运作的还不错, 每个人维护一个收件箱, 消息发完就不用管了, 因为一条消息一般不会发给非常多的人, 所以发送过程几乎瞬时完成, 同时对接收者来说单位时间收到的消息不会太多, 所以收件箱也不用非常大, 定期清理或提供更好的查询方式就行了 (前者比如功能手机的短信收件箱, 后者比如 Gmail)

而在 SNS 上这个模式就不那么适用, 从消息获取机制上来看, 应该是 “我去看我的朋友们都在干什么” 而不是 “我的朋友们有什么事情要分享给我”, 从技术上来说, 因为 SNS 的消息非常多, 为每个人维护一个足够大的收件箱是非常耗资源的, 另外, 对 SNS 上的超级用户 (比如有上千万好友的人人公共主页或小站, 几千万粉丝的微博大号) 来说, 推送消息这个过程也非常耗资源和时间. 所以很多 SNS 采用的是所谓的拉模式, 即对每个用户维护一份发件箱, 用户需要获取信息时主动发起对所有其收听的好友一个拉取的操作, 从不同好友的发件箱拉回所有消息, 并实时组织这些消息

至此, 所谓消息的推模式和拉模式都简单说完了, 听起来都各有各的道理, 到底要怎么用才合适?

从存储的角度来说, 拉模式一定会节省资源, 因为消息都是一个源, 而接收者可能有多个, 如果收件箱和发件箱同时存在, 则所有的收件箱大小应该等于发件箱乘上单条消息的平均接受人数, 按一般理论上 SNS 平均好友数量是 150~200 的规模算, 拉模式比推模式节省 150~200 倍的存储空间, 另外考虑到好友更多的用户活跃度更高, 因而这个数字会更大, 再者人人网存在公共主页和小站小组等超大规模接收者的实体, 微博只限制单个用户收听其他人的数量而不限制单个用户被多少人收听, 所以这个差异还会更大

不过从网络流量的角度来说则两种方式各有利弊, 看具体的用户分布是怎样的, 如果那些收听了很多人的用户频繁的获取消息, 即意味着会有非常频繁的消息获取操作, 而这些操作都需要进行远程调用并带来网络流量开销. 不过这个问题应该可以用临时收件箱来解决, 把用户获取到的信息缓存起来, 下次有拉操作时只需要判断对应的好友那是否有更新的内容产生, 如果有则把新的信息拉过来, 否则只是一次远程查询的操作. 缓存只要维持一个不那么长的失效时间, 就应该可以在 cache 命中率和占用内容容量上获得一个比较好的折中

说来说去似乎都是拉模式更好, 那为什么还会有推模式存在的意义呢? 当然推模式也并不是一无是处, 从信息的异步角度出发推是比拉要好的, 试想如果别人说给你发了条短信, 等你要看的时候还必须对方在联网状态你才能看到他发的什么, 那不是坑爹么, 但是在 SNS 上这个问题基本不存在, 因为所有的信息发送源也都是同一公司下的服务器存储, 不可能不在线, 只是对于第三方应用来说, 需要把在第三方产生的消息推到 SNS 上来, 至少推到活动人的发件箱, 这样看推还是没有特别大的优势? 从用户体验来说, 推模式可以更快的拿到信息, 省去了多一层的信息获取流程, 登陆后就可以立即看到自己收到的消息无疑更有吸引力, 而且如果用户存在短时间密集登陆的行为, 则推模式下只要直接取收件箱就行了, 不会在后面还有 1*n 的拉取操作. 不过话说回来, 对用户密集登陆的情况, 只要高峰流量不大的离谱, 拉模式还是应该能扛住, 按上一段我们的优化方案, 不还有一层缓存么, 而且拉模式所谓登陆后要过一会才能看到信息, 这个 “过一会” 的时间绝大部分情况下应该只有不到一秒, 甚至不到零点一秒, 那这个延迟对用户而言完全感觉不到或不觉得有问题, 用户的宽带接入或手机带宽反而更可能是打开慢的原因

说到这里某狗作为拉模式的铁杆粉丝对推模式的不屑之意已经表露无疑, 估计有很多推模式的拥趸已经在准备找数据找架构要拍死我了, 那最后我再补一个拉模式更好的理由来对推模式一剑封喉, 那就是, 隐私

从本质上来说, 推模式是在维护一个巨大的面向所有用户的 cache, 而天底下几乎所有的 cache 设计思想都应该是满足超大的读请求, 一定的追加操作, 以及极少的修改操作 (如果是 FIFO 或 LRU 删除以保持空间大小这个应该是 cache 内部的事情不算调用者的操作, 所谓的修改是指改 cache 里某个 key 对应的内容), 如果是普通的消息发送-收件人阅读的模式, 推模式没有任何问题, 短信邮件活了这么久都好好的. 但是, 凡事就怕但是, 如果消息流有大量的垃圾信息, 那就会崩溃掉, 除非在收件箱里另开一块用于处理垃圾, 比如电子邮件一般都有个垃圾邮件分类, 自动帮你判别, 但在 SNS 上, 对垃圾信息的判断无法做到那么有效, 就算能判断的比较准, 也没有另一个信息流来存放 (从这点来说 Facebook 的 ticker 其实就能起到垃圾信息收件箱的作用, 信息不丢, 但是也基本不会干扰用户, 如果要找回来也有地方可以去找), 而且 SNS 上太多用户的随意行为想做撤销, 比如发了不该发的照片, 或是 spammer 被举报后要将起发送的垃圾信息收回或做过滤, 如果再考虑上因隐私范围修改而要对已发出去的消息做限制, 这一大堆修改操作会让 cache 痛不欲生欲仙欲死

考虑下 SNS 上好友关系的频繁变化, 如果有新增好友关系或收听关系, 则推模式下后台应该立即对 Social Graph 上这条新的边做消息推送, 这时候还要依赖发件箱, 即推模式无法抛弃发件箱模块. 而如果是删除好友关系, 也应该立即把这条边做个逆操作, 这个操作更重, 需要扫收件箱的所有内容并删除特定的消息. 万一还有用户注销, 或是 spammer 被封需要收回其发出去的各种垃圾信息, 或是被 XSS/CSRF 攻击后要做清理, 都需要对大量用户的收件箱做扫描和选择性删除, 这些操作既重又要求很高的时效性, 否则就可能是安全事故, 这些都让推模式下 cache 的设计初衷被破坏的一塌糊涂

再说隐私控制, 最早的 SNS 压根就没有隐私这回事, 发出去的东西谁都可以看可以评论可以分享可以做任何演绎操作, 只是我的好友能有个简单快捷的入口找到, 后来就有了仅好友可见, 发送给指定分组 (其实是发送给特定的某些人的简化版), 不可分享不可回复等各种要求, 如果这个要求一直都是固定的也还好, 再消息发送的时候加个限制, 对不该收到此消息的人不做推送, 然后消息本身自带权限标记来说明收件人可以对此消息做什么动作. 可惜的是咱们亲爱的用户永远不会这么想, 发送对象会一直变, 今天是密友的明天可能是工作同事, 那推送时的判断就是一个一直在变的表达式, 维护这个表达式和查询判断又是个很重的操作, 而用户如果再发送完成后再改权限, 那就涉及到更多的对已推送消息的修改, 比如用户从所有人可见改为仅好友可见且不能被分享, 那其实是要重复一次消息的发送过程, 万一这中间有延迟或用户过了段时间才做这个操作导致以及有好友把该消息分享了出去, 那整个更新操作就不是一步而是一个 BFS 了, 对网络调用对 cache 都是莫大的伤害

如果我们把权限收回到消息本体, 每个人的收件箱或发件箱只是一个索引, 是不是就能解决问题呢? 好像是? 但是推模式下每次从收件箱给用户显示消息时还加一次判断, 这不还是在做拉操作么? 带了拉操作的推模式? 那为什么不直接改拉模式, 还节省 cache

再回到推模式更快的用户体验, 既然加了权限验证等操作, 那这个用户体验估计也省不到哪去, 而且 发送-验证-到收件箱 和 拉取-验证-取发件箱 都是三步操作, 谁也没有更简单, 反倒是拉模式的验证过程只在拉操作时发生, 而推模式下有修改时还要补发验证流. 另外因为收件箱容量不可能非常大, 不管是 cache 的用户数还是单个用户 cache 的消息条数都有限, 那 cache 不命中时还是必须走拉模式取消息, 如果把收件箱变成拉模式触发的短时小 cache, 或用推拉结合对热点用户做一些预处理, 整个用户体验应该还是可以保证的了的, 对于 cache 里可能的消息权限改动, 只要有一次通知, 让此 cache 失效, 下次还走纯拉模式应该就能搞定

上面都是理论扯淡, 具体应用还是要看 SNS 模型和消息模型来决定怎么用好. 以下根据公开资料和个人猜测来八卦下各家的做法

Twitter 公开资料说他们走的推拉结合, 有 cache, 但是大部分还是用拉的操作, 很多调用来源是移动端或 API, 慢点就慢点大家都无所谓, 第三方 API 本身就是在定期做拉操作以变相完成推模式, 而且发出去的东西容易收不回

Facebook 对离线用户应该是拉模式加收件箱 cache, 用不经常登陆的小号很容易验证, 只要稍微有几天没登陆, 一上去 news feed 也一定是空的, 要有取的等待时间, 而且明显不是因为翻墙带来的延迟. 而且 FB 对 news feed 默认不采用时间序, 如果用推模式用户查看时从收件箱取还是要做一次排序, 且这个排序操作不是非常轻, 那再前面套一层拉操作影响也不会大, 还不如直接走拉模式, 就算考虑热点用户被拉的操作会很频繁机器扛不住, 那同步几份发件箱对拉操作做负载均衡就可以了, 比起用推模式 100 倍以上的机器需求, 如果真的大量存在热点, 拉模式增加十倍机器随便就能解决这个性能问题. 不过如果用户在线, 则推模式生效, 有新消息会立马推送到 news feed 或 ticker 里来, 只是新来的消息只能按时间序放最新的地方了. 另外删除还是一个老大难问题, 经常发现有好友被攻击后发的垃圾消息要过很久才会被干掉 (退出后 cache 失效下一次登陆改拉操作才去掉的?)

新浪微博号称他们用推拉结合, 不过据我观察和小道消息应该还是纯拉加很小的 cache, 因为新浪微博活跃的都是一群公知大号, 给他们的消息做推操作会把网络压死 (另外吐个槽草根大号的运营人员都是准点上班的, 他们会几乎同时发大量内容, 这一瞬间如果用推估计就把全网给搞嗝屁了). 对用户而言, 登陆时拉出一整页的内容放 cache, 就新浪那个前端加载速度, 绝对不比后台做一次拉操作快, 所以用户几乎感觉不到, 等用户往下滚动页面时候依次吐出 cache 内容, 速度飞快体验完美, 吐完了就该手动翻页了, 不过有多少人会往后翻? 根据我在搜索上的经验, 应该不到 10%, 而这时候慢点大家也还是可以忍, 都主动翻了还在乎这一两秒? 在天朝政治正确很重要, 所以微博删帖的效率也一定要高, 以微博的删帖量, 走推模式估计还是会把网络拖挂, 而拉模式下只要判断下最原始微博是否不存在或属被证实的谣言就 OK

QQ 空间走的应该是推, 大部分时间都一亿多用户在线, 空间上有点新动态还是很快会在 QQ 面板上跳数字, 而且腾讯一直做的是实时通讯, 在实时过滤黄反方面经验好的很, 基本不用担心有太多类似删帖的更新操作把网络弄的很崩溃. 不过具体到 QQ 空间里的一些模块, 比如个人主页等, 那就看应用场景是推还是拉了

至于人人, 可能会比较敏感不便多说, 之前号称是推拉结合, 不过在我看来就是个比较单纯的推模式, 且目前看来推模式的各种坑爹问题都存在, 比如 cache 占用太多资源, 删除操作多且难做到实时等等都有. 还因为是推模式, 整个隐私框架也难有大的改进

最后给大家瞎掰一些数据算算不同模式的 cache 需求 (包括总 cache 大小和为负载均衡用的机器数) 和网络开销 (包括调用量和带宽), 看到底怎样好 (以下涉及到平均的数字多半都是长尾分布):
A. 某网, 日活跃用户 10M, 月活跃用户 50M, 总用户 100M, 平均每个人有 150 个双向好友, 每个活跃用户在活跃天内平均有 10 次查看操作, 平均每次操作取 20 条消息, 并有平均 3 次消息发布操作, 每条消息索引 1K, 消息本体 20K
B. 某网, 日活跃用户 15M, 月活跃用户 60M, 总用户 200M, 平均每个人有 100 个单向出好友边和 200 个单向入好友边, 每个活跃用户在活跃天内平均有 20 次查看操作, 平均每次操作取 10 条消息, 并有平均 2 次消息发布操作, 每条消息索引 1K, 消息本体 2K

极端情况 1: 如果消息发送者都是出边数在 M 这个级别且其每天发送量要比平均值高一两个数量级的怎么办? (比如新浪微博的各种大号, 算完后估计你也会理解除了商业原因, 某些架构下技术原因也还是对他们做点限制好)
极端情况 2: 如果消息查看者的入边数都在 K 这个级别且其每天的查看操作比平均值高一两个数量级怎么办? (比如新浪微博的 VIP 用户, 最多关注大几千人, 而且频繁刷)
极端情况 3: 考虑下活跃用户的各项数据平均值会比全局平均值高一倍

用沟通模型分析社交网络用户诉求

关于在社交网络 (Social Network Service, SNS) 上, 用户到底想要什么, 这个问题一直在想并且想了很久, 最近对个人认识体系有个相对完整的想法, 感觉还是用沟通模型来解释比较好

在得到这个想法前, 翻看了很多别的地方的讨论, 包括知乎上被转比较多那个 “上人人网就是为了泡妞” 的说法, 如果抛开这些非持续性的稳定需求, SNS 也好, IM 等也好, 最后一定还是回到沟通的本质上来. 虽然人人的早期 (当时还是校内和 5Q 在 PK), 以及其他的很多 SNS (比如早期的 51.com, 还有陌陌) 的第一波增长都是约炮, 但是约炮的人毕竟还是有限, 做成十万或百万规模还行, 而且有道德和法律风险, 要想继续做大, 必须还是走正路, 就还是沟通

在这里把不同的沟通模型拿进来看, 个人感觉主要的差异性在: 1) 实时与否; 2) 反馈与否; 3) 私密与否; 4) 重要与否. 当然这个划分方法不一定能很好区别, 不过大体来看可以如此. 实时性是指是否可以异步进行, 还是必须参与方必须实时参与; 反馈是说沟通是否单向, 收到消息的人是否需要反馈, 在这如果加个强要求就是是否必须反馈; 私密是说这个沟通是否有限制参与方, 非预期内的人是否也能参与; 重要表示对参与方的重视程度, 比如是否需要当面或书面等方式表达. 按我这个定义, 把常用的方式列举如下 (后面符号分别表示是否 实时/反馈/私密/重要, o 表是 x 表否 ? 表可能)

会议 o/o/o/o
聊天 o/o/x/x
电话 o/o/o/o
短信 x/o/o/o
电邮 x/o/o/o
IM ?/o/o/x
SNS x/o/?/x
博客 x/?/x/?
微信 ?/o/o/?

基本上越重要的事情应该是需要当面说, 并且最好是有记录的, 而一些随便的东西就不一定要当面, 而且不一定要是同步通讯, 再随便一点就也可以不要求私密性, 博客谁都可以看, 在轻松环境下的聊天也可以任何人都来参与. 另外一个比较大的差异就是是否需要反馈, 这事是你自说自话就行了, 还是必须有其他人反馈你才能继续下去, 或有动力持续下去.

扯回到 SNS (特别是人人) 上, 这四个特征对应的分别是:
1) 实时性. 信息是否能被实时获取, 甚至实时的推送到收件人那并有明显提示. 更严格对应到人人上, 就是新鲜事的到达速度, 以及导航栏气泡/聊天窗等信息到达速度. 应该说人人对实时性要求没那么高, 最多也就是数分钟这个实时性, 有爆炸性事件能保证可以被传播, 热点内容的传播足够快就行, 类似 IM 那样的实时性要求并无太多必要
2) 反馈性. 用户行为是否需要有反馈, 且反馈是否需要有明确通知. 对应到人人上, 就是新鲜事是否可以被回复, 被分享, 被喜欢 (或其他的快速情感表达, 赞/踩等都算), 反馈的通知就还是气泡或其他推送信息了. 不过很多反馈会要求实时, 比如两个人版聊起来了, 这时候微观交流就会被从 SNS 变成 IM. 其他的反馈可以不那么实时, 但是一定要有
3) 私密性. 用户行为是否需要限制可见人或参与人. 对应到人人上, 就类似个人主页是否任何人可见所有内容, 相片等内容是否只有好友可见或更复杂的隐私模型 (这个近期也想写点东西说下)
4) 重要性. 是否需要区分不同重要性的内容? 比如我女朋友的新鲜事我一定会关注, 而一些公共主页, 类似我们爱讲冷笑话这样的, 可能就是兴趣来了看一下, 没兴趣时就不看了, 来自这些地方的新鲜事丢了就丢了我也不在乎

SNS 的默认模型不需要那么实时, 所以太过频繁的消息推送会让用户觉得反感, 获取信息的主动权应该由用户来拉, 除非是用户非常关注的信息值得去推送 (比如某屌丝暗恋关注的女神有新动态, 他可能需要去抢沙发以获得更多好感)
另外用户的行为需要获得反馈来提升 TA 的黏度, 所以当用户的信息是被朋友或陌生人看到且作出相应回应 (我看过了, 我觉得赞, 我来说几句, 我来骂醒你) 后, 这个消息一定要推送给 TA, 至于实时性与否可以分情况讨论. 另外如果是太频繁且无用的提醒, 那此反馈渠道基本就算废了

来看看现在人人网上的用户都是啥样:
1) 有人喜欢显摆, 发个照片或日志希望大家都来看看我有多牛逼, 这种人需要更多更实时的反馈, 所以消息应该尽快推给他的朋友或其他人, 并让他的朋友尽快反馈 (哪怕只是很简单的一个赞按钮), 这样能促使他更多的活跃
2) 有人喜欢观察, 就是看自己订阅的信息, 这时候需要让他的信息流的实时性和完整性更好, 同时因为其拉信息足够频繁, 所以可以让其自己决定查看方式 (新鲜事是否按时间序这时候就很重要, 同时是否支持分好友组或分类型查看也很有用)
3) 有人就是 “我跟大家说个事, 我说完了, 再见” 这样的风格, 以工作了发婚纱照和娃的照片居多, 不过其实他们还是希望有反馈的, 比如 “婚纱照真漂亮” “娃好可爱” 等, 但是他对反馈的时效性不敏感, 只要定期有一个汇总就好, 并且他很可能不会主动来看反馈, 需要我们去推送 (一天一次? 一周一次?)
4) 有人就是 “今儿大爷心情好上来看看朋友们有啥好玩的”, 以工作了偶尔上来看的居多, 这些人需要尽可能快的让其获取关键信息 (主要是为了完成反馈操作), 然后再用起感兴趣的内容做扩散阅读希望能让其有更多的黏性

第一种和第二种人会是重度用户, 但第三种第四种才会是更多人的存活状态, 而且大部分人同时兼有 34 两种特性
第一种人需要的是更好的发布器, 让其发布内容更方便更爽, 同时把反馈尽可能快的推送给他并让他获得满足感, 并能跟其他人互动起来
第二种人需要的是更合理的信息获取方式, 优化新鲜事, 相册分享等浏览方式 (比如严格按时间序, 指定用户范围或新鲜事类型), 并给他足够简单高效的反馈让 13 两种用户能持续活动
第三种人更需要一个合适频度的反馈渠道 (邮箱? 合并了的手机通知?), 让他们能从发布信息获得成就感, 并保持活跃度继续发布内容或跟人交互, 过频的通知反倒会逼走他们
第四种人的信息流组织是个很有挑战性的活, TA 的收件箱可能压了一堆没读的东西, 那怎么把重要的东西挑出来让他不要错过, 同时也满足 13 两种人的反馈需求, 这个事情很重要, 那新鲜事就不应该按纯时间序而是按重要性组织, 或单独提供一个要闻模块, 以在可能很短的访问时间里更多完成他的信息获取需求和让他完成其他人需要的反馈行为

具体到一些产品上, 个人感觉应该做的
1) 消息本体, 保证其能被进行回复/分享/喜欢等操作, 并且消息展现的不同地方体验一致 (不管是新鲜事, 还是个人主页或时间轴, 以及终端页)
2) 新鲜事, 保证信息不会因为消息传递阻塞或蹩脚的排序/折叠/聚合方式而丢失或有很大延迟, 同时提供多种查看方式让用户自己选 (时间序/分组/分类/特别关注等)
3) 分享/收藏, 有算法聚合或人工推荐的公开信息聚合页供随便逛的用户打发时间, 也有多维度的查询方式让用户定位自己看过或收藏过的特定信息
4) 搜索, 类 Facebook Graph Search 那样的有点科幻, 而且实用性不高, 能按关键词搜人, 个体的新鲜事中的文本标题或正文, 以及全站公开信息的文本部分就 OK (比如状态, 相片/相册描述或标题, 分享的视频标题和评论等, 特别是用户自己的新鲜事内部搜索)
5) 通知系统, 更精准的消息推送, 现在导航栏上有消息气泡, 加好友气泡, 提醒气泡, 这仨应该被合成两个, 如果需要有实时的聊天需求, 类似私信或站内信这样的可以单拉一个气泡, 且无关紧要的进 ticker (这是个神器, 后面会讨论), 如果导航栏上的通知做的足够优, 网页内的右下角弹窗应该也能被整合
6) Ticker, 不得不说 Facebook 的这个东西是我在其他地方都没见过且我觉得非常赞的神器, 这里面糅合了不重要的新鲜事和通知, 保证信息的完整性, 且因为其占据的位置不大且不那么醒目, 又不会干扰用户正常行为, 同时 ticker 可以作为实验田, 我们猜测不重要的新鲜事可以试着先移到这, 如果用户还持续交互, 说明用户对此消息源或此类型的消息还是感兴趣的, 应该被更重视用更重的产品来展现, 通知反馈也是一样 (比如我的好友 x 跟 y 加为好友, 我要不要也跟 y 加为好友), 另外如果要对信息流做货币化, 这里显然也是个很好的切入点(做广告做久了的职业病, 啥都想到卖钱上去). 总之, 这个东西是少数几个我觉得一定要从别人那腆着脸抄过来并将其好好优化的功能之一
7) 隐私体系, 大部分人当这个地方是公开场合 (谁都能看, 比如微博), 或有限开放的公共场合 (大家对人人的默认定位, 好友可见, 其他人看我的内容被分享的情况了), 如果一旦有不适合按这个规模公开的内容, 用户又找不到方便的手段限制, 那势必会流失或遗憾 (比如我有一些以前的猥琐照片想分享给大学同宿舍那几个哥们, 现在就是放哪都不好, 人人上的隐私体系管不住, QQ 群别人不一定看到, 大家的交流也是时间序的而不是围绕这张照片进行, 不过 QQ 空间似乎有这样的功能了?), 而相反, 如果给用户提供隐私选项让其对部分内容加限制, 反倒应该能促进他更多的发布公开内容, 并让全站良性循环

租房提取公积金流程记录

更新 2014-09-30, 因政策变化, 本文部分内容已不适用 (新闻来源: 人民网: 北京提取公积金无需购房合同 租房可3月提1次)
更新 2013-04-18, 发票和租房合同原件已取回
更新 2013-03-28, 钱已到账, 发票暂未取回

大约半年前发现公积金放在国家那是不划算的 (计算方法见最后), 所以一直想着把钱盘出来, 最近完成了提取的大部分步骤, 把过程写下来供他人参考

步骤和注意事项
a. 开租房发票和完税证明
a.1) 房屋所在区的任一地税或代征点办理, 代征点一般几个小区就有一个
a.2) 带上 1/2/3/4/7/8 去, 交租房合同上总租金的 5% 税费, 一般都只收现金, 得到 11/13
a.3) 注意发票的付款人是租房人, 收款人是房东
a.4) 注意完税证明的纳税人名称是房东
a.5) 注意发票上的租房时间和合同一致
a.6) 注意发票上项目只能是 “房租”
a.7) 注意发票上总额除以租房月数后是整数
a.8) 房产证在最近一年及发票上租房周期内没有其他租房提取记录
b. 在中智办理支取手续
a.1) 中智在汉威大厦 27 层 4 号窗口
a.2) 先在后面电脑上提交电子申请, 桌面第三个快捷方式, 点打印 (实际不用打出来) 后再提交
a.3) 提交 1/2/3/4/5/6/7/8/9/10/11/12/13/14/15 给窗口工作人员, 验证后当场返还 1/3/5/9
a.4) 据说 7/11/13 办妥后由驻公司的中智员工还我
a.5) 每月 20 日前办理当月的申请, 月底到账
a.6) 提取人最近一年需没有提取记录

所需材料
1. 房东身份证原件 (a/b 用, 验证后当场返还)
2. 房东身份证复印件 (a/b 用, 收走)
3. 房东房产证原件 (a/b 用, 验证后当场返还)
4. 房东房产证复印件 (a/b 用, 收走)
—- 如果房产多人所有则需每个人的身份证和房产证原件复印件
5. 租房人身份证原件 (b 用, 验证后当场返还)
6. 租房人身份证复印件 (b 用, 收走)
7. 租房合同原件 (a/b 用, b 处收走, 办妥后归还)
8. 租房合同复印件 (a/b 用, 收走)
—- 非中介用合同建议用北京住建给的模板, 没用的可以删掉, 关键是要有房东和租房人信息, 房屋地址, 租期, 租金这几个
9. 支取用银行卡原件 (b 用, 验证后当场返还)
10. 支取用银行卡复印件 (b 用, 收走)
—- 不强制要求公积金联名卡 (反正是一年一次的操作)
11. 租房发票原件 (步骤 a 获得, b 处收走付款人一联, 办妥后归还?)
12. 租房发票复印件 (b 用, 收走)
13. 完税证明原件 (步骤 a 获得, b 处收走, 办妥后归还)
14. 完税证明复印件 (b 用, 收走)
15. 提取申请书原件 (b 用, 收走)
—- 中智的在这里下载

提前支取的理由和其他的一些感慨
公积金中心的计息方法是: 当年缴存的公积金按活期利率算存款利息 (目前是 0.72%), 去年及之前的按三个月定期利率算存款利息 (目前是 2.75% 左右)
一般的投资收益应该在 4% 以上 (随便哪个银行的理财产品都不会低于 4% 吧? 这还是最稳妥收益最低的)
提取公积金要交的税是 5%
所以, 如果一年半内不买房, 花 5% 的手续费 (税费) 把钱取出来做投资, 一年半内能回本 (如果有其他更好的投资渠道回本时间更短), 而且钱放自己手里比放国家那显然更放心, 谁知道政策以后会变成怎样

感觉我办这坨事还算是没怎么折腾, 关键是有朋友肯借我房本和身份证用, 不然就算是正常租房, 一般的房东也绝对不会把这两样东西给你哪怕半天, 而且对应房本在这个时间段内还不能有其他租房提取, 所以现在中介帮弄都是要 15%~20% 的手续费, 他们租房本什么的也还是挺贵的, 而且都是把一个房本对应到好几个合租租房合同上去帮人取. 另外公积金中心不对个人, 必须是以公司或人才市场的名义去, 这应该也是中介手续费高的原因.

ps. 朝阳的公积金管的比较严, 中智卡的更严 (那个房东房本和身份证原件就是中智的土规定), 所以如果在海淀能取建议在海淀取了, 据某些中介说可以用买房等发票套出来, 最低的时候手续费只要 3%

12306 和火车票那点事

每年春运时铁道部和 12306 都要被喷死, 自己也和 12306 斗智斗勇了两三年, 这个冬天跟着 @scat 君折腾了很久, 随手写点什么说说这事.

提前说明我只是火车迷, 不是铁道部的人, 用不着帮铁道部把黑的说成白的, 我自己也有各种怨气要喷, 只是希望能提供一个相对客观的事实供大家来参考参考. 前半段跟喷子对喷和对 12306 的吐槽的会多点, 后面有一些胡思乱想的一些可能称得上是建议的东西.

喷子和不那么容易的 12306

然后以一个标准喷子的口气对那些说 12306 做的很烂随便找个本科生就能写的人骂一句, 去你大爷的什么时候国内的学生素质这么高你有多少我要多少; 再对一些所谓业内人士说的这种负荷找淘宝什么的能轻松解决的观点说句很抱歉, 这两个虽然在规模和突发性上有不少相似点, 但是还是有很多不一样的地方, 比如淘宝上一件商品如果有多件是无区别的, 而火车票一张就是一张, 有人买到上铺还不干非得换下铺, 而且这里面一张票就是一个锁, 而且淘宝超售了最多补货或退款, 火车可不是说加床或加位子就能加上去的, 而且要是先跟你说买到票了然后说不好意思超售了我们退钱给你, 不知道有多少人想直接穿过显示器把那边的服务器给砸了; 最后说说 12306NG 那帮人, 最近没关注, 一年前看了下那个论坛和所谓的发起人, 很可惜里面大部分都只是夸夸其谈一些自称砖家的喷子, 很多人估计都没做过百万规模的系统就敢各种意气风发指点江山, 这种人都能说出靠谱的整体解决方案和细节注意点来那就见鬼了.

喷爽了咱们来摆事实讲道理说说 12306 的各种不容易, 先说我们是怎么搞他的:

> 最早的 12306 基本上就是一个高校实验室的产品, 空闲时段可用, 用的也还凑合. 据说有收钱不出票的情况, 不过我还没遇到过, 所以不好评论. 退票的钱不是实时到账的, 快的几天慢的一个月我也都遇到过

> 等到了高峰期的时候, 开始各种登陆不上, 各种刷不开页面, 或提交不成功. 这时候最大的问题是带宽和前端服务器不够, 压根抢不到一个有效连接.

> 等把带宽问题基本解决后, 发现每一次页面加载都需要做太多次 GET 操作, 而且很多页面数据不优化不压缩, 虽然系统还用了 jQuery 什么的至少看起来算是跟上先进生产力的技术, 但是整体还是比较糙, 据说是用 CDN 和大量加机器来算扛住. // 不过到现在一次页面加载需要获取的资源还是太多, 而且一开始没做内部的负载均衡, 容易出现一个 ISP 解析过去都在少数几台机器, 所以同一地区不同 ISP 接入的速度会有明显差异 (比如北京联通用户多, 基本就卡成幻灯片, 用用户少的电信线路就相对靠谱点), 而且个人认为不少机器加的很浪费

> 有了缓存机制后发现一个巨坑爹的地方, 12306 似乎把后台实时数据和 CDN cache 在某些地方用反了, 比如余票等实时性非常强的数据反倒在前端有一个 cache, 平时还好, 但是高峰期放票瞬间这个 cache 就要命了, 如果你赶巧碰上一个更新较慢的 CDN, 估计等你刷到数据时票都被别人买完了 // 这个问题现在还是没有解决, 所以才有使用一些专线 CDN (比如传说中的海外线路) 可能会保证网络比较通畅 cache 更新也比较快的说法

> 等机器, 带宽, 缓存什么的搞差不多后, 开始有技术流的 hack 手段出现, 曾经有这样的刷票方法: 要买 2.3 的票, 但是还有几分钟才放票, 不确定自己是否一定能命中更新较及时的 CDN, 于是可以先查 2.2 的票找到对应车次的任意席位的票, 在填写乘车人信息时改 POST 请求中的参数, 把时间改成 2.3, 席位改成自己想要的 (比如硬卧), 然后强制提交, 只要到了放票时间, 不管自己连的前端服务器是否更新余票缓存, 都可以把这个请求提到后端进行处理. 这方法我用过, 很爽, 可惜现在被封了. // 封的手段是在提交订单时加了一个加密串, 发到站, 时间和车次必须和加密串对应才能提交. 不过这个加密串在同样条件下每次查询都可能不一样, 但是同一个验证码可以用无数次 (或者是一个比较长时间段内都可用, 没确认), 所以可以用大量的机器密集轮询 12306 不同的前端服务器获得对应的加密串, 一旦有这个数据就可以构建数据强制提交了. 此方法目前还可用且有人在用, 不过需要考虑 12306 现在开始限 IP 或限同 IP 的连接数了

> 12306 注册帐号需要提供证件号, 不能坑别人, 所以默认大家一人就是一个帐号, 同帐号只要有订单没完成, 就不能去下别的订单, 如果一次要买不同车的票, 那就疯了, 还好 12306 允许护照/港澳通行证什么的也可以注册, 谢天谢地又多几个帐号可以一起刷了, 果然办个护照什么的还是没坏处的. // 这个限制其实也能绕过去, 你收集一堆朋友的帐号给你抢一张票不就行了. 还有个更 ws 方法能很容易搞到成百上千的帐号, 个人使用怎么着也都够了, 具体方法还是不说了, 免得被封

> 能搞到提交所需数据, 也有足够的帐号去刷, 那接下来的问题就是怎么把能自动化的地方自动化. 各种抢票助手的原理大致都是做一个浏览器插件, 自动重试查询, 并且监控对应的票额, 然后把一些能自动完成的步骤自动完成 (比如点下一步什么的) // 这里还是有带宽的问题, 其实并不是每次都要把所有的流程都走完, 获取的数据也只要核心数据, 不少插件应该没考虑好这个, 还是对用户的网络有比较高要求. 另外 12306 也做了一些限制, 比如连续两次重试时间不能小于五秒, 偶尔也改一下 URL, 做个 302 跳转什么的. 不过整体而言这个封不了, 完全模拟用户行为, 后面的一些 hack 也基本是这个思路

> 一直到上一步, 应该说已经能将大部分操作自动化完成, 唯一的麻烦就是验证码. 12306 一直到 2013/01/25 用的都还是用一套非常弱的验证码, 字迹清晰颜色差异明显, 最关键的是字体似乎只有两种, 随便找个学过基本的图形学的本科生应该就可以搞定, 先做二值化提取出有字的部分, 然后做水平和垂直方向的投影, 按区块直接跟已知的单个验证码特征库最对比就可以了. 死猫君和其同伙用 C/C++ 实现, 能做到 1ms 一个验证码, 99%+ 的准确率, 12306 在这样的识别效率面前已经完全不设防, 想怎么搞就怎么搞. // 但是超简单的验证码已经从 2013/01/26 开始变成了一个相对复杂的, 原来的方法需要做一些优化才能用, 且识别率可能不那么高

> 就算验证码的识别率下降, 但哪怕只有一两成的成功率, 机器还是比人快的. 12306 的对策一开始是加浏览器参数校验, 如果是裸的 POST 请求就拒绝掉, 但是 http header 这种东西, 自己人肉走一遍流程把对应的数据扒下来让机器模拟还是毫无压力. 接下来 12306 是不停的改接口 URL, 虽然最后还是落到同一个处理接口上, 但是加上了跳转判断, 直接提到最终接口的会被拒绝, 到这就变成猫鼠游戏, 12306 改一次 URL 对应的机器行为就要跟着改一次. 估计是今年各种机器行为搞 12306 搞的比较疼, 虽然他们已经提供了超过一千个对外 IP, 也还是怕被这么搞, 接下来的一招是加了更严格的间隔时间限制, 这时候机器行为的成功率就很重要了, 一旦重试最少五秒就过去了, 而且有一些步骤加了很猥琐的隐藏等待时间, 机器提交太快会报错, 而慢一点接近人的速度就没事. // 最后那个限制真心无解, 不过对手快的人也是很伤的, 别人眼尖手快你还能不让别人买? 跟 @scat 吐槽说看来 12306 对他们的网络很有信心, 正常人五秒内是刷不开第二次或能提交上请求的. 另外机器重试时加个随机附加时间, 可以对人的行为模仿的更像, 这个 12306 没法做特征库来判断是人的行为还是被机器刷

> 攻防到这阶段, 两边基本就没什么办法了, 不过 12306 干了件更 NB 且 WS 的事情: 同 IP 限制登陆人数和封 IP. // 不知道 12306 怎么判断的, 反正 jike 他们那种抢法绝逼是要被封 IP 的, 但是很多企业对外出口就一个, 要赶上员工集体抢票, 结局就是集体悲剧, 反正我在公司悲剧过几次 -.-|

目前拉锯战就到此, 如果是真的搞技术的人, 要是自己的产品成天都在被一群这么蛋疼的人这么玩, 估计早就疯了, 所以说 12306 今年系统一直还可用 (虽然还是会卡还是没有票), 且一直在增强防御, 还是挺不容易的

关于 12306 和铁路客运的吐槽及建议

前面在同情了半天 12306 后还是吐槽没票这个现实, 没票的最大原因还是运力不足, 大家都想过年前一天到家, 那单日发送量必然爆表, 但车就那么多, 只能靠抢

运力不足有一些变通的方法, 比如加挂车厢, 动车重联等方式来提升已有运力, 这个大家都很爽; 比如卧代座 (硬卧车厢当硬座买, 一节车厢大概多卖 20 来张票), 这个大家也觉得还好, 遇上比较 nice 的车上铺还能爬上去轮流躺着睡觉; 比如开临客, 这个似乎就不那么灵光了, 大家对临客的印象还是又慢又破的绿皮车, 经常让车和晚点, 殊不知现在连高铁都有临客, 只是不挂 L 的车次, 临客最大的问题还是时间不好, 一般都半夜出发或到达, 除了这个其他都还好, 我坐过北京到南宁的临客, 空调车人也不多, 除了慢了点其他都巨爽; 比如提升车底周转率, 普速时代最多就是把长途车到终点后再开个短途, 把到下一次发车前的这段间隔用起来, 这个意义好像不大, 而且本来车还是要整备的, 但是动车和高铁时代提升周转率就很有意义了, 同样的北京到武汉 1225 公里, 一路不停按 250 的速度要至少五个小时, 但按 380 的速度跑就不到四个小时了, 同一列车底长短混跑, 一天可能就能多开一趟车, 可惜这个被现任铁道部的猪头领导以安全为由强制降速, 而且给动车组生产厂家的订单也不加, 导致需要车的时候没车, 单车底也还有检修里程限制, 不可能 7*24 连轴转, 坑爹啊这不是

另一个导致运力不足的问题是车票价格, 现行火车票价格已经十多年没变了, 期间还经历了六次大提速, 其他交通方式和物价已不知道涨了多少, 偏偏铁道部自己还涨不了价 (发改委什么的一堆流程要走), 所以只能绿皮改空调, 普速变快速 (虽然实际时间可能还慢了) 来曲线救国, 动车和高铁的票价是明显上了一个档次, 所以也能解释为什么有高铁后普速必然会少一堆, 大部分国人还是缺钱不缺时间的主, 特别是学生这种巨叽歪的群体. 造成同样结果的还因为人民群众的生活水平提高了, 也娇气了, 以前有硬座就很好, 现在很多人还非卧铺不坐, 最狠的是只要硬卧下铺的, 人家理由多充分: 软卧太贵硬座不爽上铺难爬, 需求就这样被密集化 (很多人都是只坐某趟特定车的某种特定铺)

在供给远小于需求的供需现状下怎么搞都无解, 那只能把问题退一步, 让大家怎样以一个 “公平” 的方式来搞. 我自己想过一个方案, 后面有一次问了 @cnberg 印度是怎么弄的, 发现跟我想的基本一样, 我先说说印度怎么订票:

1. 订票提前周期很长. 订票时
– 1.a 如果有票则付全款出票, 完成
– 1.b 如果没票则交押金 (大约 10 人民币) 进入一个排队队列
2. 排队过程中
– 2.a 可随时查询在队列里的位置, 当新票额放出或有人退票或退出排队, 你在队列里前进, 排到后付全款出票, 退押金, 完成
– 2.b 如果到开车时间还没排到有票的位置, 退押金, 完成
– 2.c 主动退出排队队列, 押金不退, 完成
3. 退票
– 3.a 退票收取大约 10% 的手续费, 完成

这里面最爽的是引入了排队机制和获知自己排队位置的查询接口, 让整个过程对乘客而言更透明. 但是当时我们讨论时也说到, 中国春运是刚需, 提前半年估计也会在订票的时候就把系统和队列压爆, 只是把现在提前 20 天的坑爹提前了而已, 而且对那些没法提前那么长时间确定行程的人是一种伤害. 而且估计印度网民远没中国多 (具体数据没查, 但是用脚也能想到), 所以系统压力没那么大

我的方案比这个更激进点, 不同的是
1. 排队时就可以先付全款, 这样一旦排到票马上就能出票, 不至于说排到票时自己不方便, 因为没法付款而导致被从队列里强制踢出去
2. 退票费按退票时间到开车时间的间隔依次递增, 越晚退票手续费越高, 这样也让那些买多张票备用但最后只用一张的人提前把资源让出来给有需要的人 // 现在就很多人买好几张票备着, 走之前才退, 结果其他有需要的人也来不及捡漏

这些都是比较大的系统性变化, 我们这些玩票也就吐吐槽, 如果有不妥或没考虑到的地方也欢迎讨论

落到 12306 本身, 感觉可以提供一个精简版入口来满足订票需求, 像界面/退票/添加修改常用联系人之类的操作很少用到, 没必要每次都为了兼容这些操作而走那套有巨多图片和 .js 加载的系统, 刷票助手什么的其实就是在帮忙减轻网络压力, 反正大家只要能定到票, 直接做个纯文本界面也无不可

压缩 VirtualBox 下安装 Linux 的 .vdi 虚拟硬盘文件

之前虚拟机里装过一个 Ubuntu, 闲的蛋疼还装了 KDE 等一陀东西, 后来不想玩了折腾把不用的删掉 (主要是 KDE 及其相关, 还有升级内核留下的一堆 linux-image)

删除 KDE 我用的是 http://www.cnblogs.com/wangvsa/archive/2012/07/22/2603626.html 这个帖里提到的方法, 直接复制命令删除就行了, 不过粗看了一眼这一把应该也删掉了不少其他的依赖, 算了, 有要用到的时候再 apt-get install 好了, 另外也有类似 http://os.51cto.com/art/201001/176255.htm 这个帖里提到的用 apt-get --purge remove 移除某个核心库的方法, 但我没试.

删除多余 linux-image 用的是 http://blog.csdn.net/c9h8o4/article/details/6647220 这个帖里提到的方法, 简单实用. 用 dpkg --get-selections | grep linux-image 找到现在安装了哪些版本, 接着用 uname -a 看当前版本, 再通过 apt-get remove 的方式把不用的移除.

把多余的东西删掉后发现虚拟机对应的 .vdi 虚拟硬盘文件还是很大, 查了下说是在允许容量范围内, 动态扩展的 .vdi 容量会一直扩大而不会缩小, 必须手工做压缩. 搜了一堆方法后发现 http://www.kilobug.com/archives/624 这里说的最简单, 用了一下确实, 从之前的 14.1G 压缩到 5.67G (删了一陀东西也有帮助), 简单复述一遍:

1. 在虚拟机里把没用的磁盘空间置零 (这一步耗时比较长, 且没提示. 另外如果有权限问题记得前面加 sudo)

dd if=/dev/zero of=/zero.tmp
rm -f /zep.tmp

2. 关闭虚拟机

3. 执行压缩命令 (宿主机是 Win 或 Linux 都自行找 VboxManager 的路径)

VboxManager modifyhd /PATH_TO_VDI/name.vdi --compact

在搜索过程中发现其他几个看起来靠谱的链接, 记录供他人参考:
虚拟机是 Windows: http://city5.com/space/reannounce.asp?spaceid=344&announceid=517778
Linux 的复杂折腾法: http://cypromet.site90.net/blog/?p=41