Reactor

Linux网络编程基础之Reactor模式和Proactor模式

混江龙づ霸主 提交于 2020-08-18 07:32:29
在Linux平台下的服务器开发中,如何去构建高性能的网络通信框架是重中之重,自然就绕不开网络通信模型的选择和应用;目前网络通信模型中涉及到的模式有两个:Reactor模式和Proactor模式。 在介绍这两个模式之前,先详细地阐述下阻塞IO、非阻塞IO、同步、异步的概念,因为经常有很多同学能把这些词汇编出各种奇怪的组合出来,连自己都不知道是什么意思。 阻塞IO:当应用层发起read请求时,发出read请求的线程会被挂起,直到操作系统完成数据从内核区到应用层缓冲区的拷贝,read调用才返回;write操作也是一样。 非阻塞IO:当应用层发起read请求,而操作系统没有准备好数据,read调用会立刻返回;同时操作系统会返回一个EWOULDBLOCK的错误码。但发起read请求的线程会不断地去询问操作系统“数据准备好了吗?”,如果准备好了,那么就把数据从内核空间拷贝到应用层缓冲区。 上面就是阻塞IO和非阻塞IO,但是有一点需要说明,在操作系统把数据准备好,并把数据拷贝出来的过程是同步的,也就是说必须要拷贝完,read才会返回。所以同步/异步是用于形容数据从内核空间拷贝到应用程序缓冲区的过程。 同步:当操作系统内核准备好数据,应用程序发出read请求,数据的拷贝是和read函数同步进行的,如果数据较多,那么read调用的耗时会较长。 异步:当应用程序发出***aio_read***请求后

Redis 6.0 多线程重磅发布!!!

自古美人都是妖i 提交于 2020-08-17 12:25:52
Redis 6.0在5.2号这个美好的日子里悄无声息的发布了,这次发布在IT圈犹如一颗惊雷一般,因为这是redis最大的一次改版,首次加入了 多线程 。 作者Antirez在RC1版本发布时在他的博客写下: the most “enterprise” Redis version to date // 最”企业级”的 the largest release of Redis ever as far as I can tell // 最大的 the one where the biggest amount of people participated // 参与人数最多的 这次改变,性能有个飞速的提升~ 先po出新版和旧版性能图 从上面可以看到 GET/SET 命令在 4 线程 IO 时性能相比单线程是几乎是翻倍了。另外,这些数据只是为了简单验证多线程 IO 是否真正带来性能优化,并没有针对严谨的延时控制和不同并发的场景进行压测。数据仅供验证参考而不能作为线上指标,且只是目前的 unstble分支的性能,不排除后续发布的正式版本的性能会更好。 Redis 6.0 之前的版本真的是单线程吗? Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。

解Bug之路-中间件"SQL重复执行"

杀马特。学长 韩版系。学妹 提交于 2020-08-16 23:13:37
前言 我们的分库分表中间件在线上运行了两年多,到目前为止还算稳定。在笔者将精力放在处理各种灾难性事件(例如中间件物理机宕机/数据库宕机/网络隔离等突发事件)时。竟然发现还有一些奇怪的corner case。现在就将排查思路写成文章分享出来。 Bug现场 应用拓扑 应用通过中间件连后端多个数据库,sql会根据路由规则路由到指定的节点,如下图所示: 错误现象 应用在做某些数据库操作时,会发现有比较大的概率失败。他们的代码逻辑是这样: int count = updateSql(sql1); ... // 伪代码 int count = updateSql("update test set value =1 where id in ("100","200") and status = 1; if( 0 == count ){ throw new RuntimeException("更新失败"); } ...... int count = updateSql(sql3); ... 即每做一次update之后都检查下是否更新成功,如果不成功则回滚并抛异常。 在实际测试的过程中,发现经常报错,更新为0。而实际那条sql确实是可以更新到的(即报错回滚后,我们手动执行sql可以执行并update count>0)。 中间件日志 笔者根据sql去中间件日志里面搜索。发现了非常奇怪的结果,日志如下:

「人造太阳」背后,能源为什么值得关注?

