#165 转载:藏龙岛局部地块规划(2016-08-02)

2016-08-02

根据江夏区政府的申请,按照市政府对藏龙岛办事处局部地块规划用地性质调整的有关意见的批示精神,拟对武汉市新城组群 F0401、F0402、F0403、E0303 编制单元控制性详细规划导则进行规划调整,具体内容如下:

#164 我们天天都接触的 IP 地址到底是什么东西?

2016-08-02

IP 地址

IP 就是一个编号,用 32 位二进制数表示,范围是 [0, 4294967295]。

为了阅读方便,IP 地址可以用点分十进制表示,也就是说,每八位用一个十进制数字表示,然后用小数点连接,比如 127.0.0.1。

那么,IP 的范围就可以表示为:0.0.0.0 ~ 255.255.255.255

总数:$2^{32} = 4294967296$ (约 43 亿)

分配机制

IP 的管理和分配是互联网号码分配局(Internet Assigned Numbers Authority,IANA)负责。

早期,IANA 是由美国南加州大学信息科学研究所(USC/ISI)依据美国国防部授权负责,后来移交给非盈利组织 ICANN。

由于互联网是从美国发展起来的,所以美国拿了大量可分配 IP 地址。

为了保证 IP 资源相对公平高效的分配,目前互联网的实际 IP 分配工作是在 IANA 的协调下,由五个区域互联网注册机构(Regional Internet Registry,RIR)负责:

  • 美洲互联网号码注册管理机构(American Registry for Internet Numbers,ARIN
    管理北美、南极洲和部分加勒比地区事务
  • 欧洲 IP 网络资源协调中心(RIPE Network Coordination Centre,RIPE NCC
    管理欧洲、中东和中亚地区事务
  • 亚太网络信息中心(Asia-Pacific Network Information Centre,APNIC
    管理亚洲和太平洋地区事务
  • 拉丁美洲及加勒比地区互联网地址注册管理机构(Latin American and Caribbean Internet Address Registry,LACNIC
    管理拉丁美洲和部分加勒比地区事务
  • 非洲网络信息中心(African Network Information Centre,AfriNIC
    管理非洲事务

我国的网络地址就由 APNIC 分配。APNIC 总部之前在日本东京,后来由于成本问题,1998 年搬到了澳大利亚布里斯班。

非公网 IP(特殊用途地址)

最知名的 10/8, 172.16/12, 192.168/16 三个网段,我们在各种局域网中见到,完整的信息在负责网络地址分配的 IANA 那里可以拿到。

  1. IANA IPv4 Address Space Registry
  2. IANA IPv4 Special-Purpose Address Registry
网段 数量 说明
0.0.0.0/8 $2^{24} = 16777216$ 本地网络,其中 0.0.0.0 表示本机。
10.0.0.0/8 $2^{24} = 16777216$ 私有
100.64.0.0/10 $2^{16} \times 64 = 4194304$ 私有, (100.64 - 100.127),ISP NAT
127.0.0.0/8 $2^{24} = 16777216$ 环回地址
169.254.0.0/16 $2^{16} = 65536$ 链路本地地址(Link-local address)
172.16.0.0/12 $2^{16} \times 16 = 1048576$ 私有,(172.16 - 172.31)
192.0.0.0/24 256 IETF Protocol Assignments
192.0.2.0/24 256 TEST-NET-1
192.31.196.0/24 256
192.52.193.0/24 256
192.88.99.0/24 256 IPv6 to IPv4 relay
192.168.0.0/16 $2^{16} = 65536$ 私有
192.175.48.0/24 256
198.18.0.0/15 $2^{16} \times 2 = 131072$ 私有,(192.18 - 192.19)
198.51.100.0/24 256
203.0.113.0/24 256 MCAST-TEST-NET
240.0.0.0/4 $2^{24} \times 16 = 268435456$ (240 - 255),保留

不知道上面为什么没有列出组播网段 224/4 (224 - 239), 和 240/4 网段一样,共 268435456 个地址。

$2^{32} - (16777216 \times 3 + 4194304 + 65536 \times 2 + 1048576 + 256 \times 8 + 131072 + 268435456 \times 2) = 3702257664$

2 ** 32 - 16777216 * 3 - 4194304 - 65536 * 2 - 1048576 - 256 * 8 - 131072 - 268435456 * 2
3702257664

3702257664 * 100 / (2 ** 32)
392519680 * 100 / (2 ** 32)
392519680 * 100 / 3702257664

所以,可分配地址大约 37 亿,占总 IP 地址数的 86.2%。

根据 全中国一共有多少 IP 地址? 一文的计算(来自 APNIC 数据),中国(含港澳台)一共分配到 IP 地址大约 4 亿,占总 IP 数的 9.14,占可分配 IP 数的 10.6。

大陆 343881984
香港  12612096
澳门    336640
台湾  35688960
--------------
总计 392519680

网络分类

早期,可能包括我们的教科书,总是提到 A 类地址,B 类地址等概念。

标准的说法,叫做 Classful Addressing,分类地址,分级寻址,分类路由。

最早 IP 分配都是按照 IP 第一个字节分配,十分大方。但是最多只能分配 256 次。
眼看着网络发展壮大,接入的机构越来越多,这样下去 IP 地址根本就不够分。
所以想出了分级的概念,按照实际需求来分配 (RFC791, 1981)。

所有的 IP 按照前缀被分成 A, B, C, D, E 五类。

Class 前缀位 网络地址位数 剩余的位数 网络数 每个网络的主机数
A 类地址 0 8 24 128 16,777,214
B 类地址 10 16 16 16,384 65,534
C 类地址 110 24 8 2,097,152 254
D 类地址(群播) 1110 未定义 未定义 未定义 未定义
E 类地址(保留) 1111 未定义 未定义 未定义 未定义

比如:
A 类:100.0.0.0/8 0110
B 类:160.0.0.0/16 1010
C 类:208.0.0.0/24 1101

地址的分配按 8 位,16 位,24 位,三种级别,也就是说每次分配可以选择 256、65536、16777214,三种 IP 数量,IP 不够分配问题暂时得到缓解。

后来,IP 地址还是不够分配,又改成了更加合理的无类别域间路由(Classless Inter-Domain Routine)方案,支持 1, 2, 4, 8, 16, 32, 64, 128, 256, 512...更多细粒度的选择。

到现在为止,又支撑了一些年,不过眼看着 IP 最后还是会耗尽。

IPv4 耗尽问题

为了推迟 IPv4 地址耗尽的问题,电信运营商早就不默认分配公网地址了。
给每户分配一个私有地址,层层 NAT,可能一个小区才一个公网 IP。

好处是再也不用怕 IP 用完。
坏处就是网络变得复杂(依赖中间的 NAT 服务),降低了可靠性。
而且,网络用户变得无法直接通信(P2P),被运营商卡了一道。

局域网 IP

RFC 1918 中定义了内网使用的地址。

10.0.0.0        -   10.255.255.255  (10/8 prefix)
172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
192.168.0.0     -   192.168.255.255 (192.168/16 prefix)

参考资料与拓展阅读

#162 Linux: find 命令

2016-07-29

目录

  • -path
  • -prune 不进入指定目录
find . -path ./.git -prune -o -print
find . -path ./.git -prune -o -path ./build -prune

目录深度

如果使用这几个参数,那么这个参数应该放到最前面

  • -depth
  • -maxdepth 最大迭代深度
  • -mindepth 最小迭代深度

文件名

  • -name
  • -iname

正则

  • -regex
  • -iregex
find ./apps/api/ -maxdepth 3 -regextype "posix-egrep" -regex ".*/(vpc.py|server.py)"

空目录/空文件

# 空目录
find . -type d -empty
# 删除空目录
find . -type d -empty -delete
find . -type d -empty -exec rmdir {} \;

# 空文件
find . -type f -size 0c
find . -type f -empty
# 删除空文件
find . -type f -empty -exec rm {} \;
find . -type f -empty | xargs rm -f
# 如果文件名中有空格,0 是很有必要的
find . -type f -empty -print0 | xargs -0 rm -f
# 交互式
find . -type f -empty -ok rm -rf {} \;

类型

选项:b, c, d (目录), p, f (文件), l (链接), s (Socket), D

用的多的还是目录和文件查找:

  • -type d
  • -type f

大小过滤

可用单位:b (块,512B,默认), c (Byte), w (字,2B), k , M, G

说明:+n, -n, n 分别表示大于,小于,等于。这个规则对 -amin (距离上次访问分钟数), -mtime (距离上次编辑天数), -gid, -inum (inode 数), -links (硬链数), -size, -uid, -used 有效。

大于/小于 10M 的文件:

find . -maxdepth 1 -type f -size +10M
find . -maxdepth 1 -type f -size -10M

# 列出小于三兆的 mp3 文件
find ~/Music -name '*.mp3' -size -3M -ls

权限过滤

# 精准匹配
find . -type f -perm 755 -iname "*.md" -exec chmod 644 {} \;
# 与:u g o 都有执行权限,最低权限判断
find . -type f -perm -111 -iname "*.md" -exec chmod 644 {} \;
# 或:u+x | g+x | o+x 满足一个条件即可
find . -type f -perm /111 -iname "*.md" -exec chmod 644 {} \;

# 这几个参数可以注意一下:
# -writable
# -readable
# -executable
find . -type f -executable -ls

时间过滤

创建和访问时间:

  • -amin 访问时间(分钟)
  • -atime 访问时间(天)
  • -cmin 创建时间(分钟)
  • -ctime 创建时间(天)
  • -mmin 修改时间(分钟)
  • -mtime 修改时间(天)

值得注意的是,上面按天为单位的那些时间过滤参数是按整除来算的,比如:find $HOME -mtime 0,表示一天以内,应为修改时间整除 24 小时为 0 的就是 24 小时以内。

还有一个参数 used,好像是文件状态变更之后的访问时间。

PS: 关于三种时间的差异,参考:2015-01-03 Linux 时间: atime, mtime, ctime

执行命令

  • -print 默认行为,打印文件名

使用 ls 参数

-lsls 命令一样,列出详细信息

find . -name '*.py' -ls

find $HOME -maxdepth 1 -type d -ls

# ls 输出非 ASCII 字符会转义,对中文环境不友好
find $HOME -maxdepth 1 -exec ls -ldh {} + | column -t

使用 delete 参数

find . -maxdepth 1 -type f -name '*~' -delete
find . -maxdepth 1 -type f -name '*.pyc' -delete

使用 exec 参数

find . -type f -exec chmod 644 {} \;
find . -name "*.php" -exec mv {} ~/codes/php \;

find . -type d -name "__pycache__" -exec rm -rf \;
find . -type d -name "__pycache__" -exec rm -rf {} +
find . -type d -name "__pycache__" -depth +4 -print0 -exec rm -rf {} +

联合 xargs 命令:

find . -type d -empty -print0 | xargs -0 -I {} /bin/rm -rf "{}"
find /var/cache/TheSunProject/ -type d -name "backup_*" -print0 | xargs -0 -I {} /bin/rm -rf "{}"
find . -type d -mtime +30 -print0 | xargs -I dir -0 /bin/rm -rvf "dir" > /tmp/delete.log

大部分时候,我们都是用 \; 结果,但其实是有两种方案的:

  • -exec command ; Shell 中,分号需要转义 (\;)
    总是成功返回
  • -exec command +
    一次提供所有参数
echo "import sys; print('>>> %r <<<' % (sys.argv[1:], )); exit(2)" > /tmp/a.py
mkdir -p /tmp/a; cd /tmp/a; touch a " b c " "d;" e;
find . -type f -exec python /tmp/a.py {} \;
# >>> ['./ b c '] <<<
# >>> ['./e'] <<<
# >>> ['./a'] <<<
# >>> ['./d;'] <<<
echo $?
# 0
find . -type f -exec python /tmp/a.py {} +
# >>> ['./ b c ', './e', './a', './d;'] <<<
echo $?
# 1

复杂逻辑

参考手册中 OPERATORS 一节:

  • ( expr ) 在 shell 中括号需要转义
  • expr1 expr2
  • expr1 -a expr2
  • expr1 -and expr2
  • expr1 -or expr2
  • expr1 -o expr2
  • -not expr
  • ! expr
  • expr1 , expr2

排除

find . -path ./.git -prune -false -o -type f
find . -name .git -prune -false -o -used -7 -type f -print
find . -type d \( -name .git -o -name node_modules -o -name build \) -prune -false -o -print

#161 转载:性能测试应该怎么做?

2016-07-08

偶然间看到了阿里中间件Dubbo的性能测试报告,我觉得这份性能测试报告让人觉得做这性能测试的人根本不懂性能测试,我觉得这份报告会把大众带沟里去,所以,想写下这篇文章,做一点科普。

#160 高效的代码部署 [编辑中]

2016-07-08

对于一个服务来讲,代码部署的速度和便捷性并不是一件很要紧的事情。但是对于开发者来说,能够高效部署代码,还是能够在一定程度上提升自己开发和测试的效率。

#158 逻辑运算与位运算

2016-07-01

逻辑运算,一共十六种结果:

  1. 0 矛盾 F
  2. 1 恒真 T
  3. p
  4. q
  5. not p
  6. not q 非 not
  7. p and q 与 and
  8. p or q 或 or
  9. p xor q 异或 xor(相异为 1,相同为 0)
  10. not (p and q) 与非 nand
  11. not (p or q) 或非 nor
  12. not (p xor q) 异或非 xnor(又叫同或,相同为 1,相异为 0)**
  13. (not p) and q 逆非蕴含
  14. p and (not q) 实质非蕴含
  15. (not p) or q 实质条件
  16. p or (not q) 逆命题

基础运算符:与、或、非、异或。

逻辑运算有与或非:&&, ||, !
按位运算有与或非和异或:&|~^

| 按位运算 | 运算符 |
| -------- | ------ | --- |
| 与 | & |
| 或 | | |
| 非 | ~ |
| 异或 | ^ |

参考资料与拓展阅读

#156 Linux 创建用户帐号

2016-06-28

概念

  • 用户
  • 用户组
  • ACL
  • SELinux

useradd 命令

sudo useradd testuser -m -d /home/testuser -s /bin/bash

如果忘记加上 -m 参数,那就只好手动创建用户主目录(家目录):

sudo mkdir /home/testuser
sudo cp -rT /etc/skel /home/testuser
sudo chown -R testuser:testuser /home/testuser

此外,修改用户信息可以使用 usermod 命令:

sudo usermod -d /home/testuser
sudo usermod -s /bin/bash
$ tail -1 /etc/passwd
testuser:x:1001:1001::/home/testuser:/bin/bash

adduser 命令

就相当于封装了比较低级的 useradd 命令,除了执行上面的全部操作,还提供更多的配置项。

# 创建普通的用户帐号
sudo adduser testuser2

# 创建不能用于登录的系统帐号
sudo adduser --system share
$ tail -2 /etc/passwd
testuser2:x:1002:1002:Test User,303,15812345678,02788888888,hello world:/home/testuser2:/bin/bash
share:x:131:65534::/home/share:/bin/false

“Test User,303,15812345678,02788888888,hello world” 这一串是创建过程中让你输入的 “全名”、“房间号”、“工作电话”、“家庭电话”、“其他”,最后逗号隔开,放在 /etc/passwd 文件的注释字段里面。

用户组

addgroup
groupadd
groupdel
groupmems
groupmod
groups