热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

netty客户端服务端能否在一个项目里单元测试_Netty系列带你深入刨析Netty运用IO模型和Reactor模型...

周五咯,今天上班主要实现多个服务端如何通信,如何实现每个服务端部署多台。运维不在没法安装Redis,下周继续这块功能实现。继续不加班&#x
87837c81ba5152add26ea1394ceb87f4.png周五咯,今天上班主要实现多个服务端如何通信,如何实现每个服务端部署多台。运维不在没法安装Redis,下周继续这块功能实现。继续不加班,文章走起。前面几篇文章讲述了Netty前置知识,接下来正式介绍Netty。我们都知道Netty基于NIO实现的,但是相对NIO有什么好处呢?从IO模型和Reactor模型来刨析Netty。

1

一 概述

接下来就要接触Netty了,我们先对Netty有一个简单的认识,看下面介绍。11.1 初步了解Netty
  1. Netty是什么?

Netty是一个高性能的、异步的、基于事件驱动的网络应用型框架。

  1. 为什么使用netty?

a Netty是基于Java的NIO实现的,对各种API进行统一封装。    
b 基于事件模型,我们可以在对应事件编码自己业务。让开发者聚焦业务。   
c 高度可定制线程模型,单线程,一个或者多个线程池。    
d Netty只依赖JDK底层api。    
e 在通信方面,减少不必要内存拷贝,提高性能。    
f 在安全方面,完整的SSL/TLS和StartTLS。 

  1. Netty相对于NIO有什么优势?

a 对NIO中的API进行封装,使用简单。    
b 写出高质量的NIO程序,需要多线程和网络编程的知识积累。   
c NIO可靠性差,如:客户端从连、网络闪退、半包读写、失败缓存等问题。   
d NIO会导致Selector空轮询,最终导致CPU100%,jdk1.7仍然会有这个问题,只是发送概率变低了。  
21.2 Netty的架构是什么?

6ad83cb3f8268a409e209001019e43ca.png
  1. 核心(Core)

a 可扩展的事件模型。         
b 统一的通信api(无论是http还是socket都使用同意的api)。      
c 零拷贝机制与字节缓冲区。 

  1. 传输服务(Transport Services)

a 支持socket和datagram(数据报)。     
b 支持http协议。    
c In-VM Pipe(管道协议)。 

  1. 协议支持(Protocol Support)

a http 以及 websocket。     
b SSL 安全套接字协议⽀持。      
c Google Protobuf (序列化框架)。       
d ⽀持zlib、gzip压缩。    
e ⽀持⼤⽂件的传输。    
f RTSP(实时流传输协议,是TCP/IP协议体系中的⼀个应⽤层协议)。    
g ⽀持⼆进制协议并且提供了完整的单元测试。  
上面已经对Netty有个简单的认识,也了解使用Netty的好处。下面从IO模型和Reactor模型这两个角度来刨析使用Netty的好处。

2

二 Netty中的模型(IO、Reactor)

为什么学习Netty时候,为什么要刨析IO模型和Reactor模型呢?我也有这个疑问。查看下面文章,能否有个结论?欢迎在评论区写下独到见解。

32.1 常见IO模型

2.1.1 BIO模型

d4b53290bd7b5fd87d11226bb86d888c.png
对上图分析

a 客户端的并发数和服务端的线程数是一样多,随着并发量增加服务端线程数增加,服务端性能下降。     
b 当连接创建后,该线程没有操作,会进行堵塞,不会释放线程。极大浪费服务器资源。

2.1.2 NIO模型

0440433f02ef1551bf22e0d19e735b4f.png
1. 对上图组件解释

a Buffer:是缓冲区、底层通过数组实现。在NIO中所有的读写操作都是基于Buffer的。Java基本类型除了boolean都有缓冲区对象。 

b Channel:通常叫为通道,用于连接客户端和服务端。是双向的,可以读也可以写。 

