Unix 50 年:Ken Thompson 的密码
50年前,除了Apollo上天之外,还有一个大事的发生,就是Unix操作系统的诞生,若干年前我写过《Unix的传奇,上篇,下篇》,Unix是我入行前十年伴我成长的操作系统,虽然现在Linux早已接过了Unix的时代交接棒,但是,Unix文化对我个人的技术观影响是非常大的(注:《Unix编程艺术》是一本对影响我很深的书),而对于 Ken Thompson 和 Dennis Ritchie 这两位 Unix 的缔造者,也是计算机圈中的神一般的人物。今天,Dennis已经去逝,Ken在Google里跟 Rob Pike和 Robert Griesemer 这两位大神在开发Go语言。
P.S. 今年,我一直想写篇Unix 50周年纪念的文章,但一直无从下手,因为不想写过大的命题,如果能写个轶事最好不过。正好过完国庆节,技术圈里有个“热搜”——Ken Thompson的密码。但一直没有时间,所以拖到今天才写下来。
正文开始,2014年,有个叫Leah Neukirchen的程序员(blog)在 BSD 3 的源代码中的 /etc/passwd 看到了早年Unix黑客们的被 hash了 ...
打造高效的工作环境 – Shell 篇
注:本文由雷俊(Javaer/Emacser)和我一起编辑,所以文章版权归雷俊与我共同所有,转载者必需注明出处和我们两位作者。原文最早发于酷壳微信公众号,后来我又做了一些修改,再发到博客这边。
程序员是一个很懒的群体,总想着能够让代码为自己干活,他们不断地把工作生活中的一些事情用代码自动化了,从而让整个社会的效率运作地越来越高。所以,程序员在准备去优化这个世界的时候,都会先要优化自己的工作环境,是所谓“工欲善其事,必先利其器”。
我们每个程序员都应该打造一套让自己更为高效的工作环境。那怕就是让你少输入一次命令,少按一次键,少在鼠标和键盘间切换一次,都会让程序员的工作变得更为的高效。所以,程序员一般需要一台性能比较好,不会因为开了太多的网页或程序就卡得不行的电脑,还要配备多个显示器,一个显示器写代码,一个查文档,一个测试运行结果,而不必在各种窗口来来回回的切换……在大量的窗口间切换经常会迷路,而且也容易出错(分不清线上或测试环境)……
除了硬件上的装备,软件上也是能够提升程序员生产力的地方,在软件层面提升程序员生产力的东西有一个很重要的事就是命令行和脚本,使用鼠标和图形界面则会 ...
记一次Kubernetes/Docker网络排障
昨天周五晚上,临下班的时候,用户给我们报了一个比较怪异的Kubernetes集群下的网络不能正常访问的问题,让我们帮助查看一下,我们从下午5点半左右一直跟进到晚上十点左右,在远程不能访问用户机器只能远程遥控用户的情况找到了的问题。这个问题比较有意思,我个人觉得其中的调查用到的的命令以及排障的一些方法可以分享一下,所以写下了这篇文章。
目录
问题的症状
问题的排查
问题初查
重新梳理
柳暗花明
总结
问题原因
其它事宜
问题的症状
用户直接在微信里说,他们发现在Kuberbnetes下的某个pod被重启了几百次甚至上千次,于是开启调查这个pod,发现上面的服务时而能够访问,时而不能访问,也就是有一定概率不能访问,不知道是什么原因。而且并不是所有的pod出问题,而只是特定的一两个pod出了网络访问的问题。用户说这个pod运行着Java程序,为了排除是Java的问题,用户用 docker exec -it 命令直接到容器内启了一个 Python的 SimpleHtt ...
Linux PID 1 和 Systemd
要说清 Systemd,得先从Linux操作系统的启动说起。Linux 操作系统的启动首先从 BIOS 开始,然后由 Boot Loader 载入内核,并初始化内核。内核初始化的最后一步就是启动 init 进程。这个进程是系统的第一个进程,PID 为 1,又叫超级进程,也叫根进程。它负责产生其他所有用户进程。所有的进程都会被挂在这个进程下,如果这个进程退出了,那么所有的进程都被 kill 。如果一个子进程的父进程退了,那么这个子进程会被挂到 PID 1 下面。(注:PID 0 是内核的一部分,主要用于内进换页,参看:Process identifier)
目录
SysV Init
UpStart
Systemd
Systemd 争论和八卦
其它
延伸阅读
SysV Init
PID 1 这个进程非常特殊,其主要就任务是把整个操作系统带入可操作的状态。比如:启动 UI – Shell 以便进行人机交互,或者进入 X 图形窗口。传统上,PID 1 和传统的 Unix System V 相兼容的,所以也叫 sysvin ...
缓存更新的套路
看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。然而,这个是逻辑是错误的。试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。
我不知道为什么这么多人用的都是这个逻辑,当我在微博上发了这个贴以后,我发现好些人给了好多非常复杂和诡异的方案,所以,我想写这篇文章说一下几个缓存更新的Design Pattern(让我们多一些套路吧)。
这里,我们先不讨论更新缓存和更新数据这两个事是一个事务的事,或是会有失败的可能,我们先假设更新数据库和更新缓存都可以成功的情况(我们先把成功的代码逻辑先写对)。
更新缓存的的Design Pattern有四种:Cache aside, Read through, Write through, Write behind caching,我们下面一一来看一下这四种Pattern。
目录
Cache A ...
Docker基础技术:DeviceMapper
在上一篇介绍AUFS的文章中,大家可以看到,Docker的分层镜像是怎么通过UnionFS这种文件系统做到的,但是,因为Docker首选的AUFS并不在Linux的内核主干里,所以,对于非Ubuntu的Linux分发包,比如CentOS,就无法使用AUFS作为Docker的文件系统了。于是作为第二优先级的DeviceMapper就被拿出来做分层镜像的一个实现。
目录
Device Mapper 简介
Thin Provisioning 简介
Thin Provisioning Snapshot 演示
Docker的DeviceMapper
Device Mapper 行不行?
Device Mapper 简介
DeviceMapper自Linux 2.6被引入成为了Linux最重要的一个技术。它在内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构,它包含三个重要的对象概念,Mapped Device、Mapping Table、Target device ...
Docker基础技术:AUFS
AUFS是一种Union File System,所谓UnionFS就是把不同物理位置的目录合并mount到同一个目录中。UnionFS的一个最主要的应用是,把一张CD/DVD和一个硬盘目录给联合 mount在一起,然后,你就可以对这个只读的CD/DVD上的文件进行修改(当然,修改的文件存于硬盘上的目录里)。
AUFS又叫Another UnionFS,后来叫Alternative UnionFS,后来可能觉得不够霸气,叫成Advance UnionFS。是个叫Junjiro Okajima(岡島順治郎)在2006年开发的,AUFS完全重写了早期的UnionFS 1.x,其主要目的是为了可靠性和性能,并且引入了一些新的功能,比如可写分支的负载均衡。AUFS在使用上全兼容UnionFS,而且比之前的UnionFS在稳定性和性能上都要好很多,后来的UnionFS 2.x开始抄AUFS中的功能。但是他居然没有进到Linux主干里,就是因为Linus不让,基本上是因为代码量比较多,而且写得烂(相对于只有3000行的union mount和10000行的UnionFS,以及其它平均下来只有60 ...
Docker基础技术:Linux CGroup
前面,我们介绍了Linux Namespace,但是Namespace解决的问题主要是环境隔离的问题,这只是虚拟化中最最基础的一步,我们还需要解决对计算机资源使用上的隔离。也就是说,虽然你通过Namespace把我Jail到一个特定的环境中去了,但是我在其中的进程使用用CPU、内存、磁盘等这些计算资源其实还是可以随心所欲的。所以,我们希望对进程进行资源利用上的限制或控制。这就是Linux CGroup出来了的原因。
Linux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。这个项目最早是由Google的工程师在2006年发起(主要是Paul Menage和Rohit Seth),最早的名称为进程容器(process containers)。在2007年时,因为在Linux内核中,容器(container)这个名词太过广泛,为避免混乱,被重命名为cgroup,并且被合并到2.6.24版的内核中去。然后,其它开始了他的发展。
Linux CGroupCgroup 可让 ...
Docker基础技术:Linux Namespace(上)
时下最热的技术莫过于Docker了,很多人都觉得Docker是个新技术,其实不然,Docker除了其编程语言用go比较新外,其实它还真不是个新东西,也就是个新瓶装旧酒的东西,所谓的The New “Old Stuff”。Docker和Docker衍生的东西用到了很多很酷的技术,我会用几篇 文章来把这些技术给大家做个介绍,希望通过这些文章大家可以自己打造一个山寨版的docker。
当然,文章的风格一定会尊重时下的“流行”——我们再也没有整块整块的时间去看书去专研,而我们只有看微博微信那样的碎片时间(那怕我们有整块的时间,也被那些在手机上的APP碎片化了)。所以,这些文章的风格必然坚持“马桶风格”(希望简单到占用你拉一泡屎就时间,而且你还不用动脑子,并能学到些东西)
废话少说,我们开始。先从Linux Namespace开始。
目录
简介
clone()系统调用
UTS Namespace
IPC Namespace
PID Namespace
Mount Namespace
Docker的 Mount Nam ...
Docker基础技术:Linux Namespace(下)
在 Docker基础技术:Linux Namespace(上篇)中我们了解了,UTD、IPC、PID、Mount 四个namespace,我们模仿Docker做了一个相当相当山寨的镜像。在这一篇中,主要想向大家介绍Linux的User和Network的Namespace。
好,下面我们就介绍一下还剩下的这两个Namespace。
目录
User Namespace
Network Namespace
Namespace文件
参考文档
User Namespace
User Namespace主要是用了CLONE_NEWUSER的参数。使用了这个参数后,内部看到的UID和GID已经与外部不同了,默认显示为65534。那是因为容器找不到其真正的UID所以,设置上了最大的UID(其设置定义在/proc/sys/kernel/overflowuid)。
要把容器中的uid和真实系统的uid给映射在一起,需要修改 /proc/<pid>/uid_map 和 /proc/<pid>/gid_map 这两个文件。这 ...
bash代码注入的安全漏洞
很多人或许对上半年发生的安全问题“心脏流血”(Heartbleed Bug)事件记忆颇深,这两天,又出现了另外一个“毁灭级”的漏洞——Bash软件安全漏洞。这个漏洞由法国GNU/Linux爱好者Stéphane Chazelas所发现。随后,美国电脑紧急应变中心(US-CERT)、红帽以及多家从事安全的公司于周三(北京时间9月24日)发出警告。 关于这个安全漏洞的细节可参看美国政府计算安全的这两个漏洞披露:CVE-2014-6271 和 CVE-2014-7169。
这个漏洞其实是非常经典的“注入式攻击”,也就是可以向 bash注入一段命令,从bash1.14 到4.3都存在这样的漏洞。我们先来看一下这个安全问题的症状。
目录
Shellshock (CVE-2014-6271)
AfterShock – CVE-2014-7169 (又叫Incomplete fix to Shellshock)
原理和技术细节
bash的环境变量
bash的函数
bash的bug
...
Alan Cox:大教堂、市集与市议会
(感谢网友 @我的上铺叫路遥 投稿)
在网上搜到的Cox大叔于1998年在开源社区写的一篇文章,当时很轰动,明眼人一看就知道是针对ESR那篇《大教堂与市集》,从中可见Alan在项目管理风格上乃至个人性格上都与ESR、Linus等人不同之处。顺便说一句,Alan现在出于“家庭原因”已经离开了Linux项目,他曾经评价Linus是a good developer but a terrible engineer,甚至在Google+上直接说Linus就是一a*sh**e。不管如何,两位曾经十余年里并肩战斗惺惺相惜的大牛就此分道扬镳还是惹人唏嘘。
言归正传,以下为slashdot收录的英文原文:Cathedrals, Bazaars and the Town Council。
以下是一些我对市集模式的想法,我认为这值得分享,这种模式会教你如何完全毁掉一个自由软件项目。我还举了一个我称之为“市议会”(Town Council)效应的实例(虽然那些市议员们可不这么认为,注:此处指Linux项目开发者)。
关于软件开发人员,你必须去了解一些情况。首先要了解的是真正优秀的程序员相 ...
sed 简明教程
awk于1977年出生,今年36岁本命年,sed比awk大2-3岁,awk就像林妹妹,sed就是宝玉哥哥了。所以 林妹妹跳了个Topless,他的哥哥sed坐不住了,也一定要出来抖一抖。
sed全名叫stream editor,流编辑器,用程序的方式来编辑文本,相当的hacker啊。sed基本上就是玩正则模式匹配,所以,玩sed的人,正则表达式一般都比较强。
同样,本篇文章不会说sed的全部东西,你可以参看sed的手册,我这里主要还是想和大家竞争一下那些从手机指缝间或马桶里流走的时间,用这些时间来学习一些东西。当然,接下来的还是要靠大家自己双手。
目录
用s命令替换
多个匹配
圆括号匹配
sed的命令
N命令
a命令和i命令
c命令
d命令
p命令
几个知识点
Pattern Space
Address
命令打包
Hold Space
用s命令替换
我使用下面的这段文本做演示:
$ ...
AWK 简明教程
有一些网友看了前两天的《Linux下应该知道的技巧》希望我能教教他们用awk和sed,所以,出现了这篇文章。我估计这些80后的年轻朋友可能对awk/sed这类上古神器有点陌生了,所以需要我这个老家伙来炒炒冷饭。况且,AWK是贝尔实验室1977年搞出来的文本出现神器,今年是蛇年,是AWK的本命年,而且年纪和我相仿,所以非常有必要为他写篇文章。
之所以叫AWK是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。要学AWK,就得提一提AWK的一本相当经典的书《The AWK Programming Language》,它在豆瓣上的评分是9.4分!在亚马逊上居然卖1022.30元。
我在这里的教程并不想面面俱到,本文和我之前的Go语言简介一样,全是示例,基本无废话。
我只想达到两个目的:
1)你可以在乘坐公交地铁上下班,或是在坐马桶拉大便时读完(保证是一泡大便的工夫)。
2)我只想让这篇博文像一个火辣的脱衣舞女挑起你的兴趣,然后还要你自己去下工夫去撸。
废话少说, ...
从面向对象的设计模式看软件设计
前些天发了一篇《如此理解面向对象编程》的文章,然后引起了大家的热议。然后我在微博上说了一句——“那23个经典的设计模式和OO半毛钱关系没有,只不过人家用OO来实现罢了……OO的设计模式思想和Unix的设计思想基本没什么差别”,结果引来了一点点争议。所以,我写下这篇文章把我的观点说明一下。我希望这样可以让大家更容易地理解什么是设计模式。我顺便帮OO和 Unix/Linux搞搞基。
目录
什么是模式
GoF的23个设计模式
后记
餐后甜点
再送一个果盘
什么是模式
在正式说明GoF的那23个经典的设计模式其实和OO关系不大并和Unix的设计思想很相似的这个观点之前,让我先来说说什么是模式?设计模式的英文是Design Pattern,模式是Pattern的汉译。所谓Pattern就是一种规则,或是一种模型,或是一种习惯。Pattern这个东西到处都是,并不只有技术圏子里才有。比如:
文章有文章的Pattern。如新闻有新闻的Pattern(第一段话简述了整个新闻),诗歌总是抒情的,论文总是死板的,讲稿总是高谈的,漫画总 ...
应该知道的Linux技巧
这篇文章来源于Quroa的一个问答《What are some time-saving tips that every Linux user should know?》—— Linux用户有哪些应该知道的提高效率的技巧。我觉得挺好的,总结得比较好,把其转过来,并加了一些自己的理解。 首先,我想告诉大家,在Unix/Linux下,最有效率技巧的不是操作图形界面,而是命令行操作,因为命令行意味着自动化。如果你看过《你可能不知道的Shell》以及《28个Unix/Linux的命令行神器》你就会知道Linux有多强大,这个强大完全来自于命令行,于是,就算你不知道怎么去做一个环保主义的程序员,至少他们可以让你少熬点夜,从而有利于你的身体健康和性生活。下面是一个有点长的列表,正如作者所说,你并不需要知道所有的这些东西,但是如果你还在很沉重地在使用Linux的话,这些东西都值得你看一看。 (注:如果你想知道下面涉及到的命令的更多的用法,你一定要man一点。对于一些命令,你可以需要先yum或apt-get来安装一下,如果有什么问题,别忘了Google。如果你要Baidu的话,我仅代表这个地球上所有的 ...
你可能不知道的Shell
Shell也叫做命令行界面,它是*nix操作系统下用户和计算机的交互界面。Shell这个词是指操作系统中提供访问内核服务的程序。
这篇文章向大家介绍Shell一些非广为人知、但却实用有趣的知识,权当品尝shell主食后的甜点吧。
科普
先科普几个你可能不知道的事实:
Shell几乎是和Unix操作系统一起诞生,第一个Unix Shell是肯·汤普逊(Ken Thompson)以Multics上的Shell为模范在1971年改写而成,并命名Thompson sh。即便是后来流行的bash(shell的一种变体),它的年龄实际上比当前流行的所有的Linux kernel都大,可谓在Linux系统上是先有Shell再有Kernel。
当前绝大部分*nix和MacOS操作系统里的默认的Shell都是bash,bash由Brian Fox在1987年创造,全称Bourne Again shell ( bash)。
你或许听说除了bash之外,还有Bourne shell ( sh),Korn shell ( ksh),C shell (包括 csh and tcsh),但是你知 ...
性能调优攻略
关于性能优化这是一个比较大的话题,在《由12306.cn谈谈网站性能技术》中我从业务和设计上说过一些可用的技术以及那些技术的优缺点,今天,想从一些技术细节上谈谈性能优化,主要是一些代码级别的技术和方法。本文的东西是我的一些经验和知识,并不一定全对,希望大家指正和补充。
在开始这篇文章之前,大家可以移步去看一下酷壳以前发表的《代码优化概要》,这篇文章基本上告诉你——要进行优化,先得找到性能瓶颈! 但是在讲如何定位系统性能瓶劲之前,请让我讲一下系统性能的定义和测试,因为没有这两件事,后面的定位和优化无从谈起。
目录
一、系统性能定义
二、系统性能测试
三、定位性能瓶颈
3.1)查看操作系统负载
3.2)使用Profiler测试
四、常见的系统瓶颈
一、系统性能定义
让我们先来说说如何什么是系统性能。这个定义非常关键,如果我们不清楚什么是系统性能,那么我们将无法定位之。我见过很多朋友会觉得这很容易,但是仔细一问,其实他们并没有一个比较系统的方法,所以,在这里我想告诉大家如何系统地来定位性能。 ...
用Unix的设计思想来应对多变的需求
之前,@风枫峰 在“这是谁的错?”中说过开发团队对需求来者不拒,而@weidagang 也在“需求变更和IoC”中说过用IoC来最大程度地解决需求变更。今天我也想从Unix设计思想的角度来说说什么是好的软件设计,什么样的设计可以把需求变更对开发的影响降低。(注意:这并不能解决用户或是PM的无理需求,面对无理需求,需要仔细分析需求,而用技术的手段无法搞定这个事,但是可以减轻需求变更带来的痛苦) 我曾经在《Unix传奇》的下篇中写过一些Unix的设计哲学和思想(这里重点推荐大家看一下《The Art of Unix Programming》,我推荐过多次了),以前也发过一篇《一些软件设计的原则》,不过,这些东西都太多了,记不住。其实,这么多年来,我的经验告诉我,无论是Unix设计,还是面向对象设计,还是别的什么如SOA,ECB,消息,事件,MVC,网络七层模型,数据库设计,等等,他们都在干三件事——解耦,解耦,还是解耦!所谓解耦,就是让软件的模块和模块间尽量少地依赖起来。
现实当中的例子
让我先举几个现实生活中的例子:
1、现实社会中,制造灯具的工厂完全不关心制造灯 ...
面向对象的Shell脚本
还记得以前那个用算素数的正则表达式吗?编程这个世界太有趣了,总是能看到一些即别出心裁的东西。你有没有想过在写Shell脚本的时候可以把你的变量和函数放到一个类中?不要以为这不可能,这不,我在网上又看到了一个把Shell脚本整成面向对象的东西。Shell本来是不支持的,需要自己做点东西,能搞出这个事事的人真的是hacker啊。
当然,这里并不是真正的面向对象,因为其只是封装罢了,还没有支持继承和多态。最变态的是他居然还支持typeid,靠!
下面让我们看看他是怎么来做的。下面的脚本可能会有点费解。本想解释一下,后来想想,还是大家自己专研一下吧,其实看懂也不难,给大家提几个点吧。
我们可以看到,下面的这个脚本定义了class, func, var, new 等函数,其实这些就是所谓的关键字。
class是一个函数,主要是记录类名。
func和var实际上是把成员函数名和成员变量记成有相同前缀的各种变量。
new方法主要是记录实例。大家重点看看new函数里的那个for循环,最核心的就在那里了。
脚本如下所示:
#!/bin/bash
# ------ ...