IT牛人博客聚合网站 发现IT技术最优秀的内容, 寻找IT技术的价值 http://www.udpwork.com/ zh_CN http://www.udpwork.com/about hourly 1 Wed, 12 Dec 2018 20:34:13 +0800 <![CDATA[异步 API 的设计]]> http://www.udpwork.com/item/17238.html http://www.udpwork.com/item/17238.html#reviews Wed, 12 Dec 2018 08:31:46 +0800 阮一峰 http://www.udpwork.com/item/17238.html 网站的前后端通信,往往会有异步请求,这时应该怎么设计 API?

我最近读到一篇文章,作者介绍了他的做法,设计得很精细,我觉得值得借鉴,可以当作异步 API 的标准设计。

一、同步 API

为了便于比较,先看看同步 API 的设计。下面是一个很简单的例子。

客户端发出一个请求,要求创建资源。

POST https://api.service.io/stars

name='Death Star' 

服务器回应 201。

HTTP/1.1 201 Created
Location: /stars/12345

201 Created告诉客户端,请求成功,资源已经创建。新的资源的网址请看Location字段。

二、异步请求

如果服务器不能立即返回结果,就形成了异步操作。

客户端的请求还是一样的。

POST https://api.service.io/stars

name='Death Star' 

服务器回应 202。

HTTP/1.1 202 Accepted
Location: /queue/12345

202 Accepted告诉客户端,请求已经接受,但还没有处理,可以去Location字段查询进展。

除了上面的头信息,服务器的回应如果有数据体,可以返回一些有效信息(比如任务完成的估计时间、当前状态等等)。

三、查询进展

过了一段时间,客户端就发出请求,查询异步处理的进展。

GET https://api.service.io/queue/12345 

服务器回应 200。

HTTP/1.1 200 Ok  

<response>
 <status>PENDING</status>
  <eta>2 mins.</eta>
  <link rel="cancel" method="delete" href="/queue/12345" /> 
</response>

200 Ok告诉客户端,请求成功,具体情况查看数据体。数据体里给出提示,异步操作已成功或还需要等待。

四、异步操作成功

有一种特殊情况,用户查询异步操作的进展的时候,可能会希望,如果异步操作已经完成,就直接跳转到新资源。

这时,服务器回应 303。

HTTP/1.1 303 See Other 
Location: /stars/97865

303 see other告诉客户端,重定向到不同的资源。Location字段就是跳转的目标,也就是新资源的网址。

五、删除查询链接

一旦异步操作完成,客户端可以要求服务器删除查询链接。

DELETE https://api.service.io/queue/12345 

服务器回应 204。

HTTP/1.1 204 No Content

204 No Content告诉客户端,删除成功。以后,客户端再访问这个查询链接,服务器回应404 Not Found。

如果客户端不删除查询链接,服务器完成异步任务后,也可以自动删除。客户端再请求这个链接,服务器回应410 Gone,表示该链接永久性不再可用。

(完)

文档信息

]]>
网站的前后端通信,往往会有异步请求,这时应该怎么设计 API?

我最近读到一篇文章,作者介绍了他的做法,设计得很精细,我觉得值得借鉴,可以当作异步 API 的标准设计。

一、同步 API

为了便于比较,先看看同步 API 的设计。下面是一个很简单的例子。

客户端发出一个请求,要求创建资源。

POST https://api.service.io/stars

name='Death Star' 

服务器回应 201。

HTTP/1.1 201 Created
Location: /stars/12345

201 Created告诉客户端,请求成功,资源已经创建。新的资源的网址请看Location字段。

二、异步请求

如果服务器不能立即返回结果,就形成了异步操作。

客户端的请求还是一样的。

POST https://api.service.io/stars

name='Death Star' 

服务器回应 202。

HTTP/1.1 202 Accepted
Location: /queue/12345

202 Accepted告诉客户端,请求已经接受,但还没有处理,可以去Location字段查询进展。

除了上面的头信息,服务器的回应如果有数据体,可以返回一些有效信息(比如任务完成的估计时间、当前状态等等)。

三、查询进展

过了一段时间,客户端就发出请求,查询异步处理的进展。

GET https://api.service.io/queue/12345 

服务器回应 200。

HTTP/1.1 200 Ok  

<response>
 <status>PENDING</status>
  <eta>2 mins.</eta>
  <link rel="cancel" method="delete" href="/queue/12345" /> 
</response>

200 Ok告诉客户端,请求成功,具体情况查看数据体。数据体里给出提示,异步操作已成功或还需要等待。

四、异步操作成功

有一种特殊情况,用户查询异步操作的进展的时候,可能会希望,如果异步操作已经完成,就直接跳转到新资源。

这时,服务器回应 303。

HTTP/1.1 303 See Other 
Location: /stars/97865

303 see other告诉客户端,重定向到不同的资源。Location字段就是跳转的目标,也就是新资源的网址。

五、删除查询链接

一旦异步操作完成,客户端可以要求服务器删除查询链接。

DELETE https://api.service.io/queue/12345 

服务器回应 204。

HTTP/1.1 204 No Content

204 No Content告诉客户端,删除成功。以后,客户端再访问这个查询链接,服务器回应404 Not Found。

如果客户端不删除查询链接,服务器完成异步任务后,也可以自动删除。客户端再请求这个链接,服务器回应410 Gone,表示该链接永久性不再可用。

(完)

文档信息

]]>
0
<![CDATA[百度:聚焦内容的设计语言 —— 为亿万用户打造阅读体验的“高级感”]]> http://www.udpwork.com/item/17237.html http://www.udpwork.com/item/17237.html#reviews Tue, 11 Dec 2018 11:17:09 +0800 UXC http://www.udpwork.com/item/17237.html  

1972年,Massimo Vignelli为纽约地下铁的114座车站设计了极简而实用的标识系统。他告诉人们:“统一规格,人们才不会迷路”。7年后,这套设计图被收藏至美国大都会博物馆。

对百度产品而言,百度拥有以搜索、Feed双引擎驱动,容纳了知道、百科、贴吧、地图等等众多产品线的“百度APP”,各产品线又分别拥有亿级用户的独立APP。从内容丰富度和体验流量的复杂性而言,不亚于一座大型城市的交通网络。

 

百度用户体验中心(UXC)为此重构了百度全线移动产品的基础交互框架,并设计了具有包容性和百度独特性的品牌风格、设计语言。在2017-2018年,由数百名设计师、产品经理、工程师合作,对包括“百度app、百度搜索、百度地图、百度贴吧、百度网盘、百度贴吧、百度百科、百度知道、百度文科”等全线产品进行整体改版。

这个以“聚焦于内容为理念的设计语言”,在内部项目代号“高级感”

 

高级感在交互及设计层面,最核心的2个理念是:理性布局、极简克制

 

1. 理性布局

“Good design is a language, not a style.”设计是一种沟通工具,让所有的人能够共同的理解,并从规则通往平等。

在结构设计理念上,“高级感”采用了栅格化设计。栅格化设计理念来源于城市规划师塞尔达(Cerda),他在进行巴塞罗那城市规划中,在中世纪的时代预测到了未来城市所需马路的形态。以适合快速交通工具运行的直线道路为基础,将巴塞罗那规划成为严谨和理性的模块空间。并在精心设计的模块尺度中容纳了创新和发展的空间,最终使巴塞罗那成为最富盛名的艺术之城。

 

通过复杂计算,将页面设计为12n的“栅格”结构。12n的结构在手机屏幕上最优化的容纳了“舒适边距”“三图”“单列文字”等排版元素。给用户舒适清晰的阅读体验,并给予不同来源信息平等展示的机会,让用户拥有自主阅读的权利。

 

2. 极简克制

“极简克制”是解决信息爆炸时代体验最重要的方式之一。

现在,移动互联网几乎填补了人们所有的碎片时间。信息的丰富程度是过去的上百倍倍,触达的频次是过去的几十倍。在这些信息汹涌而来中,人们混淆了“高频”和“高效”的区别。阅读数量越来越多,阅读体验却在下降。

 

“高级感”通过“设计极简”“设计克制”改善用户阅读体验。

 

元素极简

“所有的设计,都带有干扰和视觉负累”

 

“高级感”去掉界面中所有装饰性元素,更突出内容本身。强调内容本身排版的舒适性和审美。使用户在阅读时轻松而舒适。

 

icon 极简

高级感在icon的处理上非常简练,以尽可能少和轻的元素及线条,表达清楚其含义。

 

用色克制

与元素极简一样,高级感在用色方面,不追求色彩冲击和表象审美,而是非常克制的使用。让用户聚焦到内容本身,不喧宾夺主,避免繁杂的色彩吸引用户的视觉注意力。

 

直到百度网盘9.0,高级感才开始使用一些清新的颜色,对界面视觉权重进行配重。

 

值得一提的是搜索标题,在2017年之前。全世界的搜索引擎标题都是蓝色。这是继承自互联网起源时代的PC链接设计。但在移动互联网时代,所有的操作和点击都是模块化响应。蓝色链接已经失去存在的意义,但是用户对长达20年的视觉习惯有很强的惯性。高级感设计团队经过3个月*9组的小流量实验后,确认了去除蓝色字体对用户体验的正面影响,并在2017年8月上线。时至今日,我们发现国内外很多搜索引擎都已在逐步改为黑色字体。

 

一致性、理性布局、极简克制。

 

这些“栅格化、信息模块、克制的色彩、数学计算的行间距、强调节奏的排版”是否就是高级感的全部?一个设计语言的升级,需要牵动数百人、8个月、数十款产品的全线改版。高级感的未来会如何发展?

 

对此,百度设计体验主席关岱松曾说:“真正可长期发展的设计,从来不是模仿别人,而是找到你自己。高级感的设计是表象,灵魂是百度和用户”。

 

 

 

 

]]>
 

1972年,Massimo Vignelli为纽约地下铁的114座车站设计了极简而实用的标识系统。他告诉人们:“统一规格,人们才不会迷路”。7年后,这套设计图被收藏至美国大都会博物馆。

对百度产品而言,百度拥有以搜索、Feed双引擎驱动,容纳了知道、百科、贴吧、地图等等众多产品线的“百度APP”,各产品线又分别拥有亿级用户的独立APP。从内容丰富度和体验流量的复杂性而言,不亚于一座大型城市的交通网络。

 

百度用户体验中心(UXC)为此重构了百度全线移动产品的基础交互框架,并设计了具有包容性和百度独特性的品牌风格、设计语言。在2017-2018年,由数百名设计师、产品经理、工程师合作,对包括“百度app、百度搜索、百度地图、百度贴吧、百度网盘、百度贴吧、百度百科、百度知道、百度文科”等全线产品进行整体改版。

这个以“聚焦于内容为理念的设计语言”,在内部项目代号“高级感”

 

高级感在交互及设计层面,最核心的2个理念是:理性布局、极简克制

 

1. 理性布局

“Good design is a language, not a style.”设计是一种沟通工具,让所有的人能够共同的理解,并从规则通往平等。

在结构设计理念上,“高级感”采用了栅格化设计。栅格化设计理念来源于城市规划师塞尔达(Cerda),他在进行巴塞罗那城市规划中,在中世纪的时代预测到了未来城市所需马路的形态。以适合快速交通工具运行的直线道路为基础,将巴塞罗那规划成为严谨和理性的模块空间。并在精心设计的模块尺度中容纳了创新和发展的空间,最终使巴塞罗那成为最富盛名的艺术之城。

 

通过复杂计算,将页面设计为12n的“栅格”结构。12n的结构在手机屏幕上最优化的容纳了“舒适边距”“三图”“单列文字”等排版元素。给用户舒适清晰的阅读体验,并给予不同来源信息平等展示的机会,让用户拥有自主阅读的权利。

 

2. 极简克制

“极简克制”是解决信息爆炸时代体验最重要的方式之一。

现在,移动互联网几乎填补了人们所有的碎片时间。信息的丰富程度是过去的上百倍倍,触达的频次是过去的几十倍。在这些信息汹涌而来中,人们混淆了“高频”和“高效”的区别。阅读数量越来越多,阅读体验却在下降。

 

