《Go组件设计与实现》-netpoll的总结
主要针对字节跳动的netpoll网络库进行总结。netpoll网络库相比于go本身的net标准库更适合高并发场景。
基础知识
netpoll与go.net库一样使用epoll这种IO多路复用机制处理网络请求。
基本理解
我们知道linux万物皆文件,每个文件有个文件标识符fd,我们可以想象linux提供给我们的socket fd就是操作系统将传输层及以下的协议进行封装抽象化的一个接口。我们可以简单把socket理解成对应的一次tcp连接。 那么网络操作根本上也是针对网卡的IO操作,我们需要读取数据/写入数据,那么如何更加高效地处理数据呢?目前大多数网络库都使用IO多路复用机制,在linux系统中最先进的io多路复用就是epoll机制。
epoll工作方式
- 事件通知机制
- epoll_ctl/epoll_wait
- ET(边缘触发)/LT(水平触发)
事件通知机制
- 注册事件:epoll需要注册一些可读的事件
- 监听事件:监听到可读的数据
- 触发事件:通知数据可读
主要还是有两个系统调用:
- epoll_ctl
- epoll_wait
工作模式
epoll有两种触发工作模式:ET和LT
- ET也叫边缘触发,注册的事件满足条件之后,epoll只会触发一次通知。就算你这一次的读写事件的数据没有处理完,下一次epoll_wait也不会再触发通知。
- LT也叫水平触发,注册的事件满足条件之后,不管数据是否读写完成,每一次epoll_wait都会通知当前监听的fd事件。
BIO/NIO
- BIO:blocking I/O,阻塞I/O。就是当我们向一个socket发起read的时候,数据读取完成之前一直是阻塞的。
- NIO:nonblocking I/O,非阻塞I/O。就是read数据的时候不阻塞,立即返回。
那么我们每次发现socket中有可读数据的时候,我们就会开启一个goroutine读取数据。
Netpoll的优化点
go的net库是BIO的,浪费了更多的goroutine在阻塞,并且难以对连接池中的连接进行探活。 netpoll采用了LT的触发方式,这种触发方式也就导致编程思路的不同
ET
LT
netpoll采用LT的编程思路 由于netpoll想在 系统调用 和 buffer 上做优化,所以采用LT的形式。
优化系统调用
syscall这个方法其实有三步:
- enter_runtime
- raw_syscall
- exit_runtime
由于系统调用是一个耗时的阻塞操作,容易造成goroutine阻塞,所以需要加入一些runtime的调度流程。 但是,epoll_wait触发的事件,保证不会被阻塞,所以netpoll直接采用RawSyscall方法做系统调用,跳过了runtime的一些逻辑。
优化调度
使用msec动态调参和runtime.Gosched主动让出P
msec动态调参
epoll_wait的系统调用有个参数是,等待时间,设置成-1是无限等待事件到来,0是不等待。
这样就有事件到来的时候下次循环的epoll_wait采用立即返回,没有事件就一直阻塞,减少反复无用的调用。
runtime.Gosched主动让出P
如果msec为-1的话会立即进入下一次循环,开启新的epoll_wait调用,那么调用就阻塞在这里,goroutine阻塞时间长了之后会被runtime切换掉,只能等到下一次执行这个goroutine才行,导致时间浪费。 netpoll调用runtime.Gosched方法主动将GMP中的P让出,减少runtime的调度过程。
优化buffer
我们在读取和写入数据的时候需要使用到buffer。 多数框架使用环形buffer,可以做到流式读写。但是环形buffer容量是死的,需要扩容的话,需要重新copy数组,引入了很多的并发问题。
LinkBuffer
netpoll使用的buffer实现包括:
- 链表解决扩容copy问题
- sync.Pool复用链表节点
- atomic访问size,规避data race和锁竞争
还有一些nocopy方面的优化,减少了write和read的次数,从而提高了读取和发送的时候的编解码效率。
更多信息看:https://www.cloudwego.io/zh/blog/2021/10/09/字节跳动在-go-网络库上的实践/#nocopy-buffer
《Go组件设计与实现》-netpoll的总结的更多相关文章
- 《WePayUI组件设计的秘密》——2016年第一届前端体验大会分享
本文是博主参加第一届前端体验大会 | 物勒工名做的分享<WePayUI组件设计的秘密>,内容主要分为2个部分: 一.浅析UI库/框架的未来 讨论的UI库或者框架,主要包含展示和交互的css ...
- HTML5拓扑图形组件设计之道(一)
HT for Web(http://www.hightopo.com/guide/readme.html)提供了涵盖通用组件.2D拓扑图形组件以及3D引擎的一站式解决方案,正如Hightopo官网所表 ...
- HT图形组件设计之道(四)
在<HT图形组件设计之道(二)>我们展示了HT在2D图形矢量的数据绑定功能,这种机制不仅可用于2D图形,HT的通用组件甚至3D引擎都具备这种数据绑定机制,此篇我们将构建一个3D飞机模型,展 ...
- HT图形组件设计之道(三)
上篇我们通过定制了CPU和内存展示界面,体验了HT for Web通过定义矢量实现图形绘制与业务数据的代码解耦及绑定联动,这类案例后续文章还会继续以便大家掌握更多的矢量应用场景,本篇我们先切换个话题, ...
- HT图形组件设计之道(一)
HT for Web简称HT提供了涵盖通用组件.2D拓扑图形组件以及3D引擎的一站式解决方案,正如Hightopo官网所表达的我们希望提供:Everything you need to create ...
- xmlplus 组件设计系列之零 - xmlplus 简介
xmlplus 是什么 xmlplus 是博主写的一个 JavaScript 框架,用于快速开发前后端项目. xmlplus 基于组件设计,组件是基本的构造块.评价组件设计好坏的一个重要标准是封装度. ...
- React组件设计
React组件设计 组件分类 展示组件和容器组件 展示组件 容器组件 关注事物的展示 关注事物如何工作 可能包含展示和容器组件,并且一般会有DOM标签和css样式 可能包含展示和容器组件,并且不会有D ...
- React组件设计(转)
React组件设计 组件分类 展示组件和容器组件 展示组件 容器组件 关注事物的展示 关注事物如何工作 可能包含展示和容器组件,并且一般会有DOM标签和css样式 可能包含展示和容器组件,并且不会有D ...
- 【转载】COM 组件设计与应用(十七)——持续性
原文:http://vckbase.com/index.php/wv/1264.html 一.前言 我们写程序,经常需要实现这样的需求: 例一.程序运行产生一个窗口,用户关闭的时候需要记录窗口的位置, ...
- 【转载】COM 组件设计与应用(十一)—— IDispatch 及双接口的调用
原文:http://vckbase.com/index.php/wv/1236.html 一.前言 前段时间,由于工作比较忙,没有能及时地写作.其间收到了很多网友的来信询问和鼓励,在此一并表示感谢.咳 ...
随机推荐
- malloc实现
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放 掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚 ...
- python selenium 多账户自动登入163邮箱
pycharm一些快捷键: ' ctrl ' +' / ' :注释 ' Tab ' :同时缩进 ' shift ' +' Tab ' :左移 一次缩进 本文webinfo.txt路径:C:\Pytho ...
- iNeuOS工业互联网操作系统,发布3.6.4版本:云端安全控制和实时日志功能,附Chrome、Firefox和Edge浏览器测试性能对比
目 录 1. 概述... 2 2. 平台演示... 2 3. 云端控制和实时日志设计和技术... 2 4. 实时日志测试... 2 1. 概述 ...
- WebRTC音频通话升级为视频通话
我们有时候在音频通话过程中,想要改成视频通话.如果挂断当前通话再重新发起视频通话就会显得比较麻烦. 因此很多app提供了将音频通话升级成视频通话的功能,同时也有将视频通话降为音频通话的功能. 本文演示 ...
- CF977B Two-gram 题解
Content 给定一个字符串 \(s\),请求出出现次数最多的长度为 \(2\) 的子串. 数据范围:\(2\leqslant |s|\leqslant 100\). Solution 直接求出所有 ...
- CF1490D Permutation Transformation 题解
Content 给定一个排列 \(a\),按照以下方法构造一棵树: 选择当前排列中的最大数作为根的编号. 最大数左边的所有数按照上述方法建左子树,若没有数则该节点没有左儿子. 最大数右边的所有数按照上 ...
- Solon 1.6.10 重要发布,现在有官网喽!
关于官网 千呼万唤始出来: https://solon.noear.org .整了一个月多了,总体样子有了...还得不断接着整! 关于 Solon Solon 是一个轻量级应用开发框架.支持 Web. ...
- c/c++实现CRC查表及算法
说明 CRC被广泛应用到各个领域.足见其厉害之处 本文介绍的是CRC查表法. 拷贝代码即可使用 CRC 的起始值 本来默认是0, 实际生产中遇到过,CRC初始值为0xFFFF, 故将其初始值以参数的形 ...
- 【LeetCode】1464. 数组中两元素的最大乘积 Maximum Product of Two Elements in an Array (Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 找最大次大 日期 题目地址:https://le ...
- 【LeetCode】1056. Confusing Number 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcode ...