网络寻租

Programmer, Gamer, Hacker

正确使用社交网络的方法

| Comments

我们常用的社交网络有:微信,微博,QQ,豆瓣,它们消耗了我们大量的时间,其中绝大部分都被浪费了。

我们在无聊的时候会拿出手机,刷一下动态。刷动态的时候,大脑通过接受信息,获得了奖励:感觉到和他人建立了联系,学到了新的知识,享受到了快感。 这个过程强化了神经反射:我们有了冲动,经常拿出手机来刷一下,期望能够获得奖励。这是上瘾症状。

我们需要反省一下,应该如何更好地使用社交网络。它对我们的用途有:

  • 娱乐:从其他人分享的内容上面取乐。
  • 关注认识的人:获取动态,能够保持联系。
  • 关注有意思的人:获取资讯和洞见。

在满足这些用途的前提下,我期望能够更少消耗时间,更好和他人保持联系,获得真正重要的信息。所以这里列了一下更好的使用方式:

  • 社交网络核心的用法是记录人:记录认识的人的联系方式,收集有趣的人的讯息。
  • 我不建议把社交网络作为娱乐方式,因为:娱乐正是给我们大脑奖励的主要手段,娱乐性内容是成瘾的主要一环,娱乐要么正正经经地玩个痛快,而不是一点点的享受,欲求不满容易刺激上瘾。
  • 和他人的沟通和联系,尽量用语音聊天或者见面聊,时间成本更低,收益更高。
  • 保持联系和关注认识的人:每天最多过一遍认识人的动态,尽量回复,而不是点赞,这样他人对你印象更深刻。觉得无关注价值的人,就不用看他的资讯了,记录联系方式即可。
  • 获得洞见:大多数的信息是碎片化的,不成体系没有阅读价值,建议通过看书获得。最新资讯可以关注一些高质量的讯息来源。
  • 只利用碎片时间查看和处理动态:没其他事情可做,以及有明确截止时间。比如:等车,等饭,上厕所的时间。整块的时间里,千万不要打开这些手机应用。

Rails容灾恢复策略

| Comments

我们可以把一个运行的rails环境,根据处置的方式,拆分成以下几个部分:

  • 系统环境:跑rails必须的服务器系统环境,比如特定版本的ruby,各种第三方库,第三方工具等。
  • 项目配置:和当前运行环境相关的变量,比如数据库帐号,各种第三方API和服务的连接方式。
  • 项目代码:除去和运行环境相关的rails应用代码。
  • 应用数据:比如数据库,本地一些需要持久化的文件等。

拆分的原因是因为以上几个部分有不同的特性,在构建,备份,恢复的过程中需要用不同的方式来对待。 特性包括是否经常发生变化,变化的频率,是否和运行环境相关等。

首先看构建过程。构建过程往往非常繁琐,需要能够自动化进行。拆分成以上几个部分后,构建方案如下:

  • chef构建系统环境。
  • cap把项目配置和项目代码构建出应用的执行环境。
  • backup Gem备份和恢复应用数据。

发布新版本,因为只改动了项目代码,只需要重新用cap重新构建执行环境。 需要增加配置,或者修改应用数据,也不复杂,执行一些特定脚本即可。

系统恢复:可以重头构建,但是时间消耗太长,更好的方案是针对服务器做镜像,也可以用docker做应用级别的镜像。 另外也需要备份好项目配置,以及隔离和备份出来应用数据。 出现问题的时候从镜像创建环境,修改配置,恢复备份的应用数据,然后发布最新的代码。

Rails项目的发布

| Comments

capistrano/mina可以用来发布rails项目,它们是应用发布的最佳实践。

关于应用发布,需要满足以下要求:

  • 发布的版本确保可以运行之后,才替代现有版本。
  • 留存有旧的版本,必要的时候可以恢复。
  • 发布版本不应该带有版本管控信息,防止不必要的信息泄漏。
  • 配置文件,数据文件和代码分离:另外存放,不和发布的代码混在一起。