与世无争的帅哥 提交于 2020-08-16 03:46:31
作者|赵子潇 来源|极客公园 圣波莱迪朗克坐落在法国南部,属于普罗旺斯地区,离同在法国南部的马赛市约 66 公里。这个鲜为人知的地方最近却受到了广泛关注,尤其是新科技爱好者们。不出意外的话,未来几年,人们可能还会对这个地方顶礼膜拜。 在这里, 世界上最大的核聚变装置—— 国际热核聚变实验反应堆(International Thermonuclear Experimental Reactor,下称 ITER)正式开始组装工作。数百万个零件从世界各地运到法国,仅组装时间长达 4.5 年,最终变成直径约 30 米,高度约 10 层楼的大型反应堆。 如果 ITER 成功运行,对于全世界来说,都是核技术的一大突破。更重要的是,它可能会改写全球的能源历史,清洁能源届时将成为主流。已经有 35 年历史, 还有 15 年才能实现的「人造太阳」ITER,正在试图冲破地球能源危机的考验。 01 ITER 到底是什么? 关于 ITER 的历史,最早可以追溯到上世纪 80 年代,是美国总统里根与苏联领导人戈尔巴乔夫提出的倡议。 当时,美国、欧洲共同体、苏联和日本等国家都在进行核聚变相关研究,但研究的经费超过了任何一个国家的预算,所以才有了这一国际合作项目的诞生。 2006 年,欧盟、美国、中国、日本、韩国、俄罗斯和印度作为联合参加 ITER 项目的国家正式签署了一系列相关协议,项目才算真正启动。按照预期

gateway欺人太甚!

戏子无情 提交于 2020-08-15 18:09:09
需求: 通过gateway来转义请求参数中的html标签的“<”、“>”等,来防止xss攻击 版本: springbootVersion:2.1.6RELASE springCloudGatewayVersion:2.1.2RELASE 因为gateway版本不同所以获取请求参数的方式也不同,这个版本的gateway是通过webflux来处理参数的,什么是 webflux 请点击查看,这里就不过多赘述了 对于gateway的过滤器有很多种实现方式,根据具体的业务需求来选定最便捷、最简单的处理方式 这里是我自定义gatewayfilter过滤器代码实现: 此代码只处理了两种contentType是:application/json和application/json;charset=UTF-8 对于contentType是multipart/form-data没有处理这是缺陷,如有好的处理方式请留言,大家一起学习一起进步 import lombok.extern.slf4j.Slf4j; import org.owasp.esapi.ESAPI; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter

Reactor和Proactor对比

試著忘記壹切 提交于 2020-08-14 03:23:18
常见的IO事件处理模型有两种:Reactor和Proactor。Redis中的ae就是采用的Reactor事件处理模型,Proactor需要操作系统的支持,目前暂时还没接触到相关的使用场景,主要是学习模型结构。 Reactor模型 Handler :用来标识一个文件描述符 Synchronous Event Demultiplexer :同步事件多路分解器,由select、poll或者epoll函数来实现,调用后会阻塞,直到等待Handler上的一个或多个事件发生 Event Handler :事件处理接口 Concrete Event Handler :事件处理接口的实现类,用来实现应用程序所提供的特定事件处理逻辑 Reactor :Reactor反应堆,主要实现以下功能: 1)注册和删除关注的文件描述符 2)运行事件循环 3)有就绪事件到来时,分发事件到之前注册的回调函数上处理 Reactor时序图 运行主程序,将关注的事件handler注册到Reactor中 主程序调用Reactor,进入无限事件循环,等待注册的事件到来 当事件到来时,调用select返回待处理的事件,Reactor将事件分发到之前注册的回调函数中去处理 Proactor模型 Handler :用来标识一个文件描述符; Asynchronous Operation Processor :异步操作处理器

Netty源码死磕一(netty线程模型及EventLoop机制)

