IOCP模型与EPOLL模型的比较 服务器优化

2023-11-23 06:48

本文主要是介绍IOCP模型与EPOLL模型的比较 服务器优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://www.cnblogs.com/lancidie/archive/2013/05/02/3054063.html

一:IOCP和Epoll之间的异同。
异:
1:IOCP是WINDOWS系统下使用。Epoll是Linux系统下使用。
2:IOCP是IO操作完毕之后,通过Get函数获得一个完成的事件通知。
Epoll是当你希望进行一个IO操作时,向Epoll查询是否可读或者可写,若处于可读或可写状态后,Epoll会通过epoll_wait进行通知。
3:IOCP封装了异步的消息事件的通知机制,同时封装了部分IO操作。但Epoll仅仅封装了一个异步事件的通知机制,并不负责IO读写操作。Epoll保持了事件通知和IO操作间的独立性,更加简单灵活。
4: 基于上面的描述,我们可以知道Epoll不负责IO操作,所以它只告诉你当前可读可写了,并且将协议读写缓冲填充,由用户去读写控制,此时我们可以做出额 外的许多操作。IOCP则直接将IO通道里的读写操作都做完了才通知用户,当IO通道里发生了堵塞等状况我们是无法控制的。

同:
1:它们都是异步的事件驱动的网络模型。
2:它们都可以向底层进行指针数据传递,当返回事件时,除可通知事件类型外,还可以通知事件相关数据。

二:描述一下IOCP:
扯远点。首先传统服务器的网络IO流程如下:
接到一个客户端连接->创建一个线程负责这个连接的IO操作->持续对新线程进行数据处理->全部数据处理完毕->终止线程。
但是这样的设计代价是:
1:每个连接创建一个线程,将导致过多的线程。
2:维护线程所消耗的堆栈内存过大。
3:操作系统创建和销毁线程过大。
4:线程之间切换的上下文代价过大。
此时我们可以考虑使用线程池解决其中3和4的问题。这种传统的服务器网络结构称之为会话模型。
后来我们为防止大量线程的维护,创建了I/O模型,它被希望要求可以:
1:允许一个线程在不同时刻给多个客户端进行服务。
2:允许一个客户端在不同时间被多个线程服务。
这样做的话,我们的线程则会大幅度减少,这就要求以下两点:
1:客户端状态的分离,之前会话模式我们可以通过线程状态得知客户端状态,但现在客户端状态要通过其他方式获取。
2:I/O请求的分离。一个线程不再服务于一个客户端会话,则要求客户端对这个线程提交I/O处理请求。
那么就产生了这样一个模式,分为两部分:
1:会话状态管理模块。它负责接收到一个客户端连接,就创建一个会话状态。
2:当会话状态发生改变,例如断掉连接,接收到网络消息,就发送一个I/O请求给 I/O工作模块进行处理。
3:I/O工作模块接收到一个I/O请求后,从线程池里唤醒一个工作线程,让该工作线程处理这个I/O请求,处理完毕后,该工作线程继续挂起。
上面的做法,则将网络连接 和I/O工作线程分离为两个部分,相互通讯仅依靠 I/O请求。
此时可知有以下一些建议:
1:在进行I/O请求处理的工作线程是被唤醒的工作线程,一个CPU对应一个的话,可以最大化利用CPU。所以 活跃线程的个数 建议等于 硬件CPU个数。
2:工作线程我们开始创建了线程池,免除创建和销毁线程的代价。因为线程是对I/O进行操作的,且一一对应,那么当I/O全部并行时,工作线程必须满足I/O并行操作需求,所以 线程池内最大工作线程个数 建议大于或者等于 I/O并行个数。
3:但是我们可知CPU个数又限制了活跃的线程个数,那么线程池过大意义很低,所以按常规建议 线程池大小 等于 CPU个数*2 左右为佳。例如,8核服务器建议创建16个工作线程的线程池。
上面描述的依然是I/O模型并非IOCP,那么IOCP是什么呢,全称 IO完成端口。
它是一种WIN32的网络I/O模型,既包括了网络连接部分,也负责了部分的I/O操作功能,用于方便我们控制有并发性的网络I/O操作。它有如下特点:
1:它是一个WIN32内核对象,所以无法运行于Linux.
2:它自己负责维护了工作线程池,同时也负责了I/O通道的内存池。
3:它自己实现了线程的管理以及I/O请求通知,最小化的做到了线程的上下文切换。
4:它自己实现了线程的优化调度,提高了CPU和内存缓冲的使用率。
使用IOCP的基本步骤很简单:
1:创建IOCP对象,由它负责管理多个Socket和I/O请求。CreateIoCompletionPort需要将IOCP对象和IOCP句柄绑定。
2:创建一个工作线程池,以便Socket发送I/O请求给IOCP对象后,由这些工作线程进行I/O操作。注意,创建这些线程的时候,将这些线程绑定到IOCP上。
3:创建一个监听的socket。
4:轮询,当接收到了新的连接后,将socket和完成端口进行关联并且投递给IOCP一个I/O请求。注意:将Socket和IOCP进行关联的函数和创建IOCP的函数一样,都是CreateIoCompletionPort,不过注意传参必然是不同的。
5:因为是异步的,我们可以去做其他,等待IOCP将I/O操作完成会回馈我们一个消息,我们再进行处理。
其中需要知道的是:I/O请求被放在一个I/O请求队列里面,对,是队列,LIFO机制。当一个设备处理完I/O请求后,将会将这个完成后的I/O请求丢回IOCP的I/O完成队列。
我们应用程序则需要在GetQueuedCompletionStatus去询问IOCP,该I/O请求是否完成。
其中有一些特殊的事情要说明一下,我们有时有需要人工的去投递一些I/O请求,则需要使用PostQueuedCompletionStatus函数向IOCP投递一个I/O请求到它的请求队列中。


