一种高性能的服务器处理框架

一种高性能的服务器处理框架

1、首先需要一个内存池,目的在于:
减少频繁的分配和释放,提高性能的同时,还能避免内存碎片的问题;能够存储变长的数据,不要很傻瓜地只能预分配一个最大长度;基于SLAB算法实现内存池是一个好的思路:分配不同大小的多个块,请求时返回大于请求长度的最小块即可,对于容器而言,处理固定块的分配和回收,相当容易实现。当然,还要记得需要设计成线程安全的,自旋锁比较好,使用读写自旋锁就更好了。分配内容的增长管理是一个问题,比如第一次需要1KB空间,随着数据源源不断的写入,第二次就需要4KB空间了。扩充空间容易实现,可是扩充的时候必然 涉及数据拷贝。甚至,扩充的需求很大,上百兆的数据,这样就不好办了。暂时没更好的想法,可以像STL一样,指数级增长的分配策略,拷贝数据虽不可避免, 但是起码重分配的几率越来越小了。上面提到的,如果是上百兆的数据扩展需要,采用内存映射文件来管理是一个好的办法:映射文件后,虽然占了很大的虚拟内存,但是物理内存仅在写入的时候才会被分配,加上madvice()来加上顺序写的优化建议后,物理内存的消耗也会变小。用string或者vector去管理内存并不明智,虽然很简单,但服务器软件开发中不适合使用STL,特别是对稳定性和性能要求很高的情况下。

2、第二个需要考虑的是对象池,与内存池类似:
减少对象的分配和释放。其实C++对象也就是struct,把构造和析构脱离出来手动初始化和清理,保持对同一个缓冲区的循环利用,也就不难了。可以设计为一个对象池只能存放一种对象,则对象池的实现实际就是固定内存块的池化管理,非常简单。毕竟,对象的数量非常有限。

3、第三个需要的是队列:
如果可以预料到极限的处理能力,采用固定大小的环形队列来作为缓冲区是比较不错的。一个生产者一个消费者是常见的应用场景,环形队列有其经典的锁无关算法,在一个线程读一个线程写的场景下,实现简单,性能还高,还不涉及资源的分配和释放。实在是好!
4、第四个需要的是映射表,或者说hash表:
因为epoll是事件触发的,而一系列的流程可能是分散在多个事件中的,因此,必须保留下中间状态,使得下一个事件触发的时候,能够接着上次处理的位置继续处理。要简单的话,STL的hash_map还行,不过得自己处理锁的问题,多线程环境下使用起来很麻烦。
5、核心的线程是事件线程:
事件线程是调用epoll_wait()等待事件的线程。一个线程干了所有的事情,而需要开发一个高性能的服务器的时候,事件线程应该专注于事件本身的处理,将触发事件的socket句柄放到对应的处理队列中去,由具体的处理线程负责具体的工作。

6、accept()单独一个线程:
服务端的socket句柄(就是调用bind()和listen()的这个)最好在单独的一个线程里面做accept(),阻塞还是非阻塞都无所谓,相比整个服务器的通讯,用户接入的动作只是很小一部分。而且,accept()不放在事件线程的循环里面减少了判断。

7、接收线程单独一个:
接收线程从发生EPOLLIN事件的队列中取出socket句柄,然后在这个句柄上调用recv接收数据,直到缓冲区没有数据为止。接收到的数据写入以socket为键的hash表中,hash表中有一个自增长的缓冲区,保存了客户端发过来的数据。这样的处理方式适合于客户端发来的数据很小的应用,比如HTTP服务器之类;假设是文件上传的服务器,则接受线程会一直处理某个连接的海量数据,其他客户端的数据处理产生了饥饿。所以,如果是文件上传服务器一类的场景,就不能这样设计。

8、发送线程单独一个:
发送线程从发送队列获取需要发送数据的SOCKET句柄,在这些句柄上调用send()将数据发到客户端。队列中指保存了SOCKET句柄,具体的信息还需要通过socket句柄在hash表中查找,定位到具体的对象。如同上面所讲,客户端信息的对象不但有一个变长的接收数据缓冲区,还有一个变长的发送数据缓冲区。具体的工作线程发送数据的时候并不直接调用send()函数,而是将数据写到发送数据缓冲区,然后把SOCKET句柄放到发送线程队列。SOCKET句柄放到发送线程队列的另一种情况是:事件线程中发生了EPOLLOUT事件,说明TCP的发送缓冲区又有了可用的空间,这个时候可以把SOCKET句柄放到发送线程队列,一边触发send()的调用;需要注意的是:发送线程发送大量数据的时候,当频繁调用send()直到TCP的发送缓冲区满后,便无法再发送了。这个时候如果循环等待,则其他用户的发送工作受到影响;如果不继续发送,则EPOLL的ET模式可能不会再产生事件。解决这个问题的办法是在发送线程内再建立队列,或者在用户信息对象上设置标志,等到线程空闲的时候再去继续发送这些未发送完成的数据。

9、需要一个定时器线程:
一位将epoll使用的高手说道:单纯靠epoll来管理描述符不泄露几乎是不可能的。完全解决方案很简单,就是对每个fd设置超时时间,如果超过timeout的时间,这个fd没有活跃过,就close掉。所以,定时器线程定期轮训整个hash表,检查socket是否在规定的时间内未活动。未活动的SOCKET认为是超时,然后服务器主动关闭句柄,回收资源。

