读《淘宝技术这十年》感

  这本书春节放假的时候就在家里读完了,本来想年初写一下感受总结的,但是没有带电脑回去,也就算是搁置了。感觉整本书还是不错的,以淘宝网的萌生和成长、个人在淘宝的工作经历以及淘宝牛人访谈录三个主要部分组成的。书中虽然没有各个技术的具体实现细节,但是将淘宝和自己的成长例程淋漓尽致地展现在了我们面前,淘宝的实力很强,干货还是有的。

  先不论马云私有化的非议,以及众人诟病的淘宝假货和侵权商品肆意横流,就如快播王欣所言:“技术本身并不可耻!”,淘宝网和淘宝技术团队的不断成长,对于整个互联网技术发展和进步还是做出了很大的贡献的:为不断应对淘宝用户规模和数据量的快速增长,从最初购买别人一个现成的LAMP网站改版,到现在能每日处理几十亿个PV访问量、PB级别的数据存储与快速访问,自己改进和开发出各项存储、缓存、中间件、分布文件系统等技术,而且很多技术都以开源、博文、书籍等形式贡献给了社区。

终极文件系统ZFS的使用与优化技巧

  ZFS一直都算是一个神器级别的东西,由于Z是字母表中的最后一个字母,所以很多人将其奉为“终极文件系统”,而我本人对ZFS也是情有独钟,从FreeBSD到Gentoo,都是使用ZFS作为根文件系统。作为文件系统的几个要素来说:ZFS的性能算是中规中矩,对内存要求比较高;稳定性来说,最初是Solaris的文件系统,所以经受过工业环境的考验;而最重要的是ZFS支持相当多的功能特性,告诉我们——文件系统居然可以这样玩。
  当然,由于许可证兼容性的问题,导致ZFS不能集成到Linux内核,所以在Linux下必须是模块的形似使用,这就导致每次更新内核,都需要重新编译安装这些模块。反正都是编译,这让Gentoo的用户感觉不到什么区别,哈哈!

一、ZFS的安装和迁移

  新系统安装,可以参照ZFS文件系统的Gentoo安装,安装和迁移操作系统涉及到的用法罗列在下文。需要注意的是,ZFS的设计颠覆了传统的文件系统,涉及到存储池的概念,具体的原理可以参考ZFS官方手册。

1.1 创建ZFS存储池和文件系统

  个人的使用经验,觉得为系统以及Gentoo的编译部分开辟两个单独的文件系统比较好:一方面可以根据两个不同的使用场景进行参数的设置和优化;同时编译部分的数据是没有意义的,那么在快照和备份的时候,可以不为这部分文件系统进行操作;在迁移和重装系统的时候,也可以忽略这部分数据。

1
2
3
4
5
6
zpool create -f -o ashift=12 -o cachefile=/tmp/zpool.cache -O normalization=formD -m none -R /mnt/gentoo zroot /dev/sda3
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/gentoo #根文件系统
zfs create -o mountpoint=none zroot/GENTOO
zfs create -o mountpoint=/usr/portage/distfiles -o atime=off zroot/GENTOO/portage
zfs create -o mountpoint=/var/tmp/portage -o sync=disabled zroot/GENTOO/build-dir

1.2 导出和导入ZFS存储池

  由于文件系统的信息都包含在了存储池中,所以导出和导入存储池和挂载卸载文件系统的效果是相同的。

1
2
zpool export -f zroot
zpool import -f -o cachefile= -R /mnt/gentoo zroot

Pebble嵌入式开发环境搭建和开发测试样例

  随着Apple Watch和Andriod Wear的兴起,智能手表迅速走到了人们眼前,作为kickstarter上成功的众筹项目,说明很多人对这款手表还是抱有很大期望的。他作为独立于iOS和安卓的智能手表的一个独立阵营而存在着,提供了相应的开发接口和开发包,目前线上的表盘和软件已经成千上万款了。
  也不知道是人们对iOS和安卓已经审美疲倦了,或者是对安卓和iOS设备电池续航太过失望,抑或想追求电纸屏幕的那种古典美而选择了他。在我看来,Pebble手表可以为我记步,提醒我定时喝水和起座,震动电话和闹钟提醒,以及为我推送手机的各种通知,或许你可以说这些功能智能手环已经可以做到了,但是Pebble是开放的,而且目前还在积极的开发中,全球的开发者都在这上面发挥着他们的智慧和创新写出新奇的应用程序,任何时候都可能给你带来惊喜。
  在贴吧和论坛,Pebble已经有自己的铁杆粉丝,他们常常自嘲道:不识货的人都说Pebble是山寨苹果的,而且名字pebble也是山寨apple的。俨然,这种自嘲中流露出了一种优越感,是对自己选择的欣喜和肯定。