capistrano/mina的解决方案:

  • 发布的各个项目版本放在releases目录下面,各个版本的目录名称按照1,2,3的顺序递增。
  • current是真正跑的版本,是指向release的软链接,当新项目发布成功的时候,再修改软链接。
  • scm目录存放带有项目管控的代码。
  • shared目录存放配置文件,数据文件,按照需要软链接到各个发布版本里面去。

配置:

capistrano(以下简称cap)写一个config/deploy.rb,里面定义了一系列的rake任务,以及一系列的role(角色,比如数据库,应用服务器,网站服务器), rake任务定义了在什么role上面执行什么命令。各种配置环境写在config/deploy/文件夹里面,命名producton, staging等, 当需要发布项目的时候,执行cap production deploy,就根据配置环境和deploy脚本执行操作。

执行任务过程如下:

  • 创建目标环境releases/n
  • scm获取最新的项目,然后根据配置中指定的版本号,拷贝代码到releases/n
  • 初始化releases/n
  • 把app/release/23链接到app/current,然后重启服务
  • 清理releases/目录,只保留最新的几个版本

cap在服务器上面执行代码的方式,是通过维护一个ssh连接实现的,每次执行任务都要上传命令,返回结果,如果ssh连接比较慢的话,整体消耗时间就很长。 mina它的原理是生成一个bash脚本,上传到服务器上面执行,这样执行效率比cap高太多,大家可以考虑作为替代使用。

这种方式是传统的编译发布,另外有直接发布环境的方法,比如用docker。不过这种发布方式我没有研究清楚,等研究过之后再比较吧。

Slack介绍-企业级实时通讯工具

| Comments

最近我在团队里面推广了slack,它是一个文字实时通讯工具,为什么要用它呢? 比起QQ,skype等通用实时文字通讯工具,有几个好处:

  • 文字交流内容可以在团队之间分享。
  • 交流按照channel主题分组,比如项目1,服务器管理,客服等。
  • 可以存档,以及搜索历史记录。
  • 安装了手机应用或者桌面应用了之后,可以实时收到提醒。
  • 可以和其他各种系统整合,比如redmine,gitlab,或者程序员撰写提醒插件(比如监控服务器性能,登录,应用发布,定期任务等)
  • 聊天机器人:机器人可以通过监控聊天室的内容,执行特定操作:
    • 这样团队成员可以控制机器人做一些事情(查看系统状态,执行特定任务等),这些控制指令可以在手机上面发出。
    • 机器人监控各种提醒,执行操作。

因为这些好处,我觉得slack这种工具值得所有的技术团队使用。

不过同时slack也有一些其他问题:

  • 聊天分组是按照channel来的,不能进一步区分,比如服务器管理下面还有系统性能,系统重启,系统登录等子分组。这样用户可以关注特定的子分组,而不会被大分组的其他内容刷屏。
  • 通讯不够实时,有的时候可能好几分钟才能响应,一些紧急时间几分钟是很长的时间了。

比特币介绍

| Comments

大家应该对比特币不陌生了吧,不过弄懂比特币原理的人应该不是很多。 这里有一篇中文介绍,讲得非常清楚。

主要的原理:

  • 比特币简称BTC,一个比特币可以拆分到10的-8次方。
  • 用户拥有钱包,钱包由公钥私钥组成。这样用户可以给交易做签名。
  • 比特币网络维护一个全局的账本,账本里面记录的是交易:一个用户转多少BTC给另外一个用户,所以BTC本质上是通过账本计算得到一个用户到底有多少钱。
  • 一次交易就是交易双方广播一条交易记录到比特币网络里面,被大多数人接受了,那么这个交易就成立了。

那么比特币如何产生?交易需要写入全局账本才算正式成立,全局账本拆分成一个个block,任何人都可以收集交易,创建block。每创建一个block,创建者可以在里面记录自己获得若干BTC,这是比特币产生的唯一途径。比特币网络每个小时只能接受若干数量的block,这样保证比特币产生的数量稳定。创建block的人要互相PK,谁运算量更大就更有可能被接受。创建block的过程叫做挖矿,挖矿可以获得比特币,同时也为大家服务:创建新的账本。