10、多个工作线程:
工作线程由接收线程去触发:每次接收线程收到数据后,将有数据的SOCKET句柄放入一个工作队列中;工作线程再从工作队列获取SOCKET句柄,查询hash表,定位到用户信息对象,处理业务逻辑。
工作线程如果需要发送数据,先把数据写入用户信息对象的发送缓冲区,然后把SOCKET句柄放到发送线程队列中去。对于任务队列,接收线程是生产者,多个工作线程是消费者;对于发送线程队列,多个工作线程是生产者,发送线程是消费者。在这里需要注意锁的问题。

11、仅仅只用scoket句柄作为hash表的键,并不够:
假设这样一种情况:事件线程刚把某SOCKET因发生EPOLLIN事件放入了接收队列,可是随即客户端异常断开了,事件线程又因为EPOLLERR事件删除了hash表中的这一项。假设接收队列很长,发生异常的SOCKET还在队列中,等到接收线程处理到这个SOCKET的时候,并不能通过SOCKET句柄索引到hash表中的对象。索引不到的情况也好处理,难点就在于,这个SOCKET句柄立即被另一个客户端使用了,接入线程为这个SCOKET建立了hash表中的某个对象。此时,句柄相同的两个SOCKET,其实已经是不同的两个客户端了。极端情况下,这种情况是可能发生的。解决的办法是,使用socket fd + sequence为hash表的键,sequence由接入线程在每次accept()后将一个整型值累加而得到。这样,就算SOCKET句柄被重用,也不会发生问题了。

12、监控,需要考虑:
框架中最容易出问题的是工作线程:工作线程的处理速度太慢,就会使得各个队列暴涨,最终导致服务器崩溃。因此必须要限制每个队列允许的最大大小,且需要监视每个工作线程的处理时间,超过这个时间就应该采用某个办法结束掉工作线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux高性能服务器项目是一个基于Linux操作系统的服务器项目,旨在提供高性能、高可靠性、高安全性的服务器解决方案。该项目采用了先进的技术和优化策略,可以满足各种规模和需求的企业和个人用户的需求。该项目的特点包括高效的资源利用、可扩展性强、易于管理和维护等。同时,该项目还提供了丰富的应用程序和工具,可以满足用户的各种需求。 ### 回答2: Linux高性能服务器项目是针对构建高性能服务器应用程序而开发的一种工具集,主要用于解决服务器应用程序对高并发、高扩展性和高可用性的需求。 在传统的服务器应用程序开发中,常常会使用C/C++等语言开发,但是由于这些语言的代码效率低下、开发效率较低等问题,在高并发、高扩展性和高可用性的需求下表现不尽如人意。因此,Linux高性能服务器项目通过提供针对Linux操作系统的高性能应用程序开发框架和工具集,使开发人员可以更高效地构建高性能服务器应用程序。 Linux高性能服务器项目包括众多开源工具和库,如Nginx、Redis、Mysql、Postgresql、Apache、Tomcat、Memcached等。这些工具和库可以在Linux下构建高性能服务器应用程序,并支持高并发、高扩展性和高可用性。 其中,Nginx是最为著名的Linux高性能服务器应用程序开发工具之一,其采用事件驱动、非阻塞I/O等高效构架,能够提供高并发、高吞吐量和低内存消耗等特点。Nginx同时支持多种反向代理、负载均衡和缓存等功能,在大规模网站和高并发访问场景下表现尤为突出。 另外,在Linux高性能服务器项目中,Mysql和Postgresql是两个重要的关系型数据库软件,它们可以提供高效的数据访问和管理功能,而Redis和Memcached则是两个重要的缓存软件,能够提供高速缓存和分布式缓存等功能,从而进一步提高服务器性能。 总之,Linux高性能服务器项目是一个完整的工具集,支持开发人员构建高性能、高可用和高扩展性的服务器应用程序,有助于提高网站和应用的性能和用户体验。 ### 回答3: Linux高性能服务器项目是指基于Linux系统开发、优化和部署的高性能服务器系统。随着互联网和移动互联网的发展,海量数据的处理和高并发的请求成为了许多企业必须面对的问题。而Linux作为一种自由开放的操作系统,在服务器领域有着广泛的应用,并且具备高度的可定制性和实时性,因此成为了众多企业构建高性能服务器系统的首选。 Linux高性能服务器项目的核心是系统优化,包括系统内核优化、网络配置优化、磁盘IO优化、内存管理优化等,通过这些手段提升系统的性能和稳定性,进一步提高服务器的吞吐量和并发处理能力。在系统优化的基础上,还需要根据不同的应用场景进行架构设计和开发,构建高可靠、高可扩展、低延迟的服务器系统。 在实际项目中,Linux高性能服务器系统往往需要承载大量的用户请求和数据处理任务,因此需要具备高度的稳定性和可靠性。在系统架构上需要采用分布式集群架构,通过负载均衡、故障切换等手段提高系统的可用性和可靠性。同时,还需要采用自动化运维工具,对系统进行监控、调优和故障处理,提高系统运维效率和问题响应速度。 总之,Linux高性能服务器项目是一项综合性工程,需要多方面的知识和技能。但是相信随着技术的不断发展和应用的不断拓展,Linux高性能服务器系统将会在越来越多的领域得到应用,并且发挥更加重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值