“高级感”通过“设计极简”“设计克制”改善用户阅读体验。

 

元素极简

“所有的设计,都带有干扰和视觉负累”

 

“高级感”去掉界面中所有装饰性元素,更突出内容本身。强调内容本身排版的舒适性和审美。使用户在阅读时轻松而舒适。

 

icon 极简

高级感在icon的处理上非常简练,以尽可能少和轻的元素及线条,表达清楚其含义。

 

用色克制

与元素极简一样,高级感在用色方面,不追求色彩冲击和表象审美,而是非常克制的使用。让用户聚焦到内容本身,不喧宾夺主,避免繁杂的色彩吸引用户的视觉注意力。

 

直到百度网盘9.0,高级感才开始使用一些清新的颜色,对界面视觉权重进行配重。

 

值得一提的是搜索标题,在2017年之前。全世界的搜索引擎标题都是蓝色。这是继承自互联网起源时代的PC链接设计。但在移动互联网时代,所有的操作和点击都是模块化响应。蓝色链接已经失去存在的意义,但是用户对长达20年的视觉习惯有很强的惯性。高级感设计团队经过3个月*9组的小流量实验后,确认了去除蓝色字体对用户体验的正面影响,并在2017年8月上线。时至今日,我们发现国内外很多搜索引擎都已在逐步改为黑色字体。

 

一致性、理性布局、极简克制。

 

这些“栅格化、信息模块、克制的色彩、数学计算的行间距、强调节奏的排版”是否就是高级感的全部?一个设计语言的升级,需要牵动数百人、8个月、数十款产品的全线改版。高级感的未来会如何发展?

 

对此,百度设计体验主席关岱松曾说:“真正可长期发展的设计,从来不是模仿别人,而是找到你自己。高级感的设计是表象,灵魂是百度和用户”。

 

 

 

 

]]>
0
<![CDATA[腾讯的历史]]> http://www.udpwork.com/item/17236.html http://www.udpwork.com/item/17236.html#reviews Sun, 09 Dec 2018 22:31:24 +0800 阮一峰 http://www.udpwork.com/item/17236.html 今天,我读到一篇英语文章,向美国读者介绍腾讯公司的历史。

我觉得,这篇文章整理了好多资料,写得非常清楚。腾讯是怎么发展起来的,只看这篇文章就够了。下面就是它的译文,供大家参考。

1、

1971年,马化腾生于海南。13岁,随家人移居到深圳。

1989年,父母希望马化腾在本地读大学,所以他选择了深圳大学,尽管他的高考分数可以上清华大学。马化腾早年对天文学着迷,打算选择这个专业,但是深圳大学没有天文系,所以马化腾改学计算机工程。

大学里,他开发了一个股票分析软件,后来以5万元人民币的价格卖掉了。这相当于那时大学毕业生3年的工资。

1993年,大学毕业后,马化腾加入深圳润讯公司担任软件工程师。他的大学朋友张志东和许晨晔,继续攻读研究生课程,后来他们成为腾讯的首席技术官和首席信息官。

2、

1994年,马化腾对 FidoNet 产生了浓厚的兴趣。FidoNet 是一个全球性的计算机网络,用于不同的公告板系统(BBS)之间的通信,把它们连在一起。1991年,罗依成立了中国第一家名为 CFido 的 FidoNet。

马化腾决定建立自己的 FidoNet。他用出售股票软件获得的所有资金,购买了4条电话线和8台电脑。值得一提的是,1995年雷军在北京也成立了自己的 FidoNet。

1995年,马化腾遇到了丁磊。丁磊当时积极参与中国的 FidoNet 社区,而马化腾是 FidoNet 深圳地区的管理员。

丁磊也是一名程序员,大学时就想创办一家公司。当时他加入了广州的一家美国软件公司 Sybase,一年后辞职离开,进入一家 ISP(互联网服务提供商)公司。他注意到了电子邮件的革命性潜力,与别人合作开发了第一个免费的中文电子邮件服务"网易"。网易通过向中国电信销售服务赚钱,这使丁磊成为第一个盈利的中国互联网企业家。

丁磊的故事激励了马化腾。1998年春天,马化腾约了张志东在咖啡店见面,跟他说:"让我们创办一家公司吧。"马化腾的创业想法是,将互联网与寻呼机结合起来,使用互联网向寻呼机发送电子邮件、新闻等。

张志东被马化腾的激情感染,很快就辞去工作投入创业(当时马化腾甚至还没有从润讯离职)。他们又找来了朋友许晨晔和陈一丹,组成了一个由四名工程师组成的团队。很快,他们意识到团队里没人有销售经验,就又去找了当时在深圳市电信部门工作的曾李青。这就是腾讯的5个创始人。

3、

1996年,三名以色列人开发了 ICQ(I seek U,我寻找你)。这是一种互联网通讯工具。可以在线聊天和共享文件。1998年底,ICQ 拥有约1000万用户,被美国在线 AOL 收购。

(上图是 ICQ 的界面)

腾讯成立后,受到 ICQ 的启发,想做一个中文版的 ICQ,于是开发了 OICQ,其中"O"代表"开放"。于是,腾讯就有两个产品线:寻呼软件和 OICQ。

很快,事情就清楚了。ICQ 代表的即时通讯市场有巨大空间,而寻呼软件没有太大市场。而且,AOL 并购 ICQ 以后,对中国市场并没有兴趣。因此腾讯决定专注开发 OICQ,使其适合中国大陆的用户。他们为 OICQ 添加了脱机消息(ICQ 不支持)和陌生人作为联系人等功能。

推出9个月以后,OICQ 达到了100万用户。随着用户增长,就需要添置越来越多的服务器。但是,腾讯只剩下10,000美元现金,没钱购买那么多服务器,工程师不得不花了很多精力,设法减轻服务器的负担。而且腾讯没有收入模式,OICQ 继续增长变得越来越困难。

1999年,腾讯收到了美国 AOL 律师信:起诉 OICQ 侵犯 ICQ 的知识产权,要求腾讯停止使用域名"OICQ.com"和"OICQ.net"。马化腾知道他们没钱去法院打官司,此时只剩下两种选择:融资并削减成本,或出售腾讯。

4、

没有人愿意收购腾讯,因为马化腾回答不了腾讯如何赚钱。有一次,为了计算腾讯的估值,收购者甚至统计了办公室电脑、办公桌和椅子的数量。

马化腾希望以300万元出售腾讯,但最高报价是60万元。创始团队只好想办法借钱,一个朋友借钱的时候,对马化腾说:"如果你真的破产了,不用担心怎么还钱,千万不要把你的股票给我。"

这时,销售专家曾李青建议去找风险投资,"我们现在找的投资者都太老派了,我们需要找到一些更疯狂的人。"这是马化腾第一次了解到 VC 的概念。

当时,中国最著名的风险投资公司是 IDG Capital。曾李青安排了与 IDG 的会面,并准备了一份长达20页的商业计划书。当马化腾和曾李青与 IDG 的王树会面时,他们说道:"如果 IDG 现在没有投资我们,腾讯可能会死。但即使你给我们钱,未来仍然是不确定的。"王树问他们对腾讯未来的看法,马化腾回答说:"我不知道。"多年后,王树回忆道:"那时我觉得他是一个非常脚踏实地的领导者,一个可以信赖的人。"

IDG 内部讨论腾讯交易的时候,高层问:"他们如何赚钱?"马化腾只能回答,他们的产品是人们喜欢使用的,但现在还不知道从哪里赚钱。

最终,IDG 同意了投资腾讯。有两个主要原因:首先,OICQ 确实是一种受欢迎的产品,具有吸引力;其次,他们看到了 ICQ 买给 AOL 从而成功退出,因此认为 OICQ 可能也卖得出去。

腾讯的估值为550万美元,创始人团队希望保留公司的多数股权,因此以220万美元的价格向外部投资者出售高达40%的股份。IDG 不愿意独自承担风险,又拉来了另一个投资者----香港的电讯盈科,管理者是李嘉诚的儿子李泽楷。IDG 和电讯盈科分别拿到腾讯的20%的股权。

当 IDG 和电讯盈科投资的220万美元最终到帐时,腾讯已经没有钱了。如果资金晚一步进来,腾讯肯定会死。不仅是因为缺乏资金,还因为那时全球网络股已经开始崩溃了。2000年4月,纳斯达克股价暴跌,雅虎的市值从930亿美元降至90亿美元,亚马逊从220亿美元降至40亿美元。如果马化腾和曾李青没有及时找到并说服 IDG,或者 IDG 的王树对腾讯没兴趣,腾讯今天可能就不存在了。

5、

法院最终判决,腾讯将域名"OICQ.com"和"OICQ.net"归还给 AOL。这意味 OICQ 必须改名。

一位腾讯员工在公交车上听到,一些 OICQ 用户在谈论这个软件时,将它称为 QQ,于是这个名字成了产品的新名称。

腾讯拿到的风险投资,主要用于购买服务器和支付工资,但是依然没有收入来源。很快,不得不又去寻找买家,考虑把自己卖掉。

腾讯询问了搜狐、雅虎中国和其他几家公司,所有人都拒绝。但是,在这段绝望的时期,用户数量继续大幅增长。具有讽刺意味的是,QQ 的用户数量已经达到1亿,而中国没有一个人想收购腾讯。

有一天,一个声称来自 MIH 中国办事处的人,走进腾讯的深圳办公室。这是南非媒体巨头 Naspers 拥有的投资公司。它的中国代表是一个老外, 中文名字叫做网大伟。他每访问的每一个新城市,都要去网吧看一下。他注意到,每个网吧的电脑桌面上都有一个名为 QQ 的程序,因此他认为这肯定是一个强大的互联网公司。每个人的名片都包含他们的 QQ 号码,这进一步激起了他的好奇心。

马化腾向网大为展示了用户增长图,并告诉他 QQ 每天新增50万用户。这导致了 MIH 和腾讯之间的投资谈判。MIH 认为腾讯估值为6000万美元,并希望成为该公司的最大股东。腾讯团队强烈反对放弃公司的多数控制权,但对于一年之内,公司的估值增加了11倍,而感到非常高兴。

IDG 也对 MIH 的估值感到兴奋,这标志着他们投资得到了良好回报。IDG 卖出了其在腾讯20%股权中的12.8%,保留了7.2%,电讯盈科则是放弃了所拥有的腾讯所有20%的股份。MIH 一共拿到了腾讯32.8%的股份,成为继创始人之后的第二大股东。MIH 的这笔交易后来是风险投资史上获利最大的交易之一。

6、

腾讯想了各种办法,多次尝试从 QQ 获利,直到2002年才找到了途径。

产品经理许良了解到一个韩国网站 sayclub.com,允许用户拥有个性化发型、表情、服装等,但必须付费。该网站拥有150万用户,平均每人每月支付5元人民币。许良迅速推动腾讯也提供类似的功能。

在说服高管后,QQ 及时推出了 QQ 秀。用户可以定制自己的头像,方法是先付钱购买"Q币",然后用其购买 QQ 市场中的头像。所有头像的价格在0.5元至1元人民币之间。付费的 QQ 用户可以在聊天时显示他们的新头像。QQ 秀推出半年后,该服务有大约500万付费用户,每人每月贡献约5元人民币。

为了将 QQ 秀提升到一个新水平,腾讯又推出了名为"红钻会员"的 VIP 会员。每月支付10元人民币,付费用户可以独家获得虚拟礼品,并在头像旁边有一个红色菱形图标,享受 QQ 市场的折扣价。这些货币化努力使腾讯每月可以收入数千万美元。

7、

2001年,90%的计算机使用 Windows 系统。微软公司当时宣布,在中国进一步扩展即时通信工具 MSN 的战略,这对腾讯构成巨大威胁。

2004年,新版 QQ 推出时,它没有得到企业的支持。对企业来说,QQ 看起来像一个普通的聊天应用程序,而不是一个严肃的沟通工具,MSN 才是办公首选。为了反击,腾讯希望进入电子邮件市场。