比特币协议规定,随着时间的增长,每个block获得的BTC会变少,总体来说,比特币是通货紧缩的(如果更多交易用到比特币的话)。开始的人更容易获得比特币,大家更愿意把比特币囤积起来一段时间。同时币值完全取决于市场,大家对比特币多有信心,它就值多少钱。比特币的用户数量,真实交易频率可以作为它生命力的象征。

我觉得比特币的实际用处在于交易本身。因为比特币是去中心化,以及不需要用户信息的,可以利用它进行匿名跨国交易,比如快速从中国转钱到国外或者相反,以及各种黑市交易。有了比特币,资金交易可以真正做到匿名安全。从这个角度看,它是相当有价值的。

因为账本是全局的,我们可以看到有史以来所有的比特币交易记录,比如这一条,里面列出来创建者获得25BTC,以及各种交易记录。我看了一下最开始的记录,应该是比特币的发明者自己留的,他留了至少100万个比特币,按照现在的币值,价值2亿美元。

初始创建者获利甚多,于是就有无数的山寨币出来。但是同时货币的去中心化,匿名特性,让它变得无保障,经常会有黑客盗窃,网上交易所诈骗等现象,用户同时也没有办法维权。加上币值容易被操作,个人觉得比特币不适合持有,而是用来进行货币交易转换。

采用node-webkit进行C/S架构客户端设计

| Comments

2014年我在医院信息科工作, 医院需要一个通知系统用来进行信息的传达,于是我设计了一个客户端的信息通知系统, 同时整合有医院各大系统的启动器。

选型

我希望能够做把通知系统做成医院的统一化信息化入口,同时带有信息通讯,通知传达,监控等功能。 医院上上下下有无数的科室,科室里面的电脑操作系统各异(虽然都是windows),性能也一般(有很多老的电脑)。

我选择采用C/S架构而不是B/S架构,因为很多操作(开启另外的应用程序,后台监控)需要系统权限,不能用系统自带的浏览器完成。 考虑了各种GUI框架:包括Qt,PyQt,winform,MFC,html,最后选择了node-webkit,几个原因:

  • 我对前端这一块比较熟悉,用html用来进行内容展示比较容易实现。
  • 客户端电脑只有IE,并且版本不一,node-webkit可以统一浏览器环境,方便后续基于浏览器的应用导入。
  • node-webkit可以执行相当多的本地操作,包括开启应用程序,执行后台脚本,窗口控制等。
  • node-webkit经过测试,可以跑在我们医院各种旧电脑上,不会有很大的性能问题。

设计

启动器:客户端带有程序启动器的功能,限制用户必须采用该系统启动各种医院信息系统(原先都是用桌面快捷方式的方案)。 用了启动器,才能强制用户看到通知,另外也把各种启动的方法都汇总起来。 启动器可以自动化安装:点击了某信息系统,如果发现本地没有安装,就可以连接到服务器上面,拷贝下来自动化安装。 autoit可以实现自动化安装的功能。 启动器也可以提供一些帮助功能:比如显示电脑的IP地址,开启远程桌面,链接到文件服务器等,方便系统管理员处理问题。

通知系统:通知系统整合到启动器中,内嵌一个网页,链接到远程的Rails服务器,展示通知。 有需要发放通知的科室,可以根据信息科发放的账户,登录到服务器中,撰写通知,发布。各个客户端会定时轮询远端服务器, 如果有新的通知,就会弹出窗口。这样可以达到全院信息传达的目的。 同时通知历史都存储在服务器上面,所有客户端都可以查看历史通知,以及下载通知带有的附件文件。

启动性能:医院的部分信息系统采用delphi开发,使用者已经习惯系统的瞬间开启。 新一代的软件基本上都达不到这样的开启速度,更别说是node-webkit了。我让客户端开机启动,驻留在系统中, 用户点击开启触发程序窗口,达到快速开启的效果。

更新:客户端软件的更新是一个大问题。我采用的方法:定时监控一台远程服务器上面的某个文件, 如果发现远端有更新(根据版本判断),后台下载新的程序文件,自动重启。因为windows上面可执行文件不能修改自己, 客户端首先运行一个加载小程序:如果发现本地有更新程序,拷贝更新程序,再执行node-webnit程序。 这个加载小程序我用前面说的autoit编写,启动速度很快。

