📚 第一章 网络基础知识
📄 一句话概括

网络最早的作用就一条:共享资源——一份数据存一处,大家来取。 但「共享」省的是存储,不是带宽;这两件事经常被混为一谈。

📝 本节和前面几节的关系

1.1.3 讲的是「信息怎么被理解」,这一节讲「信息为什么值得被传」。 1.2 会从用途转到历史:七个阶段,每一个都是被需求推出来的。

一、三样东西可以被共享

书里列的用途可以归成三类:

共享什么 典型场景 省下了什么
数据 文件服务器、网盘 磁盘空间
设备 网络打印机、共享摄像头 硬件采购
算力 服务器、云主机 本地机器性能

注意第一列的加粗:三类共享里,只有「数据」这一类会随使用人数线性增加网络流量。 共享打印机不会——打一份文件传输的是几十 KB 的打印指令,不是整台打印机。 这个区别决定了两类系统的设计方向完全不同:数据共享要抗带宽,设备共享要抗并发。

二、共享省的不是带宽

这是最容易错的一句话:「共享文件省磁盘,不省带宽」。

做法 磁盘占用 网络流量
每人存一份 N 份 0
集中存一份 1 份 N 份(每人取一次)

表格里两列正好反着:省下的磁盘,变成了必须付出的流量。 所以「上文件服务器」这件事,对磁盘是好事,对网络是压力—— 在没有做缓存的情况下,100 个人同时取一个 1 GB 的文件,网络上就要跑 100 GB。 解决办法不是加大带宽,而是「让数据离用户近一点」:缓存、CDN、边缘节点,本质都是这一句话。

三、共享的反面是依赖

共享一旦成立,就产生了单点依赖。 文件服务器坏了,所有人都干不了活——这是「集中」必然的代价。

架构 好处 代价
每人一份 没有单点 数据不一致
集中一份 数据一致 有单点

两行都不完美,所以现实里是混合的:关键数据集中、常用数据本地缓存。 这也是整套分布式系统的起点:一致性、可用性、分区容忍,三者只能挑两个(CAP 定理)。 本书不展开 CAP,但记住「共享必有代价」这句话——后面讲 DNS、讲缓存、讲 CDN 都会用到它。

四、动手 Demo:一台机器上的资源,怎么给多个人用

起一个最小的 HTTP 服务,里面只放一份 760 字节的内容, 让 5 个客户端依次来取,统计每次取到多少、总共花了多久。 服务端的内存里只有一份数据,网络上却送了 5 份。

import http.server, socketserver, socket, threading, time

body = (u'36 课共享测试\n' * 40).encode('utf-8')

class H(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-Length', str(len(body)))
        self.end_headers()
        self.wfile.write(body)
    def log_message(self, *a):
        pass

httpd = socketserver.TCPServer(('127.0.0.1', 0), H)
port = httpd.server_address[1]
threading.Thread(target=httpd.serve_forever, daemon=True).start()

t0 = time.perf_counter()
for _ in range(5):
    c = socket.create_connection(('127.0.0.1', port), timeout=2)
    c.sendall(b'GET / HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n')
    while c.recv(4096):
        pass
    c.close()
print('5 次共 %.2f 毫秒' % ((time.perf_counter() - t0) * 1000))
httpd.shutdown()

实跑输出:

--------------------------------------------------------------------
一台机器上的资源,怎么给多个人用
--------------------------------------------------------------------
**计算机网络最早的作用就是共享资源**——
**一份文件存在一台机器上,别人通过网络来取,不必每人存一份。**

服务端只存一份 760 字节,端口 54126。

5 个客户端依次取完,累计 56.84 毫秒,每次拿到 874 字节(含 HTTP 头)。

**磁盘上只有一份,网络上送了 5 份**——**共享的是「存储」,不是「流量」**,这一点常被弄混:
**共享文件省的是磁盘,不是带宽;带宽反而不够用。**

「服务端 760 字节、每次拿到 874 字节」这两个数差 114——多出来的是 HTTP 响应头。 这就是「信息通信」的固定开销:为了让对方看懂,每次都要附带说明。 注意这里 5 个客户端是「依次」取的,不是并发。 并发下的数字会完全不同——本章的 Demo 只验证「一份数据被送多次」这件事,不测并发性能。

30 秒实验

  1. 把 5 次改成 50 次,看总耗时是不是正好涨 10 倍——如果不是,说明有固定开销在里面。
  2. 把 body 从 760 字节改成 7600 字节,看「每次拿到的字节」与「服务端存的字节」差多少。
  3. 用 threading 把 5 个客户端改成同时跑,看总耗时是变短还是变长,想想为什么。

常见误区

  1. 以为共享就是「大家都能访问」。 共享真正的代价是「必须有人维护」,而且坏了会影响所有人。
  2. 以为文件服务器省带宽。 恰恰相反,它把本地的磁盘读取变成了网络传输,带宽压力更大。
  3. 以为并发一定比串行快。 回环上的并发要处理锁与调度,小数据量下反而更慢。
自测三问(点开对答案) 1. 「共享文件省磁盘不省带宽」这句话怎么理解? —— **存储从 N 份变成 1 份,但每次访问都要走网络**。访问人数越多,网络压力越大。 **省下的磁盘变成了付出的流量。** 2. 服务端只存 760 字节,客户端每次收到 874 字节,差的是什么? —— **差的是 HTTP 响应头**(状态行、Content-Length、日期等)。 **这部分是「让对方看懂」的固定成本**,数据越短占比越高。 3. 集中共享带来了什么必然的代价? —— **单点依赖**。服务器一坏,所有人受影响。 **所以现实里是「关键数据集中、常用数据缓存」的混合结构。**

1.1 节到此结束。下一节换个视角看历史:七个阶段,每一步都是被一个具体需求推出来的。

相关笔记