当时,微软的 Hotmail 是电子邮件巨头,因此腾讯决定收购其在中国的最大竞争对手之一 Foxmail。Foxmail 由张小龙在1996年推出,是一个免费的电子邮件客户端,推出后一年内就有400万用户。

2005年,Foxmail 被腾讯收购,升级成为了 QQ 邮箱。

8、

2010年,美国出现了一款名为 Kik messenger 的应用程序,允许用户通过无线网络与通讯录中的人交换免费消息。在15天内,Kik 就拥有了100万用户。这引起了张小龙的注意,他要求马化腾让他开发一个类似的产品。

(上图为 Kik 的界面)

雷军也注意到了 kik,他的公司小米反应非常迅速。经过短短一个月的开发,小米推出了米聊。不久之后,张小龙团队推出了微信。接下来的几个月里,这两个应用程序相互竞争,米聊支持语音留言,微信也效仿。添加此功能后,微信的用户数量从每天新增 10-20k,增加到 50-60k。微信继续推出新功能,如"摇一摇"(看看谁在附近),"漂流瓶"等等,而米聊没有跟上用户的增长,曾经一天内多次中断服务。

2012年,微信用户达到1亿。它是社交媒体应用程序历史上,用户增长速度最快的软件,只用了433天就达到了这个里程碑。相比之下,QQ 用了10年,Facebook 耗时5.5年,推特4年。

(完)

文档信息

]]>
今天,我读到一篇英语文章,向美国读者介绍腾讯公司的历史。

我觉得,这篇文章整理了好多资料,写得非常清楚。腾讯是怎么发展起来的,只看这篇文章就够了。下面就是它的译文,供大家参考。

1、

1971年,马化腾生于海南。13岁,随家人移居到深圳。

1989年,父母希望马化腾在本地读大学,所以他选择了深圳大学,尽管他的高考分数可以上清华大学。马化腾早年对天文学着迷,打算选择这个专业,但是深圳大学没有天文系,所以马化腾改学计算机工程。

大学里,他开发了一个股票分析软件,后来以5万元人民币的价格卖掉了。这相当于那时大学毕业生3年的工资。

1993年,大学毕业后,马化腾加入深圳润讯公司担任软件工程师。他的大学朋友张志东和许晨晔,继续攻读研究生课程,后来他们成为腾讯的首席技术官和首席信息官。

2、

1994年,马化腾对 FidoNet 产生了浓厚的兴趣。FidoNet 是一个全球性的计算机网络,用于不同的公告板系统(BBS)之间的通信,把它们连在一起。1991年,罗依成立了中国第一家名为 CFido 的 FidoNet。

马化腾决定建立自己的 FidoNet。他用出售股票软件获得的所有资金,购买了4条电话线和8台电脑。值得一提的是,1995年雷军在北京也成立了自己的 FidoNet。

1995年,马化腾遇到了丁磊。丁磊当时积极参与中国的 FidoNet 社区,而马化腾是 FidoNet 深圳地区的管理员。

丁磊也是一名程序员,大学时就想创办一家公司。当时他加入了广州的一家美国软件公司 Sybase,一年后辞职离开,进入一家 ISP(互联网服务提供商)公司。他注意到了电子邮件的革命性潜力,与别人合作开发了第一个免费的中文电子邮件服务"网易"。网易通过向中国电信销售服务赚钱,这使丁磊成为第一个盈利的中国互联网企业家。

丁磊的故事激励了马化腾。1998年春天,马化腾约了张志东在咖啡店见面,跟他说:"让我们创办一家公司吧。"马化腾的创业想法是,将互联网与寻呼机结合起来,使用互联网向寻呼机发送电子邮件、新闻等。

张志东被马化腾的激情感染,很快就辞去工作投入创业(当时马化腾甚至还没有从润讯离职)。他们又找来了朋友许晨晔和陈一丹,组成了一个由四名工程师组成的团队。很快,他们意识到团队里没人有销售经验,就又去找了当时在深圳市电信部门工作的曾李青。这就是腾讯的5个创始人。

3、

1996年,三名以色列人开发了 ICQ(I seek U,我寻找你)。这是一种互联网通讯工具。可以在线聊天和共享文件。1998年底,ICQ 拥有约1000万用户,被美国在线 AOL 收购。

(上图是 ICQ 的界面)

腾讯成立后,受到 ICQ 的启发,想做一个中文版的 ICQ,于是开发了 OICQ,其中"O"代表"开放"。于是,腾讯就有两个产品线:寻呼软件和 OICQ。

很快,事情就清楚了。ICQ 代表的即时通讯市场有巨大空间,而寻呼软件没有太大市场。而且,AOL 并购 ICQ 以后,对中国市场并没有兴趣。因此腾讯决定专注开发 OICQ,使其适合中国大陆的用户。他们为 OICQ 添加了脱机消息(ICQ 不支持)和陌生人作为联系人等功能。

推出9个月以后,OICQ 达到了100万用户。随着用户增长,就需要添置越来越多的服务器。但是,腾讯只剩下10,000美元现金,没钱购买那么多服务器,工程师不得不花了很多精力,设法减轻服务器的负担。而且腾讯没有收入模式,OICQ 继续增长变得越来越困难。

1999年,腾讯收到了美国 AOL 律师信:起诉 OICQ 侵犯 ICQ 的知识产权,要求腾讯停止使用域名"OICQ.com"和"OICQ.net"。马化腾知道他们没钱去法院打官司,此时只剩下两种选择:融资并削减成本,或出售腾讯。

4、

没有人愿意收购腾讯,因为马化腾回答不了腾讯如何赚钱。有一次,为了计算腾讯的估值,收购者甚至统计了办公室电脑、办公桌和椅子的数量。

马化腾希望以300万元出售腾讯,但最高报价是60万元。创始团队只好想办法借钱,一个朋友借钱的时候,对马化腾说:"如果你真的破产了,不用担心怎么还钱,千万不要把你的股票给我。"

这时,销售专家曾李青建议去找风险投资,"我们现在找的投资者都太老派了,我们需要找到一些更疯狂的人。"这是马化腾第一次了解到 VC 的概念。

当时,中国最著名的风险投资公司是 IDG Capital。曾李青安排了与 IDG 的会面,并准备了一份长达20页的商业计划书。当马化腾和曾李青与 IDG 的王树会面时,他们说道:"如果 IDG 现在没有投资我们,腾讯可能会死。但即使你给我们钱,未来仍然是不确定的。"王树问他们对腾讯未来的看法,马化腾回答说:"我不知道。"多年后,王树回忆道:"那时我觉得他是一个非常脚踏实地的领导者,一个可以信赖的人。"

IDG 内部讨论腾讯交易的时候,高层问:"他们如何赚钱?"马化腾只能回答,他们的产品是人们喜欢使用的,但现在还不知道从哪里赚钱。

最终,IDG 同意了投资腾讯。有两个主要原因:首先,OICQ 确实是一种受欢迎的产品,具有吸引力;其次,他们看到了 ICQ 买给 AOL 从而成功退出,因此认为 OICQ 可能也卖得出去。

腾讯的估值为550万美元,创始人团队希望保留公司的多数股权,因此以220万美元的价格向外部投资者出售高达40%的股份。IDG 不愿意独自承担风险,又拉来了另一个投资者----香港的电讯盈科,管理者是李嘉诚的儿子李泽楷。IDG 和电讯盈科分别拿到腾讯的20%的股权。

当 IDG 和电讯盈科投资的220万美元最终到帐时,腾讯已经没有钱了。如果资金晚一步进来,腾讯肯定会死。不仅是因为缺乏资金,还因为那时全球网络股已经开始崩溃了。2000年4月,纳斯达克股价暴跌,雅虎的市值从930亿美元降至90亿美元,亚马逊从220亿美元降至40亿美元。如果马化腾和曾李青没有及时找到并说服 IDG,或者 IDG 的王树对腾讯没兴趣,腾讯今天可能就不存在了。

5、

法院最终判决,腾讯将域名"OICQ.com"和"OICQ.net"归还给 AOL。这意味 OICQ 必须改名。

一位腾讯员工在公交车上听到,一些 OICQ 用户在谈论这个软件时,将它称为 QQ,于是这个名字成了产品的新名称。

腾讯拿到的风险投资,主要用于购买服务器和支付工资,但是依然没有收入来源。很快,不得不又去寻找买家,考虑把自己卖掉。

腾讯询问了搜狐、雅虎中国和其他几家公司,所有人都拒绝。但是,在这段绝望的时期,用户数量继续大幅增长。具有讽刺意味的是,QQ 的用户数量已经达到1亿,而中国没有一个人想收购腾讯。

有一天,一个声称来自 MIH 中国办事处的人,走进腾讯的深圳办公室。这是南非媒体巨头 Naspers 拥有的投资公司。它的中国代表是一个老外, 中文名字叫做网大伟。他每访问的每一个新城市,都要去网吧看一下。他注意到,每个网吧的电脑桌面上都有一个名为 QQ 的程序,因此他认为这肯定是一个强大的互联网公司。每个人的名片都包含他们的 QQ 号码,这进一步激起了他的好奇心。

马化腾向网大为展示了用户增长图,并告诉他 QQ 每天新增50万用户。这导致了 MIH 和腾讯之间的投资谈判。MIH 认为腾讯估值为6000万美元,并希望成为该公司的最大股东。腾讯团队强烈反对放弃公司的多数控制权,但对于一年之内,公司的估值增加了11倍,而感到非常高兴。

IDG 也对 MIH 的估值感到兴奋,这标志着他们投资得到了良好回报。IDG 卖出了其在腾讯20%股权中的12.8%,保留了7.2%,电讯盈科则是放弃了所拥有的腾讯所有20%的股份。MIH 一共拿到了腾讯32.8%的股份,成为继创始人之后的第二大股东。MIH 的这笔交易后来是风险投资史上获利最大的交易之一。

6、

腾讯想了各种办法,多次尝试从 QQ 获利,直到2002年才找到了途径。

产品经理许良了解到一个韩国网站 sayclub.com,允许用户拥有个性化发型、表情、服装等,但必须付费。该网站拥有150万用户,平均每人每月支付5元人民币。许良迅速推动腾讯也提供类似的功能。

在说服高管后,QQ 及时推出了 QQ 秀。用户可以定制自己的头像,方法是先付钱购买"Q币",然后用其购买 QQ 市场中的头像。所有头像的价格在0.5元至1元人民币之间。付费的 QQ 用户可以在聊天时显示他们的新头像。QQ 秀推出半年后,该服务有大约500万付费用户,每人每月贡献约5元人民币。

为了将 QQ 秀提升到一个新水平,腾讯又推出了名为"红钻会员"的 VIP 会员。每月支付10元人民币,付费用户可以独家获得虚拟礼品,并在头像旁边有一个红色菱形图标,享受 QQ 市场的折扣价。这些货币化努力使腾讯每月可以收入数千万美元。

7、

2001年,90%的计算机使用 Windows 系统。微软公司当时宣布,在中国进一步扩展即时通信工具 MSN 的战略,这对腾讯构成巨大威胁。

2004年,新版 QQ 推出时,它没有得到企业的支持。对企业来说,QQ 看起来像一个普通的聊天应用程序,而不是一个严肃的沟通工具,MSN 才是办公首选。为了反击,腾讯希望进入电子邮件市场。

当时,微软的 Hotmail 是电子邮件巨头,因此腾讯决定收购其在中国的最大竞争对手之一 Foxmail。Foxmail 由张小龙在1996年推出,是一个免费的电子邮件客户端,推出后一年内就有400万用户。

2005年,Foxmail 被腾讯收购,升级成为了 QQ 邮箱。

8、

2010年,美国出现了一款名为 Kik messenger 的应用程序,允许用户通过无线网络与通讯录中的人交换免费消息。在15天内,Kik 就拥有了100万用户。这引起了张小龙的注意,他要求马化腾让他开发一个类似的产品。

(上图为 Kik 的界面)

雷军也注意到了 kik,他的公司小米反应非常迅速。经过短短一个月的开发,小米推出了米聊。不久之后,张小龙团队推出了微信。接下来的几个月里,这两个应用程序相互竞争,米聊支持语音留言,微信也效仿。添加此功能后,微信的用户数量从每天新增 10-20k,增加到 50-60k。微信继续推出新功能,如"摇一摇"(看看谁在附近),"漂流瓶"等等,而米聊没有跟上用户的增长,曾经一天内多次中断服务。