本地缓存:考虑到客户端同时具有系统启动器的功能,当远端的服务器出现问题,本地要能够保持正常使用。 启动器功能都整合在客户端之中,启动器的每个项目,用json格式描述,方便拓展。

心得

系统开发过程中,我应用了node-webkit和autoit,发现node-webkit性能还是不够好(webkit内存占用还是太高,开启速度不够), 以及用html/js开发会有一些不稳定因素(开启页面有的时候会不能正常工作)。autoit是很简陋的编程语言,不是很方便使用。

客户端导入过程:我跑了医院无数科室安装,零零散散耗时一个多星期。最后客户端的稳定性我还是很满意的。 最担心的问题是自动更新系统工作不正常造成所有客户端不能访问,需要重新安装。通知系统设计得简洁,用户使用上面没有什么问题。

还有后话:我在医院待了半年多就离职了,考虑到整体系统的维护成本,离职后我们就把这个系统废弃掉不再使用了。

Docker介绍

| Comments

我们知道虚拟化的层次有:CPU指令集级别虚拟化,操作系统级别虚拟化, 还有一种进程级别虚拟化(container),底层都采用linux内核,在内核之上的CPU资源,内存,文件系统,设备,都用虚拟化技术隔离出来。 docker就是这样的一个工具。

docker用linux内核的资源控制功能(LXC)来隔离和控制资源,用AUFS来管理虚拟的文件系统,用docker可以提供一个轻量级的虚拟机,它的特性有:

  • 快速启动,一个进程起来可能只需要几秒钟。
  • 轻量级文件系统虚拟化,带有版本控制的文件系统,改动只保存变更,存储占用非常小。
  • 进程间隔离,保证进程之间不会互相干扰。

用docker可以把应用集装箱化,快速搭建,移动,复制,分发。对于应用开发,它可以让开发和发布环境归一起来, 开发阶段测试完毕之后可以直接装箱进入发布流程。

同时docker也有一些不适合的场景,比如有状态应用(存储),资源占用比较大,或者高性能网络应用,虚拟化会带来性能损耗。

docker以及container思想对于现在系统架构的冲击比较大,现在有一个CoreOS发行版,所有发布的应用都存放在container里面执行。

Systemd初探

| Comments

最近ubuntu准备迁移到systemd,基本上linux上面init纷争大局已定,systemd赢得了主要的市场。 以后各大linux的发行版都以systemd为主,各种系统进程都会用systemd启动, 对于系统管理员们来说,systemd成为必须学习的一个模块。

那么什么是systemd?我们知道linux系统里面启动各大进程的工作都是由init来完成的, 机器启动有不同的级别(rc level),根据不同的级别设置启动进程的顺序。 这种传统架构已经不适应现代的操作系统进程管理了,问题有:

  • 设备管理:传统架构架设设备是静态的,但是现代操作系统里面设备动态插入和拔出的状况非常常见。
  • 依赖管理:传统架构靠/etc/rc3.d/下面文件名显式制定启动顺序,无法适应复杂依赖关系。
  • 进程管理:传统架构没有进程管理,只负责启动,停止的时候也不能保证进程的子进程正常关闭,往往需要系统管理员单独配置。

做过系统管理员的人,应该知道针对进程管理,需要写多少脚本,搭建各种各样的监控和管理系统。 systemd是init的替代系统,有了它,可以说解决了很大一部分的问题,脚本可以丢掉一大部分了。 systemd的解决方案:

  • 所有管理的对象都是unit,包括系统服务,文件系统,设备等
  • 做到比较好的资源依赖管理
  • 利用cgroup等工具,做到进程管理和控制
  • 内置日志系统来接收和管理各个unit的日志

systemd做的事情很多,体积也很大,网上对此也有争议。我对于它的涉及领域没有意见,因为进程管理相关的事情是很多,彼此也有依赖。 用了systemd,管理一个进程,只需要写好对应的一个配置文件就好了,对于系统管理员来说,事情变得更简单了, 配置文件的格式也不是很复杂。

