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
[IBM TechXchange Dojo]Watson Discoveryとwatsonx.aiでRAGを実現!座学①
siyuanzh09
0
110
0→1事業こそPMは営業すべし / pmconf #落選お披露目 / PM should do sales in zero to one
roki_n_
PRO
1
1.2k
Docker Desktop で Docker を始めよう
zembutsu
PRO
0
150
生成AI × 旅行 LLMを活用した旅行プラン生成・チャットボット
kominet_ava
0
150
Git scrapingで始める継続的なデータ追跡 / Git Scraping
ohbarye
5
480
Cloudflareで実現する AIエージェント ワークフロー基盤
kmd09
0
280
AWSマルチアカウント統制環境のすゝめ / 20250115 Mitsutoshi Matsuo
shift_evolve
0
110
自社 200 記事を元に整理した読みやすいテックブログを書くための Tips 集
masakihirose
2
320
ドメイン駆動設計の実践により事業の成長スピードと保守性を両立するショッピングクーポン
lycorptech_jp
PRO
10
1.1k
PaaSの歴史と、 アプリケーションプラットフォームのこれから
jacopen
7
1.4k
WantedlyでのKotlin Multiplatformの導入と課題 / Kotlin Multiplatform Implementation and Challenges at Wantedly
kubode
0
240
2024年活動報告会(人材育成推進WG・ビジネスサブWG) / 20250114-OIDF-J-EduWG-BizSWG
oidfj
0
180
Featured
See All Featured
Facilitating Awesome Meetings
lara
51
6.2k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
98
18k
Unsuck your backbone
ammeep
669
57k
Fireside Chat
paigeccino
34
3.1k
Making the Leap to Tech Lead
cromwellryan
133
9k
How GitHub (no longer) Works
holman
312
140k
RailsConf 2023
tenderlove
29
970
Embracing the Ebb and Flow
colly
84
4.5k
GraphQLとの向き合い方2022年版
quramy
44
13k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.3k
How to train your dragon (web standard)
notwaldorf
89
5.8k
Building Applications with DynamoDB
mza
93
6.2k
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和端口,突破端口数量限制,用途: 访问代理服务器
内网/外网百万长连接压力测试 ......
谢谢聆听!