2012年,微信用户达到1亿。它是社交媒体应用程序历史上,用户增长速度最快的软件,只用了433天就达到了这个里程碑。相比之下,QQ 用了10年,Facebook 耗时5.5年,推特4年。

(完)

文档信息

]]>
0
<![CDATA[记一次Kubernetes/Docker网络排障]]> http://www.udpwork.com/item/17235.html http://www.udpwork.com/item/17235.html#reviews Sat, 08 Dec 2018 11:57:35 +0800 陈皓 http://www.udpwork.com/item/17235.html 昨天周五晚上,临下班的时候,用户给我们报了一个比较怪异的Kubernetes集群下的网络不能正常访问的问题,让我们帮助查看一下,我们从下午5点半左右一直跟进到晚上十点左右,在远程不能访问用户机器只能远程遥控用户的情况找到了的问题。这个问题比较有意思,我个人觉得其中的调查用到的的命令以及排障的一些方法可以分享一下,所以写下了这篇文章。

问题的症状

用户直接在微信里说,他们发现在Kuberbnetes下的某个pod被重启了几百次甚至上千次,于是开启调查这个pod,发现上面的服务时而能够访问,时而不能访问,也就是有一定概率不能访问,不知道是什么原因。而且并不是所有的pod出问题,而只是特定的一两个pod出了网络访问的问题。用户说这个pod运行着Java程序,为了排除是Java的问题,用户用docker exec -it 命令直接到容器内启了一个 Python的 SimpleHttpServer来测试发现也是一样的问题。

我们大概知道用户的集群是这样的版本,Kuberbnetes 是1.7,网络用的是flannel的gw模式,Docker版本未知,操作系统CentOS 7.4,直接在物理机上跑docker,物理的配置很高,512GB内存,若干CPU核,上面运行着几百个Docker容器。

问题的排查

问题初查

首先,我们排除了flannel的问题,因为整个集群的网络通信都正常,只有特定的某一两个pod有问题。而用telnet ip port 的命令手工测试网络连接时有很大的概率出现connection refused 错误,大约 1/4的概率,而3/4的情况下是可以正常连接的。

当时,我们让用户抓个包看看,然后,用户抓到了有问题的TCP连接是收到了SYN 后,立即返回了RST, ACK

我问一下用户这两个IP所在的位置,知道了,10.233.14.129 是docker0,10.233.14.145 是容器内的IP。所以,这基本上可以排除了所有和kubernets或是flannel的问题,这就是本地的Docker上的网络的问题。

对于这样被直接 Reset 的情况,在telnet上会显示connection refused 的错误信息,对于我个人的经验,这种SYN完直接返回RST, ACK的情况只会有三种情况:

  1.  TCP链接不能建立,不能建立连接的原因基本上是标识一条TCP链接的那五元组不能完成,绝大多数情况都是服务端没有相关的端口号。
  2. TCP链接建错误,有可能是因为修改了一些TCP参数,尤其是那些默认是关闭的参数,因为这些参数会导致TCP协议不完整。
  3. 有防火墙iptables的设置,其中有REJECT 规则。

因为当时还在开车,在等红灯的时候,我感觉到有点像 NAT 的网络中服务端开启了tcp_tw_recycle 和tcp_tw_reuse 的症况(详细参看《TCP的那些事(上)》),所以,让用户查看了一上TCP参数,发现用户一个TCP的参数都没有改,全是默认的,于是我们排除了TCP参数的问题。

然后,我也不觉得容器内还会设置上iptables,而且如果有那就是100%的问题,不会时好时坏。所以,我怀疑容器内的端口号没有侦听上,但是马上又好了,这可能会是应用的问题。于是我让用户那边看一下,应用的日志,并用kublet describe看一下运行的情况,并把宿主机的 iptables 看一下。

然而,我们发现并没有任何的问题。这时,我们失去了所有的调查线索,感觉不能继续下去了……

重新梳理

这个时候,回到家,大家吃完饭,和用户通了一个电话,把所有的细节再重新梳理了一遍,这个时候,用户提供了一个比较关键的信息—— “抓包这个事,在docker0 上可以抓到,然而到了容器内抓不到容器返回RST, ACK ” !然而,根据我的知识,我知道在docker0和容器内的veth网卡上,中间再也没有什么网络设备了(参看《Docker基础技术:LINUX NAMESPACE(下)》)!

于是这个事把我们逼到了最后一种情况 —— IP地址冲突了!

Linux下看IP地址冲突还不是一件比较简单事的,而在用户的生产环境下没有办法安装一些其它的命令,所以只能用已有的命令,这个时候,我们发现用户的机器上有arping 于是我们用这个命令来检测有没有冲突的IP地址。使用了下面的命令:

$ arping -D -I docker0 -c 2 10.233.14.145
$ echo $?

根据文档,-D 参数是检测IP地址冲突模式,如果这个命令的退状态是0 那么就有冲突。结果返回了1 。而且,我们用arping IP的时候,没有发现不同的mac地址。 这个时候,似乎问题的线索又断了

因为客户那边还在处理一些别的事情,所以,我们在时断时续的情况下工作,而还一些工作都需要用户完成,所以,进展有点缓慢,但是也给我们一些时间思考问题。

柳暗花明

现在我们知道,IP冲突的可能性是非常大的,但是我们找不出来是和谁的IP冲突了。而且,我们知道只要把这台机器重启一下,问题一定就解决掉了,但是我们觉得这并不是解决问题的方式,因为重启机器可以暂时的解决掉到这个问题,而如果我们不知道这个问题怎么发生的,那么未来这个问题还会再来。而重启线上机器这个成本太高了。

于是,我们的好奇心驱使我们继续调查。我让用户kubectl delete 其中两个有问题的pod,因为本来就服务不断重启,所以,删掉也没有什么问题。删掉这两个pod后(一个是IP为10.233.14.145 另一个是10.233.14.137),我们发现,kubernetes在其它机器上重新启动了这两个服务的新的实例。然而,在问题机器上,这两个IP地址居然还可以ping得通

好了,IP地址冲突的问题可以确认了。因为10.233.14.xxx 这个网段是 docker 的,所以,这个IP地址一定是在这台机器上。所以,我们想看看所有的 network namespace 下的 veth 网卡上的IP。

在这个事上,我们费了点时间,因为对相关的命令也 很熟悉,所以花了点时间Google,以及看相关的man。

  • 首先,我们到/var/run/netns目录下查看系统的network namespace,发现什么也没有。
  • 然后,我们到/var/run/docker/netns目录下查看Docker的namespace,发现有好些。
  • 于是,我们用指定位置的方式查看Docker的network namespace里的IP地址

这里要动用nsenter 命令,这个命令可以进入到namespace里执行一些命令。比如

$ nsenter --net=/var/run/docker/netns/421bdb2accf1 ifconfig -a

上述的命令,到var/run/docker/netns/421bdb2accf1 这个network namespace里执行了ifconfig -a 命令。于是我们可以用下面 命令来遍历所有的network namespace。

$ ls /var/run/docker/netns | xargs -I {} nsenter --net=/var/run/docker/netns/{} ip addr

然后,我们发现了比较诡异的事情。

  • 10.233.14.145我们查到了这个IP,说明,docker的namespace下还有这个IP。
  • 10.233.14.137,这个IP没有在docker的network namespace下查到。

有namespace leaking?于是我上网查了一下,发现了一个docker的bug – 在docker remove/stop 一个容器的时候,没有清除相应的network namespace,这个问题被报告到了Issue#31597 然后被fix在了PR#31996,并Merge到了 Docker的 17.05版中。而用户的版本是 17.09,应该包含了这个fix。不应该是这个问题,感觉又走不下去了。

不过,10.233.14.137 这个IP可以ping得通,说明这个IP一定被绑在某个网卡,而且被隐藏到了某个network namespace下。

到这里,要查看所有network namespace,只有最后一条路了,那就是到/proc/ 目录下,把所有的pid下的/proc/<pid>/ns 目录给穷举出来。好在这里有一个比较方便的命令可以干这个事 : lsns

于是我写下了如下的命令:

$ lsns -t net | awk ‘{print $4}' | xargs -t -I {} nsenter -t {}&nbsp;-n ip addr | grep -C 4 "10.233.14.137"

解释一下。

  • lsns -t net 列出所有开了network namespace的进程,其第4列是进程PID
  • 把所有开过network namespace的进程PID拿出来,转给xargs 命令
  • 由xargs命令把这些PID 依次传给nsenter命令,
    • xargs -t 的意思是会把相关的执行命令打出来,这样我知道是那个PID。
    • xargs -I {} 是声明一个占位符来替换相关的PID

最后,我们发现,虽然在/var/run/docker/netns 下没有找到10.233.14.137 ,但是在lsns 中找到了三个进程,他们都用了10.233.14.137 这个IP(冲突了这么多),而且他们的MAC地址全是一样的! (怪不得arping找不到)。通过ps 命令,可以查到这三个进程,有两个是java的,还有一个是/pause (这个应该是kubernetes的沙盒)。

我们继续乘胜追击,穷追猛打,用pstree命令把整个进程树打出来。发现上述的三个进程的父进程都在多个同样叫docker-contiane 的进程下!

这明显还是docker的,但是在docker ps中却找不道相应的容器,什么鬼!快崩溃了……

继续看进程树,发现,这些docker-contiane 的进程的父进程不在dockerd 下面,而是在systemd这个超级父进程PID 1下,我靠!进而发现了一堆这样的野进程(这种野进程或是僵尸进程对系统是有害的,至少也是会让系统进入亚健康的状态,因为他们还在占着资源)。

docker-contiane 应该是dockerd 的子进程,被挂到了pid 1 只有一个原因,那就是父进程“飞”掉了,只能找 pid 1 当养父。这说明,这台机器上出现了比较严重的dockerd 进程退出的问题,而且是非常规的,因为systemd 之所以要成为 pid 1,其就是要监管所有进程的子子孙孙,居然也没有管理好,说明是个非常规的问题。(注,关于 systemd,请参看《Linux PID 1 和 Systemd》,关于父子进程的事,请参看《Unix高级环境编程》一书)

接下来就要看看systemd为dockerd记录的日志了…… (然而日志只有3天的了,这3天dockerd没有任何异常)

总结

通过这个调查,可以总结一下,

1) 对于问题调查,需要比较扎实的基础知识,知道问题的成因和范围。

2)如果走不下去了,要重新梳理一下,回头仔细看一下一些蛛丝马迹,认真推敲每一个细节。

3) 各种诊断工具要比较熟悉,这会让你事半功倍。

4)系统维护和做清洁比较类似,需要经常看看系统中是否有一些僵尸进程或是一些垃圾东西,这些东西要及时清理掉。

最后,多说一下,很多人都说,Docker适合放在物理机内运行,这并不完全对,因为他们只考虑到了性能成本,没有考虑到运维成本,在这样512GB中启动几百个容器的玩法,其实并不好,因为这本质上是个大单体,因为你一理要重启某些关键进程或是机器,你的影响面是巨大的

 

———————— 更新 2018/12/10 —————————

问题原因

这两天在自己的环境下测试了一下,发现,只要是通过systemctl start/stop docker 这样的命令来启停 Docker, 是可以把所有的进程和资源全部干掉的。这个是没有什么问题的。我唯一能重现用户问题的的操作就是直接kill -9 <dockerd pid> 但是这个事用户应该不会干。而 Docker 如果有 crash 事件时,Systemd 是可以通过journalctl -u docker 这样的命令查看相关的系统日志的。

于是,我找用户了解一下他们在Docker在启停时的问题,用户说,他们的执行systemctl stop docker 这个命令的时候,发现这个命令不响应了,有可能就直接按了 Ctrl +C了

这个应该就是导致大量的docker-containe 进程挂到PID 1 下的原因了。前面说过,用户的一台物理机上运行着上百个容器,所以,那个进程树也是非常庞大的,我想,停服的时候,系统一定是要遍历所有的docker子进程来一个一个发退出信号的,这个过程可能会非常的长。导致操作员以为命令假死,而直接按了Ctrl + C ,最后导致很多容器进程并没有终止……

 

其它事宜

有同学问,为什么我在这个文章里写的是docker-containe 而不是containd 进程?这是因为,前着是yum install 安装CentOS系统 rpm 包而来的,后者是安装 Docker 发布的安装 rpm 包而来的。

下面是这两种不同安装包的进程树的差别(其中sleep是我用buybox镜像启动的)

systemd───dockerd─┬─docker-containe─┬─3*[docker-containe─┬─sleep]
                  │                 │                    └─9*[{docker-containe}]]
                  │                 ├─docker-containe─┬─sleep
                  │                 │                 └─10*[{docker-containe}]
                  │                 └─14*[{docker-containe}]
                  └─17*[{dockerd}]
systemd───dockerd─┬─containerd─┬─3*[containerd-shim─┬─sleep]
                  │            │                 └─9*[{containerd-shim}]
                  │            ├─2*[containerd-shim─┬─sleep]
                  │            │                    └─9*[{containerd-shim}]]
                  │            └─11*[{containerd}]
                  └─10*[{dockerd}]

顺便说一下,自从 Docker 1.11版以后,Docker进程组模型就改成上面这个样子了.

  • dockerd 是 Docker Engine守护进程,直接面向操作用户。dockerd启动时会启动containerd子进程,他们之前通过RPC进行通信。
  • containerd是dockerd和runc之间的一个中间交流组件。他与dockerd 的解耦是为了让Docker变得更为的中立,而支持OCI 的标准 。
  • containerd-shim  是用来真正运行的容器的,每启动一个容器都会起一个新的shim进程, 它主要通过指定的三个参数:容器id,boundle目录(containerd的对应某个容器生成的目录,一般位于:/var/run/docker/libcontainerd/containerID), 和运行命令(默认为runc)来创建一个容器。
  • docker-proxy 你有可能还会在新版本的Docker中见到这个进程,这个进程是用户级的代理路由。只要你用ps -elf这样的命令把其命令行打出来,你就可以看到其就是做端口映射的。如果你不想要这个代理的话,你可以在dockerd 启动命令行参数上加上: --userland-proxy=false这个参数。

更多的细节,大家可以自行Google。这里推荐两篇文章:

(全文完)


关注CoolShell微信公众账号可以在手机端搜索文章

(转载本站文章请注明作者和出处酷 壳 – CoolShell,请勿用于任何商业用途)

——===访问酷壳404页面寻找遗失儿童。===——
]]>
昨天周五晚上,临下班的时候,用户给我们报了一个比较怪异的Kubernetes集群下的网络不能正常访问的问题,让我们帮助查看一下,我们从下午5点半左右一直跟进到晚上十点左右,在远程不能访问用户机器只能远程遥控用户的情况找到了的问题。这个问题比较有意思,我个人觉得其中的调查用到的的命令以及排障的一些方法可以分享一下,所以写下了这篇文章。

问题的症状

用户直接在微信里说,他们发现在Kuberbnetes下的某个pod被重启了几百次甚至上千次,于是开启调查这个pod,发现上面的服务时而能够访问,时而不能访问,也就是有一定概率不能访问,不知道是什么原因。而且并不是所有的pod出问题,而只是特定的一两个pod出了网络访问的问题。用户说这个pod运行着Java程序,为了排除是Java的问题,用户用docker exec -it 命令直接到容器内启了一个 Python的 SimpleHttpServer来测试发现也是一样的问题。

我们大概知道用户的集群是这样的版本,Kuberbnetes 是1.7,网络用的是flannel的gw模式,Docker版本未知,操作系统CentOS 7.4,直接在物理机上跑docker,物理的配置很高,512GB内存,若干CPU核,上面运行着几百个Docker容器。

问题的排查

问题初查

首先,我们排除了flannel的问题,因为整个集群的网络通信都正常,只有特定的某一两个pod有问题。而用telnet ip port 的命令手工测试网络连接时有很大的概率出现connection refused 错误,大约 1/4的概率,而3/4的情况下是可以正常连接的。

当时,我们让用户抓个包看看,然后,用户抓到了有问题的TCP连接是收到了SYN 后,立即返回了RST, ACK

我问一下用户这两个IP所在的位置,知道了,10.233.14.129 是docker0,10.233.14.145 是容器内的IP。所以,这基本上可以排除了所有和kubernets或是flannel的问题,这就是本地的Docker上的网络的问题。

对于这样被直接 Reset 的情况,在telnet上会显示connection refused 的错误信息,对于我个人的经验,这种SYN完直接返回RST, ACK的情况只会有三种情况:

  1.  TCP链接不能建立,不能建立连接的原因基本上是标识一条TCP链接的那五元组不能完成,绝大多数情况都是服务端没有相关的端口号。
  2. TCP链接建错误,有可能是因为修改了一些TCP参数,尤其是那些默认是关闭的参数,因为这些参数会导致TCP协议不完整。
  3. 有防火墙iptables的设置,其中有REJECT 规则。

因为当时还在开车,在等红灯的时候,我感觉到有点像 NAT 的网络中服务端开启了tcp_tw_recycle 和tcp_tw_reuse 的症况(详细参看《TCP的那些事(上)》),所以,让用户查看了一上TCP参数,发现用户一个TCP的参数都没有改,全是默认的,于是我们排除了TCP参数的问题。

然后,我也不觉得容器内还会设置上iptables,而且如果有那就是100%的问题,不会时好时坏。所以,我怀疑容器内的端口号没有侦听上,但是马上又好了,这可能会是应用的问题。于是我让用户那边看一下,应用的日志,并用kublet describe看一下运行的情况,并把宿主机的 iptables 看一下。

然而,我们发现并没有任何的问题。这时,我们失去了所有的调查线索,感觉不能继续下去了……

重新梳理

这个时候,回到家,大家吃完饭,和用户通了一个电话,把所有的细节再重新梳理了一遍,这个时候,用户提供了一个比较关键的信息—— “抓包这个事,在docker0 上可以抓到,然而到了容器内抓不到容器返回RST, ACK ” !然而,根据我的知识,我知道在docker0和容器内的veth网卡上,中间再也没有什么网络设备了(参看《Docker基础技术:LINUX NAMESPACE(下)》)!

于是这个事把我们逼到了最后一种情况 —— IP地址冲突了!

Linux下看IP地址冲突还不是一件比较简单事的,而在用户的生产环境下没有办法安装一些其它的命令,所以只能用已有的命令,这个时候,我们发现用户的机器上有arping 于是我们用这个命令来检测有没有冲突的IP地址。使用了下面的命令:

$ arping -D -I docker0 -c 2 10.233.14.145
$ echo $?

根据文档,-D 参数是检测IP地址冲突模式,如果这个命令的退状态是0 那么就有冲突。结果返回了1 。而且,我们用arping IP的时候,没有发现不同的mac地址。 这个时候,似乎问题的线索又断了

因为客户那边还在处理一些别的事情,所以,我们在时断时续的情况下工作,而还一些工作都需要用户完成,所以,进展有点缓慢,但是也给我们一些时间思考问题。

柳暗花明

现在我们知道,IP冲突的可能性是非常大的,但是我们找不出来是和谁的IP冲突了。而且,我们知道只要把这台机器重启一下,问题一定就解决掉了,但是我们觉得这并不是解决问题的方式,因为重启机器可以暂时的解决掉到这个问题,而如果我们不知道这个问题怎么发生的,那么未来这个问题还会再来。而重启线上机器这个成本太高了。

于是,我们的好奇心驱使我们继续调查。我让用户kubectl delete 其中两个有问题的pod,因为本来就服务不断重启,所以,删掉也没有什么问题。删掉这两个pod后(一个是IP为10.233.14.145 另一个是10.233.14.137),我们发现,kubernetes在其它机器上重新启动了这两个服务的新的实例。然而,在问题机器上,这两个IP地址居然还可以ping得通

好了,IP地址冲突的问题可以确认了。因为10.233.14.xxx 这个网段是 docker 的,所以,这个IP地址一定是在这台机器上。所以,我们想看看所有的 network namespace 下的 veth 网卡上的IP。

在这个事上,我们费了点时间,因为对相关的命令也 很熟悉,所以花了点时间Google,以及看相关的man。

  • 首先,我们到/var/run/netns目录下查看系统的network namespace,发现什么也没有。
  • 然后,我们到/var/run/docker/netns目录下查看Docker的namespace,发现有好些。
  • 于是,我们用指定位置的方式查看Docker的network namespace里的IP地址

这里要动用nsenter 命令,这个命令可以进入到namespace里执行一些命令。比如

$ nsenter --net=/var/run/docker/netns/421bdb2accf1 ifconfig -a

上述的命令,到var/run/docker/netns/421bdb2accf1 这个network namespace里执行了ifconfig -a 命令。于是我们可以用下面 命令来遍历所有的network namespace。

$ ls /var/run/docker/netns | xargs -I {} nsenter --net=/var/run/docker/netns/{} ip addr

然后,我们发现了比较诡异的事情。

  • 10.233.14.145我们查到了这个IP,说明,docker的namespace下还有这个IP。
  • 10.233.14.137,这个IP没有在docker的network namespace下查到。

有namespace leaking?于是我上网查了一下,发现了一个docker的bug – 在docker remove/stop 一个容器的时候,没有清除相应的network namespace,这个问题被报告到了Issue#31597 然后被fix在了PR#31996,并Merge到了 Docker的 17.05版中。而用户的版本是 17.09,应该包含了这个fix。不应该是这个问题,感觉又走不下去了。

不过,10.233.14.137 这个IP可以ping得通,说明这个IP一定被绑在某个网卡,而且被隐藏到了某个network namespace下。

到这里,要查看所有network namespace,只有最后一条路了,那就是到/proc/ 目录下,把所有的pid下的/proc/<pid>/ns 目录给穷举出来。好在这里有一个比较方便的命令可以干这个事 : lsns

于是我写下了如下的命令:

$ lsns -t net | awk ‘{print $4}' | xargs -t -I {} nsenter -t {}&nbsp;-n ip addr | grep -C 4 "10.233.14.137"

解释一下。

  • lsns -t net 列出所有开了network namespace的进程,其第4列是进程PID
  • 把所有开过network namespace的进程PID拿出来,转给xargs 命令
  • 由xargs命令把这些PID 依次传给nsenter命令,
    • xargs -t 的意思是会把相关的执行命令打出来,这样我知道是那个PID。
    • xargs -I {} 是声明一个占位符来替换相关的PID

最后,我们发现,虽然在/var/run/docker/netns 下没有找到10.233.14.137 ,但是在lsns 中找到了三个进程,他们都用了10.233.14.137 这个IP(冲突了这么多),而且他们的MAC地址全是一样的! (怪不得arping找不到)。通过ps 命令,可以查到这三个进程,有两个是java的,还有一个是/pause (这个应该是kubernetes的沙盒)。

我们继续乘胜追击,穷追猛打,用pstree命令把整个进程树打出来。发现上述的三个进程的父进程都在多个同样叫docker-contiane 的进程下!

这明显还是docker的,但是在docker ps中却找不道相应的容器,什么鬼!快崩溃了……

继续看进程树,发现,这些docker-contiane 的进程的父进程不在dockerd 下面,而是在systemd这个超级父进程PID 1下,我靠!进而发现了一堆这样的野进程(这种野进程或是僵尸进程对系统是有害的,至少也是会让系统进入亚健康的状态,因为他们还在占着资源)。

docker-contiane 应该是dockerd 的子进程,被挂到了pid 1 只有一个原因,那就是父进程“飞”掉了,只能找 pid 1 当养父。这说明,这台机器上出现了比较严重的dockerd 进程退出的问题,而且是非常规的,因为systemd 之所以要成为 pid 1,其就是要监管所有进程的子子孙孙,居然也没有管理好,说明是个非常规的问题。(注,关于 systemd,请参看《Linux PID 1 和 Systemd》,关于父子进程的事,请参看《Unix高级环境编程》一书)