一、开发环境的搭建

  官方的开发环境有两类:CouldPebble和本地SDK类别的,前者算是一个云端的开发套件,但是他们租用的亚马逊的云服务,在国内的速度和稳定性都感觉一般吧,而且我们也不是什么时候都有网络可用,所以下面介绍的是用后者,在本地搭建一个开发环境,搭配硬件调试也方便快捷。
  环境搭建步骤如下:

  • 下载和安装pebble sdk
      首先下载 pebble-tools,下载链接显示的是亚马逊的云服务,不加梯子是无法访问的,包括下面安装sdk的时候也是要加VPN的,WEDFD!解压后设置PATH环境变量:

    1
    export PATH=$PATH:"/home/user/Study/pebble-dev/PebbleSDK/bin"
  • Python环境安装
      注意的是,Pebble目前只支持python2,所以你的pip必须是python2的pip,有的发行版不是这样的,如果不成功注意检查这一点

    1
    2
    3
    4
    5
    user@localhost  ~/Study/pebble-dev/PebbleSDK  sudo pip2 install virtualenv
    user@localhost  ~/Study/pebble-dev/PebbleSDK  virtualenv --no-site-packages .env
    (.env) user@localhost  ~/Study/pebble-dev/PebbleSDK  pip install -r requirements.txt
    (.env) user@localhost  ~/Study/pebble-dev/PebbleSDK  deactivate
    user@localhost  ~/Study/pebble-dev/PebbleSDK 
  • 安装pebble sdk(需要梯子)

    1
    2
    3
    4
    5
    user@localhost  ~/Study/pebble-dev  pebble sdk list
    user@localhost  ~/Study/pebble-dev  pebble sdk install 3.8.2
    user@localhost  ~/Study/pebble-dev  pebble sdk list
    Installed SDKs:
    3.8.2 (active)
  • pebble是支持qemu虚拟机模拟的,所以你如果没有手表,或者想在硬件调试前用软件模拟,那么可以安装qemu虚拟机(又遇到天才大作qemu)

    1
    user@localhost  ~/Study/pebble-dev/PebbleSDK  sudo dnf install qemu libpng12 SDL

二、HelloWorld之WatchFace

  任何语言都是HelloWorld起家的。在Pebble上,如果写一个应用程序比较的麻烦,程序涉及到逻辑,最简单的可以按照官方的例程建立一个简单的watchface表盘。下面将建立表盘的代码罗列下来

  • 用pebble工具创建表盘的项目

    1
    user@localhost  ~/GitHub/PebbleFuns/watchfaces   master ●  pebble new-project watchface1
  • 修改watchfaces/watchface1/appinfo.json文件,最主要的是修改watchface为true,其他的参数根据自己喜好改

    1
    2
    3
    4
    5
    "companyName": "FreeSign",
    "targetPlatforms": ["aplite", "basalt" ],
    "watchapp": {
    "watchface": true
    },
  • 表盘的主要代码在watchfaces/watchface1/src/watchface1.c中修改。都是按照官方抄的,就不罗列了。
    watchface1.c

读《硅谷之谜》感

  今年一月份出的新书,买回来立马两个多礼拜读完了。吴军博士自从他的《浪潮之巅》一举成名之后,可以说在整个IT界已经达到无人不晓的地步,他的《数学之美》更被奉为每个理工科学生和工作者的必读之物。正如大家所称赞的,一个优秀的工程师很常见,一个优秀有见解的工程师也挺多的,而一个有见解的优秀工程师有个好的文笔就难能可贵了。我想他之所以能深得中国IT从业者之心,一方面是他在中美学习和生活的经历,对中美文化和社会有着深刻的接触和体会;其次就是他深知,在一个相对闭塞保守的中国大陆从事IT底层事业的码农,内心对IT圣殿的欧美有着一种无以言喻的神秘感和窥探欲,深得IT从业者的人性!
  废话不多说了,看完之后想对本书有个总结。其次,作为一个还在深圳打拼漂泊的人,自然不可避免地也会将硅谷和深圳联系起来看吧。

一、硅谷之谜

  如果非得要用简单的话来概括,我想说:无为而治,容忍宽容,以人为本,灵活多变,追求卓越!

1.无为而治

  主要是说给政府听的。为什么我们还是要以市场经济为主体代替计划经济,我想作为中国人在上个世纪对这个体会应该再深刻不过了,同时虽然欧美的市场经济也会有危机和萧条,也有磕磕盼盼,但是从其发展中越来越完善了。中国进行市场经济改革,获得了不小的成功,但当前经济出现了问题,我想最好的情况就是壮士断腕,让不符合客观规律的经济体被淘汰,将空间和资源留给符合条件的生存者。扯多了,闭嘴~
  按照吴军的说法,硅谷的当地政府除了干检查市容这类保姆的事情之外,对硅谷公司的发展没有丝毫影响力:他们没有权利给初创公司划地免税、没钱给公司划拨经费,更没法决定公司和产业的发展方向,一切都由硅谷这个生态圈自己处理。

2.容忍宽容

  如果你看看硅谷的地图,就会惊讶的发现处理微软、亚马逊等少数的公司之外,几乎绝大多数IT公司的总部都坐落在那一小块地方。按照常理这些大公司挤占在这一块,应该没有小的初创公司生存的空间,就像国内的BAT几乎把整个中国的IT养分给瓜分完了,其实不然,在硅谷创业才是整个地区的文化主流,因为旧金山本来就是大家一起淘金的地方,所以引得无数创客在硅谷这块IT浪潮最前沿寻宝。就是这些IT巨头会把自己竞争对象瞄准在跟自己一个界别的对手上,这些小的初创公司会有自己的生存空间,尊重这些公司的Idea;同时在大公司内部,对于多个项目的成败也会抱有很宽容的态度,因为如果要让失败付出代价,那么就不会有创新了。
  其次,我不知道这些创客是不是像我们这儿会面对着巨大的个人生存压力(这一点吴军没有在书中提到),但是这个社会对创业会十分的宽容:表现在学校、社会和风投公司不会因为创业失败而给人贴上一个失败的标签,在这个方面硅谷的创业代价比日本要低得多。

3.以人为本

  信息时代和机械时代最大的不同是,固定资产在新公司已经不重要了,信息时代最重要的资产是——人才。这表现在,对于硅谷的初创公司的员工算作是一个合作关系而不是传统的雇佣关系,围绕着这么一个基调,公司的发展方向、经营理念、员工的沟通方式等等都会产生翻天覆地的变化;而对于大型公司,公司的管理和经营和传统公司也有区别,公司工程师的地位和待遇会十分的尊重,而不是按资论辈的官僚主义。当然谷歌的工作坏境已经被传为佳话了,在此不表了。
  以人为本还包括他们的产品,吴军说硅谷的产品都是面向全球的,硅谷的人都来自全球各地,所以硅谷本生就有全球化的基因,他们的产品能在全世界风行,我想也是洞察人类的本性,满足和尊重人类最本质的需求所致吧!

4.灵活多变

  吴军在最后的“三论”中算是给了一个理论性的解释。
  都说信息社会变化万象,基于我上述的几个总结,只要有好的想法和技术,在硅谷创业的成功率算是比较高的,而且很可能会颠覆到某个行业甚至整个产业。这主要是在信息社会,已经没有了原先工业社会的资产和技术壁垒了,任何几个人拿个笔记本在辛巴克都可以创业。
  对于小公司,包袱小,目的性强,可以为达到自己的目的随时修改方案方向,而对于即使是很大的公司,也会保持一种高度警惕的状态,因为在硅谷叱咤风云的IT巨头瞬间或者慢慢陨落的例子数不胜数:Sun、HP、Yahoo!……所以你如果不观测环境的变化而迅速调整自身、如果不能不断从外部引入信息来消除自身产生的熵,公司的危机随时会到来。

5.追求卓越

  主要是硅谷的公司和硅谷人的个人信念吧。我们都能感受到硅谷成功出来的产品,基本都是能经历全球几十亿人考验的杰作,而且公司和公司之间的产品重合度比较低,基本都是各自靠着漂亮的Idea起家,不会恶意仿制和恶意竞争,这和硅谷人不会“以钱为本”,而是追求创新、追求颠覆、追求卓越的信念不无关系。反观国内,一个点子出来,如果没有壁垒门槛,大家都会蜂拥而至,创新者的利益得不到保障,整个产业必然也是死气成成。就像我住的小区,最早见到一个“易速递”进驻的,接下来什么e栈、格格货栈乱七八糟的来了七八个快递自取货柜,甚是反感,而如果这个例子不恰当的话,百度、腾讯、360这些公司对整个中国互联网的作为,应该是广大IT从业者深有体会的。

机器学习中自然语言处理之总结

  出于文本归类和数据处理之需求,这段时间研究了下文本处理类的机器学习方面的东西。也快过年放假了,在此做一个总结和感受吧。
附注:本文的项目地址

一、分词

  正如绝大多数的科学研究一样,机器学习的算法绝大多数都是西方早在几年、十几年和几十年发布出来,然后再经过西方工程化之后,国内再慢慢跟上路来。在中文和英文处理的最大问题在于中文需要分词。当然可以将单个的汉字作为算法的处理单元,但是由于汉语的词汇比起单词含有多得多的信息,所以分词算是汉语处理的第一步。
  目前汉语分词算法实现的比较好的有:

中科院张华平博士的ICTCLAS分词

  这个算是国内公认做的最好的分词实现了,在各项评测中指标都比较高,缺点是软件是闭源的,而且挂这个license需要不断更新,比较麻烦。这个还有个人做了个python的调用接口,居然是个老外,想想也比较奇葩,但更多的是羞愧。

结巴分词:

  口号是做最好的 Python 中文分词组件,调用接口可谓是最全面的,各种语言都可以用。由于是开源的,效果也还不错,Python/C都支持,所以在程序中经常用。

其它:

  我个人也根据HMM原理和深度学习实现了两个分词程序,当然效果肯定没有上面那么成熟,但作为HMM和深度学习练练手还是可以的。此外觉得在汉语的时候,中英文和数字的混排中,设想在第一步处理时候将其独立开来,然后再用纯粹的中文分词处理,当然比较懒,没有去做。
  a. HMM分词
  b. 深度学习分词

  个人感觉,中文分词目前已经到了90%以上的分词精度,已经十分满足工程应用了。但是语言是动态不断变化的,而且网络用语越来越多,变化也越来越快,分词程序如果能够快速跟踪这些变化,还是十分有现实价值的。此外,汉语分词的主观性特别的强,尺度和每个人的心里把握都有差异,所以有些分词系统也会提供一个参数,控制分词的颗粒度。

二、情感分析和归类

  这里这样列,但是实际上文本归类和情感分析是一个问题,无非就是2类和多类的关系。文本归类分为长文本归类和段文本归类:长文本比如一篇文章、一个博文之类的;短文本比如Twitter和微博之类的。短文本的归类比长文本的归类难得多,长文本字词丰富,一般采用多项式模型(词频统计);而短文本一般采用伯努利模型(词出现与否)效果会好一些。在实现测试的过程中,以下几种算法效果较好:

贝叶斯网络

  算是最简单的学习算法了,具有理论基础清晰、实现简单、计算量小、效果较好的有点。具有多项式模型和伯努利模型两种实现方式。在实践中,某东语聊好评差评两分类能达到90%的分类精度、sogou分类语聊10分类也能达到70%多的分类精度。
  a. Python实现
  b. C/C++实现
  注意,当时Python实现速度比较的慢,但是用C/C++实现后,计算资源和速度都至少有十多倍的提升!!!

最大熵模型

  这个吴军博士在《数学之美》中有介绍。用几句话来概括就是:如果有先验约束知识,就满足这些约束,否则就不做任何假设,因为不做任何假设是最可靠的,而等概率分布时候的熵最大,称之为最大熵模型。举个例子:如果没有任何条件限制,我问投一个骰子1向上的概率是多大,答案是1/6,然后我告诉你投一次出现3和4的概率之和是1/2,然后你肯定推算出这种约束下1向上的概率是1/8。正是秉着这样的观念,文献说最大熵模型在单一模型算法中效果差不多是最好的。
  最大熵模型提出的比较早了,但是利用起来还不是很悠久,就是传统的GIS迭代求解效率太低,而后面改进使得求解速度大大加快的时候,在实际中才慢慢被利用。代码中是参照nltk的Python实现进行C/C++的移植的。
  a. GIS和L-BFGS实现

