【操作系统】聊聊C10K

news2024/12/25 23:43:33

什么是C10K问题

C10K 就是 Client 10000 问题,即“在同时连接到服务器的客户端数量超过 10000 个的环境中,即便硬件性能足够, 依然无法正常提供服务。

其实说白了就是并发请求1W个请求 同时进行连接服务端,服务端可以支撑服务。带宽和内存如果够用的话,那么最后的瓶颈其实就在IO模型上。如果说为每个连接都创建一个线程进行处理,那么线程的切换,内存占用都会是瓶颈。
一要么就是一个线程同时处理多个任务,二使用更少的资源进行处理并发请求。

操作系统层面

文件句柄:每创建一个连接,都会使用一个文件描述符,当不够用的时候,就会出现 Socket/File:Can’t open so many files
而默认一个进程可以创建1024个,
在这里插入图片描述
我们可以进行设置

fs.file-max = 10000
net.ipv4.ip_conntrack_max = 10000
net.ipv4.netfilter.ip_conntrack_max = 10000

系统内存
每个TCP连接也会使用发送缓冲区和接收缓冲区,分别是最小,默认,最大值。如果1W个连接就是 156MB的发送缓冲区。 1.2G 接收缓冲区。以目前的硬件内存资源 也可以支撑。

root@qxlxi:/data# cat /proc/sys/net/ipv4/tcp_wmem
4096	16384	4194304
root@qxlxi:/data# cat /proc/sys/net/ipv4/tcp_rmem
4096	131072	6291456

网络带宽
一个连接传输1KB ,大约1W连接,需要80Mbps 也可以

因为当创建多个线程的时候,线程之间数据的切换,用户态到内核态,是不足以支撑,所以问题的瓶颈就在于IO网络模型上

IO模型优化

IO事件通知方式 是用在套接字接口的文件描述符上的

  • 水平触发:文件描述符可以非阻塞的执行IO,就触发通知,应用程序会随时查询文件描述符的状态,然后根据状态进行执行IO操作。

  • 边缘触发:只有文件描述符的状态发生改变,才发送一次通知,应用程序多执行IO,只有无法读写的时候,才停止。

阻塞IO+进程

每个连接通过fork派生一个子进程进行处理,单独的子进程负责所有连接所有IO。效率不高,拓展性差。资源占用率高。

do { 
     accept connections 
     fork for conneced connection fd 
     process_run(fd)
  }

缺点是进程模型占用资源太大。

阻塞IO+线程

可以使用轻量级的线程进行处理,每个连接就创建一个线程处理。为了提升效率 可以使用线程池。

do{ 
    accept connections pthread_create 
    for conneced connection fd 
    thread_run(fd)
 } while(true)

但是因为这样存在多个线程之间在发生IO时,在用户态和内核态之间进行频繁切换,以及数据拷贝,比较耗费资源。并且IO时线程需要进行阻塞等待,当IO执行完毕后,需要切换回执行线程。

非阻塞 I/O + readiness notification + 单线程

应用程序可以采用轮询的方式进行对创建的套接字进行询问,找出需要进行IO操作的套接字。但是当创建的连接过多的时候,其实需要O(N)的时间进行才能遍历到。CPU消耗比较大。

for fd in fdset{ 
      if(is_readable(fd) == true) { 
          handle_read(fd) 
      }else if(is_writeable(fd)==true) { 
          handle_write(fd) 
      }
}

上述的方式比较耗费CPU,并且需要O(N)的遍历。并且需要应用程序主动去判断那些IO可以操作。应该由操作系统来通知我们套接字可以读。这种是select、poll这样IO分发技术。并且需要把文件描述符集合从用户空间传入内核空间,内核修改后,在传输用户空间,也增加了成本。

do {   
      poller.dispatch() 
      for fd in registered_fdset { 
           if(is_readable(fd) == true){ 
               handle_read(fd) 
           } else if(is_writeable(fd)==true){ 
               handle_write(fd) 
           }
     }
 }while(ture)

