网络聊天室项目介绍

文章目录

  • 项目介绍
    • 项目地址
  • 项目底层核心运行架构
    • 版本1
    • 版本2
  • BUG记录
  • 后续计划

项目介绍

本项目主要是开发一个网络传输中间组件,实现1对1和1对多的网络通信,并且有效解决一些常用的丢包和粘包的问题。目前支持超大文件传输。
主要应用场景:如网络聊天室,当然可以扩展应用
开发语言:Java
涉及技术:NIO,高并发.

项目地址

https://github.com/13days/socket-learn
当前版本在socket-learn/chatRoom_1_0/这个目录下维护。

项目底层核心运行架构

版本1

网络聊天室项目介绍_第1张图片
核心连接器,包括发送和接收两部分,值得一提的是,发送和接收都是支持并发的。在发送字符串的时候我们把他封装成一个包再拆分发送到网络。
并发调度结构入下:
网络聊天室项目介绍_第2张图片
在这个版本中,对于每一个客户端/或服务端。他的接收和发送都必须连接到一个IoProvider的调度器上面。在调度器上面分别由读线程和写线程来分派任务,其中读线程监听,写线程发送。所有的任务都会委派到线程池中取完成,最后完成时收到回调通知,重写组织数据。并返回业务层做相应的处理。
发送执行调度流程如下:
网络聊天室项目介绍_第3张图片
其中SendDispatcher的两条路径分别是发送完一个Packet和继续发送当前Packet的两条路径。

版本2

在这个版本中提供了更良好的代码封装。引入了3重缓冲机制,支持超大文件发送,并做了压测,支持20WBPS,在此规模下,jvm消耗内存仅由100M左右,并且支持更多的长连接数,在压测版本中,可能同时支持10w长连接,当然,连接量还和并发发送的频率有关,此消彼长。
运行数据流图大致情况网络聊天室项目介绍_第4张图片
在这里面你会看到上个版本没有的东西,比如Frame帧的概念,比如Channel通道的概念。这是引入了3级缓冲所带了的新实体。
为什么要引入3级缓冲呢?
当需要发送的数据量过大的时候,我们总不可能期望把数据都读到内存里然后再进行发送,这样服务器内存会飙升的!!!
所以我们引入了第一级缓冲,Channel通道的方式,和上个版本保存一致的是,上个版本的数据读到Packet里,而这个版本Packet里面实际存放的是Channel。
当数据读到Channel里面后,我们就和可以分批次去读数据啦!当时还有两个问题,读多少数据进来呢?读到的数据如何保证有序呢?这就引入了第2级缓冲。
在这里缓冲里我们定义了实体帧Frame(后面你会看到具体的数据结构),每个帧由首部和实体构成,根据首部我们可以构建完整的数据,这不仅解决了顺序问题,还解决了消息粘包的问题!当然,我们不可能一次读很少的数据发送到网络中去,这样会发送很多次本地的IO,大大降低了程序的执行速率,但是,我们又不能一次把读到的数据发送到网络中去,这样发送的数据过多,会大大减少并发量。
所以针对这个问题,我们采用了第3级缓冲,IoArgs,这是具体发送到网络中的数据,多个IoArgs组成一个Frame,IoArgs的大小可以根据实际环境进行配置。
这样做的好处在哪呢?
这样能做到持久层内存>>运行内存>单次网络数据量
使得,并发量大大提升,网络被充分利用,增加了服务器的稳定性,多条数据真正并发发送

三级缓冲的数据结构
Chanel = Frame+Frame+Frame…
Frame = (报文+实体) = IoArgs+IoArgs+IoArgs…
网络聊天室项目介绍_第5张图片
下面的内容是介绍一下程序运行时的数据流图
网络聊天室项目介绍_第6张图片
网络聊天室项目介绍_第7张图片
在上面的发送流图中,我们可以看到大量使用了回调功能,比如回调发送下一个IoArgs,或者构建下一个Frame或则回调到上层发送异常或者回调通知上层应用完成处理等。
接送数据的执行流图
在TCP完成监听之后的回调任务如下
网络聊天室项目介绍_第8张图片
网络聊天室项目介绍_第9张图片
上面是一个线程在监听到有任务到达的回调,通过帧的ID来构建发送方发送过来的帧,在组装成包的形式提供给应用层使用。

BUG记录

网络聊天室项目介绍_第10张图片
网络聊天室项目介绍_第11张图片
网络聊天室项目介绍_第12张图片
主要是空指针buff,如连接断开促发。还有selectionkey没有即使注销掉的问题,导致其他链接无法使用。

后续计划

后续打算扩展业务层相关的功能。

你可能感兴趣的:(网络聊天室项目介绍)