接下来就要看看systemd为dockerd记录的日志了…… (然而日志只有3天的了,这3天dockerd没有任何异常)

总结

通过这个调查,可以总结一下,

1) 对于问题调查,需要比较扎实的基础知识,知道问题的成因和范围。

2)如果走不下去了,要重新梳理一下,回头仔细看一下一些蛛丝马迹,认真推敲每一个细节。

3) 各种诊断工具要比较熟悉,这会让你事半功倍。

4)系统维护和做清洁比较类似,需要经常看看系统中是否有一些僵尸进程或是一些垃圾东西,这些东西要及时清理掉。

最后,多说一下,很多人都说,Docker适合放在物理机内运行,这并不完全对,因为他们只考虑到了性能成本,没有考虑到运维成本,在这样512GB中启动几百个容器的玩法,其实并不好,因为这本质上是个大单体,因为你一理要重启某些关键进程或是机器,你的影响面是巨大的

 

———————— 更新 2018/12/10 —————————

问题原因

这两天在自己的环境下测试了一下,发现,只要是通过systemctl start/stop docker 这样的命令来启停 Docker, 是可以把所有的进程和资源全部干掉的。这个是没有什么问题的。我唯一能重现用户问题的的操作就是直接kill -9 <dockerd pid> 但是这个事用户应该不会干。而 Docker 如果有 crash 事件时,Systemd 是可以通过journalctl -u docker 这样的命令查看相关的系统日志的。

于是,我找用户了解一下他们在Docker在启停时的问题,用户说,他们的执行systemctl stop docker 这个命令的时候,发现这个命令不响应了,有可能就直接按了 Ctrl +C了

这个应该就是导致大量的docker-containe 进程挂到PID 1 下的原因了。前面说过,用户的一台物理机上运行着上百个容器,所以,那个进程树也是非常庞大的,我想,停服的时候,系统一定是要遍历所有的docker子进程来一个一个发退出信号的,这个过程可能会非常的长。导致操作员以为命令假死,而直接按了Ctrl + C ,最后导致很多容器进程并没有终止……

 

其它事宜

有同学问,为什么我在这个文章里写的是docker-containe 而不是containd 进程?这是因为,前着是yum install 安装CentOS系统 rpm 包而来的,后者是安装 Docker 发布的安装 rpm 包而来的。

下面是这两种不同安装包的进程树的差别(其中sleep是我用buybox镜像启动的)

systemd───dockerd─┬─docker-containe─┬─3*[docker-containe─┬─sleep]
                  │                 │                    └─9*[{docker-containe}]]
                  │                 ├─docker-containe─┬─sleep
                  │                 │                 └─10*[{docker-containe}]
                  │                 └─14*[{docker-containe}]
                  └─17*[{dockerd}]
systemd───dockerd─┬─containerd─┬─3*[containerd-shim─┬─sleep]
                  │            │                 └─9*[{containerd-shim}]
                  │            ├─2*[containerd-shim─┬─sleep]
                  │            │                    └─9*[{containerd-shim}]]
                  │            └─11*[{containerd}]
                  └─10*[{dockerd}]

顺便说一下,自从 Docker 1.11版以后,Docker进程组模型就改成上面这个样子了.

  • dockerd 是 Docker Engine守护进程,直接面向操作用户。dockerd启动时会启动containerd子进程,他们之前通过RPC进行通信。
  • containerd是dockerd和runc之间的一个中间交流组件。他与dockerd 的解耦是为了让Docker变得更为的中立,而支持OCI 的标准 。
  • containerd-shim  是用来真正运行的容器的,每启动一个容器都会起一个新的shim进程, 它主要通过指定的三个参数:容器id,boundle目录(containerd的对应某个容器生成的目录,一般位于:/var/run/docker/libcontainerd/containerID), 和运行命令(默认为runc)来创建一个容器。
  • docker-proxy 你有可能还会在新版本的Docker中见到这个进程,这个进程是用户级的代理路由。只要你用ps -elf这样的命令把其命令行打出来,你就可以看到其就是做端口映射的。如果你不想要这个代理的话,你可以在dockerd 启动命令行参数上加上: --userland-proxy=false这个参数。

更多的细节,大家可以自行Google。这里推荐两篇文章:

(全文完)


关注CoolShell微信公众账号可以在手机端搜索文章

(转载本站文章请注明作者和出处酷 壳 – CoolShell,请勿用于任何商业用途)

——===访问酷壳404页面寻找遗失儿童。===——
]]>
0
<![CDATA[每周分享第 34 期]]> http://www.udpwork.com/item/17234.html http://www.udpwork.com/item/17234.html#reviews Fri, 07 Dec 2018 11:55:42 +0800 阮一峰 http://www.udpwork.com/item/17234.html 这里记录过去一周,我看到的值得分享的东西,每周五发布。

欢迎投稿,或推荐你自己的项目,请前往 GitHub 的ruanyf/weekly提交 issue。

英国有一家叫做BioTeq的创业公司,主营业务是人体芯片,也就是在人的体内植入 NFC 和 RDIF 芯片。上图是他们把芯片植入了客户的虎口。

这个芯片里面存有客户的个人信息,可以被读卡器读取。根据这家公司的描述,植入芯片以后,就不用携带钥匙了,挥挥手,门就开了。门禁系统和刷脸支付,都会有全新的解决方案,比现在大大简化。

这个系统在技术上已经成熟了,植入手术完成了150多例。许多公司都表示有兴趣,想在雇员体内装一个芯片。这可不是科幻小说,而是完全真实的,英国最大的工会上个月已经发表声明,表示关注此事,主流大报《卫报》也发了报道。

这个事情的复杂性在于,它有两面性。一方面,这是对个人自由的一种侵犯,需要"升级"你的肉体;另一方面,它会带来巨大的便利。浅显的好处是,从此不用携带身份证(包括工牌、钥匙等),身份识别会变得异常简单,登机和过海关都会变得很快,并且整个社会有统一的身份识别接口。深层的好处在于,它提供了人的数据交换接口,简单说,以后交朋友都不用加微信,握手的时候就会自动进行信息交换。

如果植入芯片对健康无影响,并且无痛(现在就是这样),人们会接受这种技术吗?有人说,它侵犯我的自由,我坚决不用。我觉得,这种抵制可能没用。举例来说,手机也侵犯个人自由,只要你携带手机,就会暴露自己的位置,但是我们不照样使用手机吗?如果其他人都使用这个体内的数据接口,你其实没有别的选择。好比每个人都使用手机付款,你偏要坚持现金付款,就纯粹是给自己找麻烦了。

新闻

1、8K 视频

12月1日,日本广播公司 NHK 开始播出 8K 视频,即分辨率为 7680 x 4320 的节目。日本希望2020年东京奥运时向全世界提供 8K 信号,现在就是为那时做准备。由于现有的 8K 节目数量非常有限,NHK 只在每天上午10点到晚上10点播出,而且每个节目一天之中将滚动播放多次。

为了能够观看8K,您不仅需要一台8K电视(价格4000美元~6000美元),还需要一个专用的卫星天线和解码器(价格800美元~1000美元)来接收信号,这是很大一笔投入。目前,NHK 没有通过地面数字广播发送 8K 信号的计划。未来,消费者应该可以通过 5G 网络在家中接收 8K 电视信号。

2、5G 通信

12月1日,韩国三个移动运营商(SK电信,KT 和 LG U +)开始在首尔和其他主要城市提供 5G 通信服务。韩国成为世界第一个开始 5G 商用服务的国家。但是由于现在还没有支持 5G 网络的智能手机,因此这个服务只能用于企业内部的测试。

LG U+ 表示,今年底它将在韩国全国拥有7,000多个 5G 基站。

3、帕金森症的治疗

很多老年人患有帕金森症,手脚颤抖,行动迟缓,会造成生活困难,目前没有有效的治疗方法。它的病因是大脑内部分泌多巴胺的神经细胞死亡。

11月9日,京都大学医学部宣布,已经实施了世界上首例 iPS 细胞治疗帕金森病的手术。医生往一个帕金森症患者的脑部,移植了他人 iPS 细胞培养的多巴胺神经细胞,总计240万个,以补充病人死去的多巴胺神经细胞。目前,患者恢复情况良好,不过医生说,手术效果和安全性还需要长期的观察,观察期为2年。(@githubwds_ _投稿)

4、新西兰的火箭公司

11月11日,新西兰公司"火箭实验室"第三次火箭发射成功,将6颗卫星送入太空。这标志着低成本火箭公司的兴起。

主权国家的火箭发射一次的成本大约是1.5亿~3亿美元,SpaceX 公司是6000万美元,而火箭实验室只需要570万美元,因为它们的火箭比较小,而且只进入地球的低轨道。根据计划,该公司计划到2020年,每周发射一次火箭。

5、全部远程办公的 GitLab

越来越多的公司选择远程办公,其中最彻底的大概就是 GitLab。三年前这家公司只有9个人,现在有350人,分布在45个国家或地区,全部在家办公,通过视频通话和 Slack 保持联系。

去年,这家公司的收入是1050万美元。今年由于微软收购 GitHub,网站流量一下子放大了七倍。上图是公司在南非举行的年会照片。

6、平流层气球

平流层是距离地表10公里~50公里的高空,气流比较平稳,几乎没有上下对流。这意味着,如果气球进入平流层,它可以停留在那里,不会上升或下降。

问题是,气球会被吹走。美国国防部现在开发出携带风传感器的气球,这种气球能够在两公里以外感知风的方向,然后上升或下降避开这股风,从而让气球可以像地球卫星一样,固定停留在地表某一点的上空。这种气球的成本远远低于卫星。

7、覆盖任何形状的形状

上面形状的最大直径都是1。1914年,有人提出一个问题:能够覆盖所有这些形状的形状是什么?很显然,六边形可以覆盖所有形状。

然后,一直有人不断在寻找最小的形状。最近,一个业余数学家将面积缩小到0.84409359单位,之前2015年的纪录是0.8441153单位。下面就是他找到的形状。

8、新加坡的传感器网络

新加坡政府有计划在该国11万个路灯上,都安装摄像头和传感器,对行人进行面部识别,同时监控空气和降雨量,收集车辆和客流数据以帮助交通。上图是一家中国公司的类似产品展示。

10、一句话新闻

  • 宾夕法尼亚大学的科学家调查后认为,脑容量较大确实是聪明的一个因素,但是作用不是特别大,只能解释人的认知水平差异的2%。

  • 英国民航局要求航空公司,家庭成员坐在一起不得额外收费。有些航空公司默认给家庭成员分配分开的座位,如果要坐在一起必须付费。英国民航局担心,这样会影响疏散速度,有安全隐患。

  • 美国食品和药物管理局FDA 局长斯科特·戈特利布(Scott Gottlieb),就中国的基因编辑婴儿发推特称:"科学的某些用途应该被认为是不可容忍的,并导致科学家被赶出科学界。编辑人类胚胎就属于这种情况。"

  • 大卫·霍克尼(David Hockney)1972年的油画《两个人的游泳池》,11月15日拍卖出了9030万美元,创下了还活着的艺术家的最高价格。

教程

1、使用 Swift 解析 Excel 电子表格(英文)

本文使用 Swift 语言操作 Excel 电子表格。文中解释了 Excel 的格式,理论上其他语言也可以做到。

2、Clojure 语言入门教程(英文)

如果你想从头学习 Clojure 语言,可以读这篇教程,内容非常详尽。

3、网站域名是否该有 www?(英文)

www.example.com和example.com哪一个合适作为主站的域名?这里的关键问题是,example.com设置的 Cookie 可以被子域名读取,并一起发送到服务器。

4、UDP 协议到底可不可靠?(英文)

UDP 协议不如 TCP 协议可靠,这是大家都知道,但是这个协议到底丢包率有多高?有人做了测试,结果发现丢包率并不高,主要的问题是数据包的顺序。

5、调试 Node 应用的最简单方法:VS Code(英文)

本文介绍如何使用 VS Code 编辑器调试 Node 代码。

6、JavaScript 如何复制对象(英文)

