Cgroup – 从CPU资源隔离说起 (liwei.life)
一个正在运行着服务的计算机系统,跟我们高中上课的情景还是很相似的。如果把系统中的每个进程理解为一个同学的话,那么班主任就是操作系统的核心(kernel),负责管理班里的同学。而cgroup,就是班主任控制学生行为的一种手段,所以,它起名叫control groups。

既然是一种控制手段,那么cgroup能控制什么呢?当然是资源啦!对于计算机来说,资源大概可以分成以下几个部分:

1、计算资源
2、内存资源
3、io资源
4、网络资源

这就是我们常说的内核四大子系统。当我们学习内核的时候,我们也基本上是围绕这四大子系统进行研究。
我们今天要讨论的,主要是cgroup是如何对系统中的CPU资源进行隔离和分配的。其他资源的控制,我们以后有空再说喽。
by @技术头条 2017-02-05 14:42 查看详情
分布式系统中 Unique ID 的生成方法 (chenpeng.info)
在分布式系统存在多个 Shard 的场景中, 同时在各个 Shard 插入数据时, 怎么给这些数据生成全局的 unique ID?

在单机系统中 (例如一个 MySQL 实例), unique ID 的生成是非常简单的, 直接利用 MySQL 自带的自增 ID 功能就可以实现.

但在一个存在多个 Shards 的分布式系统 (例如多个 MySQL 实例组成一个集群, 在这个集群中插入数据), 这个问题会变得复杂, 所生成的全局的 unique ID 要满足以下需求:

1、保证生成的 ID 全局唯一
2、今后数据在多个 Shards 之间迁移不会受到 ID 生成方式的限制
3、生成的 ID 中最好能带上时间信息, 例如 ID 的前 k 位是 Timestamp, 这样能够直接通过对 ID 的前 k 位的排序来对数据按时间排序
4、生成的 ID 最好不大于 64 bits
5、生成 ID 的速度有要求. 例如, 在一个高吞吐量的场景中, 需要每秒生成几万个 ID (Twitter 最新的峰值到达了 143,199 Tweets/s, 也就是 10万+/秒)
6、整个服务最好没有单点

如果没有上面这些限制, 问题会相对简单, 例如:

