文档章节

服务器高并发设计模式

满小茂
 满小茂
发布于 2016/04/13 23:17
字数 1670
阅读 197
收藏 3
点赞 1
评论 0

半同步/半异步模式

先解释一下同步和异步的区别,与刚才I/O的同步、异步不一样,在并发模式中,这里的“同步"指的是程序完全按照代码的顺序执行,“异步”指的是程序的执行需要由系统事件来驱动,比如说信号、中断等。下图就清楚的解释了同步和异步操作的过程:

两种高效的事件处理模式和并发模式
 

这样看来,显然异步线程的执行效率高,但是它的编写相对复杂,难于调试,然而同步线程刚好相反,逻辑简单,但效率较差。半同步/半异步模式就结合了同步线程与异步线程的优点,它在处理I/O事件时使用异步线程,处理客户逻辑则使用同步线程。这样既满足了客户连接的实时性,又能同时处理多个连接。那么它是如何同将同步与异步结合起来的?实现半同步/半异步模式需要三个模块:异步处理模块、同步处理模块和队列模块

举个例子:

"一家律师事务所有一个前台接待员,每一位想寻找律师的客户,都会先由接待员接待,接待员会给每位顾客都安排一个律师来处理客户的案件,(假设一个律师在同一时间只能处理一个客户的案子)接待员只有一个人,但他可以接待所有客户,不过它也只负责接待,哪怕你的案件再复杂,都是律师的事儿,跟接待员没关系,而分配的依据可以是预约情况或者案件类型。"

在上面这个例子中,那个前台接待员就是异步处理模块,他一个人要处理多个I/O请求(客户),律师则是同步处理模块,每一个律师分别对应一个客户,根据客户的不同需求作出处理,而要让异步模块与同步模块连接起来,就需要插入一个队列模块,它将接待完毕的客户排一个队,等那个律师有时间的时候就来这个队列里领走一个客户处理,当然,队列怎么排,分为几个队列,就看客户到达的时间或者需求来决定了。

 

在实际使用中,我们一般使用多路复用IO在主线程上监听客户端的连接,监听到新的客户请求后,就将其封装成请求对象,然后插入请求队列中,同时,有许多工作线程可以来读取并处理该请求对象,具体选择哪个工作线程来为新的客户进行处理,取决于请求队列的设计。在这个模式中,最可能被阻塞的操作放在同步模块中,这样不会影响到异步模块的处理,不同模块可以使用不同的同步策略,互不干扰,模块间通信则使用ipc实现,但这样也造成了在同步模块和异步模块之间使用队列模块传送数据的时候,由于数据拷贝和上下文切换导致的性能消耗。

 

 

 

半同步/半反应堆模式

        半同步/半反应堆模式其实是半同步/半异步模式的一种变体,其中异步线程只有一个,由主线程充当,如果有连接到来或事件发生,主线程就将该socket插入请求队列中,直到这里与半同步/半异步模式都是一样的,但是在半同步/半反应堆模式中,当有任务到来时,选择哪个工作线程不是由算法或时间设置好的,而是由所有的工作线程竞争来的,它们通过竞争(比如申请互斥锁)来获得任务的接管权,这样的竞争机制使得当前只有空闲的工作线程才能来竞争,自然的形成了资源平衡。

 

          上图中主线程插入的请求队列是就绪的连接socket,这说明图示的半同步/半反应堆模式采用的事件处理模式是Reactor模式。半同步/半反应堆模式也可以采用模拟Proactor的事件处理模式,也就是由主线程完成数据的读写。主线程一般会将应用程序数据与其他信息一起封装为一个任务对象,然后将其插入请求队列。工作线程可以直接处理,不用读写。 半同步/半反应堆模式因为也是主线程和工作线程共享任务队列,所以也会存在与半同步/半异步模式一样的问题,就是每次堆队列进行操作,都需要进行加锁,从而消耗cpu的时间。而且一个线程同一时间只能处理一个客户请求,如果队列中积累了很多任务,增加工作线程的话,工作线程的切换也会耗费大量cpu时间,这种问题有一种相对高效的解决方式:即在每个工作线程上也使用epoll_wait,这样每个工作线程都能处理多个客户连接了。

 

 