现在我的主力服务器发行版是ubuntu,等ubuntu正式引入systemd之后,我会用它来进行进程管理,到时候会有更多的心得可供分享。

家庭NAS服务器搭建

| Comments

image

为什么要用家用NAS

去年年底,我搭建了一台家用NAS服务器。我用它来存放视频漫画等数据资料, 创建一些空间消耗大的虚拟机,备份笔记本电脑系统。 有了NAS,资料可以给家里面所有设备使用(比如多台iPad,手机), 可以跑一些消耗大量时间和空间的应用(比如虚拟机和下载), 生活工作方便许多。

NAS硬件选购

我选购的是N54L,主要是考虑到性价比。 设备买回来之后,发现做工不错,拓展性也很好。

我把内存加到12G,对于服务器来说,内存越大越好,尤其我这种希望使用虚拟机的情况。

硬盘选择的是:一个SSD,一个服务器硬盘。 SSD用来安装系统,用来保证系统执行速度。其他资料和动态数据目录都放在服务器硬盘上面。

N54L有4个硬盘位,方便拓展,到时候我会选择用RAID5方式, 因为在保证资料安全性的同时,能够有比较大的空间利用率。

系统平台

考虑了一系列操作系统,包括FreeNAS群辉等,我最后还是选择了Ubuntu Server, 因为这是我最熟悉的系统,并且我会装好多实验工具,有一个专业的服务器平台更好一些。

系统设置了自动更新,我写了一个脚本,当需要重启的时候发消息通知我。

分区我考虑了一下, 最后还是用lvm和btrfs结合的方案,没有搞懂zfs如何和lvm一起工作。

服务搭建

外网访问

首先需要让外网可以知道自己家的IP地址,我用noip来自动更新域名。

外网访问家里的内网,需要给NAS装一个VPN系统。l2tp和pptp都对网络有要求(IP层允许ESP,PPP协议), 安装的时候调试了好久,最后还是选择了softether,看起来比较简单一些, 并且可以外网配置。 VPN访问自身服务器有问题,不能同一个网卡出入,最后我还是购买了另外的一块网卡,用来提供给VPN使用。

防火墙

因为家里无线路由的开放性,服务器提供的服务都设置了密码,并且用防火墙ufw限制了开启的端口。

下载

考虑各种下载方案,最后我选择用webui-aria2,结合迅雷离线, 迅雷离线插件ThunderLixianExporter。

如果是电影等通用资源,用迅雷离线快速下载,然后用迅雷插件通知aria2下载回本地。 非常见资源直接丢链接给webui-aria2慢慢下。

timemachine备份

因为OSX的timemachine会占用全部的磁盘资源,我专门做了一个分区。 按照这里的教程搭起来服务就好了。 有的时候备份会提示已经占用磁盘,需要重启一下netatalk服务。

文件服务器

考虑了http,ftp,net,dlna,各种第三方的media server,最后发现还是samba好用, 渲染视频音频的操作还是交给客户端来做吧。

格式转换

网上下载下来的东西格式比较多,手机上面看不是很方便,我用avconv来统一把视频转换成mp4的格式(视频h264,音频aac)。同时为了方便预览,我写了脚本,自动给所有视频创建一个gif的预览,然后做一个网页,可以快速查看它们。

监控

我直接给服务器装了New Relic,它会自动通知我磁盘空间使用率,以及宕机状况。我也装了munin,但是用不太到。

虚拟机

我对VirtualBox比较熟悉,安装了命令行工具,然后再装上web前端phpVirtualBox

创建了虚拟机之后,我可以设置端口映射访问虚拟机,或者用VirtualBox的远程桌面功能。

web安全

所有通过http访问的服务,我全部都改成了https,保证传输安全性。采用自授权, 自授权需要写host域名,我自己定义了一个nas的域名(比如local-nas-server.pc),然后增加到自己电脑的/etc/hosts,地址就是nas的内网地址。

备份

NAS的重要资料我都备份到云平台上面,不重要又大的资料(比如电影)就不管了。系统的配置一定要写脚本定期备份,不然丢了就好难找回来。

