草庐IT

Linux高性能网络编程十谈 | 网络篇

最近又到了面试季,高性能网络编程对于后端程序猿是必备的知识考点,于是为了方便大家(也方便自己),整理了高性能网络编程十谈,本篇是网络篇,主要介绍一些通用的网络知识,温故知新。第一部分:tcp/ip协议栈之ip协议栈详解1、tcp/ip协议栈分为四层或者七层,但是便于大家理解,基本上都是用四层模型,如:数据链路层,网络层,传输层和应用层。其中封包的流程是:应用层数据--->tcp/udp头部(20字节)+应用层数据--->ip头部(20字节)+tcp/udp头部(20字节)+应用层数据--->以太网头部(18字节)+ip头部(20字节)+tcp/udp头部(20字节)+应用层数据这些数据每一个头

Linux高性能网络编程十谈 | TCP底层的收发过程

谈完上一篇《Linux高性能网络编程十谈|网络篇》,我们继续探索高性能网络编程,但是我觉得在谈系统API之前可以先讲一些Linux底层的收发包过程,如下这是一个简单的socket编程代码:intmain(){...fd=socket(AF_INET,SOCKET_STREAM,0);bind(fd,...);listen(fd,...);//如何建立连接...afd=accept(fd,...);//如何接收数据...read(afd,...);//如何发送数据...send(afd,...);//如何关闭连接...close(fd);...}第一部分:如何建立连接从上一篇文章我们介绍了网络协

Linux高性能网络编程十谈 | 系统调用

在谈《系统调用》之前,先解答上一篇留下的一些问题:(1)发送方法返回成功后,数据一定发送到了TCP的对端么?send方法成功返回,并不一定表示数据发送到对端,TCP是可靠的协议,如果数据遇到异常,TCP底层会重传,所以send调用成功只是代表数据拷贝到了内核态,同时调用IP层的方法返回后,也未必就保证此时数据一定发送成功。(2)1个socket套接字可能被多个进程在使用,出现并发访问时,内核是怎么处理这种状况的?socket是可能被多个进程同时访问的,所以会有内核锁锁住socket,如下内核代码:inttcp_v4_rcv(structsk_buff*skb){...//是否有进程正在使用这个

Linux高性能网络编程十谈 | IO复用和模式

通常我们写一个linux的client和server如下图:但是怎么提升性能?系统是如何快速处理网络事件?因此本文就来谈谈IO复用和模式。第一部分:模式我们都知道socket分为阻塞和非阻塞,阻塞情况就是卡住流程,必须等事件发生;而非阻塞是立即返回,不管事件是否有没有准备好,需要上层代码通过EAGAIN,EWOULDBLOCK和EINPROGRESS等errno返回值来判断,基于非阻塞有两种网络编程模式:Reactor和Proactor事件处理。1、Reactor同步IO模型一般使用Reactor,如果使用线程模式,Reactor是遇到事件就通知工作线程处理,然后主线程继续循环等待事件的发生:

Linux高性能网络编程十谈 | 信号和定时器

在Linux网络编程中,信号处理和定时器是经常遇到的功能,在聊这块内容之前如果您看过上一篇文章《Linux高性能网络编程十谈|IO复用和模式》,应该比较完整的了解epoll了,但是这里还遗漏了一个知识点,那开始先补上这个坑。关于epoll惊群问题,什么是惊群呢?比如我们在写代码过程中,使用两个线程的epoll监听socket,当socket上有事件发生时,两个epoll都会被唤醒,导致会操作同一个socket,这就是惊群,那如何解决呢?(1)使用EPOLLEXCLUSIVE:EPOLLEXCLUSIVE是epoll的扩展选项,它允许一个线程独占一个epoll实例,从而避免了epoll的惊群问题

Linux高性能网络编程十谈 | 多进程和多线程

在Linux网络编程中,我们应该见过很多网络框架或者server,有多进程的处理方式,也有多线程处理方式,孰好孰坏并没有可比性,首先选择多进程还是多线程我们需要考虑业务场景,其次结合当前部署环境,是云原生还是传统的IDC等,最后考虑可维护性,其具体的对比在第三部分具体会展开说。第一部分:多进程1、创建一个进程#includepid_tfork(void);//返回值:子进程返回0,父进程返回子进程的pid,出错返回-1。上面是一个创建进程的函数,那执行当前函数内核会做哪些事情呢?(1)如果需要创建进程需要调用fork,进程调用fork,当控制转移到内核中的fork代码;(2)内核做分配新的内存

Linux高性能网络编程十谈 | 协程

在讲协程之前,先解决上一篇文章《Linux高性能网络编程十谈|多进程和多线程》留下的思考题:(1)如果在多线程程序中fork()子进程,会发生什么,我们要考虑那些问题?首先我们会想到如果一个有多个线程的程序fork出来的子进程是否也是多个线程呢?不是,fork出来的子进程只有一个执行线程,并不会把线程也复制过来;其次fork出来的子进程都会继承父进程的部分数据,包括锁,句柄等,也就是说在父进程被锁的临界区,在子进程也会被锁,这样可能导致在子进程逻辑中继续加锁,导致出现死锁情况;最后使用pthread_atfork解决多线程下的fork问题,如下代码注释掉pthread_atfork这一行代码,

Linux高性能网络编程十谈 | 工具篇

上篇文章主要是介绍《Linux高性能网络编程十谈|协程》,整理如何设计高性能网络编程,接下来的两篇文章主要介绍工具和性能问题分析的总结,有相关的问题可以在留言区留言,我将解答大家的疑问。这是一张linux各个模块的图和对应的工具(当然这里工具比较多,本文只将讲和高性能调试和排查问题相关的工具)。第一部分:Linux服务器参数1、内核参数(1)max-file-number在linux系统中很多资源都是以文件描述符表示的,但是文件描述符并非无限的大,系统分为硬限制和软限制(软限制小于等于硬限制),如果需要修改,则通过/etc/security/limits.conf:hardnofilemax-

Linux高性能网络编程十谈 | 性能优化(CPU和内存)

上一篇文章讲了高性能编程的工具,这一篇我们基于前面的一些知识点和工具来聊一下Linux下的性能优化(本知识点分为两篇,当前主要介绍CPU和内存性能优化)。第一部分:CPU和内存性能度量系统调用这张图阐述一个应用程序需要经过这些模块调用,对于性能每一部分都可能会有影响,那么我们先需要了解每个模块需要怎么度量?1、CPU度量(1)CPU使用率CPU使用率是最直观描述当前服务状态的情况,如果CPU使用率过高,则表示当前遇到了性能瓶颈,其中过高的这个具体值在线上一般是70%-90%之间,要么扩容服务,要么就排查性能问题。查看性能工具有很多,最常用的是通过top-p或者通过查看线程top-H-p观察,另

Linux高性能网络编程十谈|性能优化(网络)

上一篇文章讲了《性能优化(CPU和内存)》,这一节我们主要是聊聊网络优化。第一部分:网络性能度量1、设备度量设备主要是指块设备,由于我们在开发过程中,需要磁盘操作,比如写日志等,所以对于块设备的I/O对于我们需要度量性能的一个重要指标。(1)I/O等待CPU等待I/O操作发生的时间,较高和持续的值很多时候表明IO有瓶颈,一般通过iostat-x命令查看:[root@VM-0-11-centos~]#iostat-xLinux3.10.0-1127.19.1.el7.x86_64(VM-0-11-centos)2023年09月23日_x86_64_(2CPU)avg-cpu:%user%nice