清静了

我们有个工作论坛,采用phpBB搭建,运行了多年,始终被一个问题困扰:应对各种垃圾帖。目前采用的方法是:

  • 注册时设置Q&A问题,阻止部分机器人注册论坛。
  • 新用户注册后,会发送邮件要求激活。这确保用户是使用有效电子邮件地址。
  • 新用户发的第一个贴必须由管理员审核通过,后续发帖则不用再审核。这确保用户是个有效的用户。

以上措施能保证论坛的基本质量。不过最近发现了另外一个问题:大量的垃圾用户注册成功后并没有发帖,而是在用户信息等处填写了大量的广告等垃圾信息。这类用户多数来自相同的邮件服务器地址,例如xxx@example.ru等,估计是破解了Q&A方式的注册方式,往往一天之内会注册几十甚至上百个用户。

我不是很理解这种行为。因为各搜索引擎其实是看不到用户的个人信息,在个人信息处填写垃圾信息并没有实际意义。这类账户如同牛皮藓般的存在,实在让人觉得心烦,于是开始手工删除它们。

开始时一个个地搜索,一个个地删除,效率很慢。一天删掉几百个账户后,感觉头晕眼花,实在是件单调乏味的工作。仔细检查了phpBB的ACP界面,发现其实是支持批量删除的,真是大快人心。具体操作方法如下:

在“USERS AND GROUPS”界面,点击“Prune users”,然后点击“ Find a member”。在对话框中,可以使用通配查询,例如设置“E-mail”为“*@example.ru”,将该邮件服务器地址的所有注册用户搜索出来,然后点击“Mark all”以及“select marked”。接着在原“Prune users”界面里,设置”Delete pruned user posts” 和”Deactivate or delete”,然后就可以删除掉所有已选择的用户。

删完这些账户后,为防止再次注册,可以强行屏蔽相应的邮件服务器地址,拒绝使用该邮件服务器地址的用户重新注册。在“USERS AND GROUPS”界面,点击“Ban e-mails”设置即可。同样,此处也支持通配符设置。

完成清理工作后(大约删除了一千多垃圾账户),对论坛本身是否有必要存在产生了一些怀疑。实际工作中,客户们往往还是采用邮件、IM以及在线联系等方式,只有少数用户愿意在论坛里公开讨论问题。后续我们再思考一下是否让论坛继续存在下去。

装机 – Ubuntu16.04

老婆公司有个让人惊讶的规定:员工笔记本三年后归自己个人所有,公司重新配新电脑! 这是多么让人热爱的公司!老婆工作这几年,家里多了几台笔记本,一水的ThinkPad。上周又过了三年,拿回一台T430。以前拿回电脑时,会恢复到Thinkpad出厂时安装的window系统,这次这台T430居然只是低格了,没有系统?!

当然可以从网上扒一个windows恢复盘下来重装,不过考虑到家里已经有几台windows的笔记本和台式机,实在没有必要再增加一台,因此这次打算装Linux系统试试。

选择发行版本

“Linux发行版本”之争在程序员迷之争论中绝对可以位列前三位!好在是给自己的笔记本选发行版,因此有幸避免了与别人的争论,只要考虑自己的需求就好了。我的基本原则其实很简单:

(1)发行版要有强大的、历史悠久的社区。

(2)或者,有商业背景企业发布的版本。

以上两点只确保一个问题:若干年后,依然能活着并得到强有力的支持。绝大多数妖艳的Linux发行版本,比如Arch等,基本不用考虑了。符合要求的版本大致也就是:Debian、CentOS、Ubuntu等寥寥数种而已。

CentOS的软件实在太老旧了点,有时候不得不自己去编译各类软件,与其这样,还不如用Arch或者Gentoo等版本来得直接。公司做项目时基本都是采用Debian系统做服务器,很满意,但是Debian桌面系统就差强人意。不知道是Debian的问题,还是KDE的问题,使用时总有各种烦人的小毛病,比如鼠标问题等。

