操作系统层面(Linux)的底层调优
- 网络栈参数调整
- 增加文件描述符限制:
- 在
/etc/security/limits.conf
文件中添加或修改以下内容,以增加用户可打开的文件描述符数量。
* hard nofile 65535
* soft nofile 65535
- 这对于处理大量并发连接非常重要,因为每个网络连接都需要一个文件描述符。
- 调整TCP参数:
tcp_tw_reuse
:允许快速重用处于TIME - WAIT状态的套接字。在/etc/sysctl.conf
中添加或修改:
net.ipv4.tcp_tw_reuse = 1
tcp_fin_timeout
:减少TIME - WAIT状态的持续时间。修改:
net.ipv4.tcp_fin_timeout = 15
tcp_max_syn_backlog
:增加TCP连接请求队列的大小,以处理更多的并发连接请求。
net.ipv4.tcp_max_syn_backlog = 16384
- 系统调用优化
- 使用
epoll
:epoll
是Linux下高性能I/O复用模型,相比传统的select
和poll
,它更适合处理大量并发连接。epoll
通过epoll_create
、epoll_ctl
和epoll_wait
等系统调用实现。
Python语言特性与相关网络库结合
- 使用
asyncio
库
asyncio
是Python的异步I/O库,与底层的epoll
(在Linux上)紧密结合,实现高性能的异步网络编程。
- 示例代码:
import asyncio
async def handle_connection(reader, writer):
data = await reader.read(1024)
message = data.decode('utf - 8')
addr = writer.get_extra_info('peername')
print(f"Received {message!r} from {addr!r}")
response = f"Hello, you sent {len(message)} bytes."
writer.write(response.encode('utf - 8'))
await writer.drain()
print("Close the connection")
writer.close()
async def main():
server = await asyncio.start_server(handle_connection, '127.0.0.1', 8888)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
- 使用
uvloop
uvloop
是asyncio
事件循环的替代品,基于libuv
(一个高性能的事件驱动I/O库),进一步提升性能。
- 安装
uvloop
:pip install uvloop
- 使用示例:
import asyncio
import uvloop
async def some_task():
await asyncio.sleep(1)
print('Task completed')
async def main():
tasks = [some_task() for _ in range(10)]
await asyncio.gather(*tasks)
if __name__ == "__main__":
uvloop.install()
asyncio.run(main())
socket
库的优化使用
- 当直接使用
socket
库时,可以设置一些套接字选项来与底层优化配合。例如,设置SO_REUSEADDR
选项来允许重用本地地址:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 8888))
sock.listen(10)