Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Linux系统服务端口的那些事
Search
yongboy
June 28, 2014
Technology
2
1.4k
Linux系统服务端口的那些事
了解Linux服务器端口的用途和局限,以及如何突破端口限制。
yongboy
June 28, 2014
Tweet
Share
Other Decks in Technology
See All in Technology
【Developers Summit 2025】プロダクトエンジニアから学ぶ、 ユーザーにより高い価値を届ける技術
niwatakeru
2
1.4k
人はなぜISUCONに夢中になるのか
kakehashi
PRO
6
1.6k
室長と気ままに学ぶマイクロソフトのビジネスアプリケーションとビジネスプロセス
ryoheig0405
0
360
エンジニアのためのドキュメント力基礎講座〜構造化思考から始めよう〜(2025/02/15jbug広島#15発表資料)
yasuoyasuo
17
6.7k
Classmethod AI Talks(CATs) #16 司会進行スライド(2025.02.12) / classmethod-ai-talks-aka-cats_moderator-slides_vol16_2025-02-12
shinyaa31
0
110
SA Night #2 FinatextのSA思想/SA Night #2 Finatext session
satoshiimai
1
140
インフラをつくるとはどういうことなのか、 あるいはPlatform Engineeringについて
nwiizo
5
2.6k
Helm , Kustomize に代わる !? 次世代 k8s パッケージマネージャー Glasskube 入門 / glasskube-entry
parupappa2929
0
250
Culture Deck
optfit
0
420
地方拠点で エンジニアリングマネージャーってできるの? 〜地方という制約を楽しむオーナーシップとコミュニティ作り〜
1coin
1
230
滅・サービスクラス🔥 / Destruction Service Class
sinsoku
6
1.6k
個人開発から公式機能へ: PlaywrightとRailsをつなげた3年の軌跡
yusukeiwaki
11
3k
Featured
See All Featured
Optimizing for Happiness
mojombo
376
70k
Writing Fast Ruby
sferik
628
61k
How to train your dragon (web standard)
notwaldorf
91
5.8k
Code Review Best Practice
trishagee
67
18k
Visualization
eitanlees
146
15k
Designing on Purpose - Digital PM Summit 2013
jponch
117
7.1k
Facilitating Awesome Meetings
lara
52
6.2k
The Pragmatic Product Professional
lauravandoore
32
6.4k
Thoughts on Productivity
jonyablonski
69
4.5k
Six Lessons from altMBA
skipperchong
27
3.6k
Mobile First: as difficult as doing things right
swwweet
223
9.3k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.7k
Transcript
Linux服务器端口的那些事 了解端口的用途和局限,以及如何突破端口限制 聂永@2014/06/26
目录 目录 IP和协议端口 网络四元组、二元组 突破端口限制 代码绑定IP和端口 外部程序绑定IP和端口 地址和TIME_WAIT 服务器地址重用和释放 演示和用途
数据进入栈封装过程
IP地址位置 IP报文 IP地址属于IP数据报,标识源主机和目标主机
协议端口在TCP数据包中位置 只有TCP数据包头部中包含端口 端口号和TCP服务器进程存在映射关系 端口,具有数据包路由作用 TCP传输层根据端口路由数据包到服务器程序所申请的缓存队列中
协议端口用途 一台服务器好比一座院子 IP地址比作院子大门;一座院子对应至少一个大门 每一个具体的服务程序进程好比一个房子 端口号好比进入房间的门
一个房间至少一个门 服务器程序可以决定由哪一个大门才能进入房间 以太网帧根据IP地址决定投递主机位置,端口决定数据报送达应用程 序映射 服务器内核接收的数据将根据端口进行路由传递到对应程序中
协议端口的一些常识 16位表示 范围:从0 到65535(2^16-1) 已知端口号[0,1023],这些端口由IANA分配和控制 Linux下需要root权限才能使用
[1024,65535],可自由使用端口数量不超过64512个 但不要和已有服务进行冲突
UNP对网络四元组的解释 《UNIX网络编程卷1:套接字联网API(第3版)》(简称UNP)解 释: 一个TCP连接的套接字对(socket pari)是一个定义该连接的两个端点 的四元组,即本地IP地址、本地TCP端口号、外地IP地址、外地TCP 端口号。套接字对唯一标识一个网络上的每个TCP连接。
...... 标识每个端点的两个值(IP地址和端口号)通常称为一个套接字。
四元组解释 仅针对TCP IP用于标识通讯的机器,端口号用于标识通信的进程。 网络四元组,一个完整TCP连接参阅双方体现: {请求者本机IP地址,请求者本机端口,目标IP地址,目标端口} 一次TCP请求必须把自身IP、PORT以及目标IP、目标PORT都要携
带上
Linux系统端口范围 默认范围:1~65535 0-1023已知端口,已被分配,需要ROOT权限 可被自由使用端口范围:65535 - 1024 ≈
64000 查看Linux系统默认可使用端口范围: sysctl -a | grep 'net.ipv4.ip_local_port_range' 32768 61000 修改其端口范围: sysctl -w net.ipv4.ip_local_port_range=1024 65535 保存修改: sysctl -p 持久化
如何突破端口数量限制 默认情况下,系统对外发出的请求数量受限于可用端口数量! 网络四元组中{本机IP,本机Port}两元组表示一个套接字 一个套接字表示系统可以向外请求的一个完整的TCP连接 套接字的数量表示系统可对外请求的完整TCP连接数量!
本机可用TCP套接字数量 = 本机IP数量 * 本机可用端口数量 绑定10个IP地址,自由可用端口约64000,那么可用端口数量 10 * 64000 = 640000,64万!
其它受限条件 打开文件句柄的限制,必须要大于可用端口数量 系统内存限制 每一个连接最少占用4K内存,连接数*4K = 需要的内存数,要求系 统内存要能够完全满足
线程/IO模型,非阻塞型:同步非阻塞/异步非阻塞,不用占满CPU 系统绑定的物理网卡数量受限
虚拟IP来帮忙 添加物理网卡,费时费劲,不太方便 可分配一个或多个IP地址给系统的虚拟IP,很方便! Linux添加虚拟IP: ifconfig eth0:0 192.168.190.151
netmask 255.255.255.0 up 写入/etc/rc.local里可防止重启后丢失 试试Docker 已经释出Docker 1.0,可以尝试一下
代码指定IP和端口 C语言如何做 struct sockaddr_in clnt_addr; clnt_addr.sin_addr.s_addr = inet_addr(server_ip); clnt_addr.sin_port
= htons(server_port); Java如何做 java.net.InetSocketAddress 此类实现 IP 套接字地址(IP 地址 + 端口号)。它还可以是一个对 (主机名 + 端口号),在此情况下,将尝试解析主机名。 如果解析失败,则该地址将被视为未解析地址,但是其在某些情形下 仍然可以使用,比如通过代理连接。 服务器程序可以绑定所有可用IP地址 客户端请求者只能绑定一个具体IP(若非手动指定,系统默认选择可 用IP)
代码示范 服务器端示范程序,绑定IP和端口 https://gist.github.com/yongboy/37875ad2476b0a8cab90 客户端示范程序,可绑定所有可用IP和端口,对外发出海量请求 https://gist.github.com/yongboy/5476214 后面会演示
指定已有程序绑定IP/端口? 已有程序,如何修改其绑定的IP地址和端口 ? 修改配置文件 试试linux系统的bindp小程序吧! https://github.com/yongboy/bindp
可在运行之前硬绑定的指定IP和端口 原理: LD_PRELOAD,允许定义在程序运行前优先加载的动态链接库 如何使用: BIND_ADDR="your ip" BIND_PORT="your port" LD_PRELOAD=/your_path/bindp.so the real command ...
bindp + nginx + curl的示范1 nginx默认80端口, 设置nginx以8888端口进行启动 BIND_PORT="8888" LD_PRELOAD=/home/yongboy/bindp/bindp.so
/usr/sbin/nginx -c /etc/nginx/nginx.conf 测试端准备 绑定特定IP和端口: BIND_ADDR="192.168.192.141" BIND_PORT="16888" LD_PRELOAD=/home/yongboy/bindp/bindp.so curl http://192.168.192.130 nginx日志输出:
bindp + nginx + curl的示范2 测试端第一次请求 BIND_ADDR="192.168.192.141" BIND_PORT="16888" LD_PRELOAD=/home/yongboy/bindp/bindp.so
curl http://192.168.192.130 测试端第二次请求(间隔很短,不超过10秒钟) BIND_ADDR="192.168.192.141" BIND_PORT="16888" LD_PRELOAD=/home/yongboy/bindp/bindp.so curl http://192.168.192.130 持续观察Nginx日志输出
端口释放以及TIME_WAIT阶段 端口释放发生在四次挥手期间 主动关闭方产生TIME_WAIT 主动方最后一次发送挥手时计算 等待真正关闭
占用端口何时释放? 测试端连接虽已关闭,但被占用端口系统不会立即释放 主动关闭方产生TIME_WAIT TIME_WAIT需要等待分组彻底消失,2倍MSL(Maximum Segment Life), 1MSL
= 30s(Linux系统) sysctl -a | grep net.ipv4.tcp_fin_timeout net.ipv4.tcp_fin_timeout = 60 原因: 1)TIME_WAIT可确保系统有足够时间让对端收到Fin ACK,如果 对方没有收到Fin Ack,会触发重发Fin ACK,2个MSL时间周期 2)系统有足够的时间让已关闭的连接不会跟后面的连接混淆(避免 连接被重用时,可能路由器层面缓存IP数据包,导致混淆) 3)TIME_WAIT下一站是真正的关闭
服务器程序地址重用 服务器程序启动时需要显式标注自身需要地址重用 C语言版: int reuseaddr_on = 1; if
(setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on))) err(1, "setsockopt failed"); Java&Netty 版本 Java: ServerSocket socket = new ServerSocket(); socket.setReuseAddress(true); Netty 3.x bootstrap.setOption("reuseAddress", true); Netty 4.x/5.x ServerBootstrap server = new ServerBootstrap(); server.group(bossGroup, workerGroup) .option(ChannelOption.SO_REUSEADDR, true); 演示实际效果 ?
服务器程序地址重用2 不指定地址重用,在短时间内(60S内)再次重启: server: bind failed: Address already in use
地址重用 可以快速重启 同一端口可以被多次使用,但需要绑定到不同IP上 不同IP绑定同一端口 绑定不存在的IP地址: bind failed: Cannot assign requested address 不指定具体IP,意味着继续使用默认IP,其它进程绑定端口 bind failed: Address already in use 已绑定的指定IP和端口,其它进程再次绑定: bind failed: Address already in use
服务器如何快速回收端口? Linux系统默认值: net.ipv4.tcp_tw_reuse = 0 net.ipv4.tcp_tw_recycle =
0 默认都是关闭 tcp_tw_recycle,比较激进,若开启需同时设置 tcp_timestamps=1 不建议修改 修改可能会产生意想不到的问题 服务器端尽量不要主动关闭连接
Linux一些小工具 通过端口查看进程 lsof -i:port 进程查看端口 netstat
–nltp|grep 进程号 SS命令
突破端口限制的示范/用途 若有时间,演示从测试机发出超过64000个对外请求 只要机器性能够好,可以发出超过100万个并发长连接请求 绑定IP和端口,突破端口数量限制,用途: 访问代理服务器
内网/外网百万长连接压力测试 ......
谢谢聆听!