c Selector:通常叫多路复用器,用于找出注册其上的发生读和写的channel。原理如下:        
 Selector不断轮询其上面的Channel,Channel发生读或者写,就会被Slector挑选出来。然后通过SelectionKey获取就绪Channel集合,进行IO读写操作。
2. 对上图进行分析

一个线程处理多个通道,避免多线程之间上下问切换造成系统开销。通道只有事件的时候,才进行读写操作。

2.1.3 AIO模型

1. 为什么要引入AIO模型

在NIO中,Selector多路复⽤器在做轮询时,如果没有事件发⽣,也会进⾏阻塞。
如何能把这个阻塞也优化掉呢?那么AIO就在这样的背景下诞⽣了。
2. AIO简介

叫异步IO,该异步依赖操作系统底层异步IO。
3. AIO的基本流程

用户线程通过系统调用,告知kernel内核启动某个IO操作,用户线程返回。kernel内核在
整个IO操作(包括数据准备、数据复制)完成后,通知⽤户程序,⽤户执⾏后续的业务操作。

59e37353e9981fe4c63617f8e152c0f9.png
4. AIO模型存在问题

a 完成事件的注册和传递,需要操作系统底层提供大量支持。
b Windows 系统下通过 IOCP 实现了真正的异步 I/O。但是目前高并发系统都是部署到Linux上。
c Linux系统支持AIO模型不稳定。该系统下异步都是以NIO实现的。
上文介绍IO模型的三种情况:BIO模型、NIO模型、AIO模型。因为AIO模型是依赖操作系统底层,而且Linux支持不稳定,所以只需对其有个简单认识。NIO相对于BIO减少了堵塞和线程开销。42.2 常见Reactor模型

2.2.1 Reactor模型概述

1.Reactor模型是什么?

是一种并发编程模型,是一种思想,具有指导意义。
2. 常见的Reactor模型

单线程模型、多线程模型、主从多线程模型。Netty非常友好支持前面三种模型,一般采用主从架构方式。
3. Reactor模型三种角色

a Reactor 监听和分配事件
b Acceptor 处理客户端新连接,并分配请求到处理链中。
c Handler 将自身和事件绑定,执行读写操作(完成channel的读入,执行业务逻辑并将结果写道channel)。

2.2.1 单线程模型

5736be55fb1d940a17e863cd3824c7cc.png上图说明

a 一个线程完成业务处理。
b Reactor相当于一个多路复用器,用于监听事件,并把发生的事件传递给Handler或者Acceptor。
c 如果是建立连接事件,Reactor传递给Acceptor。如果是读写事件,Reactor传给Handler。
1. 优点

a 优点
 结构简单、单线程完成,没有进程通信问题。对一些业务场景简单,对性能要求不高的应用场景。
2. 缺点

a 发挥不了服务器多核优势

b 客户端连接过多导致客户端连接多,Reactor线程负载过重。导致客户端连接超时,
  最终导致大量信息积压。性能低。
  
c 单点故障后,导致系统通信故障。

2.2.2 多线程模型

0b3b33b7aca5da41f17cc21a5f4e8674.png上图说明

相对于单线程而言,不同点在于,Handler只负责用户响应和事件分发。真正业务逻辑在work线程池中处理。
1. 存在问题

a 多线程数据共享比较复杂。如子线程完成业务处理后,把结果传递给主线程Reactor,
  就会涉及数据的互斥和保护机制。
  
b Reactor承担所有的监听和响应。如果百万客户端连接,获取服务端进行客户端握手安
  全认证,认证本身就很消耗性能。

2.2.3 主从多线程模型

50e817fac2c38d9afa1428954789e5ba.png上图说明

a Reactor分成两个部分,MainReactor负责监听server socket,用来处理网络io建立,
将建立的socketChannel指定注册给SubReactor。
b SubReactor建立和socket数据交互和事件业务处理。

1. 优点

a 响应快不必为单个同步事件所阻塞,虽然Reactor本身是同步的
b 可扩展性强 通过扩展SubReactor充分利用CPU资源
c 可复用性高 该模型和具体事件处理逻辑无关,具有很高复用性。

