能否在GNU/Linux系统中将TCP_NODELAY设为所有连接的默认配置?
能否在GNU/Linux系统中将TCP_NODELAY设为所有连接的默认配置?
嘿,刚好有篇文章给出了一个挺明确的结论:应该默认始终开启TCP_NODELAY。顺带提一句,2011年的时候Solaris还没法实现类似的全局设置,但在新版GNU/Linux系统上,咱们有可行的方案来满足你的两个需求:
1. 以root身份为所有用户的所有套接字全局开启
Linux本身没有直接的sysctl参数能一键全局默认开启TCP_NODELAY,但有两种靠谱的实现方式:
- 防火墙规则自动修改TCP选项:用nftables或者iptables的mangle表,给所有出站的TCP连接自动加上TCP_NODELAY选项。比如用iptables的mangle表配合相关参数,把TCP_NODELAY的设置插入到TCP头部里,这样所有新建的TCP连接都会自动启用这个选项。
- 全局共享库注入:写一个简单的共享库,hook住
socket()、connect()这类系统调用,在套接字创建好之后自动调用setsockopt()开启TCP_NODELAY。然后把这个库的路径加到系统全局的/etc/ld.so.preload文件里,这样所有系统进程都会加载这个库,自动开启TCP_NODELAY。不过这种方法要留意兼容性,别影响到那些依赖特定TCP行为的程序。
2. 以普通用户身份为自己创建的所有进程(及子进程)开启
普通用户没法改系统全局配置,但可以通过用户级的环境变量来实现:
- 用户级共享库注入:同样写一个hook套接字调用的共享库,然后在自己的shell配置文件(比如
~/.bashrc或者~/.zshrc)里加一行export LD_PRELOAD=/path/to/your/libnodelay.so。这样所有从这个shell启动的进程,包括它们的子进程,都会加载这个库,自动给新建的TCP套接字开启TCP_NODELAY。 - 临时会话设置:要是不想全局生效,也可以在启动某个程序前临时设置环境变量,比如
LD_PRELOAD=/path/to/libnodelay.so your-program,这样只有这个程序和它的子进程会应用这个设置。
备注:内容来源于stack exchange,提问作者einpoklum