因此这次就选择了Ubuntu 16.04 (Unity7),谁会做死去选择Ubuntu的非LTS版本呢?

安装软件

安装Ubuntu系统实在没什么可以说的,下载iso文件,录制u盘,直接安装即可,比装windows还简单,过程枯燥乏味。下面只是记录一些安装应用软件方面需要注意的地方。

安装virtualBox与Windows环境下稍有不同,扩展功能包也收录在软件中心,因此实际执行命令一起安装:

sudo apt-get install virtualbox virtualbox-ext-pack

将其他计算机中的vbox客机导出到新计算机中,U盘必须采用exFat格式才能支持超过4G大小的文件,ubuntu默认没提供对该格式的支持,因此也需要单独安装:

sudo apt-get install exfat-utils

qt开发工具集升级到qt5了,采用以下命令安装:

sudo apt-get install qt5-default

谁在丑怪?!

上周五台风天,香港幼稚园停课,本来安排好给苗换被褥只好推迟,今天下午赶去幼稚园换被褥。因为过关人多,通常我都不带苗一起走,放学后她自己坐校车到关口走学童通道过关,然后我再去接她,这次苗非常希望我能带她一起坐巴士回家,昨天叮嘱了很多次,让我带上她非常喜欢的一个玩具小手机,因此换完被褥,请老师把苗带出来和我一起走。

路上苗非常开心,拿着玩具手机假装打电话,边走边玩。我们去超市买了瓶饮料,顺便也买了瓶洗衣液(仅此而已,没有买其他东西,包括奶粉),朝巴士站走去。天气很晴朗,一切都很美好。

这时一位香港朋友从后面拍了一下我的肩膀,我回头看见一位中年男士,水电工人(建筑工人?)打扮,对我说了一通粤语,并且指了苗几下。老实说我完全没听懂他的意思,难道苗有什么不得体的地方吗?我非常困惑地看了看苗:因为是周一,苗穿的是学校的礼服,正规而整洁;苗正在假装打手机,声音并不喧嚣,我站在身边也听不太清她的声音。

于是我开始全方位自省:“是哪儿不对吗?…… ”这时已经走到前面去的那位香港朋友回头对我们说了句话,我听明白了:“丑怪,丑怪”。

因为给苗换被褥的关系,也算偶有往来深港两地之间,已经习惯了面对各种不耐烦。但是被人无端当面叫“丑怪”还是第一次,感觉非常错愕和震惊,回想起来也时不时觉得愤怒。

我写下这次经历时,为苗将来的生长环境感到忧心。更让我倍感压抑的是,香港近些年来的氛围越来越差,完全看不到有什么改善的希望。

2016-10-28 更新:听同学家长说:去附近几所小学问了双非孩子上小学的事,深圳教育局口头通知了各公立小学(别指望看到正式的书面文件),严禁招收双非儿童入学。香港倒是允许双非孩子入学,然而限定(指定?)了北区的学网。双非孩子像瘟疫一样被两地嫌弃,让人倍感伤痛。

鼠标滚轮太快

系统是Debian 8(64bits),一直有这个问题。比如打开Firefox浏览网页,一般习惯用鼠标滚轮翻页,问题是速度太快,一下就翻过几页,试了几个鼠标都有类似的问题,基本可以排除硬件原因(实际上切换到同一台计算机的windows系统,就一切正常)。

在Debian系统中也设置了鼠标的一些配置,例如“系统设置”中的“鼠标滚轮卷动单位”等,没有效果。

虽然比较烦人,不过勉强用键盘也能避免这个问题,于是就耽搁下来。

最近浏览文档、写文档等情况比较多,没有鼠标滚轮实在很不方便,于是下决心解决这个问题。上网搜了一些解决方案,都没有效果。搜到一个解决方法:插拔鼠标一下。这实在是无厘头,想想插拔一下也不费事,就试一下吧。

太扯了!居然真的有效!这到底是什么情况?

/bin/bash^M: bad interpreter: No such file or directory

早上发现预设置的某个脚本没有执行,手工执行时返回以下错误:

/bin/bash^M: bad interpreter: No such file or directory

检查/bin目录,能发现bash,因此不是“no such file”。搜索了一下网络,发现是文件格式问题,脚本文件可能被修改成dos格式了。用vim打开文件,输入”set ff”即可检查当前文件的格式。

将脚本文件修改为unix格式即可,同样,用vim打开文件后,输入以下命令:

set ff=unix

然后存盘保存退出即可。

Firefox吞噬硬盘

我承认是个标题党,实际是指Firefox频繁读写对硬盘有一些损害(其他浏览器也有类似的问题,都属于高IO类型软件),来自一篇网络上的文章,原文请点击这里

在这篇文章中也提到了解决方式:在firefox地址栏中输入“about:config”,然后找到参数“browser.sessionstore.interval”,默认值是15000(15秒),修改这个值即可。

从这个参数的含义看,似乎是firefox保存会话(页面)的频率,一般应用而言估计也没太大意义,改大点(例如600000)好了。

 

忙碌的一天

今天度过了忙碌的一天,然而其实什么都没有做,至少没做什么有意义的事情。

昨天收到短信,告知了上次交通违规的事(请点击这里了解细节),于是上午就打算去处理这事。先跑蛇口交警大队,据说打印机坏了,不处理,然后跑到南山交警大队去处理(人山人海啊)。结论是罚两百,不扣分,因此其实不用打印,直接在自助终端交罚款就行。在查询的时候咨询了交警同志,也认为这种罚单是有疑问的,想想折腾回江西提出异议的各种可能,还是直接交罚款了事。

一上午就这么过去了。

中午收到了windows系统升级的通知,于是习惯性的点击同意:升级失败回退一次;再次升级,中间异常退出若干次;升级完成后,出现几段鸡汤文字,然后卡死一次;冒险重新启动,然后发现程序异常一次……各种心惊肉跳的感觉。终于升级完成,版本变成”14393 187″,忍不住吐槽:真丑!微软越做越奇葩了,是因为三哥当头了么?

一下午就这么过去了。

晚上看着熊孩子写作业,怒火中烧,怎么就教不会?!

一天就这么过去了。

 

从Python到Lua

在码农世界里,有几个迷之争论:Vim/Emacs与IDE之争、Tab与Space之争、Windows与Linux(也包括macOS等)之争,诸如此类。任何一个争论都是莫名激烈、动不动就友尽,如果你恨一个人,就把他拖进这些争论吧。

其中最可能流血、最板砖横飞的争论,无疑是语言之争(当然,“PHP是世界上最好的语言”这是毋庸置疑的)。使用某个语言或者不使用某个语言,都可能轻易引发激烈的争吵,需要面对巨大的宗教、舆论压力,因此切换语言对码农来说,几乎就是死生之大事。

最近做了一件让人紧张、脸红、流汗的事:重新改写miniSIPServer产品的业务引擎部分,从Python语言切换到Lua语言。作为熟悉(非精通)Python多年的开发人员,离开自己的舒适区去面对新的挑战,去填新的坑,内心还是蛮纠结的。这个切换工作花费了几个月的时间,排除拖延症导致的时间浪费,如此耗时也是近几年罕见,通常一个复杂点的特性也就几个星期工作量而已。在产品博客上,已经简要描述了这次切换的原因,本文从开发人员视角再补充一些细节。

先泛泛了解一些Python和Lua的共性部分:都是脚本类、解释型语言;都是比较简单、干脆的语法;通常都会应用于粘合性场景。常见的不同之处主要在于:Lua更精干、小巧、速度更快,而Python是通用性、全栈型语言,有更广泛的库支持。Python即可适合开发独立的应用程序、也适合作为胶水语言嵌入到应用中,而Lua基本功能集很小,通常只适合作为辅助型语言使用,不太适合作为独立应用的开发语言使用。

从上面这些简要描述来看,Python语言的应用领域要比Lua广泛得多。实际上简单搜索一下可以发现,Lua仅仅在网络、游戏等领域才有一些应用范例。

