https://kaiwu.lagou.com/course/courseInfo.htm?courseId=837
开篇词
开篇词 | 一次搞定计算机网络,高效修炼程序员内功
课前导读 | 程序员如何打好计算机领域的基础?
模块一:互联网和传输层协议
01 | 漫游互联网:什么是蜂窝移动网络?
02 | 传输层协议 TCP:TCP 为什么握手是 3 次、挥手是 4 次?
03 | TCP 的封包格式:TCP 为什么要粘包和拆包?
04 | TCP 的稳定性:滑动窗口和流速控制是怎么回事?
05 | UDP 协议:TCP 协议和 UDP 协议的优势和劣势?
加餐 | 模块一思考题解答
模块二:网络层协议
06 | IPv4 协议:路由和寻址的区别是什么?
07 | IPv6 协议:Tunnel 技术是什么?
08 | 局域网:NAT 是如何工作的?
09 | TCP 实战:如何进行 TCP 抓包调试?
加餐 | 模块二思考题解答
模块三:网络编程
10 | Socket 编程:epoll 为什么用红黑树?
11 | 流和缓冲区:缓冲区的 flip 是怎么回事?
12 | 网络 I/O 模型:BIO、NIO 和 AIO 有什么区别?
13 | 面试中如何回答“怎样实现 RPC 框架”的问题?
RPC(Remote Procedure Call)远程过程调用
在远程必须定义这个方法,然后才可以通过 RPC 框架调用该方法
远程调用不仅可以传参数、获取到返回值
还可以捕捉调用过程中的异常。PRC 让远程调用就像本地调用一样
假设实现了一个 rpc 对象,其中的 invode 方法可以实现远程调用
var result = rpc.invoke("greetings", arg1, arg2, ...)
多路复用的优化
RPC提供的是远程方法调用
本质上是数据的传递
传递数据有一个最基本的问题要处理,就是提升吞吐量
多路复用的优化
利用一个连接顺序发送 A,B,C,D,将多个请求放入一个连接的方式
节省了多次握手、挥手的时间
顺序发送,当其中某个请求的提交较大时,容易阻塞其他请求
切片传输的方案:将数据切片可以保证大、小任务并行,不会因为大任务阻塞小任务
单个 TCP 连接的极限传输速度受到窗口大小、缓冲区等因素的制约,不一定可以用满网络资源
调用约定和命名
远程调用一个函数 命名空间 + 类名 + 方法名
比如远程调用一个支付服务对象 PayService 的 pay 方法
- 命名空间(trade,payment)
- 对象名称是(PayServer)
- 方法名称是(pay)
例如用 # 分割:trade.payment#PayService#pay
在进行远程调用的时候,给远程方法命名是调用约定的一部分
通过调用命名空间下完整的名称调用远程方法
- 常见的做法:先不具体指定调用的方法,而是先创造一个远程对象的实例
字符串名称
ip是多少,也就是方法在哪台机器上调用
端口是多少,也就是那个服务提供这个调用
注册和发现
字符串(命名)-> 获取 IP 和端口(机器和服务)
在网络的世界中,需要的只是网络接口和IP地址
而操作系统区分应用需要的是端口
在调用过程中,需要的是一个注册表,存储了字符串和IP + 端口的对应关系
- 当我们上限一个服务的时候
就在Redis的某个 hash对象中存储它和它对应的 IP地址 + 端口列表
通常将写这个 hash 对象的过程称作注册
我们远程调用一个 RPC 服务的时候
调用端提供的是 RPC 服务的名称(例如:命名空间 + 对象 + 方法)
通常将写这个 hash 对象的过程称作注册
根据名称查找到提供服务的 IP + 端口清单并指定某个 IP + 端口的过程称作发现
注册就是写一个共享的哈希表
发现就是查哈希表再决定服务的响应者
基于 Redis 的实现
如果所有 RPC 调用都需要去 Redis 查询,会造成负责发现的中间件压力较大
- RPC 调用者会缓存上一次调用的 IP + 端口
(缓存又可能会和注册表之间产生数据不一致的问题)
可以考虑由分布式共识服务比如 ZooKeeper 提供订阅
让 RPC 调用订阅到服务地址的变更,及时更新自己的缓存
在设计 RPC 框架的时候,负载均衡器的设计往往是需要和 RPC 框架一起考虑
因为 RPC 框架提供了注册、发现的能力,提供发现能力的模块本身就是一个负载均衡器
当一个服务实例崩溃的时候(不可用)
因为有发现模块的存在,可以及时从注册表中删除这个服务实例
- 只要服务本身有足够多的实例
注册表和RPC 调用者之间必然存在不一致现象
而且注册表的更新本身也可能滞后
如果遇到临时访问量剧增,需要扩容的场景
实现远程方法的调用
- 比如怎么描述一个远程的方法?在 RPC 调用时有调用约定
- 发送端怎么传递参数?
- 接收方如何解析参数?编译器在实现函数调用的时候,会有调用约定
- 如果发生异常应该如何处理?
- 思考底层具体网络的传输问题
- 如果用TCP 要思考多路复用以及连接数量的问题
- 如果是 UDP,需要增加对于可靠性保证的思考
- 如果使用了消息队列,还需要考虑服务的幂等性设计等
如何理解 Dubbo的几个组成部分 Consumer、Provider、Moitor 和 Registry?
Dubbo是一个开源、轻量级的 Java 服务框架
注册处对网络中的信息是信任的,如果 Provider 被攻击欺骗注册处会产生安全问题
Registry 需要实现分布式共识,具体可以使用 ZooKeeper 实现
加餐 | 模块三思考题解答
模块四:Web 技术
14 | DNS 域名解析系统:CNAME 记录的作用是?
15 | 内容分发网络:请简述 CDN 回源如何工作?
16 | HTTP 协议面试通关:强制缓存和协商缓存的区别是?
17 | 流媒体技术:直播网站是如何实现的?
18 | 爬虫和反爬虫:如何防止黑产爬取我的数据?
加餐 | 模块四思考题解答
模块五:网络安全
19 | 网络安全概述:对称、非对称加密的区别是?
20 | 信任链:为什么可以相信一个 HTTPS 网站?
21 | 攻防手段介绍:如何抵御 SYN 拒绝攻击?
加餐 | 模块五思考题解答
结束语
结束语 | 未来需要怎样的工程师