虽然上述的方式可以,但是每次需要对注册的套接字进行排查,如果只对有IO操作的套接字进行处理,效率可以大大提升。

do {  
        poller.dispatch() 
        for fd_event in active_event_set { 
             if(is_readable_event(fd_event) == true) { 
                  handle_read(fd_event) 
             }else if(is_writeable_event(fd_event)==true) { 
                  handle_write(fd_event) 
             }
      }
}while(ture)

非阻塞 I/O + readiness notification + 多线程

这种方式就是IO多路复用,其实就是一个主线程进行分发任务,然后子线程进行任务的处理。
在这里插入图片描述

小结

本篇简要介绍了C10K问题,本质是操作系统处理大并发请求的问题,对于客户端创建的连接到达1W个连接时,服务进程、线程就会导致数据拷贝频繁,缓存IO、内核将数据拷贝到用户进程空间、阻塞,进程/线程上下文切换开销大,从而导致资源耗尽,而导致程序崩溃。而最终其实是通过多路复用技术来解决的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1017970.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统之安装uptime-kuma服务器监控面板

Linux系统之安装uptime-kuma服务器监控面板 一、uptime-kuma介绍1.1 uptime-kuma简介1.2 uptime-kuma特点 二、本次实践环境介绍2.1 环境规划2.2 本次实践介绍2.3 环境要求 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本3.3 检查系统是否安装Node.js 四、部署…

post更新,put相当于删除重新增一条

索引数据 //删除后新增 PUT my_dynamic_temp/_doc/1 { “name”:“test”, “class”:“1204” } //覆盖更新 POST my_dynamic_temp/_update/1 { “doc”: { “name”:“test”, “class”:“1203”, “pernum”:“998” } }

springboot 集成mybatis-plus的使用

一、在spring boot中配置mybatis-plus 1、创建一个spring boot项目&#xff0c;注意勾选mysql 2、在pom.xml文件中添加mybatis-plus的依赖包 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0&qu…

瑞芯微RK3568:烧录系统

烧录系统 文章目录 烧录系统windowsLinuxupgrade_tool 工具烧写烧写 update.img擦除操作使用 rkflash.sh 脚本烧写 编译Linux_SDK后得到多个镜像文件 windows Windows 下通过瑞芯微开发工具&#xff08;RKDevTool&#xff09; 来烧写镜像。 Loader parameter uboot …

狂神docker

狂神说 docker 参考文章 -----docker 概述 docker 为什么会出现&#xff1f;–环境部署麻烦&#xff0c;两套环境&#xff08;开发-运维&#xff09; 我的电脑可以运行&#xff0c;到你那就不可用。 开发即运维–开发打包部署上线一条龙 环境配置十分麻烦&#xff0c;机器部署…

Spring Social微信登录

微信登录的appId获得可在微信开放平台申请&#xff0c;以下用测试号 1、完成WeixinProperties 用测试账号登录 public class WeixinProperties {private String appId "wxd99431bbff8305a0";private String appSecret "60f78681d063590a469f1b297feff3c4&q…

基于SSM+Vue的医学生在线学习交流平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

【数字人】1、SadTalker | 使用语音驱动单张图片合成视频(CVPR2023)

Sad Talker&#xff1a;使用一张图片和一段语音来生成口型和头、面部视频 论文&#xff1a;SadTalker: Learning Realistic 3D Motion Coefficients for Stylized Audio-Driven Single Image Talking Face Animation 代码&#xff1a;https://github.com/Winfredy/SadTalker …

Linux命令200例:dip用于用户与远程主机建立通信连接

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

Stable DIffusion 炫酷应用 | AI嵌入艺术字+光影光效

目录 1 生成AI艺术字基本流程 1.1 生成黑白图 1.2 启用ControlNet 参数设置 1.3 选择大模型 写提示词 2 不同效果组合 2.1 更改提示词 2.2 更改ControlNet 2.2.1 更改模型或者预处理器 2.2.2 更改参数 3. 其他应用 3.1 AI光影字 本节需要用到ControlNet&#xff0c;可…