JavaScript 的对象复制默认是浅拷贝,本文介绍如何深拷贝。

7、Netlify lambda 的最简单示例(英文)

Netlify 的 lambda 函数可能是现在最简单的 Serverless 实现,本文教你如何完成一个 hello world 示例。

8、不必要的 HTTP 头信息(英文)

本文统计了世界最大的前50万个网站返回的 HTTP 回应,其中最常见的30种 HTTP 头信息包括了很多错误的用法。

9、水平看板(英文)

看板(kanban)是管理 issue 的流行方式,一般的看板是垂直的。本文提出,这是因为日本文字是直排的,而看板是日本人发明的,西方文字是横排的,所以看板应该改成水平。

11、tldr

Linux 系统的 man 帮助文件通常很冗长,难以查阅,这个项目提供简化的 man 文件。(@chenylvia投稿)

资源

1、互联网技术的发展

该网站使用彩带图,以可交互的形式展现了互联网技术的发展和演变。(@tifazxy_ _投稿)

2、NLP 学习资源(英文)

本文列出初学者学习自然语言处理(NLP)时,比较有用的一些资源。

3、本月分子(英文)

英国布里斯托大学化学系制作的网站,每个月介绍一种化合物的分子。

4、Gitlab 手册

Gitlab 将公司的所有内部政策,做成一份2000页的手册,公开在网上,以做到"透明公司"的承诺。

5、C++ 程序设计

北京大学的视频课程《C++ 程序设计》,要求学习者具有 C 语言基础。该课程有B 站镜像。(@lianmt_ _投稿)

6、谷歌的技术文档写作指南(英文)

谷歌的英语技术文档的写作手册,讲解了程序员写文档的各种要求。

7、Caddy 中文文档

Caddy 是一个新的 HTTP/2 Web 服务器,该网站是志愿者翻译的中文文档。(@comdeng投稿)

工具

1、strapdown

Markdown 文件直接部署成静态网站,不需要编译。

2、codeadvice

一个支持在线协同和聊天的网页代码编辑器。

3、pydub

可以编辑、修改各种音频文件的 Python 库。

4、spectre.css

Spectre.css 是一个轻量级,响应式的、现代 CSS 框架。

5、Photopea

在线图像编辑器,免费,可以替代 PhotoShop 的一部分功能。

6、gitbase

该工具允许使用 SQL 语法查询 Git 仓库。

7、DropIt

一个浏览器拖放文件上传的 JS 库。

8、Whaler

该软件可以从 Docker image 逆向还原出 Dockerfile。

9、Bootswatch

Bootstrap 是最常用的 CSS 框架,这个网站收集免费的 Bootstrap 主题。类似的网站还有bulmaswatch,收集 Bluma 框架的免费主题。

10、WebAssembly Studio

一个 WebAssembly 的在线 IDE,支持 C / C ++ / Rust 程序在线编译成 WASM。该项目由 Mozilla 基金会开发,这里有一篇介绍

文摘

1、英制度量衡的便利之处

英美使用英制度量衡,而不是公制度量衡。这种度量衡有它的便利之处。

首先,英制度量衡采用十二进制。1英尺等于12英寸。十二进制的方便在于,它可以很容易地四等分、三等分和二等分;十进制只能二等分。另外,1英寸(2.54厘米)大约等于成人大拇指的宽度,用起来也非常方便。

其次,表示温度的华氏度比摄氏度更便于使用。100华氏度(37.8摄氏度)等于人的体温。所以,0华氏度(-17.8摄氏度)表示非常冷的天气,100华氏度表示很热的天气,50华氏度表示需要穿毛衣的天气。另外,水在 212°F 沸腾,在 32°F 时结冰,之间有180度,又是一个12的倍数。

2、除了软件工程师,加州的工资都在下降

美国的经济正处在繁荣期,失业率是多年来最低的。但是很难相信,除了软件工程师,加州其他工作岗位的工资竟然不如1997年的水平。一项研究发现,调整通货膨胀以后,过去20年,软件工程师的工资增长了32%,而普通加州人的工资下降了12%~14%。那些低收入和中等收入工作的工人,比如教师和消防员,保姆和厨师,工资都在下降。

不仅工资水平在下降,而且低工资工人的比例在过去20年增长了25%。中高薪的工作岗位越来越少。

但是,过去20年加州的 GDP 一直在快速增长,人均 GDP 增加了74%。比全国速度快了五倍多。这表明绝大多数财富都没有落入工人的口袋,谷歌和 Facebook 这样的大型科技公司在市场中占据主导地位,它们将更多的收入分配给投资者和一些顶级员工。

经济学家认为,加州经济不是沙漏型(两端大,中间小),而是正从梨型(下面大,上面小)变成图钉型:顶部在萎缩,底部在膨胀。

新奇

1、世界最小的计算机

2015年,密西根大学的科学家制造了世界最小计算机,只有2毫米。

计算机系统必须具有数据输入输出的能力,以及处理和存储数据的能力。对于这个最小计算机来说,传感器是输入,无线电是输出。它包含太阳能电池,可利用环境光为电池供电。

上图为该计算机与一美分硬币的比较。

目前,它的主要用途是监视房间的气压和温度的异常,同时将这些数据传送到基站。它的传输距离是2米。另一个用途是植入病人体内,监视青光眼患者的眼内压和脑部受伤者的颅内压,取代目前将导线插入头骨的方法,现有方法使得患者易受感染。

每周图片

1、贝克米勒粉红色

1979年,美国西雅图的海军监狱需要油漆房间。监狱的两位所长贝克和米勒,咨询心理学家亚历山大·绍斯(Alexander Schauss)。后者根据自己的研究,建议将监狱墙壁油漆为粉红色(#FF91AF),这种颜色有助于减少暴力和攻击。

监狱采纳了他的建议。因此,这种粉红色后来就被称为"贝克米勒粉红色"。根据海军后来的研究,这种颜色确实降低了监狱内的暴力行为。

2、画图机器人

澳大利亚莫纳什大学的科学家制作的画图机器人,可以自主地进行绘画。 下面是机器人的作品。

3、安藤忠雄的佛像

日本著名建筑师安藤忠雄为札幌公墓设计了一尊大佛。奇特的是,这座大佛藏在一个薰衣草覆盖的山丘里面。游客必须通过一条40米的隧道才能到达13.5米高的佛像脚下。

本周金句

1、

一家公司咨询我,如何吸引第三方开发者使用他们的平台。我问:"你们公司有人在下班后,用自己的时间鼓捣这个平台吗?"回答是没有。我告诉他们,如果你们自己都不愿意玩自己的平台,想要吸引外部工程师就是白费气力。

-- 谷歌开发者关系总监 大卫·麦克劳克林,转引自Tim O'Reilly《未来地图》

2、

GraphQL 的本质是程序员想对 JSON 使用 SQL。

-- 推特@kellybyte

3、

2012年,美国的盗窃案总金额是3.4亿美元,但是同年雇员投诉雇主克扣工资、加班费短缺,并补发成功的总金额是9.3亿美元。雇主偷窃员工应得工资的现象非常普遍。

--《工资偷窃是最大的偷窃》

欢迎订阅

这个专栏每周五发布,同步更新在我的个人网站微信公众号语雀

微信搜索"阮一峰的网络日志 "或者扫描二维码,即可订阅。

(完)

文档信息

]]>
这里记录过去一周,我看到的值得分享的东西,每周五发布。

欢迎投稿,或推荐你自己的项目,请前往 GitHub 的ruanyf/weekly提交 issue。

英国有一家叫做BioTeq的创业公司,主营业务是人体芯片,也就是在人的体内植入 NFC 和 RDIF 芯片。上图是他们把芯片植入了客户的虎口。

这个芯片里面存有客户的个人信息,可以被读卡器读取。根据这家公司的描述,植入芯片以后,就不用携带钥匙了,挥挥手,门就开了。门禁系统和刷脸支付,都会有全新的解决方案,比现在大大简化。

这个系统在技术上已经成熟了,植入手术完成了150多例。许多公司都表示有兴趣,想在雇员体内装一个芯片。这可不是科幻小说,而是完全真实的,英国最大的工会上个月已经发表声明,表示关注此事,主流大报《卫报》也发了报道。

这个事情的复杂性在于,它有两面性。一方面,这是对个人自由的一种侵犯,需要"升级"你的肉体;另一方面,它会带来巨大的便利。浅显的好处是,从此不用携带身份证(包括工牌、钥匙等),身份识别会变得异常简单,登机和过海关都会变得很快,并且整个社会有统一的身份识别接口。深层的好处在于,它提供了人的数据交换接口,简单说,以后交朋友都不用加微信,握手的时候就会自动进行信息交换。

如果植入芯片对健康无影响,并且无痛(现在就是这样),人们会接受这种技术吗?有人说,它侵犯我的自由,我坚决不用。我觉得,这种抵制可能没用。举例来说,手机也侵犯个人自由,只要你携带手机,就会暴露自己的位置,但是我们不照样使用手机吗?如果其他人都使用这个体内的数据接口,你其实没有别的选择。好比每个人都使用手机付款,你偏要坚持现金付款,就纯粹是给自己找麻烦了。

新闻

1、8K 视频

12月1日,日本广播公司 NHK 开始播出 8K 视频,即分辨率为 7680 x 4320 的节目。日本希望2020年东京奥运时向全世界提供 8K 信号,现在就是为那时做准备。由于现有的 8K 节目数量非常有限,NHK 只在每天上午10点到晚上10点播出,而且每个节目一天之中将滚动播放多次。

为了能够观看8K,您不仅需要一台8K电视(价格4000美元~6000美元),还需要一个专用的卫星天线和解码器(价格800美元~1000美元)来接收信号,这是很大一笔投入。目前,NHK 没有通过地面数字广播发送 8K 信号的计划。未来,消费者应该可以通过 5G 网络在家中接收 8K 电视信号。

2、5G 通信

12月1日,韩国三个移动运营商(SK电信,KT 和 LG U +)开始在首尔和其他主要城市提供 5G 通信服务。韩国成为世界第一个开始 5G 商用服务的国家。但是由于现在还没有支持 5G 网络的智能手机,因此这个服务只能用于企业内部的测试。

LG U+ 表示,今年底它将在韩国全国拥有7,000多个 5G 基站。

3、帕金森症的治疗

很多老年人患有帕金森症,手脚颤抖,行动迟缓,会造成生活困难,目前没有有效的治疗方法。它的病因是大脑内部分泌多巴胺的神经细胞死亡。

11月9日,京都大学医学部宣布,已经实施了世界上首例 iPS 细胞治疗帕金森病的手术。医生往一个帕金森症患者的脑部,移植了他人 iPS 细胞培养的多巴胺神经细胞,总计240万个,以补充病人死去的多巴胺神经细胞。目前,患者恢复情况良好,不过医生说,手术效果和安全性还需要长期的观察,观察期为2年。(@githubwds_ _投稿)

4、新西兰的火箭公司

11月11日,新西兰公司"火箭实验室"第三次火箭发射成功,将6颗卫星送入太空。这标志着低成本火箭公司的兴起。

主权国家的火箭发射一次的成本大约是1.5亿~3亿美元,SpaceX 公司是6000万美元,而火箭实验室只需要570万美元,因为它们的火箭比较小,而且只进入地球的低轨道。根据计划,该公司计划到2020年,每周发射一次火箭。

5、全部远程办公的 GitLab

越来越多的公司选择远程办公,其中最彻底的大概就是 GitLab。三年前这家公司只有9个人,现在有350人,分布在45个国家或地区,全部在家办公,通过视频通话和 Slack 保持联系。

去年,这家公司的收入是1050万美元。今年由于微软收购 GitHub,网站流量一下子放大了七倍。上图是公司在南非举行的年会照片。

6、平流层气球

平流层是距离地表10公里~50公里的高空,气流比较平稳,几乎没有上下对流。这意味着,如果气球进入平流层,它可以停留在那里,不会上升或下降。

问题是,气球会被吹走。美国国防部现在开发出携带风传感器的气球,这种气球能够在两公里以外感知风的方向,然后上升或下降避开这股风,从而让气球可以像地球卫星一样,固定停留在地表某一点的上空。这种气球的成本远远低于卫星。