领导者/追随者模式

           领导者/追随者模式是指多个工作线程轮流监听、分发、处理事件的一种模式。在任意事件,程序都仅有一个领导者线程,它负责监听I/O事件。其他线程都是追随者,它们休眠在线程池中等待成为新的领导者。当领导者线程检测到I/O事件时,首先要从线程池中选出新的领导者线程,然后处理I/O事件。此时,新的领导者线程等待新的I/O事件,旧的领导者线程处理I/O事件,实现并发。

           领导者/追随者模式最大的优点在于,它是自己监听I/O事件并处理客户请求,也就是说从接收到处理都是在同一线程中完成,所以不需要在线程之间传递任何额外的数据,也不用在线程间同步对请求队列的访问。但是它也有明显的缺点,就是只支持一种事件源集合,所以导致它不能像上述那样让每个线程独立的管理多个客户连接。

 

© 著作权归作者所有

共有 人打赏支持
满小茂
粉丝 65
博文 108
码字总数 121544
作品 0
成都
程序员
1、单例模式

定义: 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。 特点: 1、单例类只...

晚天吹凉风 ⋅ 02/22 ⋅ 0

设计模式学习笔记之-代理模式

代理模式中,客户不会直接调用目标对象而是通过一个代码对象,客户调用代理对象代理对象去调用目标对象,起到对象与对象间的隔离作用。有时候我么不想直接访问目标对象,有时候我们不能直接访...

申文波 ⋅ 03/05 ⋅ 0

代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

前言 今天我来全面总结开发中最常用的设计模式 - 代理模式中的动态代理模式 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(Sim...

Carson_Ho ⋅ 04/09 ⋅ 0

[设计模式]简单工厂模式

简介 简单工厂模式 (Simple Factory) 又叫静态工厂方法(Static Factory Method)模式。 简单工厂模式通常是定义一个工厂类,这个类可以根据不同变量返回不同类的产品实例。 简单工厂模式是一...

静默虚空 ⋅ 2015/06/03 ⋅ 0

JavaScript设计模式之观察者模式

前言 准备研究一下MVVM的一些东西,由于MVVM运用了观察者模式的思想,因此翻开了《JavaScript设计模式与开发实践》一书,将观察者模式学习了一遍,顺便有对一些常用的设计模式进行一些了解,...

Srtian ⋅ 05/22 ⋅ 0

C#设计模式(2)——简单工厂模式

一、引言   这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式——简单工...

技术小胖子 ⋅ 2017/11/08 ⋅ 0

JavaScript 中常见设计模式整理

开发中,我们或多或少地接触了设计模式,但是很多时候不知道自己使用了哪种设计模式或者说该使用何种设计模式。本文意在梳理常见设计模式的特点,从而对它们有比较清晰的认知。 JavaScript 中...

牧云云 ⋅ 05/18 ⋅ 0

系统架构技能之设计模式-单件模式

一、开篇 其实我本来不是打算把系统架构中的一些设计模式单独抽出来讲解的,因为很多的好朋友也比较关注这方面的内容,所以我想通过我理解及平时项目中应用到的一 些常见的设计模式,拿出来给...

wbf961127 ⋅ 2017/11/12 ⋅ 0

设计模式梳理(一)

设计模式梳理(一) 总体来说设计模式分为三大类: @案例源码地址:https://gitlab.com/lxqxsyu/DisgnPattern 创建型模式 简单工厂模式 工厂类是整个模式的关键。它包含必要的判断逻辑,能够...

lxq_xsyu ⋅ 2017/11/02 ⋅ 0

设计模式笔记(八)——单例模式

是什么——定义 一个类只有一个对象实例。 2. 为什么——特点 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 3. 什么时候用——适用性 l 一个全局使用的类频繁地创建与销毁,而需...

LinkedBear ⋅ 04/11 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 30分钟前 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 44分钟前 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 56分钟前 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

vim编辑模式、vim命令模式、vim实践

vim编辑模式 编辑模式用来输入或修改文本内容,编辑模式除了Esc外其他键几乎都是输入 如何进入编辑模式 一般模式输入以下按键,均可进入编辑模式,左下角提示 insert(中文为插入) 字样 i ...

蛋黄Yolks ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部