6.前端·新建子模块与开发(常规开发)

文章目录 学习资料常规开发创建组件与脚本菜单创建-新增自定义图标菜单创建-栏目创建 学习资料 https://www.bilibili.com/video/BV13g411Y7GS?p12&vd_sourceed09a620bf87401694f763818a31c91e 常规开发 创建组件与脚本 首先新建前端的目录结构&#xff0c;属于自己业…

CTF 全讲解:[SWPUCTF 2022 新生赛]webdog1__start

文章目录 参考环境题目learning.php信息收集isset()GET 请求查询字符串全局变量 $_GET MD5 绕过MD5韧性脆弱性 md5()弱比较隐式类型转换字符串连接数学运算布尔判断 相等运算符 MD5 绕过科学计数法前缀 0E 与 0e绕过 start.php信息收集头部检索 f14g.php信息收集 探秘 F1l1l1l1…

Springboot 实践(18)Nacos配置中心参数自动刷新测试

前文讲解了Nacos 2.2.3配置中心的服务端的下载安装&#xff0c;和springboot整合nacos的客户端。Springboot整合nacos关键在于使用的jar版本要匹配&#xff0c;文中使用版本如下&#xff1a; ☆ springboot版本: 2.1.5.RELEASE ☆ spring cloud版本 Greenwich.RELEASE ☆ sp…

Python 算数运算符

视频版教程 Python3零基础7天入门实战视频教程 Python支持所有的基本算术运算符&#xff0c;这些算术运算符用于执行基本的数学运算&#xff0c;如加、减、乘、除和求余等。下面是7个基本的算术运算符。 以下&#xff0c;假设变量a为10&#xff0c;变量b为21&#xff1a; 实…

OpenCV之YOLOv3目标检测

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 目录 前言 一、预处理 1.获取分类名 2.获取输出层名称 3.图像尺度变换 二…

【JavaSE笔记】初识Java

一、前言 Java是一种非常优秀的程序设计语言&#xff0c;它具有令人赏心悦目的语法和易于理解的语义。 本文将通过一个简单的Java程序&#xff0c;介绍Java的一些基础内容。 二、Java基本结构 1、简单的Java程序 从最简单的一个Java程序开始逐渐了解Java语言。 以下是一段…

数学建模——微分方程介绍

一、基础知识 1、一阶微分方程 称为一阶微分方程。y(x0)y0为定解条件。 其常规求解方法&#xff1a; &#xff08;1&#xff09;变量分离 再两边积分就可以求出通解。 &#xff08;2&#xff09;一阶线性求解公式 通解公式&#xff1a; 有些一阶微分方程需要通过整体代换…

echarts的折线图,在点击图例后,提示出现变化,不报错。tooltip的formatter怎么写

在点击图例的年后&#xff0c;提示框会相应的变化&#xff0c;多选和单选都会响应变化。tooptip的重度在formatter tooltip:{show:true,trigger:"axis",alwaysShowContent:true,triggerOn:"mousemove",textStyle:{color:"#fff"},backgroundColor…

结构体-时间的计算

任务描述 本关任务需要你编写函数计算一个时间之前“xx小时xx分xx秒”的时间是多少。 以24小时制的格式记录当前时间&#xff0c;譬如“09:19:52”&#xff0c;表示上午9点19分52秒&#xff0c;则“1小时20分30秒”前的时间应该是“同一天”的“07:59:22”。 提示&#xff1a;…

Scapy 解析 pcap 文件从HTTP流量中提取图片

Scapy 解析 pcap 文件从HTTP流量中提取图片 前言一、网络环境示例二、嗅探流量示例三、pcap 文件处理最后参考 ​ 作者&#xff1a;高玉涵 ​ 时间&#xff1a;2023.9.17 10:25 ​ 环境&#xff1a;Linux kali 5.15.0-kali3-amd64&#xff0c;Python 3.11.4&#xff0c;scapy…