待实现

以后有时间可以买一个摄像头,实时监控家里或者门口的情况。

Chef介绍

| Comments

chef是一个服务器自动化构建工具。最近我花了好多时间来研究它, 慢慢弄懂了如何使用,这里整理一下介绍。

为什么要自动化构建

我们搭建一台服务器,一般情况下是用ssh登录上去,手动执行一系列的安装脚本。这种方式有一些问题:

  • 手动操作费时:安装一台rails服务器,等待和操作的时间可能有一个小时。
  • 容易出现失误:不小心写错了一个参数或者执行错了一个命令,可能损失好久的调试和重新安装时间。
  • 难以复用:每次安装都需要重新手动操作一遍,虽然可以记录下操作的脚本,但是每台服务器多多少少不一样,还需要针对性地修改。
  • 难以跟踪改动:运行了一段时间之后,会因为某些需要作出修改。除非流程上面控制必须整理文档,后期完全不知道改了什么。

如果把服务器当作一个应用,针对服务器的操作就是应用的源代码,我们可以用代码库的思路来考虑服务器构建,这就是自动化构建。

chef的解决方案

服务器的一个状态(比如一个特定内容的文件,一个需要跑的进程服务),可以定义成一个resource, 用provider控制resource的状态(比如删除文件,创建文件,启动进程), 一系列这样的描述,定义了我们想要做的事情,比如安装postgresql,构成了一个cookbook。 这些描述和操作,都用ruby语言编写,cookbook用源码管控。

在每个服务器(node)上面,会跑一个chef-client,从chef-server获得cookbook, 自己需要跑的东西(run_list),服务器给自己设置的属性(attributes),通知服务器自己的状态。

更多的文档,请见:http://docs.chef.io/

如何学习

chef相当的复杂,我花费了好多时间来学习它。这里是我建议的学习过程:

  • 跟随官方教程走一遍,因为期间需要下载很多库,建议用Digital Ocean等云平台进行教程的学习,这样不需要太长的下载等待时间。
  • 自己写一个cookbook(比如我就写了pptp_server),期间遇到什么概念不明白,去官方文档阅读,并且可以借鉴第三方cookbook的写法。
  • chef引入了一个生态系统,基于chef的工具和概念相当多,请静下心来,一个个弄懂弄透。

个人的实践

掌握了工具仅仅是开始,更难的在于如何使用工具。这里整理我的一些实践操作。

  • 如果是很简单的服务器搭建,可以登录到服务器上面去,直接按照recipe的写法创建一个文件install.rb,然后用chef-apply执行。
  • 如果稍微复杂一些,可以用chef-client --local-mode,在服务器上面写一个cookbook。
  • 如果需要写cookbook,也可以用local-mode在服务器上面测试好,再保存到本地。
  • 如果你服务器比较多,或者需要快速搭建不经过server,你可以用chef-soloknife-solo是chef-solo的knife插件。
  • 创建服务器也可以自动化,比如knife-digital_ocean
  • 一般可以写一个cookbook构建一个基础系统,带有自动更新,安全管理,创建发布用户,监控等。然后基于这个基础系统来搭建服务。

个人的一些思考

  • chef很复杂,学习成本比较高,它可能解决一些问题,但是自己的复杂度可能也会引入更多的问题。
  • 普通程序员可能只是用chef来搭建一个或几个服务器,用chef可能有点杀鸡用牛刀,但是自动化构建是很有必要的,chef引入的复杂概念,很可能是领域的原生复杂度。
  • cookbook的调试过程太痛苦了,等待服务器执行操作,重新创建一个服务器来执行操作花费了好多时间。
  • 第三方cookbook库里面比较混乱,安装一个东西可能有好几个cookbook,大家对于如何安装一个东西有不同的理解。
  • cookbook可以通过node的attribute配置,也可以重新定义LWRP,我觉得这两个概念有一定程度的覆盖,设计不是很好,可能规整成一个概念。
  • 有听说docker,在操作系统上层加上一个容器层,容器层类似集装箱,可以快速导入导出应用的环境,听说docker会取代大部分chef的使用场景。