LDA(Latent Dirichlet Allocation)

  也是一个比较流行的分类算法,这种算法和上面不同的是,不知道预先的类别种类和数目,有点类似聚类的意思。该算法在Twitter和微博主题分类和主题发现中被广泛使用,同时在广告推荐和信息投放中也被大量应用。还有就是这个算法跟别的算法不同的是,涉及到的数学和统计的知识比较的多,要看明白还是需要些功夫的。
  推荐的文章:
  a. Peacock:大规模主题模型及其在腾讯业务中的应用
  b. 本人测试发现效果不是特别的理想,包括一个改进的L-LDA,后面再看吧。

我的Gentoo Overlay和Linux软件推荐

Gentoo Overlay (Self)

  Gentoo自用的overlay,没有研究怎么public出去,大家如果感兴趣的话,可以将这个仓储clone到/usr/local/,然后将文件etc_portage_repo.postsync.d_local.conf复制到对应的位置,再sync应该就可以了。

  这里面的ebuild都不是我自己写的,而是在网上收录的,创作权归原来的作者所有。

  同时,自己系统的使用软件也在此整理,并不定期同步更新(如果有更改的话),供感兴趣的人参考。

系统的桌面贴图

image

image

软件整理

内核

gentoo的主流内核有三种:sys-kernel/gentoo-sources sys-kernel/ck-sources sys-kernel/vanilla-sources,第一种是gentoo官方打了补丁的内核,优点是menuconfig的时候配置方便,缺点是毕竟改过点东西,不是最稳定的选择;第二种是打了鸡血的内核,主要修改了cpu和硬盘的调度补丁,据说对桌面系统交互相应会好很多,缺点是更不主流;第三种是官方原版的内核,干净的很。
我以前用ck-sources,现在用gentoo-sources。
分区和引导方式为GPT+EFI,grub被废弃,用的sys-boot/refind帮助引导系统。

驱动

这个跟每个人的硬件有关系,基本在编译内核的时候,根据自己的情况进行相应的精简。我的电脑用的DELL的无线网卡,内核的开源驱动性能很低,换成net-wireless/broadcom-sta,性能和稳定性好了很多。

系统美化

桌面主题

  • GNOME SHELL: ZukiShell
  • GTK: Numix

桌面图标

  • Numix-Circle

桌面壁纸:varitey

  • variety 这是个壁纸自动替换程序,最初出现在Ubuntu上(已收录),可以自己设置壁纸的源、自动切换的时间等参数。

字体:infinality + 宋体

在行内有一句话,高分屏用什么字体都好看,低分屏用什么字体都渣渣。都这么多年头了,手机都2K屏了,笔记本居然还是720p。低分屏字体需要优化一下,不然太难看了。下面的方案是折腾了很久感觉最耐看、最好效果的。(见图)
安装app-eselect/eselect-infinality和media-libs/fontconfig-infinality,然后

1
2
3
sudo eselect infinality set 2 [infinality]
sudo eselect lcdfilter set 3 [infinality]
sudo eselect fontconfig disable/enable

将fontconfig中除了52-infinality.conf和65-nonlatin.conf两个enable之外,所有的conf都disable掉。
再将你windows系统的宋体(simsun.ttc)安装到Linux系统,修改/etc/fonts/conf.d/65-nonlatin.conf,第一个字体用好看的英文字体(宋体的英文显示太难看了,我用的Liberation Sans),然后跟中文宋体(NSimSun),这样在显示的时候,英文会优先使用第一个字体,然后遇到中文没法显示的时候,用下面的宋体显示。然后你GNOME中所有的字体都设置成Liberation Sans就可以了。

GNOME SHELL插件扩展:

Gnome Shell扩展那个之多啊,我启用的都列在下面了,自己没事可以走一下GNOME插件 ,需要注意的是由于接口还是协议的变化,chrome已经不支持了,请用火狐浏览器打开。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Applications Menu
Battery percentage
Caffeine
Clipboard indicator
Dash to dock
Focus my window
Freon
Frippery move clock
Frippery panel favorites
Impatience
Input method panel
Lock keys
Native window placement
Panel-docklet v18
Recent(item)s
Refresh wifi connections
Removable drive menu
Show desktop button
Status area horizontal spacing
Suspend button
Topicons
Pixel Saver
Turn off display