1、直接利用 UUID.randomUUID() 接口来生成 unique ID (http://www.ietf.org/rfc/rfc4122.txt). 但这个方案生成的 ID 有 128 bits, 另外, 生成的 ID 中也没有带 Timestamp
2、利用一个中心服务器来统一生成 unique ID. 但这种方案可能存在单点问题; 另外, 要支持高吞吐率的系统, 这个方案还要做很多改进工作 (例如, 每次从中心服务器批量获取一批 IDs, 提升 ID 产生的吞吐率)
3、Flickr 的做法 (http://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/). 但他这个方案 ID 中没有带 Timestamp, 生成的 ID 不能按时间排序

在要满足前面 6 点要求的场景中, 怎么来生成全局 unique ID 呢?

Twitter 的 Snowflake 是一种比较好的做法. 下面主要介绍 Twitter Snowflake, 以及它的变种
by @技术头条 2017-02-05 14:40 查看详情 (1)
S.O.L.I.D.类设计原则 (chenpeng.info)
本文是由敏捷宣言签署人之一、《 Clean Code(代码整洁之道)》一书的作者Robert C. Martin为他的《Applying Principles and Patterns》这本书搜集整理而来。

单一责任原则(SRP)

  只有一个理由去修改一个类。例如,如果一个业务规则的改变会导致这个类的修改,那么,数据库、界面、报表格式或系统任何其它的部分的改变都不该迫使这个类做修改。

开发/关闭原则(OCP)

  软件构成(类,模块,方法等)向扩展行为开放,向修改行为关闭。

Liskov替换原则(LSP)

  子类必须能够用来当作基类使用。如果类A继承类B,任何能使用A的地方,B也同样可以使用。例如,是否还记得,正方形可以看作是矩形!当进行扩展时:前提条件不许绕过,后置条件不能放宽限制,可见常量不能被修改(?)。常量:在扩展之前或之后,用户都需要依靠这个常量来传递信息。正确的使用set形式的继承关系。不遵守set语义是非常危险的。归纳:使用超类的引用的任何上下文中也可以使用其子类的引用替代。这个原则极大的限制了在纯扩展(继承)机制里可以做的事情。不遵守会带来风险。

接口分离原则(ISP)


  一个类对另一个类的依赖应该限制在最小化的接口上。

反向依赖原则(DIP)

  依赖抽象层(接口),而不是具体类。

其它重要原则

Demeter定律

  也被称做封锁信息原则:只跟朋友交流

  一个对象O的任何一个方法M只能调用下列类型的对象的方法:

它自己
它的参量
它创建/实例化的对象
它的直接组件对象

好莱坞原则

  不要调用我,我会调用你的。

不要自我重复(DRY)

  去掉重复代码。

对接口编程,而不是对实现

  反向依赖的另外一种说法。

你不需要它(YAGNI)

  不要添加你“认为以后可能有用”的代码。只在“事到临头”时才添加代码。

简单化,傻瓜化(KISS)

  让它能工作的最简单的方法是什么?
by @技术头条 2017-02-05 14:38 查看详情
一个简单的 lua 对象回收再利用方案 (blog.codingnow.com)
昨天在 review 我公司一个正在开发的项目客户端代码时,发现了一些坏味道。

客户端框架创建了一个简单的对象系统,用来组织客户端用到的对象。这些对象通常是有层级关系的,顶层对象放在一个全局集里,方便遍历。通常,每帧需要更新这些对象,处理事件等等。

顶层每个对象下,还拥有一些不同类别的子对象,最终成为一个森林结构,森林里每个根对象都是一颗树。对象间有时有一些引用关系,比如,一个对象可以跟随另一个对象移动,这个跟随就不是拥有关系。

这种设计方法或模式,是非常常见的。但是在实现手法上,我闻到了一丝坏味道。
由于类别很多,所以代码中充斥着模仿静态语言如 C++/C# 般的大量构造和析构函数。我一直对同事说 Lua 不是 C++ 大部分同事也认同我的观点,但落到实处,却逃不出过去的很多经验。

比如在这次具体问题上,为什么要实现一套带构造和析构函数的类别系统呢?
by @技术头条 2017-02-05 14:30 查看详情
在 Mac 安装 Docker 环境的种种 (sexywp.com)
其实很早就听说了 Docker 了,这正是现在世界上最炙手可热的容器技术。直到去年 2015 年,我们公司才有小伙,尝试使用 Docker,当时,我们公司是全 Mac 办公,而 Docker 只支持 Linux,于是各种非官方爱好者,做出了各种方案,比如当时,如果要在 Mac 上用 Docker,就必须安装一个 boot2docker 的组件,是一个在 Mac 上使用 Docker 的封装,同时还要依托 VirtualBox 才行,当然也有 VmWare 的版本,但是又是收费的。

这个 boot2docker 的方案,不但安装麻烦,其命令行界面也丑陋不堪。而负责去研究这个方案的小伙子,最终也没有给出特别好的技术方案,只是浅尝辄止的一个分享演讲而已,比较令人失望。
by @技术头条 2017-02-05 14:29 查看详情
使用 _ 作为私有成员变量前缀 (sexywp.com)
关于编码规范,每个程序员都有自己的看法,他们通常相信自己所奉行的规范是好的并且早已养成习惯,有些看法的意念特别强大,以至于上升到了一种信仰层面。

我个人觉得,编码规范不是个人习惯,比较好的态度是,信奉编码规范可以提升大家的效率,而坚守一个团队的编码规范,而不是,坚守某种固有的做法。至于

某种规范的条例是不是“很奇怪”,“不合理”,我们都可以讨论,但是讨论不代表不遵守,这才是比较职业化的态度。或者说,即便通过讨论,认定某个规范不合理.
by @技术头条 2017-02-05 14:29 查看详情
开源移动端元素拖拽惯性弹动以及下拉加载两个JS (www.zhangxinxu.com)
开源两个起点中文网M站两个动效交互JS,封装良好,即插即用。

一个是任意元素屏幕拖移外带惯性边缘弹动效果,另外一个是基于窗体的下拉释放加载刷新效果。
by @技术头条 2017-02-05 14:21 查看详情
为相机增添地理坐标的能力 (cuikai-wh.com)
为照片标注地理坐标最通用/常见的方式,是使用美国的全球定位系统(GPS)。几乎所有的地图、手机的定位标准都是 GPS(如 iPhone)。中国的北斗系统、俄罗斯的格纳斯与欧盟的伽利略也支持,但尚未普及。

有两个办法可以达到我们的目的:
相机本身支持,即拍照后自动为照片增加地理坐标属性
通过 GPS 仪器,在拍摄途中打开定位系统;拍摄完毕后,将定位文件与照片文件合成

方案1显然简单方便,但可能考虑到 GPS 比较耗电,目前市面上的主流相机都不支持。非常遗憾。方案2有两个办法,一是购买专门的 GPS 定位仪,二是直接使用手机。

还用问吗,当然是直接使用手机。听从知友的建议,我也使用「地图加加」(iOS)。出门前打开定位追踪,应用将一直在后台运行,默默记录行动轨迹。注意,记录坐标很耗电,备好充电宝,万无一失。回家后完成追踪,将本次行程导出为 GPX 文件。

接下来,在电脑上使用「GPX Photo Tagger」(Mac),导入照片和 GPX 文件。应用会根据时间戳,自动把地理坐标作为属性,添加到照片里。

大功告成。
by @技术头条 2017-02-05 14:18 查看详情
【译文】热闹驱动开发 (www.luanxiang.org)
软件开发团队关于软件架构或技术栈的决策,很多并不是基于扎实的研究和对期望效果的认真思考,而是不准确的意见、社交媒体的信息,或者就些是“热门”玩意。这种做派的危害我见过不少,称它为“热闹驱动开发(Hype Driven Development,HDD)”。我赞成的是更专业的做法,称之为“脚踏实地的软件工程”。下面一起看看HDD的来龙去脉,想想我们能怎么改进。
新技术带来新希望
团队把最新最热的技术应用到项目里,这样的景象你见过吗?有人是因为读到了相关的博客,有人是看到Twitter上的潮流,还有人是刚刚在技术大会上听到了关于某门技术的精彩演讲。不久,团队就开始采用这种亮眼的新技术(或者软件架构设计范式),结果他们并不能更快(就像之前说的那样)开发出更优秀的产品,反而身陷囹圄。开发的速度降下来了,信心受挫了,后续版本的交付也出问题了。有些团队甚至干脆专心修bug,而不是开发新功能。他们“只需要多花几天”就能把事情搞定。
热闹驱动开发
热闹驱动开发有很多流派,也有很多渠道介入大家的项目:
Reddit驱动开发——在选择技术、架构、设计时,团队和个人的决策依据是知名博主的文章,或者reddit, hackernews, blogs, twitter, facebook, Github或者其它社交媒体上的热点。
技术会议驱动开发——仔细观察观察,参会回来的家伙们有什么表现。他们备受演讲的鼓舞。这是双刃剑。他们没有足够的研究,就开始使用最新最热的类库/框架/架构范式,而这可能是通往地狱的高速公路。
嗓门驱动开发——有人整天谈论新框架/类库/技术,他自己却没有经验,但是反复念经终于让团队决定采纳它。
Gem/类库/插件驱动开发——在RoR社区里特别流行这种情况,有时候我会发现一个gemfile太长,只有程序启动时的装载时间比它更长。这种流派源自下面的观念:Rails里的每个问题都应当有个gem来解决。有时候只要自己动手写几行代码就能解决,但是我们还是一个劲地添加类库/插件/gem/框架。
我还希望提到热闹驱动开发的一个常见流派,StackOverflow 驱动开发——开发人员从StackOverflow(总之就是互联网上)拷贝代码,而没有真正弄懂它们。
HDD就是开发团队自掘坟墓
凑热闹的问题是:它很容易导致错误决策。无论是糟糕的架构决策,还是糟糕的技术栈决策,给团队的影响都常常持续数月甚至数年。最糟的是它们会造成软件工程上千疮百孔的局面,只能推倒重来。但推倒重来几乎没有成功案例。
一切罪恶的根源似乎都是社交媒体——新观点传播得太快,还没来得及经过检验。大家还来不及细想有哪些利弊,就已经传播开去。
by @技术头条 2017-02-05 14:15 查看详情
如何抓取汽车之家的车型库 (huoding.com)
实际上,关于「如何抓取汽车之家的车型库」,我已经在「使用 Mitmproxy 分析接口」一文中给出了方法,不过那篇文章里讲的是利用 API 接口来抓取数据,一般来说,因为接口不会频繁改动,相对 WEB 页面而言更稳定,所以通常这是数据抓取的最佳选择,不过利用 API 接口来抓取数据有一些缺点,比如有的数据没有 API 接口,亦可能虽然有 API 接口,但是数据使用了加密格式,此时只能通过 WEB 页面来抓取数据。 既然要通过 WEB 页面来抓取数据,那么就不得不提到 Scrapy,它可以说是爬虫之王,我曾经听说有人用 Scrapy,以有限的硬件资源在几天的时间里把淘宝商品数据从头到尾撸了一遍,如此看来,本文用 Scrapy 来抓取汽车之家的车型库应该是绰绰有余的了。 在抓取汽车之家的车型库之前,我们应该对其结构有一个大致的了解,按照百科中的描述,其大致分为四个级别,分别是品牌、厂商、车系、车型。本文主要关注车系和车型两个级别的数据。在抓取前我们要确定从哪个页面开始抓取,比较好的选择有两个,分别是产品库和品牌找车,选择哪个都可以,本文选择的是品牌找车,不过因为品牌找车页面使用了 js 来按字母来加载数据,所以直接使用它的话可能会有点不必要的麻烦,好在我们可以直接使用从 A 到 Z 的字母页面。
by @技术头条 2017-02-05 14:13 查看详情
聊聊设计模式(2):享元模式 (www.barretlee.com)
如何理解享元模式,“享”是共享的意思,“元”指的是元件,也就是小颗粒的东西,享元顾名思义便是共享小部件,很多系统或者程序包含大量对象,但是这些对象绝大多数都是差不多的,除了一些极个别的属性外。
by @技术头条 2017-02-05 14:09 查看详情
修改bootstrap$影响数据库执行计划 (www.xifenfei.com)
在以前的文章中,我写过通过ue修改oracle二进制文件实现数据库启动的sql执行计划,这里再次提供另外一种方法,通过修改bootstrap$表实现数据库启动sql执行计划。这里试验的是数据库不走i_undo1 index。[此方法危害性巨大仅供测试]
by @技术头条 2017-02-05 14:07 查看详情
Cgroup – Linux的IO资源隔离 (liwei.life)
跟内存管理那部分复杂度类似,IO的资源隔离要讲清楚也是比较麻烦的。这部分内容都是这样,配置起来简单,但是要理解清楚确没那么简单。这次是跟Linux内核的IO实现有关系。对于IO的速度限制,实现思路跟CPU和内存都不一样。CPU是针对进程占用时间的比例限制,内存是空间限制,而当我们讨论IO资源隔离的时候,实际上有两个资源需要考虑,一个是空间,另一个是速度。对于空间来说,这个很简单,大不了分区就是了。现实手段中,分区、LVM、磁盘配额、目录配额等等,不同的分区管理方式,不同的文件系统都给出了很多不同的解决方案。所以,空间的限制实际上不是cgroup要解决的问题,那就是说,我们在这里要解决的问题是:如何进行IO数据传输的速度限制。
by @技术头条 2017-02-05 00:13 查看详情
Cgroup – Linux的网络资源隔离 (liwei.life)
Linux早在内核2.2版本就已经引入了网络QoS的机制,并且网络资源的隔离功能只是其所实现功能的一部分而已。无论如何,cgroup并没有再重新搞一套网络资源隔离的实现,而是直接使用了Linux的iproute2的traffic control(tc)功能。
by @技术头条 2017-02-05 00:10 查看详情
基于VoiceOver的移动web站无障碍访问实战 (www.zhangxinxu.com)
所谓“无障碍访问”,指的是各类设备均可以无障碍访问。例如鼠标、键盘、读屏软件或设备等。 ARIA全称“Accessible Rich Internet Applications(可访问的富互联网应用)”。 VoiceOver是苹果设备上的读屏软件,当开启VoiceOver后,交互行为和通常行为是不一样。并且和ARIA属性之间的关系也比较深,本文就将通过项目实战展示基于VoiceOver的移动端ARIA特性和注意事项。
by @技术头条 2017-02-05 00:07 查看详情
数据库设计准则(第一、第二、第三范式说明) (chenpeng.info)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
by @技术头条 2017-02-05 00:05 查看详情
数据库设计准则(第一、第二、第三范式说明) (chenpeng.info)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
by @技术头条 2017-02-05 00:04 查看详情
从Gitlab误删除数据库想到的 (coolshell.cn)
不久前,Gitlab.com发生了一个大事,某同学误删了数据库,这个事看似是个低级错误,不过,因为Gitlab把整个过程的细节都全部暴露出来了,所以,可以看到很多东西,而对于类似这样的事情,我自己以前也干过,而在最近的两公司中我也见过(Amazon中见过一次,阿里中见过至少四次),正好通过这个事来说说一下自己的一些感想和观点吧。我先放个观点:你觉得有备份系统就不会丢数据了吗?
by @技术头条 2017-02-04 23:41 查看详情