三:网络游戏服务器注意事项,优化措施
1:IO操作是最大的性能消耗点,注意优化余地很大。
2:算法数据结构。排序寻路算法的优化。list,vector,hashmap的选择。大数据寻址,不要考虑遍历,注意考虑hash.
3:内存管理。重载new/delete,内存池,对象池的处理。
4:数据的提前准备和即时计算。
5:CPU方面的统计监视。逻辑帧计数(应当50ms以内)。
6:预分配池减少切换和调度,预处理的线程池和连接池等。
7:基与消息队列的统计和信息监视框架。
8:CPU消耗排名:第一AOI同步,第二网络发包I/O操作,第三技能/BUFF判定计算处理,第四定时器的频率。
9:内存泄露检测,内存访问越界警惕,内存碎片的回收。
10:内存消耗排名:第一玩家对象包括其物品,第二网络数据缓冲。
11:注意32位和64位的内存容错。
12:减少不必要的分包发送。
13:减少重复包和重拷贝包的代价。
14:建议分紧急包(立刻发送)和非紧急包(定时轮训发送)。
15:带宽消耗排名:第一移动位置同步,第二对象加载,第三登陆突发包,第四状态机定时器消息。
16:客户端可做部分预判断机制,部分操作尽量分包发送。
17:大量玩家聚集时,部分非紧急包进行丢弃。
18:注意数据库单表内key数量。
19:活跃用户和非活跃用户的分割存取处理。
20:控制玩家操作对数据库的操作频率。
21:注意使用共享内存等方式对数据进行安全备份存储。
22:注意安全策略,对内网进行IP检查,对日志进行记录,任意两环点内均使用加密算法会更佳。
23:实时注意对网关,数据库等接口进行监察控制。
24:定时器应当存储一个队列,而非单向定位。
25:九宫格数据同步时,不需要直接进行九宫格的同步,对角色加一个AOI,基于圆方碰撞原理,抛弃不必要的格信息,可大幅节省。
26:客户端做部分的预测机制,服务器检测时注意时间戳问题。
27:定期心跳包,检查死链接是必要的。
28:为了实现更加负责多种类的AI,AI寻路独立服务器设计已经是必须的了。其次需要考虑的是聊天,同步。
29:服务器内网间可以考虑使用UDP。
30:注意所有内存池,对象池等的动态扩张分配。

1:以内存换取CPU的理念。
2:NPC不死理念。(只会disable)
3:动态扩展理念,负载均衡理念。
4:客户端不可信理念。
5:指针数据,消息均不可信理念。

这篇关于IOCP模型与EPOLL模型的比较 服务器优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/416120

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

CentOS 7部署主域名服务器 DNS的方法

《CentOS7部署主域名服务器DNS的方法》文章详细介绍了在CentOS7上部署主域名服务器DNS的步骤,包括安装BIND服务、配置DNS服务、添加域名区域、创建区域文件、配置反向解析、检查配置... 目录1. 安装 BIND 服务和工具2.  配置 BIND 服务3 . 添加你的域名区域配置4.创建区域