Docker容器技术使用实例

  本来不想这么快研究这个东西的,实在是上一个VPS Provider太让人失望和无语了:服务器无法访问,告诉我服务器配置错误。我问那该怎么办,答复我要VPS要重装。网络不通,数据也无法备份,关键是我重装之后还是不能访问,他们也没找到问题,最后发现是只有某些版本的系统的网络能通,也是无语了。之前运行了近一年了没有出现问题,现在服务器的数据全部没了,很多的额服务器需要重新配置,这也让我对系统的运营和部署产生了足够的重视。
  之前对Docker有一些了解,或许现在正是我这种情况的用武之地了,主要的服务和设置用Docker来部署,而私密的数据毕竟少量,自己按时备份。这样如果下次再出问题,几条命令就可以重新把环境部署回来了。
  对于企业级的部署,docker也是一个很好的解决方案,因为你只需要关心容器特定版本的实现,而不用关系host的环境,就是说你的服务可能只开发了RHEL的版本,但是可以方便的被部署到CentOS、Debian、Ubuntu、CoreOS等各个发行版上去,虽然对原生的性能会有所损耗,但是在现在计算机的配置几乎可以忽略不计了,国外已经有银行用容器部署他们的业务了,可靠性也是得到验证了的,是不是很酷?

下面开工:

1.注册账号

  DockerHub 注册用户账号。这个DockerHub相当于GitHub类似的,可以免费帮你存储公有的容器,别人都可以访问和下载(所以前面强调私有的数据要另外保存),然后每个用户可以免费创建一个私有的容器,更多的私有容器就需要花美刀了,跟GitHub是一个运营模式。

2.创建应用容器

2.1 安装相应的工具

  我用的是Fedora 22 Server,这些东西默认就给我装上了,其它版本请参照官方的安装手册。(官方文档说的添加docker组可以让docker在非root用户下运行,但是试验发现、改变/var/run/docker.socket权限后会自动变回来,所以fedora是没有办法的,只能sudo了)。此外docker在fedora的官方维持了一个版本,同时docker自己也维持了一个版本,两者差不多。

1
2
3
4
5
user@localhost  ~  sudo dnf install docker -y
user@localhost  ~  sudo systemctl enable docker
user@localhost  ~  sudo systemctl restart docker
user@localhost  ~  sudo docker run hello-world
user@localhost  ~  sudo docker run -it fedora:22 ping 8.8.4.4

直接使用docker可以查看docker的可用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
attach Attach to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders from a container to a HOSTDIR or to STDOUT
create Create a new container
diff Inspect changes on a container's filesystem
exec Run a command in a running container
history Show the history of an image
images List images
info Display system-wide information
kill Kill a running container
login Register or log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within a container
port List port mappings or a specific mapping for the CONTAINER
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart a running container
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save an image(s) to a tar archive
search Search the Docker Hub for images
start Start one or more stopped containers
stop Stop a running container
tag Tag an image into a repository
top Display the running processes of a container
unpause Unpause all processes within a container

搭建基于Postfix和Dovecot的邮件服务器