2.2.4 Netty模型(主要是主从多线程模型)

6eb96ea6886eef367e48f40c2499eb2b.png1. 上图解释

a 在netty模型中,负责处理新连接的是BossGroup,负责其他事件的是WorkGroup。
 (Group代表线程池的概念)
 
b NioEventLoop表示一个不断循环处理任务的线程,用于监听绑定在上面的读/写事件。

c PipeLine里面放着一个个ChannelHandler,ChannelHandler用于业务处理。

上文介绍了Reactor三种模型:单线程、多线程、主从多线程模型。也对三种模型有了个认识。来看看Netty常用的主从多线程模型,将监听客户端事件,建立连接、业务处理,且分开,对高并发更好的支持。感觉我对这三种模型没有深刻印象,欢迎留言区,留下各位高见。

预告下文

从实战带你实现服务端和客户端之间通信,并带你了解下各个组件的作用,执行原理。(与本篇文章一起发布的,感兴趣进入公众号,查看菜单Netty系列)

END公众号简介

在上班之余,学习黑马架构课程一段时间了。持续的分享一些干货,如:Netty、MySQL、缓存、中间件、中台、自动化部署、设计模式、JVM、Spring源码、MyBatis源码。如果你想对该公众号有深入了解,在公众号回复【故事】。

公众号福利

1efe9e9e77151fa3494d7c6b07cac977.png

关注公众号,回复【架构面试】,获取架构课程面试题。如果有任何建议或者想说的话,请直接向公众号发消息。运营小姐姐看到后会立即处理。烦请耐心等待!蟹蟹!




推荐阅读
  • 提升 Kubernetes 集群管理效率的七大专业工具
    Kubernetes 在云原生环境中的应用日益广泛,然而集群管理的复杂性也随之增加。为了提高管理效率,本文推荐了七款专业工具,这些工具不仅能够简化日常操作,还能提升系统的稳定性和安全性。从自动化部署到监控和故障排查,这些工具覆盖了集群管理的各个方面,帮助管理员更好地应对挑战。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 本文详细介绍了如何使用OpenSSL自建CA证书的步骤,包括准备工作、生成CA证书、生成服务器待签证书以及证书签名等过程。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • NFT市场热度持续攀升,波卡能否抓住机遇迎来NFT夏季热潮?
    NFT市场热度持续攀升,波卡能否抓住机遇迎来NFT夏季热潮? ... [详细]
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • 在PHP多线程扩展开发中,面临的主要挑战之一是多线程调用PHP用户类方法时可能出现的内存错误。具体表现为当多个线程同时调用同一个类实例的同一方法时,系统会抛出内存错误。为了解决这一问题,本文深入分析了PHP多线程扩展的实现机制,并提出了几种有效的解决方案和技术思路,包括线程安全的类设计、内存管理优化以及线程同步机制的改进。通过这些方法,可以显著提升PHP多线程扩展的稳定性和性能。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 在深入研究 React 项目的过程中,特别是在探索 react-router 源码时,我发现了其中蕴含的中间件概念。这激发了我对中间件的进一步思考与整理。本文将详细探讨 Redux 中间件的原理及其在实际项目中的应用,帮助读者更好地理解和使用这一强大工具。通过具体示例和代码解析,我们将揭示中间件如何提升应用的状态管理和异步操作处理能力。 ... [详细]
  • 投融资周报 | Circle 达成 4 亿美元融资协议,唯一艺术平台 A 轮融资超千万美元 ... [详细]
  • 优化后的标题:深入解析09版Jedis客户端
    深入解析09版Jedis客户端,本文将详细介绍如何在Java项目中正确配置Jedis以操作Redis。首先,确保项目的JDK版本和编译器设置正确。接着,通过Maven或Gradle导入必要的依赖项,如 `redis.clients:jedis`。此外,文章还将探讨Jedis连接池的配置与优化,以及常见问题的解决方案,帮助开发者高效使用Jedis进行Redis操作。 ... [详细]
author-avatar
浩哥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有