前言

因为最近的工作需要用到不少网络方面的知识,从头学习了遍计算机网络,主要参考:

结合平常的工作整理下最近学到的内容以及相关的资料,可能会比较杂乱。

目标问题

  • 如何分析一个网络请求的延时?
  • 如何分析一个网络请求的转发路径?

互联网结构

互联网可以理解为互相连接的网络,是由很多小型网络互相连接成更大的网络,很多更大的网络再互相连接成更大的网络,最终构成一个覆盖全球的巨大网络。

下图简单描绘了一个家用 PC 向远程服务器发出网络请求的场景,互联网可以划分为网络边缘接入网网络核心。图中的 PC、服务器以及我们日常使用的联网设备都属于网络边缘;通过 Wi-Fi 或者有线方式连接至路由器的这段链路属于接入网;路由器、交换机等分组交换设备构成网络核心。

img

应用层

常用的应用层协议有 HTTP、FTP、Telnet、SSH、DNS、SMTP 等。

HTTP

HTTP 是平常工作中最常用到的应用层协议,主要有 1.0、1.1 与 2.0 三个版本。

  • 1.0 版本:

网络层

如何证明自己拥有某个 IP,以及如何宣告 IP?

比如我购买了一台云服务器,云服务器会具有一个公网 IP,这个 IP 是如何被宣告到互联网中的?通过 BGP 协议进行路由宣告。

在 BGP 中静态路由具有最高的优先级。

路由器

路由器的交换结构有三种实现方式:经内存、经总线和经互联总线三种,企业的网络入口一般使用第二种方式,互联网的核心会使用第三种方式,据说路由器最早的交换结构是由斯坦福大学的一名教授为了追求自己后来的夫人实现的,后来他们创办了 Cisco。

VXLAN

VXLAN 是指虚拟局域网扩展(Virtual Extensible LAN, VXLAN),是一种隧道协议,被定义在 RFC 7348将 L2 以太网帧封装进 L4 UDP 数据包(使用 4789 端口)中,并在 L3 网络中传输,广泛应用于云计算场景中。

VNI 为 24 比特,共有约 1600 万。

Veth

#!/bin/bash -e

# Ref: https://opengers.github.io/openstack/openstack-base-virtual-network-devices-bridge-and-vlan/

BRIDGE=br0
ADDR_PREFIX=172.16.0
BRIDGE_ADDR="$ADDR_PREFIX.1/24"
DEFAULT_ROUTE="$ADDR_PREFIX.1"
VETH_TOTAL=3
ADDR_SUFFIX_BEGIN=2

begin(){
  # sudo sysctl -w net.ipv4.ip_forward=1

  # Setup bridge
  ip link add $BRIDGE type bridge
  ip addr add dev $BRIDGE $BRIDGE_ADDR
  ip link set $BRIDGE up
  iptables -A FORWARD -i $BRIDGE -j ACCEPT
  echo "dev bridge $BRIDGE ($BRIDGE_ADDR) has been setup successfully."

  for ((i=0; i<$VETH_TOTAL; i++ ))
  do
    ns="ns$i"
    veth="c$i"
    veth_peer="c$i-br"
    addr_suffix=$(($i+$ADDR_SUFFIX_BEGIN))
    addr="$ADDR_PREFIX.$addr_suffix/24"

    ip link add $veth type veth peer name $veth_peer
    ip link set dev $veth_peer master $BRIDGE
    ip link set $veth_peer up
    ip netns add $ns
    ip link set $veth netns $ns
    ip -n $ns addr add dev $veth $addr
    ip -n $ns link set $veth up
    ip -n $ns link set lo up
    ip -n $ns route add default via $DEFAULT_ROUTE

    echo "dev veth $veth@$veth_peer (addr: $addr, namespace: $ns) has been setup successfully."
  done
}

clean(){
  ip link delete $BRIDGE
  echo "dev bridge $BRIDGE ($BRIDGE_ADDR) has been cleaned successfully."

  for ((i=0; i<$VETH_TOTAL; i++ ))
  do
    ns="ns$i"
    veth="c$i"
    veth_peer="c$i-br"
    addr_suffix=$(($i+$ADDR_SUFFIX_BEGIN))
    addr="$ADDR_PREFIX.$addr_suffix/24"

    ip netns delete $ns

    echo "dev veth $veth@$veth_peer (addr: $addr, namespace: $ns) has been cleaned successfully."
  done
}

if [[ $1 == "begin" ]]; then
  begin
elif [[ $1 == "clean" ]]; then
  clean
else
  echo "usage:"
  echo "  setup: ./$0 begin"
  echo "  clean: ./$0 clean"
fi