重学计算机网络已经有一段时间了,终于在离开大学多年后又重新拾起了一部分,时至今日已略有小成,并且写了一系列的文章了,会慢慢 发出来。
我反正在学习的过程中是画了好多张图,这些图会放到后续的文章中,有兴趣一起学习的同学记得关注加星标呀,这样就能第一时间接到文章推送了。
上大学的时候就想好好学习网络,梦想着以后成为一名网管。后来发现计算机网络还真是不太好学,非常非常抽象,发现有很多概念好像怎么学都学不明白。这才知道,原来更适合我的网吧管理员,而不是网络管理员。而写代码就不一样了,没那么抽象,而且写出来东西马上能看到成果,写一个方法一运行,马上能输出结果;写一个网页、一段样式,马上就能看到界面的变化。人的大脑最喜欢这种快速反馈了,于是觉得写代码比学网络有意思,这才走上了程序员这条路。
后来工作了,相信大家和我有同感,虽然写的是代码,但是处处离不开网络:
- 普通接口用的是 HTTP\HTTPS,HTTP 处于整个网络的最顶层应用层;
- 有一些 RPC 使用的非 HTTP 协议,例如 Dubbo 的 Hessian 直接包装的 TCP 协议;
- 还有一些场景要直接使用 TCP,例如支持前端的 websocket;
- 非常流行的高性能网络框架 Netty ;
- 使用 Dokcer 容器做开发测试的时候;
- 甚至于使用VmVare 虚拟机的时候,也要了解桥接模式、NAT、仅主机模式的区别;
就算对网络和底层完全不了解,也可以正常写代码,但是,当我们有一天发不满足于只写增删改查,或者在一些外部力量的驱动下,如果不理解网络,那必将寸步难行。
只写增删改查做咸鱼有什么区别,我们是那种甘心做咸鱼的人吗?对于想在技术上更上一层,想要做架构师的同学,网络是我们必须拿下的阵地。
在做了一段时间的咸鱼之后,我还是决定要翻一下身。否则网络这东西总会像一团迷雾一样,时不时飘来挡住视线,一直像一块面纱一样,遮住了系统真正的面容。
为什么要学习网络知识
可以出去吹牛啊
当碰到一个网络问题,别人都解决不了,你解决了,你说骄傲不,你说自豪不。
当然,就是说说而已,做人还是要低调,内心就算翻出了花儿,表面上也要淡定的表示这是基本操作。
加深对应用框架和架构的理解
现在还能找出哪个系统、哪个应用不依赖于网络吗,好像还真的不太好找。
举两个例子:
Netty 框架
Netty 可以说是当前最火的网络编程框架,如果你们的项目需要高性能、高可靠的服务端和客户端交互,最好的选择就是 Netty。比如即时沟通功能、比如游戏服务器、比如websocket的服务器端实现。
Netty 是基于TCP\UDP 实现的,其中有很大部分都是对这两个协议的封装,在理解网络(尤其是TCP)和不理解网络的情况下学习 Netty 是两种完全不同的体验,前者事半功倍,后者事倍功半。
而且现在很多框架都集成了 Netty,比如 Dubbo RPC、RocketMQ、Hadoop等,连 Spring Boot 也已经内置了 Netty 模式。更好的理解 Netty ,才能更好的理解这些框架,怎么才能更好的理解 Netty 呢,当然是要对网络有很好的理解啦。
微服务框架
微服务是由多台服务器组成的,这么多的服务器要联动起来,和稳定的网络结构是分不开的。一个复杂的微服务架构,有网关、服务、CDN、还有各种旁路的中间件。网关还分网络网关和应用网关,网关就涉及到负载均衡,负载均衡有4层负载均衡,还有7层负载均衡,各种各样的概念,哪一个都离不开网络。
有可能还用了 docker、k8s,这就更复杂了,容器内部网络、集群网络、外部网络,不了解这些怎么能更好的理解架构。
优化系统
也许某一天你当上了架构师,当系统出现瓶颈的时候,需要做优化了。如果你不懂网络,那只能从数据库、中间件、代码层面优化, 缺失了网络层面的优化,而网络优化应该是成本最低的部分。
也许能解决一些疑难杂症
有时候,很多问题都是由网络问题引起的。
最简单的相信大家都能处理,比如最常说的 ping
一下、telnet
一下。
就连阿里云这么大的平台也经常发生网络问题。很早之前,项目中有一些集成了微信服务号的功能,服务部署在阿里云,就出现过异常,现象就是无法正常调用产生临时二维码的接口。通过排查判断应该是阿里云服务器的网络出现了问题,于是立刻提交工单,经过核实,确认是某些阿里云服务器的网络出现了问题,据客服回应是网络抖动,但也不保证当时阿里云在进行某些配置更新,谁知道呢。
除了上面说的简单、明显的网络问题外,还有一些问题是隐藏在背后的,比如一些第三方框架或中间件,在某些情况下会出现非常莫名其妙的问题。我承认找到并解决这些问题确实很困难,必须要动用一些服务端工具、网络工具辅助排查,即使这样,也不一定能顺利的发现问题所在。
没关系,至少理解了网络,就多一条路,也许这条路就能帮我们找到问题呢。但如果你不了解网络,不要说解决问题了,连问题产生的原因都不会知道,连如何排查问题都不知道。
为什么看完书转头就忘
不是我不想学啊,看完了转头就忘了。这不就是说的我吗?不瞒你说,我看了好几遍《TCP-IP协议详解》卷1了,到现在还只是掌握了一个大概,理论性的内容最不容易掌握了,因为很难从中得到乐趣,大脑不容易给出积极的反馈。但是有一个好处不得不说,就是助眠,看着看着就困了。
多看
上学的时候老师经常说的就是多看多读,不得不说,这个方法确实好用,除非你有过目不忘的天才本领。不要妄想一口吃个胖子,普通的人大脑没办法一下接受那么多陌生的东西。不知道各位有没有过这样的经历,之前学过的一些知识感觉自己没学好、没学懂,学起来很吃力,最终可能糊弄过去或者直接放弃了。而过了一段时间又拿起来学了,发现之前一些没理解的部分突然理解了。
作为一个普通咸鱼,经常有些概念第一次、第二次都不太理解,比如学习 TCP 的时候,前面不理解,导致后面更不容易理解,然后就不想看了,这时候强迫自己继续看下去,当然了,最终的结果可能仍然是不理解,一次、两次都是这样。过些天,重新看的时候经常会有恍然大悟的感觉,奥,原来是这么回事。
画出来、写出来
画出来,可以帮助我们更直观的理解。大脑不容易接收文字,但是容易接收可视化的东西,为什么短视频比公众号更受欢迎,因为视频通过眼睛可以更直观的传递给大脑,而公众号上的文字要经过大脑的转化,转化的过程大脑就要工作,要工作就累啊。
比如我们学习网络模型的时候,有时候说7层,有时候说4层,因为4层是将7层中的某些层合并了,有一些网络协议工作在应用层、有一些工作在传输层。如果纯靠文字,那简直太抽象了,但是要是通过图形的方式展示出来,一目了然,可以通过下面的图感受一下。一下就知道,7层和4层的区别。
写出来,可以检验我们自己是否真的理解了,大多数时候我们以为自己理解了,但是一旦要讲给别人的时候,发现支支吾吾,有些地方模棱两可。
相信各位写过博客的同学都特别有这种感觉,真正掌握的知识点可以很快的写成文章出来,而那些其实没掌握清楚的知识点,可能一篇文章写出来要用好几天。为什么呢?写着写着发现一个细节说不清楚,如果不想糊弄,就要找相关的书籍、文章,这个过程仍然是学习的过程。
到最后,能把一个概念通过文字的形式讲清楚了,说明自己至少掌握了大部分,也不敢保证100%掌握。
要实践啊
纸上谈兵最可怕,尤其是我们程序员这个行业。空谈误自己啊,同志们。写代码就不用说了,不可能只看不实践对吧,那样的话早被公司开除了。
网络这东西都是概念性、抽象的,怎么实践啊。总不能掐个水晶头、扯根网线吧。倒也不是不可以,但是也没必要,毕竟我们不是真的要去网吧当网管的。
可以使用一些网络工具可视化的观察一下网络上的数据包,比如用 WireShark 看一下 ARP协议、IP协议、TCP 协议、HTTP协议的数据格式是怎么样的,客户端和服务端的交互过程是怎样的。
还可以用一些网络命令试验一下,比如 ping 、telnet、route 等等。
最后可以回归老本行,写一写关于 Socket 的服务端和客户端的交互程序,修改一下各个参数看一下有什么变化。
我是怎么学的呢
通过一段时间的不懈努力,我终于小有所成,从下面几个方向上梳理出了学习网络的一些脉络。
1、首先要从宏观视角大致了解一下网络到底是怎么样的,重点是网络分层模型、传输过程。抛开网络不说,接触任何一个新的知识都要先从宏观上下手。比如学习一个第三方框架,要先看介绍和架构说明,知道这个框架是干什么用的,工作原理是什么,架构设计是如何的。
2、然后就是理解各个层的主要协议了,主要就是协议的作用和协议格式,以及每种协议格子的功能特性。
3、一个数据包从发送端到目的端要经过纷繁复杂的网络结构,经过各种中间设备。从路由表、转发表和 ARP 表这三张表,可以了解数据包传输的过程。
4、最后是 Ping
、Route
命令的工作原理。遇到网络问题,我们首先想到的是 ping 一下
,ping 的原理是什么呢?其实就是对特定的网络协议特性的巧妙利用,也很好玩。
图中的每一个点,我都输出成了笔记,借此加深理解。之后,会一篇一篇的发出来,欢迎大家跟着我一起学习。