2015年12月22日星期二
不玩Docker了
最近在开发环境用Docker,总是感觉各种不方便。特别是作为Ansible管理的机器,一些系统配置都不能改,比如不能替换/etc/resolv.conf,iptables有问题,SELinux有问题。而且修改了容器状态,还得保存了才能持久。后来看了这个网站,还有和几个朋友的交流,决定在开发环境不用Docker了,重新用起Vagrant。
2015年11月20日星期五
几个监控系统选型
如果要选择几个监控系统,可选项有Nagios, Cacti, Ganglia, Zabbix和Zennos,应该选哪个呢?我除了用过Zabbix外,其它几个没有经验。如果是技术选型,我觉得未来技术的发展方向和趋势很重要,这样可以放心在上面进行长期和深入的投入。
通过Google Trends,发现Nagios,Cacti和Ganglia的关注度都在降低,而Zabbix在稳步提升,Zennos始终没有得到太多的关注。Google甚至给出了预测,在2016年11月Zabbix的关注度将超过Nagios跃为第一。
如果在“计算机和电子”类别里面比较,Zabbix的增长看起来更明显。不过我还没搞懂下图的含义。
这个结论让我消除了对统一监控系统到Zabbix上的做法的顾虑,可以有信心地长期投入。
通过Google Trends,发现Nagios,Cacti和Ganglia的关注度都在降低,而Zabbix在稳步提升,Zennos始终没有得到太多的关注。Google甚至给出了预测,在2016年11月Zabbix的关注度将超过Nagios跃为第一。
如果在“计算机和电子”类别里面比较,Zabbix的增长看起来更明显。不过我还没搞懂下图的含义。
这个结论让我消除了对统一监控系统到Zabbix上的做法的顾虑,可以有信心地长期投入。
2014年12月18日星期四
放弃Linux,投奔OS X
今年我有两大改变,或者说是“回归”或“回退”,其中之一就是在用了10年多的Linux后,开始用苹果的系统了。
从2012年拿到公司的苹果电脑后,我很快就装上了用了多年的Ubuntu,一直用到今年初。一月底时候,因为在家用经常要挪动、扣上、再打开,而Ubuntu有时会死掉,就用了几天OS X。因为不会死机,用起来很方便,就这样很快转到了完全用Apple系统工作和生活。
那我之前为什么要在苹果电脑上跑Linux,而不是苹果的系统呢?因为在我看来Ubuntu有很多优点。首先,因为我一直是自由软件的支持者,所以用一个自由的操作系统是很光荣的事情。此外,我觉得Ubuntu的Unity是设计最好的桌面环境,用户和桌面的交互只有Dock, Dash和右上角的菜单,这个设计的简洁性和易用性超过了Mac OS X。最后,我桌面上直接配置开发环境,还可以方便地查阅Linux的manpage。
不过,Ubuntu的致命的问题是软件质量太差。总体上,Ubuntu对苹果电脑的硬件支持要比PC差。在Ubuntu上,因为驱动的问题,无线网会经常断,需要写个脚本不时重启无线网。双显示器在切换时候会常常花屏,此时唯一的办法就是强制重启。待机后偶尔无法正常恢复,也只能强制重启。触控板能凑合用,但是触感严重有问题,网上有调整驱动配置的方法,我也懒得折腾。耗电厉害,发热厉害,后来用电池的时候只能撑一个小时。
此外,Ubuntu系统本身的质量也远低于OS X。软件崩溃是常有的事情。每次发布新版升级完就一堆问题,如果能进去桌面实在算是幸运了。我那时候闲的,在Launchpad上给Ubuntu提交了不少bug,基本没有人关注;而我给Debian提的bug,得到解决的比率感觉要比Ubuntu高。Ubuntu每六个月发布一个版本,除了LTS外,很难保证各个版本的质量。
用了OS X后,终于可以享受用电脑的过程了。喜欢苹果强大的触控板和便利的窗口管理功能(我第一次看到同事不用鼠标只用触控板时还很诧异),可以使用丰富的快捷键。最重要的是,电脑没有那么多的问题了,不用整天想着修复电脑问题了,可以更高效地做有产出的事情了。
当时用了linux.fatduck.org这个域名,想的是我应该会一直把Linux用下去的,没想到竟然背叛了这个多年的爱好。说到背叛,我还有另外一则故事,以后会发到另一个博客上。
从2012年拿到公司的苹果电脑后,我很快就装上了用了多年的Ubuntu,一直用到今年初。一月底时候,因为在家用经常要挪动、扣上、再打开,而Ubuntu有时会死掉,就用了几天OS X。因为不会死机,用起来很方便,就这样很快转到了完全用Apple系统工作和生活。
那我之前为什么要在苹果电脑上跑Linux,而不是苹果的系统呢?因为在我看来Ubuntu有很多优点。首先,因为我一直是自由软件的支持者,所以用一个自由的操作系统是很光荣的事情。此外,我觉得Ubuntu的Unity是设计最好的桌面环境,用户和桌面的交互只有Dock, Dash和右上角的菜单,这个设计的简洁性和易用性超过了Mac OS X。最后,我桌面上直接配置开发环境,还可以方便地查阅Linux的manpage。
不过,Ubuntu的致命的问题是软件质量太差。总体上,Ubuntu对苹果电脑的硬件支持要比PC差。在Ubuntu上,因为驱动的问题,无线网会经常断,需要写个脚本不时重启无线网。双显示器在切换时候会常常花屏,此时唯一的办法就是强制重启。待机后偶尔无法正常恢复,也只能强制重启。触控板能凑合用,但是触感严重有问题,网上有调整驱动配置的方法,我也懒得折腾。耗电厉害,发热厉害,后来用电池的时候只能撑一个小时。
此外,Ubuntu系统本身的质量也远低于OS X。软件崩溃是常有的事情。每次发布新版升级完就一堆问题,如果能进去桌面实在算是幸运了。我那时候闲的,在Launchpad上给Ubuntu提交了不少bug,基本没有人关注;而我给Debian提的bug,得到解决的比率感觉要比Ubuntu高。Ubuntu每六个月发布一个版本,除了LTS外,很难保证各个版本的质量。
用了OS X后,终于可以享受用电脑的过程了。喜欢苹果强大的触控板和便利的窗口管理功能(我第一次看到同事不用鼠标只用触控板时还很诧异),可以使用丰富的快捷键。最重要的是,电脑没有那么多的问题了,不用整天想着修复电脑问题了,可以更高效地做有产出的事情了。
当时用了linux.fatduck.org这个域名,想的是我应该会一直把Linux用下去的,没想到竟然背叛了这个多年的爱好。说到背叛,我还有另外一则故事,以后会发到另一个博客上。
2013年11月24日星期日
LightDM不能启动
开了20多天的Ubuntu 12.04,重启后LightDM不能开机自动启动了。决定查个究竟。
根据开机后的画面显示,目测是LightDM的Upstart脚本没有执行。看了看/etc/init/lightdm.conf,里面有相关的依赖服务,但我不知道是哪一步出问题了。折腾了几下,包括检查plymouth, dbus服务,删除和重装lightdm包后,lightdm服务竟然手动启动都会失败了。
还好LightDM在/var/log/lightdm/lightdm.log记录了日志,里面有/usr/share/xgreeters/default.desktop文件找不到的错误。在/usr/share/xgreeters/只有unity-greeter.desktop文件。之前正常工作的时候,/etc/lightdm/lightdm.conf里面指定了unity-greeter的,现在没有lightdm.conf这个文件,所以就出了上述的错误。我就做了一个符号链接,再次sudo start lightdm,结果还是没有起来,不过lightdm.log里面有记录启动greeter出错了,并友好地提示greeter的日志记在/var/log/lightdm/x-0-greeter.log里面。在这个文件里面看到具体的错误是没有权限打开/var/lib/lightdm/.Xauthority文件。我记得之前用Apt删除lightdm的时候,显示/var/lib/lightdm目录未能删除,现在我就把/var/lib/lightdm里面的所有文件都删除了,之后lightdm服务就能成功启动了。
从这个故事我得到的体会是,应用设计里面重要的一点,就是要有关键的日志记录,特别是错误记录,这样在事后分析的时候容易找到问题产生的原因。LightDM的日志文件就是比较清楚的,特别是在lightdm.log里面,写入其它日志文件x-0-greeter.log时,也会记下这条,这样看日志的人立刻就知道还有别的日志文件;如果安静地写到另一个日志文件里面而不提示,就会增加用户检索的成本。
根据开机后的画面显示,目测是LightDM的Upstart脚本没有执行。看了看/etc/init/lightdm.conf,里面有相关的依赖服务,但我不知道是哪一步出问题了。折腾了几下,包括检查plymouth, dbus服务,删除和重装lightdm包后,lightdm服务竟然手动启动都会失败了。
还好LightDM在/var/log/lightdm/lightdm.log记录了日志,里面有/usr/share/xgreeters/default.desktop文件找不到的错误。在/usr/share/xgreeters/只有unity-greeter.desktop文件。之前正常工作的时候,/etc/lightdm/lightdm.conf里面指定了unity-greeter的,现在没有lightdm.conf这个文件,所以就出了上述的错误。我就做了一个符号链接,再次sudo start lightdm,结果还是没有起来,不过lightdm.log里面有记录启动greeter出错了,并友好地提示greeter的日志记在/var/log/lightdm/x-0-greeter.log里面。在这个文件里面看到具体的错误是没有权限打开/var/lib/lightdm/.Xauthority文件。我记得之前用Apt删除lightdm的时候,显示/var/lib/lightdm目录未能删除,现在我就把/var/lib/lightdm里面的所有文件都删除了,之后lightdm服务就能成功启动了。
从这个故事我得到的体会是,应用设计里面重要的一点,就是要有关键的日志记录,特别是错误记录,这样在事后分析的时候容易找到问题产生的原因。LightDM的日志文件就是比较清楚的,特别是在lightdm.log里面,写入其它日志文件x-0-greeter.log时,也会记下这条,这样看日志的人立刻就知道还有别的日志文件;如果安静地写到另一个日志文件里面而不提示,就会增加用户检索的成本。
2013年9月29日星期日
批量改照片名为拍摄时间
去台北玩照的七百多张照片,是用手机和数码相机照的。摩托罗拉手机(Atrix 2)照的照片命名方式是YYYY-MM-DD_HH-MM-SS_XXX.jpg,例如2013-06-11_00-15-48_100.jpg,最后的100可能是指00:15:48秒的第100毫秒;而佳能相机(EOS 5D)照的照片命名方式是IMG_XXXX.JPG,例如IMG_5845.JPG。这些照片放到一个相册里面,按照名字排序后是混乱的,这让我在几百张照片里面很难快速找到某张照片。我用的相册软件(Picasa)不支持按拍摄时间排序,否则按照拍摄时间排序就可以了。
这么对比,才发现传统的数码相机给照片起名的方式有点蠢。我第一台数码相机是惠普的,前缀是hpim。索尼是DSC,莱卡是L,后面都跟着照片序列号。IMG_5845.JPG这样的名字没有任何有用的信息,而2013-06-11_00-15-48_100.jpg却给出了非常重要的照片元信息。在浏览相册时,看到名字就知道了这张照片是什么时候照的。
于是写了个批量改名的脚本,把佳能相机照的照片都改名为照片拍摄的时间。这样就能和手机照的照片放到一个相册里面,按名字排序,也就自然是按照拍摄时间排序了,浏览时候就很方便了。我觉得数码相机照的照片都可以这么处理,方便浏览,不过这要求数码相机的时间是准确的。
这么对比,才发现传统的数码相机给照片起名的方式有点蠢。我第一台数码相机是惠普的,前缀是hpim。索尼是DSC,莱卡是L,后面都跟着照片序列号。IMG_5845.JPG这样的名字没有任何有用的信息,而2013-06-11_00-15-48_100.jpg却给出了非常重要的照片元信息。在浏览相册时,看到名字就知道了这张照片是什么时候照的。
于是写了个批量改名的脚本,把佳能相机照的照片都改名为照片拍摄的时间。这样就能和手机照的照片放到一个相册里面,按名字排序,也就自然是按照拍摄时间排序了,浏览时候就很方便了。我觉得数码相机照的照片都可以这么处理,方便浏览,不过这要求数码相机的时间是准确的。
2013年9月25日星期三
MongoDB的高可用
一个应用的数据源是MongoDB,DBA已经配置了多机的Replication Set,但是在客户端程序用Pymongo连接的时候还指定的是一个IP。结果在网络升级的时候的网络瞬断,让MongoDB自动切换了master,导致客户端连接失败了,出现Master has changed的异常。其实早就计划要修改客户端配置,支持RS的,但是一直没有完成,终于掉进这个坑里面了。
有意思的是,如果MongoDB没有做RS,那么网络瞬断只会让服务短暂不可用,网络恢复的时候服务即可恢复;而服务端做了高可用,客户端没有进行相应的配置,可用性反而降低了。看来在服务端和客户端都进行正确配置的情况下才能实现真正的高可用性。
2013年9月17日星期二
性能比较
以下两个Python 3函数的性能差10倍。
def upgrade(url):
"""Upgrade HTTP URL to HTTPS URL."""
components = urllib.parse.urlsplit(url)
if components.scheme.lower() == 'http':
return urllib.parse.urlunsplit(['https'] + list(components[1:5]))
else:
return url
def upgrade1(url):
"""Optimized version of upgrade, 10x faster."""
if url[:5].lower() == 'http:':
return 'https' + url[4:]
else:
return url
用timeit分别测试100万次,耗时分别如下:
def upgrade(url):
"""Upgrade HTTP URL to HTTPS URL."""
components = urllib.parse.urlsplit(url)
if components.scheme.lower() == 'http':
return urllib.parse.urlunsplit(['https'] + list(components[1:5]))
else:
return url
def upgrade1(url):
"""Optimized version of upgrade, 10x faster."""
if url[:5].lower() == 'http:':
return 'https' + url[4:]
else:
return url
用timeit分别测试100万次,耗时分别如下:
4.574674844741821
0.46399807929992676
什么时候用库函数,什么时候用基本的函数实现,需要综合考虑开发速度、灵活性和性能等因素。
订阅:
博文 (Atom)