mirror of
https://github.com/cheetahlou/CategoryResourceRepost.git
synced 2025-10-19 16:33:46 +08:00
mod
This commit is contained in:
74
极客时间专栏/趣谈网络协议/答疑与加餐/加餐1 | 创作故事:我是如何创作“趣谈网络协议”专栏的?.md
Normal file
74
极客时间专栏/趣谈网络协议/答疑与加餐/加餐1 | 创作故事:我是如何创作“趣谈网络协议”专栏的?.md
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
我用将近半年的时间在“极客时间”写了一个专栏“趣谈网络协议”。对于我自己来讲,这真的是个非常特殊而又难忘的经历。
|
||||
|
||||
很多人都很好奇,这个专栏究竟是怎么一步步创作出来的,每一篇文章是怎么写出来的?自己录音频又是什么样的感受?写完整个专栏之后,我终于有时间回顾、整理一下这半年的所感所想。对我来说,这是一次难得的体验,也是一次与“极客时间”的深度沟通。
|
||||
|
||||
## 专栏是写给谁的?
|
||||
|
||||
和极客时间的编辑谈妥主题之后,他们首先要求我基于约定的主题,写一个36节至50节的大纲,之后会以每周三篇的频率,文字加音频的方式发布。每篇文章的体量要求在3000字左右,录成音频大约就是10分钟。
|
||||
|
||||
我本来觉得写这么一个专栏根本就不是个事儿。毕竟咱也是在IT圈摸爬滚打了许多年的“老司机”,干货积累得也不少。只要是熟悉的领域,不用准备,聊个把小时都没啥问题。况且我原来还写过书、写过博客、写过公众号。所以,我对自己文字方面的能力很有自信。
|
||||
|
||||
至于语言方面,咱常年出入各大技术论坛,什么场子没趟过。一个两天的线下培训,咱都能扛过来。每篇10分钟,总共36篇,那不才是6个小时嘛,肯定没问题。
|
||||
|
||||
但是,写了之后我发现,**自己会是一回事儿,能讲给别人是另一回事儿**,而能讲给“看不见的陌生人”听,是这世上最难的事儿。
|
||||
|
||||
我知道,很多技术人都有这样一个“毛病”,就是觉得掌握技术本身是最重要的,其他什么产品、市场、销售,都没技术含量。这种思维导致很多技术比较牛的人会以自我为中心,仅站在自己的角度思考问题。所以,**常常是自己讲得很爽,完全不管听的人是不是真的接受了**。写专栏的时候,这绝对是个大忌。
|
||||
|
||||
除此之外,这种思维对职业发展的影响也是很大的。单打独斗,一个人搞定一个软件的时代已经过去了。学会和别人合作,才是现代社会的生存法则,而良好的合作源于沟通。
|
||||
|
||||
但沟通不易,高质量的沟通更难。面对的人越多,沟通的难度就越大。因为每个人的背景、知识、基础都不同,想听的内容肯定更是千差万别。况且不是每个人都能准确地表达出自己的需求,加之需求的表达、转述都会因表达方式和传递媒介而发生变形,这样一来,接收信息的一方自然很难把握真实的需求。
|
||||
|
||||
写专栏的时候,“极客时间”的编辑不断地告诉我,我的受众只有一个人,就是“你”。我心想,这个简单啊,因为面对的人最少嘛!可是,事实上证明,我又“错”了。
|
||||
|
||||
这个抽象的“你”,看起来只有一个,其实却是看不到、摸不着的许许多多的人。所以,这个其实是最难的。协议专栏上线10天,就有10000多人订阅,而订阅专栏的用户里,只有少数人会留言。所以,对于很多读者的真实情况,我都无从得知,你可能每天都听但是没有留言的习惯,也可能买了之后觉得我讲得不好,骂一句“这钱白花了”,然后再也不听。
|
||||
|
||||
所以,**如何把控内容,写给广大未知受众,是我写这个专栏面临的最大挑战**。而这里面,文章的深度、广度,音频的语调、语气,每一个细节都非常重要。
|
||||
|
||||
## 专栏文章是怎么写的?
|
||||
|
||||
经过大纲和前几篇文稿的打磨,我对“极客时间”和专栏创作也有了更深的了解。我私下和很多人交流过一个问题,那就是,咱们平时聊一个话题的时候,有很多话可以说。但是真正去写一篇文章的时候,好像又没有什么可讲的,尤其是那些看起来很基础的内容。
|
||||
|
||||
我在写专栏的过程中,仔细思考过这样一个问题:很多人对某一领域或者行业研究得很深入,也有自己长期的实践,但是**有多少人可以<strong><strong>从感性认识上升到理性**</strong>认知**<strong>的**</strong>高度呢?</strong>
|
||||
|
||||
现在技术变化这么快,我们每个人的精力都是有限的,不少人学习新知识的方式就是看看书,看看博客、技术文章,或者听同事讲一下,了解个大概就觉得可以直接上手去做了。我也是这样的。可是一旦到写专栏的时候,**基础掌握不扎实的问题一下子全都“暴露”出来了。**
|
||||
|
||||
落到文字上的东西一定要是严谨的。所以,在写到很多细节的时候,我查了大量的资料,找到权威的书籍、官方文档、RFC里面的具体描述,有时候我甚至要做个实验,或者打开代码再看一下,才放心下笔。
|
||||
|
||||
尽管我对自己写文章有很多“完美倾向”的要求,但是这其实依旧是站在我自己的角度去看的。读者究竟想要看什么内容呢?
|
||||
|
||||
太深入了,看不懂;太浅显了,也不行。太长了,负担太重;太短了,没有干货;同时,每篇文字还要自成一体,所有文章要是一个完整的知识体系。我发现,原来我不仅是对知识的了解没那么全面、具体,对用户阅读和倾听场景也没有过多的考虑。
|
||||
|
||||
除了写文字,专栏还要录音频,所以为了方便“听”,文章内不能放大量代码、实验。如果很多人在通勤路上听,而我把一张图片讲得天花乱坠,听的人却根本看不到,那肯定是不行的,所以写文章的时候,我还要把故事性、画面感都考虑进去,尽量详尽而不啰嗦。
|
||||
|
||||
把这些限制条件加起来之后,我发现,写专栏这件事儿,真的太不容易了。每篇文章看起来内容不多,但是都是费了很多心思的,这也是为什么很多老师说,写完专栏就像是过了火焰山。
|
||||
|
||||
## 专栏音频是怎么录的?
|
||||
|
||||
说完写文章,我来说说录音频。我平时听播音员说话,感觉非常轻松,所以当时我毫不犹豫地就说,“我要自己录”。但是在录开篇词的时候,我就觉得这完全不是我想的那么回事啊!
|
||||
|
||||
专栏的文章在录音的时候一定会有个“音频稿”,我一开始很不理解,我对着发布的稿件直接讲就好了啊,为什么还要特意准备一个供录音频的稿件啊?
|
||||
|
||||
我在没有音频稿的情况下,自己试着“发挥”了几次,结果,我发现我的嘴会“吃”字,会反复讲一个内容而且表达不清,但是自己却经常毫无察觉,还会自己讲着讲着就收不住等等。
|
||||
|
||||
咱们平时说话的时候,会有很多口头语和重复的词语。面对面交流的时候,我们为什么没有注意这个问题呢?因为我们会更注重对方的表情、手势,但是一旦录成音频,这些“啰嗦”的地方就特别明显。
|
||||
|
||||
而有了音频稿之后,整个过程就严谨很多。如果哪句话说错了,看着稿件再说一遍就好了。而且,你会发现录音的时间大大缩短了,原来需要用十分钟,现在五分钟就可以很精炼地讲出来了。
|
||||
|
||||
有了稿子,那我是不是对着念就好了?这不是很容易吗?不,我又遇到了新的难题。
|
||||
|
||||
录音频的时候,我常常一个人关在密闭的房间里,对着显示器“读”,这和公共演讲肯定是不一样的。加上因为有写好的音频稿,我常常感觉束手束脚,找不到演讲那种有激情的感觉,很容易就变成了念课文。
|
||||
|
||||
为了同时满足自然和严谨,一方面我会先熟记“台词”;另一方面,每次录的时候,我都假想对面有个人,我在对着他缓缓地讲出来。讲到某些地方,我还会假想他对这个知识点是不是有疑问,这样就更加有互动感。
|
||||
|
||||
录音频这件事对我的改变非常大。我说话、演讲的时候变得更加严谨了。我会下意识地不去重复已经说过的话。一旦想重复,也闭嘴不发音,等想好了下一句再说。后面,我的录音也越来越顺利,一开始要录五六遍才能成功,后面基本一遍就过了。
|
||||
|
||||
创作专栏的过程还有许多事情,都是我很难得的记忆。我很佩服“极客时间”的编辑做专栏时的专业和认真。我也很庆幸,我没有固执地按照自己认为正确的方向和方式来做,而是尊重了他们的专业。很显然,**他们没有我懂技术,但是他们比我<strong><strong>更**</strong>懂“你”。</strong>
|
||||
|
||||
专栏结束后,我回看这半年的准备和努力,我发现,**无论对自己的领域多么熟悉,写这个专栏都让我又上升了一个新高度**。
|
||||
|
||||
我知道很多技术人都喜欢分享,而写文章又是最容易实现的方式。写文章的时候,可以检验你对基础知识的掌握是否扎实,是不是有换位思考能力,能不能从感性认识上升到理性认知。
|
||||
|
||||
除此之外,我觉得最重要的一点是,在创作专栏文章的过程中,我学到了很多技术之外的东西,比如换位思考能力和细节把控的能力。
|
||||
|
||||
我在这里记下与“极客时间”的相识和相知。希望看到更多人在极客时间,分享自己的知识和见解。
|
86
极客时间专栏/趣谈网络协议/答疑与加餐/加餐2 | “趣谈网络协议”专栏食用指南.md
Normal file
86
极客时间专栏/趣谈网络协议/答疑与加餐/加餐2 | “趣谈网络协议”专栏食用指南.md
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
你好,我是刘超。
|
||||
|
||||
“趣谈网络协议”专栏现在已经全部更新完毕。这里有一份「食用指南」,可以帮你找到学习本专栏的最佳姿势。
|
||||
|
||||
在这份指南中,我为你整理了**专栏的所有学习资料**,并告诉你**如何更高效地使用这些资料**,从而帮助你消化吸收,以期获得更好的学习效果。
|
||||
|
||||
不管你是刚刚打开这个专栏,还是进入温故的阶段,我的这份指南,都可以帮你更上一个台阶。一起加油吧!
|
||||
|
||||
## 1. 能力测试
|
||||
|
||||
我从常用的网络协议中,精心筛选了核心知识点,编成了10道题。这里面的题目和答案都是我精心设计的。希望你一定要先拿出纸笔,认真思考,记录下自己的答案,之后再和文末的详细解析进行对照。
|
||||
|
||||
刚刚打开这个专栏的你,可以据此寻找自己的薄弱点,**对症下药**;已经学习了一段时间的你,可以检测学习成果,**查漏补缺**。
|
||||
|
||||
点击查看:[网络协议能力测试题](https://time.geekbang.org/column/article/14384)
|
||||
|
||||
## 2. 答疑解惑
|
||||
|
||||
每篇文章后,我都会留两个思考题,其中第一个问题意在启发你的思考,是对本节内容的延伸学习;第二个问题是为引出下一节,下一节的内容其实就是答案(所以我就不单独解答啦)。
|
||||
|
||||
我希望你能够好好地利用这些思考题,毕竟所有的“知”,只有经过了自己的思考之后,才能成为“识”。
|
||||
|
||||
如果你是刚刚加入学习,你可以继续在思考题后的“留言区”写下你的答案,学习过程中遇到的问题和思考也欢迎多多分享,我依然会在这里回复你的留言,和你一起讨论。
|
||||
|
||||
我知道你肯定也很好奇我对这些问题的思考是怎样的,因此,我针对每一节课后的第一道思考题及留言区比较有代表性的、有深度的问题,特意写了一系列答疑文章。
|
||||
|
||||
我再强调一遍,对于这一系列的答疑文章,你一定要在自己进行深度思考之后,再来看文章对比答案,这样可以更有效地拓展你的知识边界。
|
||||
|
||||
点击查看:
|
||||
|
||||
[第一期:第1讲至第2讲答疑解惑合辑](https://time.geekbang.org/column/article/13520)
|
||||
|
||||
[第二期:第3讲至第6讲答疑解惑合辑](https://time.geekbang.org/column/article/13847)
|
||||
|
||||
[第三期:第7讲至第13讲答疑解惑合辑](https://time.geekbang.org/column/article/14028)
|
||||
|
||||
[第四期:第14讲至第21讲答疑解惑合辑](https://time.geekbang.org/column/article/14194)
|
||||
|
||||
[第五期:第22讲至第36讲答疑解惑合辑](https://time.geekbang.org/column/article/14381)
|
||||
|
||||
## 3. 知识串讲
|
||||
|
||||
在学习完前面36讲的内容之后,我详细讲解了一个“下单”的过程。我把这个过程分为十个阶段,从云平台中搭建一个电商开始,到BGP路由广播,再到DNS域名解析;从客户看商品图片,到最终下单的整个过程,每个步骤我都画了详细的分解图。
|
||||
|
||||
你可以用这个过程,串起我们讲过的所有网络协议,还原真实的使用场景,学以致用。我相信,学完前面的详细内容之后,再来看这个串讲内容,你对网络协议一定会有一个全面、深入的把握。
|
||||
|
||||
点击查看:
|
||||
|
||||
[知识串讲(上篇)](https://time.geekbang.org/column/article/12991)
|
||||
|
||||
[知识串讲(中篇)](https://time.geekbang.org/column/article/12996)
|
||||
|
||||
[知识串讲(下篇)](https://time.geekbang.org/column/article/13099)
|
||||
|
||||
## 4. 知识图谱
|
||||
|
||||
专栏中最精华的内容,我都整理在这张图上了。
|
||||
|
||||
点击查看:[网络协议知识图谱](https://time.geekbang.org/column/article/14905)
|
||||
|
||||
## 5. 实验环境
|
||||
|
||||
纸上得来终觉浅。网络是一门实验性很强的学科,我在写专栏的过程中也深深体会到了。有时候,遇到疑问,我常常会拿一个现实的环境,上手操作一下,抓个包看看,这样心里就会有定论。
|
||||
|
||||
网络方面最权威的书籍《TCP/IP详解》([TCP/IP illustrated](https://book.douban.com/subject/1741925/))的作者斯蒂文森(W. Richard Stevens),也是经过无数次实验,才完成这本巨著。
|
||||
|
||||
因此,我在这本书中的实验基础上,带你搭建一个实验环境,希望你能够上手操作一下学过的知识。毕竟,只有经过你自己动手和思考产生的内容,才是真正属于你的知识。
|
||||
|
||||
点击查看我搭建实验环境时候的具体操作,希望给你的思维晋升指路:[《搭建一个网络实验环境:授人以鱼不如授人以渔》](https://time.geekbang.org/column/article/13124)
|
||||
|
||||
## 6. 专栏音频
|
||||
|
||||
我在这里想特别提一下专栏音频。我的每篇专栏文章都包含了很多图片,为了帮助你更好地理解文章内容,我在录音的时候,常常会对图片做一些补充解释和说明,所以音频和文字稿并非完全一一对应。不知道你具体的学习习惯是怎样的,我建议你除了阅读文字以外,一定要听一下音频,可以利用“**倍速播放**”的功能,还可以自由把控播放速度,更高效地学习。
|
||||
|
||||
## 7. 记录,高效;分享,快乐
|
||||
|
||||
我们专栏还有不少功能,提醒你好好利用起来,成为高效的学习者。
|
||||
|
||||
比如,在学习的过程中,遇到自己不懂的地方,或者是有深刻感受的地方,一定要及时利用“**划线笔记**”的功能,记录下自己当时的想法。这样在过程中点滴积累,等学完后,还可以回过头来再过一遍。如果有可能,你可以把自己的这些思考梳理成文。相信我,这样做,你的提升速度会快到让自己意外。
|
||||
|
||||
再比如“**请朋友读**”功能。如果你觉得某篇内容对自己很有帮助,不妨把它推荐给身边有同样需求的朋友,这一个动作或许就能帮他解决一个手边的问题。最重要的是,通过这些分享,你会找到那些和你一样热爱学习的伙伴,一起学习更快乐。
|
||||
|
||||
最后,还有一个小小的彩蛋。我把自己这半年写专栏的经历,写成了一篇文章。我是如何写专栏中每一篇文章的?每一篇音频又是如何录出来的?创作专栏给我带来了哪些改变?带你走进“**极客时间万人专栏**”背后的创作故事。
|
||||
|
||||
点击查看:[我是如何创作“趣谈网络协议”专栏的?](https://time.geekbang.org/column/article/17846)
|
209
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第一期.md
Normal file
209
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第一期.md
Normal file
@@ -0,0 +1,209 @@
|
||||
<audio id="audio" title="协议专栏特别福利 | 答疑解惑第一期" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/75/5b/757ec1a4f577ec091171aeffda08885b.mp3"></audio>
|
||||
|
||||
你好,我是刘超。
|
||||
|
||||
首先,感谢大家关注并在留言区写下近3000条留言。留言太多,没有及时回复,一是每周写三篇文章压力真的挺大的。为了保质保量地产出,晚上和周末的时间基本上都搭进去了。二是很多人的留言非常有深度,水平很高,提的问题一两句话解释不清楚。
|
||||
|
||||
每一节结尾我基本都会留两个思考题,其中第一个问题是启发思考的,是对本节内容的延伸学习;第二个问题是为了引出下一节,下一节的内容其实就是答案。
|
||||
|
||||
所以我会回答一下每一节的第一个问题,并列出第一个同我的思路最相近的同学,并对留言中比较有代表性的问题,做一个统一的回答,顺便也实现之前要送知识图谱和奖励礼券的承诺。
|
||||
|
||||
当然,这并不能说明我的回答就是一定是正确的或者全面的,有很多同学的留言有非常大的信息量,甚至更广的思路,也对这些同学表示感谢。还有些同学指出了我的错误,也感谢你们。
|
||||
|
||||
### [《第1讲 | 为什么要学习网络协议?》](https://time.geekbang.org/column/article/7581)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
当网络包到达一个城关的时候,可以通过路由表得到下一个城关的 IP 地址,直接通过 IP地址找就可以了,为什么还要通过本地的MAC地址呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/16/69/16e0b76fe90ce10d8e5c16cad0010e69.png" alt="">
|
||||
|
||||
徐良红同学说的比较接近。在网络包里,有源IP地址和目标IP地址、源MAC地址和目标MAC地址。从路由表中取得下一跳的IP地址后,应该把这个地址放在哪里呢?如果放在目标IP地址里面,到了城关,谁知道最终的目标在哪里呢?所以要用MAC地址。
|
||||
|
||||
所谓的下一跳,看起来是IP地址,其实是要通过ARP得到MAC地址,将下一跳的MAC地址放在目标MAC地址里面。
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.MAC地址可以修改吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/b3/1b/b3591518b266a3558f9dd61061c6271b.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/3a/5d/3abde3f5607b0278cc87ccfadb88875d.png" alt="">
|
||||
|
||||
我查了一下,MAC(Media Access Control,介质访问控制)地址,也叫硬件地址,长度是48比特(6字节),由16进制的数字组成,分为前24位和后24位。
|
||||
|
||||
前24位叫作**组织唯一标志符**(Organizationally Unique Identifier,OUI),是由IEEE的注册管理机构给不同厂家分配的代码,用于区分不同的厂家。后24位是厂家自己分配的,称为**扩展标识符**。同一个厂家生产的网卡中MAC地址后24位是不同的。
|
||||
|
||||
也就是说,MAC本来设计为唯一性的,但是后来设备越来越多,而且还有虚拟化的设备和网卡,有很多工具可以修改,就很难保证不冲突了。但是至少应该保持一个局域网内是唯一的。
|
||||
|
||||
MAC的设计,使得即便不能保证绝对唯一,但是能保证一个局域网内出现冲突的概率很小。这样,一台机器启动的时候,就能够在没有IP地址的情况下,先用MAC地址进行通信,获得IP地址。
|
||||
|
||||
好在MAC地址是工作在一个局域网中的,因而即便出现了冲突,网络工程师也能够在自己的范围内很快定位并解决这个问题。这就像我们生成UUID或者哈希值,大部分情况下是不会冲突的,但是如果碰巧出现冲突了,采取一定的机制解决冲突就好。
|
||||
|
||||
2.TCP重试有没有可能导致重复下单?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ce/71/ced92fc92921a47918704f1657fb2771.png" alt="">
|
||||
|
||||
答案是不会的。这个在[TCP](https://time.geekbang.org/column/article/8975)那一节有详细的讲解。因为TCP层收到了重复包之后,TCP层自己会进行去重,发给应用层、HTTP层。还是一个唯一的下单请求,所以不会重复下单。
|
||||
|
||||
那什么时候会导致重复下单呢?因为网络原因或者服务端错误,导致TCP连接断了,这样会重新发送应用层的请求,也即HTTP的请求会重新发送一遍。
|
||||
|
||||
如果服务端设计的是无状态的,它记不住上一次已经发送了一次请求。如果处理不好,就会导致重复下单,这就需要服务端除了实现无状态,还需要根据传过来的订单号实现幂等,同一个订单只处理一次。
|
||||
|
||||
还会有的现象是请求被黑客拦截,发送多次,这在HTTPS层可以有很多种机制,例如通过 Timestamp和Nonce随机数联合起来,然后做一个不可逆的签名来保证。
|
||||
|
||||
3.TCP报平安的包是原路返回吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/36/ac/361fee74d932bac74f0b26bb280bf2ac.png" alt="">
|
||||
|
||||
谢谢语鬼同学的指正。这里的比喻不够严谨,容易让读者产生误会,这里的原路返回的意思是原样返回,也就是返回也是这个过程,不一定是完全一样的路径。
|
||||
|
||||
4.IP地址和MAC地址的关系?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/9c/e3/9c359d2c20ab3f77f5a7e87dcb6fd7e3.png" alt="">
|
||||
|
||||
芒果同学的理解非常准确,讲[IP和MAC的关系](https://time.geekbang.org/column/article/7772)的时候说了这个问题。IP是有远程定位功能的,MAC是没有远程定位功能的,只能通过本地ARP的方式找到。
|
||||
|
||||
我个人认为,即便有了IPv6,也不会改变当前的网络分层模式,还是IP层解决远程定位问题,只不过改成IPv6了,到了本地,还是通过MAC。
|
||||
|
||||
5.如果最后一跳的时候,IP改变了怎么办?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/08/c1/08029e8c3dce6413558c4819b380c5c1.png" alt="">
|
||||
|
||||
对于IP层来讲,当包到达最后一跳的时候,原来的IP不存在了。比如网线拔掉了,或者服务器直接宕机了,则ARP就找不到了,所以这个包就会发送失败了。对于IP层的工作就结束了。
|
||||
|
||||
但是IP层之上还有TCP层,TCP会重试的,包还是会重新发送,但是如果服务器没有启动起来,超过一定的次数,最终放弃。
|
||||
|
||||
如果服务器重启了,IP还是原来的IP地址,这个时候TCP重新发送的一个包的时候,ARP是能够得到这个地址的,因而会发到这台机器上来,但是机器上面没有启动服务端监听那个端口,于是会发送ICMP端口不可达。
|
||||
|
||||
如果服务器重启了,服务端也重新启动了,也在监听那个端口了,这个时候TCP的服务端由于是新的,Sequence Number根本对不上,说明不是原来的连接,会发送RST。
|
||||
|
||||
那有没有可能有特殊的场景Sequence Number也能对的上呢?按照Sequence Number的生成算法,是不可能的。
|
||||
|
||||
但是有一个非常特殊的方式,就是虚拟机的热迁移,从一台物理机迁移到另外一台物理机,IP不变,MAC不变,内存也拷贝过去,Sequence Number在内存里面也保持住了,在迁移的过程中会丢失一两个包,但是从TCP来看,最终还是能够连接成功的。
|
||||
|
||||
6.TCP层报平安,怎么确认浏览器收到呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/f3/48/f39ceca92d67db24b42ef9d31f9bff48.png" alt="">
|
||||
|
||||
TCP报平安,只能保证TCP层能够收到,不保证浏览器能够收到。但是可以想象,如果浏览器是你写的一个程序,你也是通过socket编程写的,你是通过socket,建立一个TCP的连接,然后从这个连接里面读取数据,读取的数据就是TCP层确认收到的。
|
||||
|
||||
这个读取的动作是本地系统调用,大部分情况下不会失败的。如果读取失败呢,当然本地会报错,你的socket读取函数会返回错误,如果你是浏览器程序的实现者,你有两种选择,一个是将错误报告给用户,另一个是重新发送一次请求,获取结果显示给用户。
|
||||
|
||||
7.ARP协议属于哪一层?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/e7/9f/e77d85e7260df7611b90a45b7e77ce9f.png" alt="">
|
||||
|
||||
ARP属于哪个层,一直是有争议的。比如《TCP/IP详解》把它放在了二层和三层之间,但是既然是协议,只要大家都遵守相同的格式、流程就可以了,在实际应用的时候,不会有歧义的,唯一有歧义的是参加各种考试,让你做选择题,ARP属于哪一层?平时工作中咱不用纠结这个。
|
||||
|
||||
## [《第2讲 | 网络分层的真实含义是什么?》](https://time.geekbang.org/column/article/7724)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
如果你也觉得总经理和员工的比喻不恰当,你有更恰当的比喻吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/21/27/21cd2dba241413bcfc5bb74fc8dd2527.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/3b/3e/3b69f685c893bfd6746ef03c395e8e3e.png" alt="">
|
||||
|
||||
我觉得,寄快递和寄信这两个比喻都挺好的。关键是有了封装和解封装的过程。有的同学举了爬楼,或者公司各层之间的沟通,都无法体现封装和解封装的过程。
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.为什么要分层?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/4d/92/4d6c7f391ca5a55fdde3dbf62d69ab92.png" alt="">
|
||||
|
||||
是的,仅仅用复杂性来解释分层,太过牵强了。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/85/78/856b8040cd0a9f2206ad6f27ad3e9078.png" alt="">
|
||||
|
||||
其实这是一个架构设计的通用问题,不仅仅是网络协议的问题。一旦涉及到复杂的逻辑,或者软件需求需要经常变动,一般都会通过分层来解决问题。
|
||||
|
||||
假如我们将所有的代码都写在一起,但是产品经理突然想调整一下界面,这背后的业务逻辑变不变,那要不要一起修改呢?所以会拆成两层,把UI层从业务逻辑中分离出来,调用API来进行组合。API不变,仅仅界面变,是不是就不影响后台的代码了?
|
||||
|
||||
为什么要把一些原子的API放在基础服务层呢?将数据库、缓存、搜索引擎等,屏蔽到基础服务层以下,基础服务层之上的组合逻辑层、API层都只能调用基础服务层的API,不能直接访问数据库。
|
||||
|
||||
比如我们要将Oracle切换成MySQL。MySQL有一个库,分库分表成为4个库。难道所有的代码都要修改吗?当然只要把基础服务层屏蔽,提供一致的接口就可以了。
|
||||
|
||||
网络协议也是这样的。有的想基于TCP,自己不操心就能够保证到达;有的想自己实现可靠通信,不基于TCP,而使用UDP。一旦分了层就好办了,定制化后要依赖于下一层的接口,只要实现自己的逻辑就可以了。如果TCP的实现将所有的逻辑耦合在了整个七层,不用TCP的可靠传输机制都没有办法。
|
||||
|
||||
2.层级之间真实的调用方式是什么样的?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/95/57/95510f25eb463c4302fb58bd518a8957.png" alt="">
|
||||
|
||||
如果文中是一个逻辑图,这个问题其实已经到实现层面上来了,需要看TCP/IP的协议栈代码了。这里首先推荐一本书《深入理解Linux网络技术内幕》。
|
||||
|
||||
其实下层的协议知道上层协议的,因为在每一层的包头里面,都会有上一层是哪个协议的标识,所以不是一个回调函数,每一层的处理函数都会在操作系统启动的时候,注册到内核的一个数据结构里面,但是到某一层的时候,是通过判断到底是哪一层的哪一个协议,然后去找相应的处理函数去调用。
|
||||
|
||||
调用的大致过程我这里再讲一下。由于TCP比较复杂,我们以UDP为例子,其实发送的包就是一个sk_buff结构。这个在[Socket](https://time.geekbang.org/column/article/9293)那一节讲过。
|
||||
|
||||
```
|
||||
int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
|
||||
|
||||
```
|
||||
|
||||
接着,UDP层会调用IP层的函数。
|
||||
|
||||
```
|
||||
int ip_send_skb(struct net *net, struct sk_buff *skb)
|
||||
|
||||
```
|
||||
|
||||
然后,IP层通过路由判断,最终将包发给下一层。
|
||||
|
||||
```
|
||||
int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
```
|
||||
|
||||
发送的时候,要进行ARP。如果有MAC,则调用二层的函数,neigh其实就是邻居系统,是二层的意思。
|
||||
|
||||
```
|
||||
int neigh_output(struct neighbour *n, struct sk_buff *skb)
|
||||
|
||||
```
|
||||
|
||||
接收的时候,会调用这里的接收函数。
|
||||
|
||||
```
|
||||
int netif_receive_skb(struct sk_buff *skb)
|
||||
|
||||
```
|
||||
|
||||
这个函数会根据是ARP或者IP等,选择调用不同的函数。如果是IP协议的话,就调用这里的函数。
|
||||
|
||||
```
|
||||
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
|
||||
|
||||
```
|
||||
|
||||
这里也有路由判断。如果是本地的,则继续往上提交这个结构。
|
||||
|
||||
```
|
||||
int ip_local_deliver(struct sk_buff *skb)
|
||||
|
||||
```
|
||||
|
||||
接着,还是根据IP头里面的协议号,来判断是什么协议,从而调用什么函数。下面这个是对UDP的调用。
|
||||
|
||||
```
|
||||
int udp_rcv(struct sk_buff *skb)
|
||||
|
||||
```
|
||||
|
||||
3.什么情况下会有下层没上层?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/f6/c3/f6414085ec89ba0dfae79436aad2b2c3.png" alt="">
|
||||
|
||||
有时候我们自己写应用的时候,不一定是直接调用应用层协议的接口,例如HTTP等,而是自己写Socket编程,来约定应用层的协议。再如,ping也是一个应用,但是它没有用传输层的协议,而是用了ICMP的协议。
|
||||
|
||||
最后,感谢留言次数前15名的同学,谢谢你们持之以恒的学习,相信你们一定有自己的收获。(统计数据截止到2018年8月8日)
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ca/91/caeec16c4e959e250da1db6c6543b791.jpg" alt="">
|
||||
|
||||
同时感谢第1讲、第2讲中对内容有深度思考和提出问题的同学。我会为你们送上奖励礼券和知识图谱。(稍后运营同学会发送短信通知。)
|
||||
|
||||
欢迎你继续提问!
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/00/5b/0057c2d7c99924366c94c5ed58e3385b.jpg" alt="">
|
368
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第三期.md
Normal file
368
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第三期.md
Normal file
@@ -0,0 +1,368 @@
|
||||
<audio id="audio" title="协议专栏特别福利 | 答疑解惑第三期" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/6a/17/6a6883051cf676be036547a1f2b47f17.mp3"></audio>
|
||||
|
||||
你好,我是刘超。
|
||||
|
||||
第三期答疑涵盖第7讲至第13讲的内容。我依旧对课后思考题和留言中比较有代表性的问题作出回答。你可以点击文章名,回到对应的章节复习,也可以继续在留言区写下你的疑问,我会持续不断地解答。希望对你有帮助。
|
||||
|
||||
## [《](https://time.geekbang.org/column/article/8445)[第7讲 | ICMP与ping:投石问路的侦察兵](https://time.geekbang.org/column/article/8445)[》](https://time.geekbang.org/column/article/8445)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
当发送的报文出问题的时候,会发送一个ICMP的差错报文来报告错误,但是如果 ICMP 的差错报文也出问题了呢?
|
||||
|
||||
我总结了一下,不会导致产生ICMP差错报文的有:
|
||||
|
||||
<li>
|
||||
ICMP差错报文(ICMP查询报文可能会产生ICMP差错报文);
|
||||
</li>
|
||||
<li>
|
||||
目的地址是广播地址或多播地址的IP数据报;
|
||||
</li>
|
||||
<li>
|
||||
作为链路层广播的数据报;
|
||||
</li>
|
||||
<li>
|
||||
不是IP分片的第一片;
|
||||
</li>
|
||||
<li>
|
||||
源地址不是单个主机的数据报。这就是说,源地址不能为零地址、环回地址、广播地址或多播地址。
|
||||
</li>
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.ping使用的是什么网络编程接口?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/3b/e6/3b2b3f4abaed8a485e8933efbcc304e6.png" alt="">
|
||||
|
||||
咱们使用的网络编程接口是Socket,对于ping来讲,使用的是ICMP,创建Socket如下:
|
||||
|
||||
```
|
||||
socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
|
||||
|
||||
```
|
||||
|
||||
SOCK_RAW就是基于IP层协议建立通信机制。
|
||||
|
||||
如果是TCP,则建立下面的Socket:
|
||||
|
||||
```
|
||||
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
|
||||
|
||||
```
|
||||
|
||||
如果是UDP,则建立下面的Socket:
|
||||
|
||||
```
|
||||
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||
|
||||
```
|
||||
|
||||
2.ICMP差错报文是谁发送的呢?
|
||||
|
||||
我看留言里有很多人对这个问题有疑惑。ICMP包是由内核返回的,在内核中,有一个函数用于发送ICMP的包。
|
||||
|
||||
```
|
||||
void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
|
||||
|
||||
```
|
||||
|
||||
例如,目标不可达,会调用下面的函数。
|
||||
|
||||
```
|
||||
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0);
|
||||
|
||||
```
|
||||
|
||||
当IP大小超过MTU的时候,发送需要分片的ICMP。
|
||||
|
||||
```
|
||||
if (ip_exceeds_mtu(skb, mtu)) {
|
||||
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
|
||||
goto drop;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## [《第8讲 | 世界这么大,我想出网关:欧洲十国游与玄奘西行》](https://time.geekbang.org/column/article/8590)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
当在你家里要访问 163 网站的时候,你的包需要 NAT 成为公网 IP,返回的包又要 NAT 成你的私有 IP,返回包怎么知道这是你的请求呢?它怎么能这么智能地 NAT 成了你的 IP 而非别人的 IP 呢?
|
||||
|
||||
这是个比较复杂的事情。在讲云中网络安全里的iptables时,我们讲过conntrack功能,它记录了SNAT一去一回的对应关系。
|
||||
|
||||
如果编译内核时开启了连接跟踪选项,那么Linux系统就会为它收到的每个数据包维持一个连接状态,用于记录这条数据连接的状态。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/a9/fc/a924ccda5d54bcad6f67fdebe0a6c1fc.jpg" alt="">
|
||||
|
||||
根据咱们学过的Netfilter的流程图,我们知道,网络包有三种路径:
|
||||
|
||||
<li>
|
||||
发给我的,从PREROUTING到INPUT,我就接收了;
|
||||
</li>
|
||||
<li>
|
||||
我发给别人的,从OUTPUT到POSTROUTING,就发出去的;
|
||||
</li>
|
||||
<li>
|
||||
从我这里经过的,从PREROUTING到FORWARD到POSTROUTING。
|
||||
</li>
|
||||
|
||||
如果要跟踪一个网络包,对于每一种路径,都需要设置两个记录点,相当于打两次卡,这样内核才知道这个包的状态。
|
||||
|
||||
对于这三种路径,打卡的点是这样设置的:
|
||||
|
||||
<li>
|
||||
发给我的,在PREROUTING调用ipv4_conntrack_in,创建连接跟踪记录;在INPUT调用ipv4_confirm,将这个连接跟踪记录挂在内核的连接跟踪表里面。为什么不一开始就挂在内核的连接跟踪表里面呢?因为有filter表,一旦把包过滤了,也就是丢弃了,那根本没必要记录这个连接了。
|
||||
</li>
|
||||
<li>
|
||||
我发给别人的,在OUTPUT调用ipv4_conntrack_local,创建连接跟踪记录,在POSTROUTING调用ipv4_confirm,将这个连接跟踪记录挂在内核的连接跟踪表里面。
|
||||
</li>
|
||||
<li>
|
||||
从我这里经过的,在PREROUTING调用ipv4_conntrack_in,创建连接跟踪记录,在POSTROUTING调用ipv4_confirm,将这个连接跟踪记录挂在内核的连接跟踪表里面。
|
||||
</li>
|
||||
|
||||
网关主要做转发,这里主要说的是NAT网关,因而我们重点来看“从我这里经过的”这种场景,再加上要NAT,因而将NAT的过程融入到连接跟踪的过程中来:
|
||||
|
||||
<li>
|
||||
如果是PREROUTING的时候,先调用ipv4_conntrack_in,创建连接跟踪记录;
|
||||
</li>
|
||||
<li>
|
||||
如果是PREROUTING的时候,有NAT规则,则调用nf_nat_ipv4_in进行地址转换;
|
||||
</li>
|
||||
<li>
|
||||
如果是POSTROUTING的时候,有NAT规则,则调用nf_nat_ipv4_out进行地址转换;
|
||||
</li>
|
||||
<li>
|
||||
如果是POSTROUTING的时候,调用ipv4_confirm,将这个连接跟踪记录挂在内核的连接跟踪表里面。
|
||||
</li>
|
||||
|
||||
接下来,我们来看,在这个过程中涉及到的数据结构:连接跟踪记录、连接跟踪表。
|
||||
|
||||
在前面讲网络包处理的时候,我们说过,每个网络包都是一个struct sk_buff,它有一个成员变量_nfct指向一个连接跟踪记录struct nf_conn。当然当一个网络包刚刚进来的时候,是不会指向这么一个结构的,但是这个网络包肯定属于某个连接,因而会去连接跟踪表里面去查找,之后赋值给sk_buff的这个成员变量。没找到的话,就说明是一个新的连接,然后会重新创建一个。
|
||||
|
||||
连接跟踪记录里面有几个重要的东西:
|
||||
|
||||
<li>
|
||||
nf_conntrack其实才是_nfct变量指向的地址,但是没有关系,学过C++的话应该明白,对于结构体来讲,nf_conn和nf_conntrack的起始地址是一样的;
|
||||
</li>
|
||||
<li>
|
||||
tuplehash虽然是数组,但是里面只有两个,IP_CT_DIR_ORIGINAL为下标0,表示连接的发起方向,IP_CT_DIR_REPLY为下标1,表示连接的回复方向。
|
||||
</li>
|
||||
|
||||
```
|
||||
struct nf_conn {
|
||||
......
|
||||
struct nf_conntrack ct_general;
|
||||
......
|
||||
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
|
||||
......
|
||||
unsigned long status;
|
||||
......
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
在这里面,最重要的是nf_conntrack_tuple_hash的数组。nf_conn是这个网络包对应的一去一回的连接追踪记录,但是这个记录是会放在一个统一的连接追踪表里面的。
|
||||
|
||||
连接跟踪表nf_conntrack_hash是一个数组,数组中的每一项都是一个双向链表的头,每一项后面都挂着一个双向链表,链表中的每一项都是这个结构。
|
||||
|
||||
这个结构的第一项是链表的链,nf_conntrack_tuple是用来标识是否同一个连接。
|
||||
|
||||
从上面可以看出来,连接跟踪表是一个典型的链式哈希表的实现。
|
||||
|
||||
每当有一个网络包来了的时候,会将网络包中sk_buff中的数据提取出来,形成nf_conntrack_tuple,并根据里面的内容计算哈希值。然后需要在哈希表中查找,如果找到,则说明这个连接出现过;如果没找到,则生成一个插入哈希表。
|
||||
|
||||
通过nf_conntrack_tuple里面的内容,可以唯一地标识一个连接:
|
||||
|
||||
<li>
|
||||
src:包含源IP地址;如果是TCP或者UDP,包含源端口;如果是ICMP,包含的是ID;
|
||||
</li>
|
||||
<li>
|
||||
dst:包含目标IP地址;如果是TCP或者UDP,包含目标端口;如果是ICMP,包含的是type, code。
|
||||
</li>
|
||||
|
||||
有了这些数据结构,我们接下来看这一去一回的过程。
|
||||
|
||||
当一个包发出去的时候,到达这个NAT网关的时候,首先经过PREROUTING的时候,先调用ipv4_conntrack_in。这个时候进来的包sk_buff为: {源IP:客户端IP,源端口:客户端port,目标IP:服务端IP,目标端口:服务端port},将这个转换为nf_conntrack_tuple,然后经过哈希运算,在连接跟踪表里面查找,发现没有,说明这是一个新的连接。
|
||||
|
||||
于是,创建一个新的连接跟踪记录nf_conn,这里面有两个nf_conntrack_tuple_hash:
|
||||
|
||||
<li>
|
||||
一去:{源IP:客户端IP,源端口:客户端port,目标IP:服务端IP,目标端口:服务端port};
|
||||
</li>
|
||||
<li>
|
||||
一回:{源IP:服务端IP,源端口:服务端port,目标IP:客户端IP,目标端口:客户端port}。
|
||||
</li>
|
||||
|
||||
接下来经过FORWARD过程,假设包没有被filter掉,于是要转发出去,进入POSTROUTING的过程,有NAT规则,则调用nf_nat_ipv4_out进行地址转换。这个时候,源地址要变成NAT网关的IP地址,对于masquerade来讲,会自动选择一个公网IP地址和一个随机端口。
|
||||
|
||||
为了让包回来的时候,能找到连接跟踪记录,需要修改两个nf_conntrack_tuple_hash中回来的那一项为:{源IP:服务端IP,源端口:服务端port,目标IP:NAT网关IP,目标端口:随机端口}。
|
||||
|
||||
接下来要将网络包真正发出去的时候,除了要修改包里面的源IP和源端口之外,还需要将刚才的一去一回的两个nf_conntrack_tuple_hash放入连接跟踪表这个哈希表中。
|
||||
|
||||
当网络包到达服务端,然后回复一个包的时候,这个包sk_buff为:{源IP:服务端IP,源端口:服务端port,目标IP:NAT网关IP,目标端口:随机端口}。
|
||||
|
||||
将这个转换为nf_conntrack_tuple后,进行哈希运算,在连接跟踪表里面查找,是能找到相应的记录的,找到nf_conntrack_tuple_hash之后,Linux会提供一个函数。
|
||||
|
||||
```
|
||||
static inline struct nf_conn *
|
||||
nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
|
||||
{
|
||||
return container_of(hash, struct nf_conn,
|
||||
tuplehash[hash->tuple.dst.dir]);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
可以通过nf_conntrack_tuple_hash找到外面的连接跟踪记录nf_conn,通过这个可以找到来方向的那个nf_conntrack_tuple_hash,{源IP:客户端IP,源端口:客户端port,目标IP:服务端IP,目标端口:服务端port},这样就能够找到客户端的IP和端口,从而可以NAT回去。
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.NAT能建立多少连接?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/3d/d6/3d9249834f730926c2b2f350aba6e1d6.png" alt="">
|
||||
|
||||
SNAT多用于内网访问外网的场景,鉴于conntrack是由{源IP,源端口,目标IP,目标端口},hash后确定的。
|
||||
|
||||
如果内网机器很多,但是访问的是不同的外网,也即目标IP和目标端口很多,这样内网可承载的数量就非常大,可不止65535个。
|
||||
|
||||
但是如果内网所有的机器,都一定要访问同一个目标IP和目标端口,这样源IP如果只有一个,这样的情况下,才受65535的端口数目限制,根据原理,一种方法就是多个源IP,另外的方法就是多个NAT网关,来分摊不同的内网机器访问。
|
||||
|
||||
如果你使用的是公有云,65535台机器,应该放在一个VPC里面,可以放在多个VPC里面,每个VPC都可以有自己的NAT网关。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/d0/8d/d08e3a727681751037f715c3f5bd398d.png" alt="">
|
||||
|
||||
其实SNAT的场景是内网访问外网,存在端口数量的问题,也是所有的机器都访问一个目标地址的情况。
|
||||
|
||||
如果是微信这种场景,应该是服务端在数据中心内部,无论多少长连接,作为服务端监听的都是少数几个端口,是DNAT的场景,是没有端口数目问题的,只有一台服务器能不能维护这么多连接,因而在NAT网关后面部署多个nginx来分摊连接即可。
|
||||
|
||||
2.公网IP和私网IP需要一一绑定吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/2d/f1/2d134e61e8cc945c71969be7391b3ff1.png" alt="">
|
||||
|
||||
公网IP是有限的,如果使用公有云,需要花钱去买。但是不是每一个虚拟机都要有一个公网IP的,只有需要对外提供服务的机器,也即接入层的那些nginx需要公网IP,没有公网IP,使用SNAT,大家共享SNAT网关的公网IP地址,也是能够访问的外网的。
|
||||
|
||||
我看留言中的困惑点都在于,要区分内主动发起访问外,还是外主动发起访问内,是访问同一个服务端,还是访问一大批服务端。这里就很明白了。
|
||||
|
||||
## [《第9讲 | 路由协议:西出网关无故人,敢问路在何方》](https://time.geekbang.org/column/article/8729)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
路由协议要在路由器之间交换信息,这些信息的交换还需要走路由吗?不是死锁了吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/b5/da/b5834f4f10c51cb8c91e570bf83f7eda.png" alt="">
|
||||
|
||||
OSPF是直接基于IP协议发送的,而且OSPF的包都是发给邻居的,也即只有一跳,不会中间经过路由设备。BGP是基于TCP协议的,在BGP peer之间交换信息。
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.多线BGP机房是怎么回事儿?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/18/cd/18040a74506276b23e672d2d818d37cd.png" alt="">
|
||||
|
||||
BGP主要用于互联网AS自治系统之间的互联,BGP的最主要功能在于**控制路由的传播**和**选择最好的路由**。各大运营商都具有AS号,全国各大网络运营商多数都是通过BGP协议与自身的AS来实现多线互联的。
|
||||
|
||||
使用此方案来实现多线路互联,IDC需要在CNNIC(中国互联网信息中心)或APNIC(亚太网络信息中心)申请自己的IP地址段和AS号,然后通过BGP协议将此段IP地址广播到其它的网络运营商的网络中。
|
||||
|
||||
使用BGP协议互联后,网络运营商的所有骨干路由设备将会判断到IDC机房IP段的最佳路由,以保证不同网络运营商用户的高速访问。
|
||||
|
||||
## [《第10讲 | UDP协议:因性善而简单,难免碰到“城会玩”》](https://time.geekbang.org/column/article/8924)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
都说 TCP 是面向连接的,在计算机看来,怎么样才算一个连接呢?
|
||||
|
||||
赵强强在留言中回答的是正确的。这是TCP的两端为了维护连接所保持的数据结构。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/3c/e1/3cba74151564c129057b2cd246a332e1.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/95/e0/9507374c04e0908f29d5a3050d905fe0.png" alt="">
|
||||
|
||||
|
||||
|
||||
## [《第11讲 | TCP协议(上):因性恶而复杂,先恶后善反轻松》](https://time.geekbang.org/column/article/8975)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
TCP 的连接有这么多的状态,你知道如何在系统中查看某个连接的状态吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/3c/d7/3c997ad09a1c72cbb32a992e7c9588d7.png" alt="">
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.TIME_WAIT状态太多是怎么回事儿?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/85/b8/8535df3de9f426b44def750330dcf2b8.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/1f/11/1f6a5e17b34f00d28722428b7b8ccb11.jpg" alt="">
|
||||
|
||||
如果处于TIMEWAIT状态,说明双方建立成功过连接,而且已经发送了最后的ACK之后,才会处于这个状态,而且是主动发起关闭的一方处于这个状态。
|
||||
|
||||
如果存在大量的TIMEWAIT,往往是因为短连接太多,不断的创建连接,然后释放连接,从而导致很多连接在这个状态,可能会导致无法发起新的连接。解决的方式往往是:
|
||||
|
||||
<li>
|
||||
打开tcp_tw_recycle和tcp_timestamps选项;
|
||||
</li>
|
||||
<li>
|
||||
打开tcp_tw_reuse和tcp_timestamps选项;
|
||||
</li>
|
||||
<li>
|
||||
程序中使用SO_LINGER,应用强制使用rst关闭。
|
||||
</li>
|
||||
|
||||
当客户端收到Connection Reset,往往是收到了TCP的RST消息,RST消息一般在下面的情况下发送:
|
||||
|
||||
<li>
|
||||
试图连接一个未被监听的服务端;
|
||||
</li>
|
||||
<li>
|
||||
对方处于TIMEWAIT状态,或者连接已经关闭处于CLOSED状态,或者重新监听seq num不匹配;
|
||||
</li>
|
||||
<li>
|
||||
发起连接时超时,重传超时,keepalive超时;
|
||||
</li>
|
||||
<li>
|
||||
在程序中使用SO_LINGER,关闭连接时,放弃缓存中的数据,给对方发送RST。
|
||||
</li>
|
||||
|
||||
2.起始序列号是怎么计算的,会冲突吗?
|
||||
|
||||
有同学在留言中问了几个问题。Ender0224的回答非常不错。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/af/47/afed5f0593647c0b64971c2fef7e4247.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c3/e1/c39c723c9389c4414401366a32b69fe1.jpg" alt="">
|
||||
|
||||
起始ISN是基于时钟的,每4毫秒加一,转一圈要4.55个小时。
|
||||
|
||||
TCP初始化序列号不能设置为一个固定值,因为这样容易被攻击者猜出后续序列号,从而遭到攻击。 RFC1948中提出了一个较好的初始化序列号ISN随机生成算法。
|
||||
|
||||
ISN = M + F (localhost, localport, remotehost, remoteport)
|
||||
|
||||
M是一个计时器,这个计时器每隔4毫秒加1。F是一个Hash算法,根据源IP、目的IP、源端口、目的端口生成一个随机数值。要保证Hash算法不能被外部轻易推算得出,用MD5算法是一个比较好的选择。
|
||||
|
||||
## [《第12讲 | TCP协议(下):西行必定多妖孽,恒心智慧消磨难》](https://time.geekbang.org/column/article/9141)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
TCP的BBR听起来很牛,你知道它是如何达到这个最优点的吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/33/03/33b035bd326e9c1f811d667104a54003.png" alt="">
|
||||
|
||||
## [《第13讲 | 套接字Socket:Talk is cheap, show me the code》](https://time.geekbang.org/column/article/9293)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
epoll是Linux上的函数,那你知道Windows上对应的机制是什么吗?如果想实现一个跨平台的程序,你知道应该怎么办吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/74/e9/74d6535a22f5dc8ab2f782b4484ca7e9.png" alt="">
|
||||
|
||||
epoll是异步通知,当事件发生的时候,通知应用去调用IO函数获取数据。IOCP异步传输,当事件发生时,IOCP机制会将数据直接拷贝到缓冲区里,应用可以直接使用。
|
||||
|
||||
如果跨平台,推荐使用libevent库,它是一个事件通知库,适用于Windows、Linux、BSD等多种平台,内部使用select、epoll、kqueue、IOCP等系统调用管理事件机制。
|
||||
|
||||
感谢第7讲至第13讲中对内容有深度思考和提出问题的同学。我会为你们送上奖励礼券和知识图谱。(稍后运营同学会发送短信通知。)
|
||||
|
||||
欢迎你继续提问!
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ed/57/edc42141381c0458ab65f70628e88557.jpg" alt="">
|
251
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第二期.md
Normal file
251
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第二期.md
Normal file
@@ -0,0 +1,251 @@
|
||||
<audio id="audio" title="协议专栏特别福利 | 答疑解惑第二期" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/03/c0/035030be01889cd02f5e909528650bc0.mp3"></audio>
|
||||
|
||||
你好,我是刘超。
|
||||
|
||||
第二期答疑涵盖第3讲至第6讲的内容。我依旧对课后思考题和留言中比较有代表性的问题作出回答。你可以点击文章名,回到对应的章节复习,也可以继续在留言区写下你的疑问,我会持续不断地解答。希望对你有帮助。
|
||||
|
||||
## [《第3讲 | ifconfig:最熟悉又陌生的命令行》](https://time.geekbang.org/column/article/7772)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
你知道 net-tools 和 iproute2 的“历史”故事吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/02/ba/02ae5ca5ab1c87bf5fea29196725c0ba.png" alt="">
|
||||
|
||||
这个问题的答案,盖同学已经写的比较全面了。具体的对比,我这里推荐一篇文章[https://linoxide.com/linux-command/use-ip-command-linux/](https://linoxide.com/linux-command/use-ip-command-linux/),感兴趣的话可以看看。
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.A、B、C类地址的有效地址范围是多少?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/eb/c5/ebf13d11cb0bc03d520c6cc4796ee8c5.png" alt="">
|
||||
|
||||
我在写的时候,没有考虑这么严谨,平时使用地址的时候,也是看个大概的范围。所以这里再回答一下。
|
||||
|
||||
A类IP的地址第一个字段范围是0~127,但是由于全0和全1的地址用作特殊用途,实际可指派的范围是1~126。所以我仔细查了一下,如果较真的话,你在答考试题的时候可以说,A类地址范围和A类有效地址范围。
|
||||
|
||||
2.网络号、IP地址、子网掩码和广播地址的先后关系是什么?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/25/56/254f28a3623ca8b4ee368ac02f0cf656.png" alt="">
|
||||
|
||||
当在一个数据中心或者一个办公室规划一个网络的时候,首先是网络管理员规划网段,一般是根据将来要容纳的机器数量来规划,一旦定了,以后就不好变了。
|
||||
|
||||
假如你在一个小公司里,总共就没几台机器,对于私有地址,一般选择192.168.0.0/24就可以了。
|
||||
|
||||
这个时候先有的是网络号。192.168.0就是网络号。有了网络号,子网掩码同时也就有了,就是前面都是网络号的是1,其他的是0,广播地址也有了,除了网络号之外都是1。
|
||||
|
||||
当规划完网络的时候,一般这个网络里面的第一个、第二个地址被默认网关DHCP服务器占用,你自己创建的机器,只要和其他的不冲突就可以了,当然你也可以让DHCP服务自动配置。
|
||||
|
||||
规划网络原来都是网络管理员的事情。有了公有云之后,一般有个概念虚拟网络(VPC),鼠标一点就能创建一个网络,网络完全软件化了,任何人都可以做网络规划。
|
||||
|
||||
3.组播和广播的意义和原理是什么?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/92/f1/92654ed9549bba6c4e609e256ba083f1.png" alt="">
|
||||
|
||||
C类地址的主机号8位,去掉0和255,就只有254个了。
|
||||
|
||||
在《TCP/IP详解》这本书里面,有两章讲了广播、多播以及IGMP。广播和组播分为两个层面,其中MAC层有广播和组播对应的地址,IP层也有自己的广播地址和组播地址。
|
||||
|
||||
广播相对比较简单,MAC层的广播为ff:ff:ff:ff:ff:ff,IP层指向子网的广播地址为主机号为全1且有特定子网号的地址。
|
||||
|
||||
组播复杂一些,MAC层中,当地址中最高字节的最低位设置为1时,表示该地址是一个组播地址,用十六进制可表示为01:00:00:00:00:00。IP层中,组播地址为D类IP地址,当IP地址为组播地址的时候,有一个算法可以计算出对应的MAC层地址。
|
||||
|
||||
多播进程将目的IP地址指明为多播地址,设备驱动程序将它转换为相应的以太网地址,然后把数据发送出去。这些接收进程必须通知它们的IP层,它们想接收的发给定多播地址的数据报,并且设备驱动程序必须能够接收这些多播帧。这个过程就是“加入一个多播组”。
|
||||
|
||||
当多播跨越路由器的时候,需要通过IGMP协议告诉多播路由器,多播数据包应该如何转发。
|
||||
|
||||
4.MTU 1500的具体含义是什么?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/0b/3d/0b43a6d8c1b77daef705e6b08f40a43d.png" alt="">
|
||||
|
||||
MTU(Maximum Transmission Unit,最大传输单元)是二层的一个定义。以以太网为例,MTU为1500个Byte,前面有6个Byte的目标MAC地址,6个Byte的源MAC地址,2个Byte的类型,后面有4个Byte的CRC校验,共1518个Byte。
|
||||
|
||||
在IP层,一个IP数据报在以太网中传输,如果它的长度大于该MTU值,就要进行分片传输。如果不允许分片DF,就会发送ICMP包,这个在[ICMP](https://time.geekbang.org/column/article/8445)那一节讲过。
|
||||
|
||||
在TCP层有个MSS(Maximum Segment Size,最大分段大小),它等于MTU减去IP头,再减去TCP头。即在不分片的情况下,TCP里面放的最大内容。
|
||||
|
||||
在HTTP层看来,它的body没有限制,而且在应用层看来,下层的TCP是一个流,可以一直发送,但其实是会被分成一个个段的。
|
||||
|
||||
## [《第4讲 | DHCP与PXE:IP是怎么来的,又是怎么没的》](https://time.geekbang.org/column/article/8015)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
PXE 协议可以用来安装操作系统,但是如果每次重启都安装操作系统,就会很麻烦。你知道如何使得第一次安装操作系统,后面就正常启动吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/8d/c2/8db1eca548b4eaacfd9fbbb544a467c2.png" alt="">
|
||||
|
||||
|
||||
|
||||
一般如果咱们手动安装一台电脑的时候,都是有启动顺序的,如果改为硬盘启动,就没有问题了。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/05/cc/053273db99e6ef2458fcf48a534ac4cc.png" alt="">
|
||||
|
||||
好在服务器一般都提供IPMI接口,可以通过这个接口启动、重启、设置启动模式等等远程访问,这样就可以批量管理一大批机器。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/8f/09/8f423b7215d40642f8c712250b65b709.png" alt="">
|
||||
|
||||
|
||||
|
||||
这里提到Cobbler,这是一个批量安装操作系统的工具。在OpenStack里面,还有一个Ironic,也是用来管理裸机的。有兴趣的话可以研究一下。
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.在DHCP网络里面,手动配置IP地址会冲突吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/6c/bc/6cd736774a770fe0ca5e6d42ad3425bc.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/62/d0/62b7fbe964db964060d501e3ef5252d0.png" alt="">
|
||||
|
||||
|
||||
|
||||
在一个DHCP网络里面,如果某一台机器手动配置了一个IP地址,并且在DHCP管理的网段里的话,DHCP服务器是会将这个地址分配给其他机器的。一旦分配了,ARP的时候,就会收到两个应答,IP地址就冲突了。
|
||||
|
||||
当发生这种情况的时候,应该怎么办呢?DHCP的过程虽然没有明确如何处理,但是DHCP的客户端和服务器都可以添加相应的机制来检测冲突。
|
||||
|
||||
如果由客户端来检测冲突,一般情况是,客户端在接受分配的IP之前,先发送一个ARP,看是否有应答,有就说明冲突了,于是发送一个DHCPDECLINE,放弃这个IP地址。
|
||||
|
||||
如果由服务器来检测冲突,DHCP服务器会发送ping,来看某个IP是否已经被使用。如果被使用了,它就不再将这个IP分配给其他的客户端了。
|
||||
|
||||
2.DHCP的Offer和ACK应该是单播还是广播呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/2c/b0/2c3c71b16ffca3442ffb60c36de8dcb0.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/a6/68/a6745f6d648ce8819976fed6fdc82468.png" alt="">
|
||||
|
||||
没心没肺 回答得很正确。
|
||||
|
||||
|
||||
|
||||
这个我们来看[DHCP的RFC](http://www.faqs.org/rfcs/rfc2131.html),我截了个图放在这儿:
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/5b/ba/5ba44ea86352594b78c30ce75cc123ba.jpg" alt="">
|
||||
|
||||
这里面说了几个问题。
|
||||
|
||||
正常情况下,一旦有了IP地址,DHCP Server还是希望通过单播的方式发送OFFER和ACK。但是不幸的是,有的客户端协议栈的实现,如果还没有配置IP地址,就使用单播。协议栈是不接收这个包的,因为OFFER和ACK的时候,IP地址还没有配置到网卡上。
|
||||
|
||||
所以,一切取决于客户端的协议栈的能力,如果没配置好IP,就不能接收单播的包,那就将BROADCAST设为1,以广播的形式进行交互。
|
||||
|
||||
如果客户端的协议栈实现很厉害,即便是没有配置好IP,仍然能够接受单播的包,那就将BROADCAST位设置为0,就以单播的形式交互。
|
||||
|
||||
3.DHCP如何解决内网安全问题?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/f7/8c/f7ff8bed68c94247a19772113d87e18c.png" alt="">
|
||||
|
||||
|
||||
|
||||
其实DHCP协议的设计是基于内网互信的基础来设计的,而且是基于UDP协议。但是这里面的确是有风险的。例如一个普通用户无意地或者恶意地安装一台DHCP服务器,发放一些错误或者冲突的配置;再如,有恶意的用户发出很多的DHCP请求,让DHCP服务器给他分配大量的IP。
|
||||
|
||||
对于第一种情况,DHCP服务器和二层网络都是由网管管理的,可以在交换机配置只有来自某个DHCP服务器的包才是可信的,其他全部丢弃。如果有SDN,或者在云中,非法的DHCP包根本就拦截到虚拟机或者物理机的出口。
|
||||
|
||||
对于第二种情况,一方面进行监控,对DHCP报文进行限速,并且异常的端口可以关闭,一方面还是SDN或者在云中,除了被SDN管控端登记过的IP和MAC地址,其他的地址是不允许出现在虚拟机和物理机出口的,也就无法模拟大量的客户端。
|
||||
|
||||
## [《第5讲 | 从物理层到MAC层:如何在宿舍里自己组网玩联机游戏?》](https://time.geekbang.org/column/article/8094)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
1.在二层中我们讲了 ARP 协议,即已知 IP 地址求 MAC;还有一种 RARP 协议,即已知 MAC 求 IP 的,你知道它可以用来干什么吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/e3/51/e3f91712382b9322beb02ec3d12ce851.png" alt="">
|
||||
|
||||
2.如果一个局域网里面有多个交换机,ARP 广播的模式会出现什么问题呢?
|
||||
|
||||
盖还说出了环路的问题。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/74/a8/74de5ae71807bd0ee3d95f44d7e82aa8.png" alt="">
|
||||
|
||||
没心没肺不但说明了问题,而且说明了方案。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/fa/a4/fa42fea4d9b4b8ed75008e3f1eadd7a4.png" alt="">
|
||||
|
||||
|
||||
|
||||
## [《第6讲 | 交换机与VLAN:办公室太复杂,我要回学校》](https://time.geekbang.org/column/article/8386)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
STP 协议能够很好地解决环路问题,但是也有它的缺点,你能举几个例子吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/b4/61/b4cb0842468ab9bb16916e9fb29ccb61.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ee/a1/eebc423ca8a37fbc3e7dfc06f07e4ea1.png" alt="">
|
||||
|
||||
|
||||
|
||||
STP的主要问题在于,当拓扑发生变化,新的配置消息要经过一定的时延才能传播到整个网络。
|
||||
|
||||
由于整个交换网络只有一棵生成树,在网络规模比较大的时候会导致较长的收敛时间,拓扑改变的影响面也较大,当链路被阻塞后将不承载任何流量,造成了极大带宽浪费。
|
||||
|
||||
## 留言问题
|
||||
|
||||
1.每台交换机的武力值是什么样的?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ae/51/ae72cc32931fc72918dd2f5da0ea9e51.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c2/d8/c24fe02c21f41449a3a896442bc3b4d8.png" alt="">
|
||||
|
||||
当一台交换机加入或者离开网络的时候,都会造成网络拓扑变化,这个时候检测到拓扑变化的网桥会通知根网桥,根网桥会通知所有的网桥拓扑发生变化。
|
||||
|
||||
网桥的ID是由网桥优先级和网桥MAC地址组成的,网桥ID最小的将成为网络中的根桥。默认配置下,网桥优先级都一样,默认优先级是32768。这个时候MAC地址最小的网桥成为根网桥。但是如果你想设置某台为根网桥,就配置更小的优先级即可。
|
||||
|
||||
在优先级向量里面,Root Bridge ID就是根网桥的ID,Bridge ID是网桥的ID,Port ID就是一个网桥上有多个端口,端口的ID。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c0/95/c04244bf0b91ae964871698e7811d695.png" alt="">
|
||||
|
||||
按照RFC的定义,ROOT PATH COST是和出口带宽相关的,具体的数据如下:
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/d6/b9/d606b2c9f636ea3bc5694ac95d51f7b9.jpg" alt="">
|
||||
|
||||
2.图中的LAN指的是什么?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/48/83/48efc105d54eff1ca6099e44df5c5a83.png" alt="">
|
||||
|
||||
在这一节中,这两张图引起了困惑。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/a5/85/a57a66bf97d326fd0b1355a0ba844e85.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/92/17/92450a4c1d7f261a3fbf06a12d621d17.png" alt="">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
本来是为了讲二层的原理,做了个抽象的图,结果引起了大家的疑问,所以这里需要重新阐述一下。
|
||||
|
||||
首先,这里的LAN1、LAN2、LAN 3的说法的确不准确,因为通过网桥或者交换机连接,它们还是属于一个LAN,其实这是三个物理网络,通过网桥或者交换机连接起来,形成一个二层的LAN。
|
||||
|
||||
对于一层,也即物理层的设备,主要使用集线器(Hub),这里我们就用Hub将物理层连接起来。
|
||||
|
||||
于是我新画了两个图。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ea/48/ea499064396aa5078b9fe9cd5f4fcc48.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/7d/e5/7d0ec3b857e7c85bba8aefc340a86ce5.png" alt="">
|
||||
|
||||
|
||||
|
||||
在这里,我用Hub将不同的机器连接在一起,形成一个物理段,而非LAN。
|
||||
|
||||
3.在MAC地址已经学习的情况下,ARP会广播到没有IP的物理段吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/1f/f4/1f0ae48921ea404705d93e8bcbf4daf4.png" alt="">
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/0c/a8/0c5d8df850a2fff54c175789645bd7a8.png" alt="">
|
||||
|
||||
|
||||
|
||||
首先谢谢这两位同学指出错误,这里ARP的目标地址是广播的,所以无论是否进行地址学习,都会广播,而对于某个MAC的访问,在没有地址学习的时候,是转发到所有的端口的,学习之后,只会转发到有这个MAC的端口。
|
||||
|
||||
4.802.1Q VLAN 和Port-based VLAN有什么区别?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/98/4d/988673f41c561228c017e96435ea264d.png" alt="">
|
||||
|
||||
所谓Port-based VLAN,一般只在一台交换机上起作用,比如一台交换机,10个口,1、3、5、7、9属于VLAN 10。1发出的包,只有3、5、7、9能够收到,但是从这些口转发出去的包头中,并不带VLAN ID。
|
||||
|
||||
而802.1Q的VLAN,出了交换机也起作用,也就是说,一旦打上某个VLAN,则出去的包都带这个VLAN,也需要链路上的交换机能够识别这个VLAN,进行转发。
|
||||
|
||||
感谢第3讲至第6讲中对内容有深度思考和提出问题的同学。我会为你们送上奖励礼券和知识图谱。(稍后运营同学会发送短信通知。)
|
||||
|
||||
欢迎你继续提问!
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c6/9c/c65176654fe6305665399da89cfe909c.jpg" alt="">
|
265
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第五期.md
Normal file
265
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第五期.md
Normal file
@@ -0,0 +1,265 @@
|
||||
<audio id="audio" title="协议专栏特别福利 | 答疑解惑第五期" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/64/18/64d2e85a551930e15c4537ba6e0d1518.mp3"></audio>
|
||||
|
||||
你好,我是刘超。
|
||||
|
||||
第五期答疑涵盖第22讲至第36讲的内容。我依旧对课后思考题和留言中比较有代表性的问题作出回答。你可以点击文章名,回到对应的章节复习,也可以继续在留言区写下你的疑问,我会持续不断地解答。希望对你有帮助。
|
||||
|
||||
## [《第22讲 | VPN:朝中有人好做官》](https://time.geekbang.org/column/article/10386)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
当前业务的高可用性和弹性伸缩很重要,所以很多机构都会在自建私有云之外,采购公有云,你知道私有云和公有云应该如何打通吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/88/2b/882fbc4105dcfb68e9da055065ad0f2b.jpg" alt="" />
|
||||
|
||||
### 留言问题
|
||||
|
||||
DH算法会因为传输随机数被破解吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/59/b5/5985bcc89e863897eecb18097e8430b5.jpg" alt="" />
|
||||
|
||||
这位同学的[笔记](https://mubu.com/doc/1cZYndRrAg)特别认真,让人感动。DH算法的交换材料要分公钥部分和私钥部分,公钥部分和其他非对称加密一样,都是可以传输的,所以对于安全性是没有影响的,而且传输材料远比传输原始的公钥更加安全。私钥部分是谁都不能给的,因此也是不会截获到的。
|
||||
|
||||
## [《第23讲 | 移动网络:去巴塞罗那,手机也上不了脸书》](https://time.geekbang.org/column/article/10534)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
咱们上网都有套餐,有交钱多的,有交钱少的,你知道移动网络是如何控制不同优先级的用户的上网流量的吗?
|
||||
|
||||
这个其实是PCRF协议进行控制的,它可以下发命令给PGW来控制上网的行为和特性。
|
||||
|
||||
## [《第24讲 | 云中网络:自己拿地成本高,购买公寓更灵活》](https://time.geekbang.org/column/article/10742)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
为了直观,这一节的内容我们以桌面虚拟化系统举例。在数据中心里面,有一款著名的开源软件OpenStack,这一节讲的网络连通方式对应OpenStack中的哪些模型呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/dd/c2/dde85e3ca5c02dfcde75b8bb96a264c2.jpg" alt="" />
|
||||
|
||||
OpenStack的早期网络模式有Flat、Flat DHCP、VLAN,后来才有了VPC,用VXLAN和GRE进行隔离。
|
||||
|
||||
## [《第25讲 | 软件定义网络:共享基础设施的小区物业管理办法》](https://time.geekbang.org/column/article/10755)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
在这一节中,提到了通过VIP可以通过流表在不同的机器之间实现负载均衡,你知道怎样才能做到吗?
|
||||
|
||||
可以通过ovs-ofctl下发流表规则,创建group,并把端口加入group中,所有发现某个地址的包在两个端口之间进行负载均衡。
|
||||
|
||||
```
|
||||
sudo ovs-ofctl -O openflow11 add-group br-lb "group_id=100 type=select selection_method=dp_hash bucket=output:1 bucket=output:2"
|
||||
sudo ovs-ofctl -O openflow11 add-flow br-lb "table=0,ip,nw_dst=192.168.2.0/24,actions=group:100"
|
||||
|
||||
```
|
||||
|
||||
### 留言问题
|
||||
|
||||
SDN控制器是什么东西?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/e5/a4/e5401b93f60da5b95fdc0e060a0a51a4.jpg" alt="" />
|
||||
|
||||
SDN控制器是一个独立的集群,主要是在管控面,因为要实现一定的高可用性。
|
||||
|
||||
主流的开源控制器有OpenContrail、OpenDaylight等。当然每个网络硬件厂商都有自己的控制器,而且可以实现自己的私有协议,进行更加细粒度的控制,所以江湖一直没有办法统一。
|
||||
|
||||
流表是在每一台宿主机上保存的,大小限制取决于内存,而集中存放的缺点就是下发会很慢。
|
||||
|
||||
## [《第26讲 | 云中的网络安全:虽然不是土豪,也需要基本安全和保障》](https://time.geekbang.org/column/article/10978)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
这一节中重点讲了iptables的filter和nat功能,iptables还可以通过QUEUE实现负载均衡,你知道怎么做吗?
|
||||
|
||||
我们可以在iptables里面添加下面的规则:
|
||||
|
||||
```
|
||||
-A PREROUTING -p tcp -m set --match-set minuteman dst,dst -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j NFQUEUE --queue-balance 50:58
|
||||
-A OUTPUT -p tcp -m set --match-set minuteman dst,dst -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j NFQUEUE --queue-balance 50:58
|
||||
|
||||
```
|
||||
|
||||
NFQUEUE的规则表示将把包的处理权交给用户态的一个进程。–queue-balance表示会将包发给几个queue。
|
||||
|
||||
libnetfilter_queue是一个用户态库,用户态进程会使用libnetfilter_queue连接到这些queue中,将包读出来,根据包的内容做决策后,再放回内核进行发送。
|
||||
|
||||
## [《第27讲 | 云中的网络QoS:邻居疯狂下电影,我该怎么办?》](https://time.geekbang.org/column/article/10994)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
这一节中提到,入口流量其实没有办法控制,出口流量是可以很好控制的,你能想出一个控制云中的虚拟机的入口流量的方式吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/0a/26/0ae24cd15cda3eb8aba91666650d1526.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
在云平台中,我们可以限制一个租户的默认带宽,我们仍然可以配置点对点的流量控制。
|
||||
|
||||
在发送方的OVS上,我们可以统计发送方虚拟机的网络统计数据,上报给管理面。在接收方的OVS上,我们同样可以收集接收方虚拟机的网络统计数据,上报给管理面。
|
||||
|
||||
当流量过大的时候,我们虽然不能控制接收方的入口流量,但是我们可以在管理面下发一个策略,控制发送方的出口流量。
|
||||
|
||||
### 留言问题
|
||||
|
||||
对于HTB借流量的情况,借出去的流量能够抢回来吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ec/79/ec406e7e9502859e9b6b80c04d703979.jpg" alt="" />
|
||||
|
||||
首先,借出去的流量,当自己使用的时候,是能够抢回来的。
|
||||
|
||||
有一篇著名的文章[《HTB Linux queuing discipline manual》](http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm)里面很详细,你可以看看。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/2b/0b/2bf7de23e5bda856c606a73f66dd050b.jpg" alt="" />
|
||||
|
||||
很多人看不懂,这是一棵HTB树,有三个分支。A用户使用www访问网页,SMTP协议发送邮件,B用户不限协议。
|
||||
|
||||
在时间0的时候,0、1、2都以90k的速度发送数据,也即A用户在访问网页,同时发送邮件;B也在上网,干啥都行。
|
||||
|
||||
在时间3的时候,将0的发送停止,A不再访问网页了,红色的线归零,A的总速率下来了,剩余的流量按照比例分给了蓝色的和绿色的线,也即分给了A发邮件和B上网。
|
||||
|
||||
在时间6的时候,将0的发送重启为90k,也即A重新开始访问网页,则蓝色和绿色的流量返还给红色的流量。
|
||||
|
||||
在时间9的时候,将1的发送停止,A不再发送邮件了,绿色的流量为零,A的总速率也下来了,剩余的流量按照比例分给了蓝色和红色。
|
||||
|
||||
在时间12,将1的发送恢复,A又开始发送邮件了,红色和蓝色返还流量。
|
||||
|
||||
在时间15,将2的发送停止,B不再上网了,啥也不干了,蓝色流量为零,剩余的流量按照比例分给红色和绿色。
|
||||
|
||||
在时间19,将1的发送停止,A不再发送邮件了,绿色的流量为零,所有的流量都归了红色,所有的带宽都用于A来访问网页。
|
||||
|
||||
## [《第28讲 | 云中网络的隔离GRE、VXLAN:虽然住一个小区,也要保护隐私》](https://time.geekbang.org/column/article/11324)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
虽然VXLAN可以支持组播,但是如果虚拟机数目比较多,在Overlay网络里面,广播风暴问题依然会很严重,你能想到什么办法解决这个问题吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c3/0e/c354402836976d9defcf67d36ba2ae0e.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
很多情况下,物理机可以提前知道对端虚拟机的MAC地址,因而当发起ARP请求的时候,不用广播全网,只要本地返回就可以了,在Openstack里面称为L2Population。
|
||||
|
||||
## [《第29讲 | 容器网络:来去自由的日子,不买公寓去合租》](https://time.geekbang.org/column/article/11465)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
容器内的网络和物理机网络可以使用NAT的方式相互访问,如果这种方式用于部署应用,有什么问题呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/68/25/683db80f520ddc094817d5e780099025.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
_CountingStars对这个问题进行了补充。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/97/3f/978d279627a1388c54c2eb2466cd0d3f.jpg" alt="" />
|
||||
|
||||
其实就是性能损耗,随机端口占用,看不到真实IP。
|
||||
|
||||
## [《第30讲 | 容器网络之Flannel:每人一亩三分地》](https://time.geekbang.org/column/article/11643)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
通过 Flannel 的网络模型可以实现容器与容器直接跨主机的互相访问,那你知道如果容器内部访问外部的服务应该怎么融合到这个网络模型中吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ac/83/acb3aef79240c8707f70491604dbde83.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
Pod内到外部网络是通过docker引擎在iptables的POSTROUTING中的MASQUERADE规则实现的,将容器的地址伪装为node IP出去,回来时再把包nat回容器的地址。
|
||||
|
||||
有的时候,我们想给外部的一个服务使用一个固定的域名,这就需要用到Kubernetes里headless service的ExternalName。我们可以将某个外部的地址赋给一个Service的名称,当容器内访问这个名字的时候,就会访问一个虚拟的IP。然后,在容器所在的节点上,由iptables规则映射到外部的IP地址。
|
||||
|
||||
## [《第31讲 | 容器网络之Calico:为高效说出善意的谎言》](https://time.geekbang.org/column/article/11940)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
将Calico部署在公有云上的时候,经常会选择使用IPIP模式,你知道这是为什么吗?
|
||||
|
||||
_CountingStars的回答是部分正确的。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/17/a2/1769832623a4a14e4bc79a67b3e522a2.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
一个原因是中间有路由,如果VPC网络是平的,但是公有云经常会有一个限制,那就是器的IP段是用户自己定义的,一旦出虚拟机的时候,云平台发现不是它分配的IP,很多情况下直接就丢弃了。如果是IPIP,出虚拟机之后,IP还是虚拟机的IP,就没有问题。
|
||||
|
||||
## [《第32讲 | RPC协议综述:远在天边,近在眼前》](https://time.geekbang.org/column/article/12230)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
在这篇文章中,mount的过程是通过系统调用,最终调用到RPC层。一旦mount完毕之后,客户端就像写入本地文件一样写入NFS了,这个过程是如何触发RPC层的呢?
|
||||
|
||||
_CountingStars的回答很有深度。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/7a/60/7ab3228c9cb73e7f0cf0b922332d1d60.jpg" alt="" />
|
||||
|
||||
是的,是通过VFS实现的。
|
||||
|
||||
在讲[Socket](https://time.geekbang.org/column/article/9141)那一节的时候,我们知道,在Linux里面,很多东西都是文件,因而内核中有一个打开的文件列表File list,每个打开的文件都有一项。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/60/8c/602d09290bd4f9e0183f530e9653348c.jpg" alt="" />
|
||||
|
||||
对于Socket来讲,in-core inode就是内存中的inode。对于nfs来讲,也有一个inode,这个inode里面有一个成员变量file_operations,这里面是这个文件系统的操作函数。对于nfs来讲,因为有nfs_file_read、nfs_file_write,所以在一个mount的路径中读取某个文件的时候,就会调用这两个函数,触发RPC,远程调用服务端。
|
||||
|
||||
## [《第33讲 | 基于XML的SOAP协议:不要说NBA,请说美国职业篮球联赛》](https://time.geekbang.org/column/article/12388)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
对于HTTP协议来讲,有多种方法,但是SOAP只用了POST,这样会有什么问题吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/8a/19/8a889ea32a5a404c432a1102b90a4819.jpg" alt="" />
|
||||
|
||||
## [《第34讲 | 基于JSON的RESTful接口协议:我不关心过程,请给我结果》](https://time.geekbang.org/column/article/12512)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
在讨论RESTful模型的时候,举了一个库存的例子,但是这种方法有很大问题,那你知道为什么要这样设计吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/4a/a2/4ab1e3cb5b48a843d6dc5967cc1238a2.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
这个我在双十一包的例子中已经分析过了。
|
||||
|
||||
## [《第35讲 | 二进制类RPC协议:还是叫NBA吧,总说全称多费劲》](https://time.geekbang.org/column/article/12521)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
对于微服务模式下的RPC框架的选择,Dubbo和SpringCloud各有优缺点,你能做个详细的对比吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/49/33/49d571110301eab5cf61560bfee2f333.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
## [《第36讲 | 跨语言类RPC协议:交流之前,双方先来个专业术语表》](https://time.geekbang.org/column/article/12819)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
在讲述Service Mesh的时候,我们说了,希望Envoy能够在服务不感知的情况下,将服务之间的调用全部代理了,你知道怎么做到这一点吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/0b/d3/0b13bbed598d0d9b9a783d1a3fa881d3.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/56/f8/56e282315a2ef361aa0a8bb1cf0b38f8.jpg" alt="" />
|
||||
|
||||
|
||||
|
||||
iptables规则可以这样来设置:
|
||||
|
||||
首先,定义的一条规则是ISTIO_REDIRECT转发链。这条链不管三七二十一,都将网络包转发给envoy的15000端口。但是一开始这条链没有被挂到iptables默认的几条链中,所以不起作用。
|
||||
|
||||
接下来,在PREROUTING规则中使用这个转发链。从而,进入容器的所有流量都被先转发到envoy的15000端口。而envoy作为一个代理,已经被配置好了,将请求转发给productpage程序。
|
||||
|
||||
当productpage往后端进行调用的时候,就碰到了output链。这个链会使用转发链,将所有出容器的请求都转发到envoy的15000端口。
|
||||
|
||||
这样,无论是入口的流量,还是出口的流量,全部用envoy做成了“汉堡包”。envoy根据服务发现的配置,做最终的对外调用。
|
||||
|
||||
这个时候,iptables规则会对从envoy出去的流量做一个特殊处理,允许它发出去,不再使用上面的output规则。
|
||||
|
||||
感谢第22讲至第36讲中对内容有深度思考和提出问题的同学。我会为你们送上奖励礼券和知识图谱。(稍后运营同学会发送短信通知。)
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/90/99/90874109328ea2f88d097f58dddc4e99.jpg" alt="" />
|
||||
|
||||
咱们的答疑环节暂时告一段落了,如果你在学习过程中有什么问题,欢迎你继续留言给我!
|
||||
|
||||
|
207
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第四期.md
Normal file
207
极客时间专栏/趣谈网络协议/答疑与加餐/协议专栏特别福利 | 答疑解惑第四期.md
Normal file
@@ -0,0 +1,207 @@
|
||||
<audio id="audio" title="协议专栏特别福利 | 答疑解惑第四期" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ad/d4/ad9d6ddf788e6c9a1d7cb9b771901fd4.mp3"></audio>
|
||||
|
||||
你好,我是刘超。
|
||||
|
||||
第四期答疑涵盖第14讲至第21讲的内容。我依旧对课后思考题和留言中比较有代表性的问题作出回答。你可以点击文章名,回到对应的章节复习,也可以继续在留言区写下你的疑问,我会持续不断地解答。希望对你有帮助。
|
||||
|
||||
## [《第14讲 | HTTP协议:看个新闻原来这么麻烦》](https://time.geekbang.org/column/article/9410)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
QUIC是一个精巧的协议,所以它肯定不止今天我提到的四种机制,你知道还有哪些吗?
|
||||
|
||||
云学讲了一个QUIC的特性。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/4e/02/4eb79fc072ad11cf3e938616259f0502.png" alt="">
|
||||
|
||||
QUIC还有其他特性,一个是**快速建立连接**。这个我放在下面HTTPS的时候一起说。另一个是**拥塞控制**,QUIC协议当前默认使用了TCP协议的CUBIC(拥塞控制算法)。
|
||||
|
||||
你还记得TCP的拥塞控制算法吗?每当收到一个ACK的时候,就需要调整拥塞窗口的大小。但是这也造成了一个后果,那就是RTT比较小的,窗口增长快。
|
||||
|
||||
然而这并不符合当前网络的真实状况,因为当前的网络带宽比较大,但是由于遍布全球,RTT也比较长,因而基于RTT的窗口调整策略,不仅不公平,而且由于窗口增加慢,有时候带宽没满,数据就发送完了,因而巨大的带宽都浪费掉了。
|
||||
|
||||
CUBIC进行了不同的设计,它的窗口增长函数仅仅取决于连续两次拥塞事件的时间间隔值,窗口增长完全独立于网络的时延RTT。
|
||||
|
||||
CUBIC的窗口大小以及变化过程如图所示。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/fe/5f/fe9fb6d6e9deea8c3543f54572ec765f.jpg" alt="">
|
||||
|
||||
当出现丢包事件时,CUBIC会记录这时的拥塞窗口大小,把它作为Wmax。接着,CUBIC会通过某个因子执行拥塞窗口的乘法减小,然后,沿着立方函数进行窗口的恢复。
|
||||
|
||||
从图中可以看出,一开始恢复的速度是比较快的,后来便从快速恢复阶段进入拥塞避免阶段,也即当窗口接近Wmax的时候,增加速度变慢;立方函数在Wmax处达到稳定点,增长速度为零,之后,在平稳期慢慢增长,沿着立方函数的开始探索新的最大窗口。
|
||||
|
||||
### 留言问题
|
||||
|
||||
HTTP的keepalive模式是什么样?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/77/7c/77df27b180a8d0390322bd9137d21d7c.png" alt="">
|
||||
|
||||
在没有keepalive模式下,每个HTTP请求都要建立一个TCP连接,并且使用一次之后就断开这个TCP连接。
|
||||
|
||||
使用keepalive之后,在一次TCP连接中可以持续发送多份数据而不会断开连接,可以减少TCP连接建立次数,减少TIME_WAIT状态连接。
|
||||
|
||||
然而,长时间的TCP连接容易导致系统资源无效占用,因而需要设置正确的keepalive timeout时间。当一个HTTP产生的TCP连接在传送完最后一个响应后,还需要等待keepalive timeout秒后,才能关闭这个连接。如果这个期间又有新的请求过来,可以复用TCP连接。
|
||||
|
||||
## [《第15讲 | HTTPS协议:点外卖的过程原来这么复杂》](https://time.geekbang.org/column/article/9492)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
HTTPS 协议比较复杂,沟通过程太繁复,这样会导致效率问题,那你知道有哪些手段可以解决这些问题吗?
|
||||
|
||||
通过HTTPS访问的确复杂,至少经历四个阶段:DNS查询、TCP连接建立、TLS连接建立,最后才是HTTP发送数据。我们可以一项一项来优化这个过程。
|
||||
|
||||
首先如果使用基于UDP的QUIC,可以省略掉TCP的三次握手。至于TLS的建立,如果按文章中基于TLS 1.2的,双方要交换key,经过两个来回,也即两个RTT,才能完成握手。但是咱们讲IPSec的时候,讲过通过共享密钥、DH算法进行握手的场景。
|
||||
|
||||
在TLS 1.3中,握手过程中移除了ServerKeyExchange和ClientKeyExchange,DH参数可以通过key_share进行传输。这样只要一个来回,就可以搞定RTT了。
|
||||
|
||||
对于QUIC来讲,也可以这样做。当客户端首次发起QUIC连接时,会发送一个client hello消息,服务器会回复一个消息,里面包括server config,类似于TLS1.3中的key_share交换。当客户端获取到server config以后,就可以直接计算出密钥,发送应用数据了。
|
||||
|
||||
### 留言问题
|
||||
|
||||
1.HTTPS的双向认证流程是什么样的?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/93/39/934a64552c3c8c04c629383db0d6b939.jpg" alt="">
|
||||
|
||||
2.随机数和premaster的含义是什么?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/28/78/28a3938ab8efaf9fa7f313a46d0e1478.jpg" alt="">
|
||||
|
||||
|
||||
|
||||
## [《第16讲 | 流媒体协议:如何在直播里看到美女帅哥?》](https://time.geekbang.org/column/article/9688)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
你觉得基于 RTMP 的视频流传输的机制存在什么问题?如何进行优化?
|
||||
|
||||
Jason的回答很对。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/38/90/38d8dda78c277a01f85cbf7371639c90.png" alt="">
|
||||
|
||||
Jealone的回答更加具体。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c3/d9/c384054368a1f491a34ac7f6f0641dd9.png" alt="">
|
||||
|
||||
当前有基于自研UDP协议传输的,也有基于QUIC协议传输的。
|
||||
|
||||
### 留言问题
|
||||
|
||||
RTMP建立连接的序列是什么样的?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/ad/53/ada59a46a4c5d5194c322ddb34250d53.png" alt="">
|
||||
|
||||
的确,这个图我画错了,我重新画了一个。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/5a/75/5a45685536eb1c1ae354c3cc1e037275.jpg" alt="">
|
||||
|
||||
不过文章中这部分的文字描述是没问题的。
|
||||
|
||||
客户端发送C0、C1、 C2,服务器发送S0、 S1、 S2。
|
||||
|
||||
首先,客户端发送C0表明自己的版本号,不必等对方的回复,然后发送C1表明自己的时间戳。
|
||||
|
||||
服务器只有在收到C0的时候,才能返回S0,表明自己的版本号。如果版本不匹配,可以断开连接。
|
||||
|
||||
服务器发送完S0后,也不用等什么,就直接发送自己的时间戳S1。客户端收到S1的时候,发一个知道了对方时间戳的ACK C2。同理服务器收到C1的时候,发一个知道了对方时间戳的ACK S2。
|
||||
|
||||
于是,握手完成。
|
||||
|
||||
## [《第17讲 | P2P协议:我下小电影,99%急死你》](https://time.geekbang.org/column/article/9707)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
除了这种去中心化分布式哈希的算法,你还能想到其他的应用场景吗?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/fe/eb/fe12f0f41edbb4f46c3df513988760eb.png" alt="">
|
||||
|
||||
|
||||
|
||||
### 留言问题
|
||||
|
||||
99%卡住的原因是什么?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/4e/da/4e52188839de11d46050935c2a3f12da.png" alt="">
|
||||
|
||||
|
||||
|
||||
## [《第18讲 | DNS协议:网络世界的地址簿》](https://time.geekbang.org/column/article/9895)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
全局负载均衡使用过程中,常常遇到失灵的情况,你知道具体有哪些情况吗?对应应该怎么来解决呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/e3/28/e3ce7238d7fa1d7e5d9568def5832b28.jpeg" alt="">
|
||||
|
||||
### 留言问题
|
||||
|
||||
如果权威DNS连不上,怎么办?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/92/06/92579a426910452422521f6bce71be06.png" alt="">
|
||||
|
||||
一般情况下,DNS是基于UDP协议的。在应用层设置一个超时器,如果UDP发出没有回应,则会进行重试。
|
||||
|
||||
DNS服务器一般也是高可用的,很少情况下会挂。即便挂了,也会很快切换,重试一般就会成功。
|
||||
|
||||
对于客户端来讲,为了DNS解析能够成功,也会配置多个DNS服务器,当一个不成功的时候,可以选择另一个来尝试。
|
||||
|
||||
## [《第19讲 | HttpDNS:网络世界的地址簿也会指错路》](https://time.geekbang.org/column/article/9938)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
使用 HttpDNS,需要向 HttpDNS 服务器请求解析域名,可是客户端怎么知道 HttpDNS 服务器的地址或者域名呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c3/e1/c3ca8a189ac6ad10afaca2da185c5ce1.png" alt="">
|
||||
|
||||
## [《第20讲 | CDN:你去小卖部取过快递么?》](https://time.geekbang.org/column/article/10085)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
这一节讲了CDN使用DNS进行全局负载均衡的例子,CDN如何使用HttpDNS呢?
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c8/d9/c86f4fa153ff64ebaa1335933779cad9.png" alt="">
|
||||
|
||||
## [《第21讲 | 数据中心:我是开发商,自己拿地盖别墅》](https://time.geekbang.org/column/article/10098)
|
||||
|
||||
### 课后思考题
|
||||
|
||||
对于数据中心来讲,高可用是非常重要的,每个设备都要考虑高可用,那跨机房的高可用,你知道应该怎么做吗?
|
||||
|
||||
其实跨机房的高可用分两个级别,分别是**同城双活**和**异地灾备**。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/8a/71/8af9a0a7c1d24b73d26ab0ef5f54b071.jpg" alt="">
|
||||
|
||||
**同城双活**,就是在同一个城市,距离大概30km到100km的两个数据中心之间,通过高速专线互联的方式,让两个数据中心形成一个大二层网络。
|
||||
|
||||
同城双活最重要的是,数据如何从一个数据中心同步到另一个数据中心,并且在一个数据中心故障的时候,实现存储设备的切换,保证状态能够快速切换到另一个数据中心。在高速光纤互联情况下,主流的存储厂商都可以做到在一定距离之内的两台存储设备的近实时同步。数据双活是一切双活的基础。
|
||||
|
||||
基于双数据中心的数据同步,可以形成一个统一的存储池,从而数据库层在共享存储池的情况下可以近实时地切换,例如Oracle RAC。
|
||||
|
||||
虚拟机在统一的存储池的情况下,也可以实现跨机房的HA,在一个机房切换到另一个机房。
|
||||
|
||||
SLB负载均衡实现同一机房的各个虚拟机之间的负载均衡。GSLB可以实现跨机房的负载均衡,实现外部访问的切换。
|
||||
|
||||
如果在两个数据中心距离很近,并且大二层可通的情况下,也可以使用VRRP协议,通过VIP方式进行外部访问的切换。
|
||||
|
||||
下面我们说**异地灾备**。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/e5/94/e561d8a5ec5842a67513ba42bda09494.jpg" alt="">
|
||||
|
||||
异地灾备的第一大问题还是数据的问题,也即生产数据中心的数据如何备份到容灾数据中心。由于异地距离比较远,不可能像双活一样采取近同步的方式,只能通过异步的方式进行同步。可以预见的问题是,容灾切换的时候,数据会丢失一部分。
|
||||
|
||||
由于容灾数据中心平时是不用的,不是所有的业务都会进行容灾,否则成本太高。
|
||||
|
||||
对于数据的问题,我比较建议从业务层面进行容灾。由于数据同步会比较慢,可以根据业务需求高优先级同步重要的数据,因而容灾的层次越高越好。
|
||||
|
||||
例如,有的用户完全不想操心,直接使用存储层面的异步复制。对于存储设备来讲,它是无法区分放在存储上的虚拟机,哪台是重要的,哪台是不重要的,只会完全根据块进行复制,很可能就会先复制了不重要的虚拟机。
|
||||
|
||||
如果用户想对虚拟机做区分,则可以使用虚拟机层面的异步复制。用户知道哪些虚拟机更重要一些,哪些虚拟机不重要,则可以先同步重要的虚拟机。
|
||||
|
||||
对业务来讲,如果用户可以根据业务层情况,在更细的粒度上区分数据是否重要。重要的数据,例如交易数据,需要优先同步;不重要的数据,例如日志数据,就不需要优先同步。
|
||||
|
||||
在有异地容灾的情况下,可以平时进行容灾演练,看容灾数据中心是否能够真正起作用,别容灾了半天,最后用的时候掉链子。
|
||||
|
||||
感谢第14讲至第21讲中对内容有深度思考和提出问题的同学。我会为你们送上奖励礼券和知识图谱。(稍后运营同学会发送短信通知。)
|
||||
|
||||
欢迎你继续提问!
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/7e/7e/7e172a2e3bb3cbc926d138dd2bd9297e.jpg" alt="">
|
21
极客时间专栏/趣谈网络协议/答疑与加餐/第2季回归 | 这次我们来“趣谈Linux操作系统”.md
Normal file
21
极客时间专栏/趣谈网络协议/答疑与加餐/第2季回归 | 这次我们来“趣谈Linux操作系统”.md
Normal file
@@ -0,0 +1,21 @@
|
||||
<audio id="audio" title="第2季回归 | 这次我们来“趣谈Linux操作系统”" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/3a/69/3abcd0c589a74d612cdd5ff5c1c18169.mp3"></audio>
|
||||
|
||||
你好,我是你的老朋友刘超。在“趣谈网络协议”结课半年之后,我又给你带来了一个新的基础课程,“趣谈Linux操作系统”。
|
||||
|
||||
在咱们“趣谈网络协议”的留言里,我和同学们进行了很多互动,同时,我也和其他做基础知识专栏的作者有了不少交流,我发现,无论是从个人的职业发展角度,还是从公司招聘候选人的角度来看,扎实的基础知识是很多人的诉求。这让我更加坚信,我应该在“趣谈基础知识”这条道路上走下去。
|
||||
|
||||
**在设计“趣谈Linux操作系统”专栏的时候,我仍然秉承“趣谈”和“故事化”的方式,将枯燥的基础知识结合某个场景,给你生动、具象地讲述出来,帮你加深理解、巩固记忆、夯实基础。**
|
||||
|
||||
在我看来,操作系统在计算机中承担着“大管家”的角色,这个“大管家”就好比一家公司的老板,我们的目标就是把这家公司做上市,具体的过程,我用了一张图来表示:
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/7d/a5/7d7b2f705d4877bb331b4ea3ff3450a5.jpg" alt="">
|
||||
|
||||
Linux操作系统中的概念非常多,数据结构也很多,流程也复杂,一般人在学习的过程中很容易迷路。我希望能够将这些复杂的概念、数据结构、流程通俗地讲解出来,争取每篇文章都用一张图串起这篇的知识点。
|
||||
|
||||
最终,整个专栏下来,你如果能把这些图都掌握了,你的知识就会形成体系和连接。在此基础上再进行深入学习,就会如鱼得水、易如反掌。
|
||||
|
||||
一段新的征途即将开始,期待与你继续同行。为了感谢老同学,我为你送上一张10元专属优惠券,可以与限时优惠同享,优惠券有效期仅5天,建议你抓紧使用。点击下方图片,可试读专栏最新文章。
|
||||
|
||||
我们新专栏见!
|
||||
|
||||
[<img src="https://static001.geekbang.org/resource/image/57/44/57f047be7ebb1f4aba7e8064e1c11544.jpg" alt="">](https://time.geekbang.org/column/intro/164?utm_term=zeusOLMNR&utm_source=app&utm_medium=geektime&utm_campaign=164-presell&utm_content=qutanwangluoxieyi)
|
Reference in New Issue
Block a user