7、覆盖任何形状的形状

上面形状的最大直径都是1。1914年,有人提出一个问题:能够覆盖所有这些形状的形状是什么?很显然,六边形可以覆盖所有形状。

然后,一直有人不断在寻找最小的形状。最近,一个业余数学家将面积缩小到0.84409359单位,之前2015年的纪录是0.8441153单位。下面就是他找到的形状。

8、新加坡的传感器网络

新加坡政府有计划在该国11万个路灯上,都安装摄像头和传感器,对行人进行面部识别,同时监控空气和降雨量,收集车辆和客流数据以帮助交通。上图是一家中国公司的类似产品展示。

10、一句话新闻

  • 宾夕法尼亚大学的科学家调查后认为,脑容量较大确实是聪明的一个因素,但是作用不是特别大,只能解释人的认知水平差异的2%。

  • 英国民航局要求航空公司,家庭成员坐在一起不得额外收费。有些航空公司默认给家庭成员分配分开的座位,如果要坐在一起必须付费。英国民航局担心,这样会影响疏散速度,有安全隐患。

  • 美国食品和药物管理局FDA 局长斯科特·戈特利布(Scott Gottlieb),就中国的基因编辑婴儿发推特称:"科学的某些用途应该被认为是不可容忍的,并导致科学家被赶出科学界。编辑人类胚胎就属于这种情况。"

  • 大卫·霍克尼(David Hockney)1972年的油画《两个人的游泳池》,11月15日拍卖出了9030万美元,创下了还活着的艺术家的最高价格。

教程

1、使用 Swift 解析 Excel 电子表格(英文)

本文使用 Swift 语言操作 Excel 电子表格。文中解释了 Excel 的格式,理论上其他语言也可以做到。

2、Clojure 语言入门教程(英文)

如果你想从头学习 Clojure 语言,可以读这篇教程,内容非常详尽。

3、网站域名是否该有 www?(英文)

www.example.com和example.com哪一个合适作为主站的域名?这里的关键问题是,example.com设置的 Cookie 可以被子域名读取,并一起发送到服务器。

4、UDP 协议到底可不可靠?(英文)

UDP 协议不如 TCP 协议可靠,这是大家都知道,但是这个协议到底丢包率有多高?有人做了测试,结果发现丢包率并不高,主要的问题是数据包的顺序。

5、调试 Node 应用的最简单方法:VS Code(英文)

本文介绍如何使用 VS Code 编辑器调试 Node 代码。

6、JavaScript 如何复制对象(英文)

JavaScript 的对象复制默认是浅拷贝,本文介绍如何深拷贝。

7、Netlify lambda 的最简单示例(英文)

Netlify 的 lambda 函数可能是现在最简单的 Serverless 实现,本文教你如何完成一个 hello world 示例。

8、不必要的 HTTP 头信息(英文)

本文统计了世界最大的前50万个网站返回的 HTTP 回应,其中最常见的30种 HTTP 头信息包括了很多错误的用法。

9、水平看板(英文)

看板(kanban)是管理 issue 的流行方式,一般的看板是垂直的。本文提出,这是因为日本文字是直排的,而看板是日本人发明的,西方文字是横排的,所以看板应该改成水平。

11、tldr

Linux 系统的 man 帮助文件通常很冗长,难以查阅,这个项目提供简化的 man 文件。(@chenylvia投稿)

资源

1、互联网技术的发展

该网站使用彩带图,以可交互的形式展现了互联网技术的发展和演变。(@tifazxy_ _投稿)

2、NLP 学习资源(英文)

本文列出初学者学习自然语言处理(NLP)时,比较有用的一些资源。

3、本月分子(英文)

英国布里斯托大学化学系制作的网站,每个月介绍一种化合物的分子。

4、Gitlab 手册

Gitlab 将公司的所有内部政策,做成一份2000页的手册,公开在网上,以做到"透明公司"的承诺。

5、C++ 程序设计

北京大学的视频课程《C++ 程序设计》,要求学习者具有 C 语言基础。该课程有B 站镜像。(@lianmt_ _投稿)

6、谷歌的技术文档写作指南(英文)

谷歌的英语技术文档的写作手册,讲解了程序员写文档的各种要求。

7、Caddy 中文文档

Caddy 是一个新的 HTTP/2 Web 服务器,该网站是志愿者翻译的中文文档。(@comdeng投稿)

工具

1、strapdown

Markdown 文件直接部署成静态网站,不需要编译。

2、codeadvice

一个支持在线协同和聊天的网页代码编辑器。

3、pydub

可以编辑、修改各种音频文件的 Python 库。

4、spectre.css

Spectre.css 是一个轻量级,响应式的、现代 CSS 框架。

5、Photopea

在线图像编辑器,免费,可以替代 PhotoShop 的一部分功能。

6、gitbase

该工具允许使用 SQL 语法查询 Git 仓库。

7、DropIt

一个浏览器拖放文件上传的 JS 库。

8、Whaler

该软件可以从 Docker image 逆向还原出 Dockerfile。

9、Bootswatch

Bootstrap 是最常用的 CSS 框架,这个网站收集免费的 Bootstrap 主题。类似的网站还有bulmaswatch,收集 Bluma 框架的免费主题。

10、WebAssembly Studio

一个 WebAssembly 的在线 IDE,支持 C / C ++ / Rust 程序在线编译成 WASM。该项目由 Mozilla 基金会开发,这里有一篇介绍

文摘

1、英制度量衡的便利之处

英美使用英制度量衡,而不是公制度量衡。这种度量衡有它的便利之处。

首先,英制度量衡采用十二进制。1英尺等于12英寸。十二进制的方便在于,它可以很容易地四等分、三等分和二等分;十进制只能二等分。另外,1英寸(2.54厘米)大约等于成人大拇指的宽度,用起来也非常方便。

其次,表示温度的华氏度比摄氏度更便于使用。100华氏度(37.8摄氏度)等于人的体温。所以,0华氏度(-17.8摄氏度)表示非常冷的天气,100华氏度表示很热的天气,50华氏度表示需要穿毛衣的天气。另外,水在 212°F 沸腾,在 32°F 时结冰,之间有180度,又是一个12的倍数。

2、除了软件工程师,加州的工资都在下降

美国的经济正处在繁荣期,失业率是多年来最低的。但是很难相信,除了软件工程师,加州其他工作岗位的工资竟然不如1997年的水平。一项研究发现,调整通货膨胀以后,过去20年,软件工程师的工资增长了32%,而普通加州人的工资下降了12%~14%。那些低收入和中等收入工作的工人,比如教师和消防员,保姆和厨师,工资都在下降。

不仅工资水平在下降,而且低工资工人的比例在过去20年增长了25%。中高薪的工作岗位越来越少。

但是,过去20年加州的 GDP 一直在快速增长,人均 GDP 增加了74%。比全国速度快了五倍多。这表明绝大多数财富都没有落入工人的口袋,谷歌和 Facebook 这样的大型科技公司在市场中占据主导地位,它们将更多的收入分配给投资者和一些顶级员工。

经济学家认为,加州经济不是沙漏型(两端大,中间小),而是正从梨型(下面大,上面小)变成图钉型:顶部在萎缩,底部在膨胀。

新奇

1、世界最小的计算机

2015年,密西根大学的科学家制造了世界最小计算机,只有2毫米。

计算机系统必须具有数据输入输出的能力,以及处理和存储数据的能力。对于这个最小计算机来说,传感器是输入,无线电是输出。它包含太阳能电池,可利用环境光为电池供电。

上图为该计算机与一美分硬币的比较。

目前,它的主要用途是监视房间的气压和温度的异常,同时将这些数据传送到基站。它的传输距离是2米。另一个用途是植入病人体内,监视青光眼患者的眼内压和脑部受伤者的颅内压,取代目前将导线插入头骨的方法,现有方法使得患者易受感染。

每周图片

1、贝克米勒粉红色

1979年,美国西雅图的海军监狱需要油漆房间。监狱的两位所长贝克和米勒,咨询心理学家亚历山大·绍斯(Alexander Schauss)。后者根据自己的研究,建议将监狱墙壁油漆为粉红色(#FF91AF),这种颜色有助于减少暴力和攻击。

监狱采纳了他的建议。因此,这种粉红色后来就被称为"贝克米勒粉红色"。根据海军后来的研究,这种颜色确实降低了监狱内的暴力行为。

2、画图机器人

澳大利亚莫纳什大学的科学家制作的画图机器人,可以自主地进行绘画。 下面是机器人的作品。

3、安藤忠雄的佛像

日本著名建筑师安藤忠雄为札幌公墓设计了一尊大佛。奇特的是,这座大佛藏在一个薰衣草覆盖的山丘里面。游客必须通过一条40米的隧道才能到达13.5米高的佛像脚下。

本周金句

1、

一家公司咨询我,如何吸引第三方开发者使用他们的平台。我问:"你们公司有人在下班后,用自己的时间鼓捣这个平台吗?"回答是没有。我告诉他们,如果你们自己都不愿意玩自己的平台,想要吸引外部工程师就是白费气力。

-- 谷歌开发者关系总监 大卫·麦克劳克林,转引自Tim O'Reilly《未来地图》

2、

GraphQL 的本质是程序员想对 JSON 使用 SQL。

-- 推特@kellybyte

3、

2012年,美国的盗窃案总金额是3.4亿美元,但是同年雇员投诉雇主克扣工资、加班费短缺,并补发成功的总金额是9.3亿美元。雇主偷窃员工应得工资的现象非常普遍。

--《工资偷窃是最大的偷窃》

欢迎订阅

这个专栏每周五发布,同步更新在我的个人网站微信公众号语雀

微信搜索"阮一峰的网络日志 "或者扫描二维码,即可订阅。

(完)

文档信息

]]>
0
<![CDATA[A successful rescue for a remote server]]> http://www.udpwork.com/item/17233.html http://www.udpwork.com/item/17233.html#reviews Fri, 07 Dec 2018 11:15:32 +0800 Robin Dong http://www.udpwork.com/item/17233.html After installed CUDA-9.2 on a remote server, I found that the system can’t load nvidia.ko (kernel module) with dmesg:

Unknown symbol __stack_chk_fail (err 0)

The reason is the current kernel running on my system has turned on the CONFIG_CC_STACKPROTECTOR compiler option. Therefore I change the default entry of grub2 and reboot the server, for entering a new kernel without this option.
But unfortunately, the server never start up again. All my code and data (includes my colleague’s code and data) are on this server, so we get a little nervous then.

Since the server is in a remote datacenter, we can’t just plugin in a keyboard and a screen to debug. Thus I use the out-of-bound system to reboot this server to diskless-mode. After entering this mode, I mount the disk for ‘/boot’ directory:

mount /dev/sda1 /mnt/

and manually change the ‘/boot/grub2/grubenv’ like this (the ‘save_entry’ is 2 before):

# GRUB Environment Block
saved_entry=1
#########################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################

Then reboot the server again. This time, the server started up smoothly now. All our code and data is untainted.

]]>
After installed CUDA-9.2 on a remote server, I found that the system can’t load nvidia.ko (kernel module) with dmesg:

Unknown symbol __stack_chk_fail (err 0)

The reason is the current kernel running on my system has turned on the CONFIG_CC_STACKPROTECTOR compiler option. Therefore I change the default entry of grub2 and reboot the server, for entering a new kernel without this option.
But unfortunately, the server never start up again. All my code and data (includes my colleague’s code and data) are on this server, so we get a little nervous then.

Since the server is in a remote datacenter, we can’t just plugin in a keyboard and a screen to debug. Thus I use the out-of-bound system to reboot this server to diskless-mode. After entering this mode, I mount the disk for ‘/boot’ directory:

mount /dev/sda1 /mnt/

and manually change the ‘/boot/grub2/grubenv’ like this (the ‘save_entry’ is 2 before):

# GRUB Environment Block
saved_entry=1
#########################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################

Then reboot the server again. This time, the server started up smoothly now. All our code and data is untainted.

]]>
0