此生再无相见时 提交于 2020-08-14 02:30:08
引言 好久没有写博客了,近期准备把 Netty 源码啃一遍。在这之前本想直接看源码,但是看到后面发现其实效率不高, 有些概念还是有必要回头再细啃的,特别是其线程模型以及 EventLoop 的概念。 当然在开始之前还是有务必要对 IO模型 要有清晰准确的认识。 传送门 事件循环机制(EventLoop) Netty线程模型中一个非常重要的概念: 事件循环机制(EventLoop) 这个概念在 JS 上体现的也非常淋漓尽致,下面在开始介绍netty的线程模型之前,允许我简单的介绍下事件循环机 制在 JS 中的体现 JS 的语言性质: 单线程非阻塞,单线程意味着,js代码在执行的任何时候,都只有一个主线程来处理所有的任务>。非阻塞则意味着,在进行异步IO任务时不会阻塞主线程,主线程会挂起这个任务,等待异步任务完成再执行对应>的回调。 那么JS是如何实现单线程非阻塞的呢? JS 引擎遇到一个异步事件后并不会一直等待其返回结果,而是会将此事件>挂起(例如交给浏览器去执行请求),主线程会继续执行方法栈中的其他任务。之后当异步任务返回结果后,(可>能是浏览器?)会将回调函数加入到事件队列( Task Queue )中,那么什么时候会从事件队列中取出回调函数执行>呢?当前执行栈中的所有任务都执行完毕,主线程处于闲置状态时会去查找事件队列是否有任务待执行,如果有则

超详细Netty入门,看这篇就够了!

旧街凉风 提交于 2020-08-13 16:16:38
简介: 本文主要讲述Netty框架的一些特性以及重要组件,希望看完之后能对Netty框架有一个比较直观的感受,希望能帮助读者快速入门Netty,减少一些弯路。 思维导图 前言 本文主要讲述Netty框架的一些特性以及重要组件,希望看完之后能对Netty框架有一个比较直观的感受,希望能帮助读者快速入门Netty,减少一些弯路。 一、Netty概述 官方的介绍: Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty 是 一个 异步事件驱动 的网络应用程序框架,用于 快速开发可维护的高性能协议服务器和客户端 。 二、为什么使用Netty 从官网上介绍,Netty是一个网络应用程序框架,开发服务器和客户端。也就是用于网络编程的一个框架。既然是网络编程,Socket就不谈了,为什么不用NIO呢? 2.1 NIO的缺点 对于这个问题,之前我写了一篇文章 《NIO入门》 对NIO有比较详细的介绍,NIO的主要问题是: NIO的类库和API繁杂,学习成本高,你需要熟练掌握Selector、ServerSocketChannel

学习响应式编程 Reactor (2)

瘦欲@ 提交于 2020-08-12 05:01:38
Reactor Reactor 是用于 Java 的异步非阻塞响应式编程框架,同时具备背压控制的能力。它与 Java 8 函数式 Api 直接集成,比如 分为CompletableFuture、Stream、以及 Duration 。它提供了异步 Api 响应流 Flux (用于 [0 - N] 个元素)和 Mono (用于 [0或1] 个元素),并完全遵守和实现了响应式规范。 引入 reactor reactor 自 3.0.4 版本之后,采用了 BOM (Bill Of Materials)的方式,使用 BOM 可以管理一组良好集成的 maven artifacts,而无需担心不同版本组件之间的相互依赖问题,在 maven 项目中在 dependencyManagement 中 加入 reactor 的 bom 定义即可。 <dependencyManagement> <dependencies> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-bom</artifactId> <version>Dysprosium-SR8</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> <

evpp网络库代码分析(二)

江枫思渺然 提交于 2020-08-11 21:04:11
开局一张图! 上图是盗用自《Linux多线程服务端编程,使用muduo C++网络库》一书6.6.2章节(以及下面的时序图也是盗用该书的图)。该图列举出大部分常用的网络编程模型,当然了,这里并没有列出Boost.Asio的proactor模式。其中表中的“互通”是指多个客户端(连接)间是否能方便地交换数据,如chat聊天程序。我们的evpp库实际上是用到了“方案9”,方案9的时序图如下: 可以看出,每一个线程有一个EventLoop处理事件。这种方案是典型的“one loop per thread”流程,有一个“主EventLoop”负责accept连接,然后把连接通过round-robin(轮询调度)挂到底下的多个“子EventLoop”中(EventLoopThreadPool),每个连接都是由一个“子EventLoop”完成的,能保证请求的顺序性,也可以充分利用CPU,防止出现一个reactor的处理能力饱和,而且EventLoop线程池线程数量固定,不会因为连接数过多到达临界点(线程太多导致操作系统线程调度不过来)而性能下降! 另外还有一种网络编程模型比较常用,就是“方案8”,这个模型在muduo中有现成方案,而在evpp中需要自己实现,时序图如下: 这种方案,只有一个EventLoop,但它把计算密集的部分(decode、compute、encode