离开具体应用场景来谈论语言的优劣就是耍流氓,在考虑、考察了很久以后,最终还是重新选择了Lua,这个决定过程是逐步养成的。

我们自己在设计、开发产品时,总是会狂热地追求简单、精致、高效等特性,从产品名称也可以看出我们对『小巧』的迷恋。将Python及支持库打包进安装包,有数MB之大,而Lua仅仅200KB而已,完成整体打包后,体积能缩小1/3,用户下载我们应用程序的时间相应也能减少1/3!这点从一开始就很吸引我们。

然而最初我们选择的是Python,因为Python的库实在太方便了!例如其中的smtp库、xml库等,在我们产品初期的确帮了大忙。而随着我们自己逐步在MSS的核心自行开发了这些基础库,重新审视后发现:Python的库对我们的产品不再是必须的了。这也就是我们重新思考的一个触发点。

如果说Python是屠龙刀,那Lua就是铅笔刀。如果仅仅是削铅笔,那显然铅笔刀比屠龙刀更合适。对于我们而言,应用脚本语言更多的是考虑对核心功能的封装,以及基于此编写业务逻辑脚本,以脚本语言的动态性适配客户需求的多样性。因此在核心功能完备的情况下,脚本语言越轻巧越好,越简单越好,Lua太适合这种场景了。

Python另外一个让人比较诟病的地方就是GIL。由于GIL的存在,Python无法实现真正的多线程。如果用一个Python实例来满足多种业务的需求,一旦其中一个业务出现问题,整个Python虚拟机可能会锁死,导致整个系统崩溃。如果采用多个Python实例,Python的VM实在太重了,对系统的设计、实现、工作负荷都会造成很大的困扰。

而在这点恰恰发挥出Lua的优势。Lua的VM非常小巧,以至于可以毫不犹豫地启动多个VM来实现业务。实际上,我们最终实现为『一个业务启动一个Lua的VM』。具体设计、实现时不用再考虑资源锁死的问题,而且Lua提供的coroutine也很棒,很多场合下可以轻松满足高性能的要求。启动多个Lua的VM带来的最大好处就是:系统的稳定性有了进一步的提高。事实上相当于每个业务都处于沙盒之中,一旦某个业务出现异常,其他业务可以完全不受影响,即使是对已出问题的业务实例,将沙盒(VM)抹掉即可。单纯这一个特点就足以让我们决定放弃Python,改用Lua了。

而Lua带来的第二个好处是『热更新』特性。在运营级、大型企业级软件系统中,『热更新』是非常重要的特性,可以确保整个系统尽可能地稳定运行。而由于每个业务都由独立的VM运行,因此我们可以做到动态修改业务脚本。实际上,我们在开发新业务引擎时,常常在保持MSS运行的情况下,修改脚本测试各种业务逻辑,效果良好。

Lua比Python简单很多,不做特殊优化,Lua的速度比Python要高出很多。我们在开发测试过程中发现,采用Lua脚本对系统的性能影响不大,比Python要节省资源。MSS作为一个高性能SIP服务器,核心采用C、C++实现,而某些处理过程也有客户化、定制化的需求,更关键的是也存在『热更新』的需求,因此我们甚至希望在考察Lua业务引擎效果的基础上,考虑替换MSS呼叫核心部分的处理逻辑,用Lua实现部分呼叫引擎。

因为简单,所以我们可以比较随意地直接修改Lua的代码,以便满足我们应用场景的一些特殊需求。而面对Python,我们可不敢这么做。

当然Lua也有明显的缺点,『简单』在某种程度上是『简陋』的同义词。很多情况下需要扩展一些功能给Lua使用,另外就是Lua也存在不少的坑,即使是Python和C/C++老手也需要小心翼翼。

最后,老话说得好:“结合应用谈语言”。没有完美的语言,只有适合你应用的语言。当你不知道该怎么选择时,选择Python、Java这类通用型语言基本无风险,正如我们在项目早期作出的选择一样,在当时都是非常正确的。只是我们要与时俱进而已。