最近帮飞哥搭建了一个Linux Mail Server,捣鼓了一天终于搞掂了。这里记录下来以备后用,由于时间仓促,很多参数和功能还不知所以然;-(。

1. 服务器环境

操作系统:CentOS 7.1
环境:apache php mariadb
软件:postfix dovecot roundcubemail postfixadmin
其它:在域名商添加邮件服务器的A记录和MX记录,这里用的mail.freesign.net
同时请申请数字证书,中文版页面的免费申请地址很难看到,估计就是故意不想让人找到的。前段时间还是3年的,现在签发只能管一年了。
关于LAMP环境的搭建网络上已经一大堆了,此处不表。Apache推荐开启https,因为postfixadmin和roundcubemail是网页端访问的,这样会比较安全。
添加邮件专用用户vmail:vmail
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /home/vmail -m

2. 邮件服务器搭建

2.1 设置服务器

在数据库中专门添加一个邮件的数据库。同时由于邮件服务器涉及到多个软件,这些软件的系统也是通过操作数据库的操作来实现的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
user@localhost  ~  mysql -u user -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3857
Server version: 5.5.44-MariaDB MariaDB Server
Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
MariaDB [(none)]> create database postfix;
MariaDB [(none)]> CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'postfixadmin';
MariaDB [(none)]> CREATE USER 'postfix'@'localhost.localdomain' IDENTIFIED BY 'postfixadmin';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON `postfix` . * TO 'postfix'@'localhost';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON `postfix` . * TO 'postfix'@'localhost.localdomain';
MariaDB [(none)]> FLUSH PRIVILEGES;

(把数据库操作过程的输出信息省略了)

2.2 安装roundcubemail和postfixadmin

postfixadmin没有被打包到库中,所以需要手动下载源代码来安装。roundcubemail是epel中被打包了的,可以直接yum安装。

1
2
3
4
5
user@localhost  ~  sudo yum install roundcubemail
user@localhost  ~  cd /usr/share
user@localhost  /usr/share  sudo wget wget http://jaist.dl.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.93/postfixadmin-2.93.tar.gz
user@localhost  /usr/share  sudo tar xzvf postfixadmin-2.93.tar.gz
user@localhost  /usr/share  sudo mv postfixadmin-2.93 postfixadmin

把postfixadmin解压到/usr/share目录,其实这步骤是跟roundcubemail学的。在安装roundcubemail 的时候,会在/etc/httpd/conf.d/roundcubemail.conf产生一个虚拟主机,对这个虚拟主机的别名和目录做如下设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Alias /roundcubemail /usr/share/roundcubemail
Alias /mail /usr/share/roundcubemail
Alias /postfixadmin /usr/share/postfixadmin
<Directory /usr/share/roundcubemail/>
Options none
AllowOverride Limit
Require all granted
</Directory>
<Directory /usr/share/postfixadmin/>
Options none
AllowOverride Limit
Require all granted
</Directory>
<Directory /usr/share/roundcubemail/installer>
Options none
AllowOverride Limit
Require all granted
</Directory>

记得重启apache服务器。

postfixadmin算是一个postfix的管理前端,邮件服务器管理域名和用户账户都在这里。解压之后修改config.inc.php文件(官方推荐是创建config.local.php文件,便于后续升级),其实最主要是数据库相关的设置信息(重要的修改列出如下):

1
2
3
4
5
6
7
8
9
10
11
$CONF['configured'] = true;
$CONF['setup_password'] = 'abc123def';
$CONF['default_language'] = 'cn';
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'postfixadmin';
$CONF['database_name'] = 'postfix';
$CONF['admin_email'] = 'yourmailaddress@126.com';
$CONF['encrypt'] = 'dovecot:CRAM-MD5';
$CONF['dovecotpw'] = "/usr/bin/doveadm pw";

坑点说明:(1)setup_password需要满足密码复杂性要求,不是随便设置的,第一步设置明文,然后在页面生成加密后的密码,再将加密后的密文替换abc123def之后,才能进行添加管理员的操作;(2)encrypt需要修改,要跟后面其它部分设置一样;(3)CentOS7中doveadm打包到了/usr/bin目录,所以这里的路径需要更新;(4)templates_c目录的所属权限需要改为apache;
(postfixadmin的DOCUMENTS目录下的内容是个比较好的参考文档)

然后访问https://mail.freesign.net/postfixadmin/setup.php进行安装:第一步会生成加密的setup_passwd密码,替换config文件中的明文密码后,会让你创建一个管理账户,创建完成验证能登陆之后就先别做其它操作和设置了,因为很多东西还没有设置,创建域啥的没啥意义;
管理员和普通用户的管理路径在下面:
https://mail.freesign.net/postfixadmin/login.php
https://mail.freesign.net/postfixadmin/users/login.php

RedHat系列软件打包实例(二)

  上一篇算是对RPM软件一个简单的入门介绍。这一篇文章里,将对spec文件的各个参数进行较详细的探究和学习。其次,我们也将对strtest软件包进行改造,让它变的在Linux平台更“专业”像样一点。

1.修改strtest文件

  这里,我们对strtest的源代码进行修改,让它变成一个类似于后台服务进程一样的。
  当然不想弄一个复杂的服务端出来,因为这里只是进行验证测试:就让strtest心跳2s输出自己还活着的信息。由于现在的系统服务管理经过一段时间无力的抵制和抗议之后,全部屈服成systemd的了,所以这边也添加一个systemd的服务管理单元。
  src/str.cpp的代码内容如下(原谅我一个披着CPP的纯C)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[makerpm@localhost SPECS]$ cat ~/dist/strtest-1.0.2/src/str.cpp
#include "str.h"
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
const char* logfile = "/var/log/strtest.log";
int main(int argc , char **argv) {
struct timeval tv;
time_t timet;
struct tm* timep;
FILE* fp = fopen(logfile,"a");
if(!fp) {
fprintf(stderr,"Open logfile[%s] failed!\n", logfile);
return -1;
}
time(&timet);
timep = localtime(&timet);
fprintf(fp, "[%d-%d-%d %d:%d:%d]Starting service [%s] ...\n", timep->tm_year, timep->tm_mon, timep->tm_mday,
timep->tm_hour, timep->tm_min, timep->tm_sec, argv[0]);
while(true) {
fprintf(fp, "service[%s], I am alive --", argv[0]);
if(!gettimeofday(&tv, NULL)) {
fprintf(fp, "system time info:%ds-%dus\n", tv.tv_sec, tv.tv_usec);
}
fflush(fp);
sleep(2);
}
fclose(fp);
return 0;
}

2.添加strtest的systemd管理单元

2.1编写service文件

  systemd依赖于service文件管理服务,放置在/usr/lib/systemd/目录下,注意的是,systemd管理单元应当是操作系统的一部分,而不是strtest软件代码的一部分,不应当打包到源代码下面,而应该将下面的strtest.service放到和strtest-1.0.2.tar.bz2一样的~/rpmbuild/SOURCES/目录下面。(这个service文件是抄袭的openssh滴!)关于systemd的相关信息,后面可能还会再学习整理,这里先不细究。

1
2
3
4
5
6
7
8
9
10
11
12
13
[makerpm@localhost SOURCES]$ cat strtest.service
[Unit]
Description=Strtest server daemon
[Service]
ExecStart=/usr/bin/strtest $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target

2.2 修正spec文件

  修改strtest的源代码,对spec文件没有影响(主要是版本号和修改日志等无关紧要的)。目前主要修改使得strtest.service打包进去:
  在%install部分,添加如下内容

1
2
3
# 用于安装systemd服务
install -d -m755 $RPM_BUILD_ROOT/%{_unitdir}
install -m644 %{SOURCE1} $RPM_BUILD_ROOT/%{_unitdir}/strtest.service

然后在%file部分,添加如下内容

1
%{_unitdir}/strtest.service

OK, we all done!

RedHat系列RPM软件打包实例(一)

  对于Linux操作系统,由于软件大部分都是开源软件构成,所以软件打包算是维护一个发行版的绝大多数任务。在Linux那个远古的时代,大家告诉你软件的安装都是下载源码、配置、编译和安装。

  下面以Fedora 22为例子演示,CentOS可能会有一些差异,暂且不表。且是在本地进行打包的,没有用到Fedora的Koji系统。

1.配置环境

1.1 安装打包软件

1
user@localhost  ~ sudo dnf install fedora-packager @development-tools rpmdevtools

1.2 配置打包环境

  手册强烈建议不要使用root打包,以防破坏系统;也不要使用系统常用用户打包,以防上传一些用户的私密信息;所以建议建立一个专门打包的普通用户。

1
2
3
4
5
6
7
8
9
user@localhost  ~ sudo useradd makerpm
user@localhost  ~ sudo usermod -a -G mock makerpm
user@localhost  ~ sudo passwd makerpm
user@localhost  ~ su makerpm
Password:
[makerpm@localhost ~]$ rpmdev-setuptree
[makerpm@localhost ~]$ ls
rpmbuild
[makerpm@localhost ~]$

然后打包环境就建立好了。

2.编写spec文件

2.1 参考已经打好的包

  Fedora发布的软件都是包含源代码的,所以可以借鉴这些包的打包脚本,先模仿再创作是最便捷的学习方式。

1
2
3
4
[makerpm@localhost dist]$ dnf download --source p7zip
[makerpm@localhost dist]$ mkdir p7zip-9.20.1-8.fc22
[makerpm@localhost dist]$ cd p7zip-9.20.1-8.fc22/
[makerpm@localhost p7zip-9.20.1-8.fc22]$ rpm2cpio ../p7zip-9.20.1-8.fc22.src.rpm | cpio -i

然后慢慢品味p7zip.spec吧!

2.2 准备打包的源代码包

  起始环境建立好之后,打包的过程,就是编写spec文件的过程。
  使用的材料是上一次的strtest工程进行打包,注意包的命名规范:name-version.tar.gz

1
2
3
4
5
user@localhost  ~/Study/project/to_linux  mv strtest strtest-1.0.1
user@localhost  ~/Study/project/to_linux  tar czvf strtest-1.0.1.tar.gz strtest-1.0.1
user@localhost  ~/Study/project/to_linux  sudo cp strtest-1.0.1.tar.gz /home/makerpm/rpmbuild/SOURCES/
user@localhost  ~/Study/project/to_linux  sudo chown makerpm:makerpm /home/makerpm/rpmbuild/SOURCES/strtest-1.0.1.tar.gz
user@localhost  ~/Study/project/to_linux 