基于 Netty 搭建 WebSocket 集群实现服务器消息推送

本文内容是构建高性能、高可用消息推送的经典案例,在微服务 Spring Cloud 环境下基于 Netty 搭建 websocket 集群实现的。目录为:

1、背景

2、websocket

3、netty

   3.1 socket

   3.2 Java IO模型

   3.3 netty

      3.3.1 概念:

      3.3.2 三大特点:

      3.3.3 主从Reactor架构图

      3.3.4 应用场景

4、springboot环境下使用netty搭建websocket

     4.1 系统设计架构图

     4.2 架构中存在的六大经典问题

     4.3 引入pom依赖和yml配置

     4.4 Websocket 初始化器

     4.5 websocket 通道初始化器

     4.6 websocket 入站处理器

     4.7 channel中任务队列的线程任务

     4.8 websocket启动程序

     4.9 问题六解决方案

     4.10 前端代码

     4.11 wesocket在nginx中配置

     4.12 效果图

5、总结      

我们在实际的工作开发中,必然会遇到一些需要网页与服务器端保持连接(起码看上去是保持连接)的需求,比如类似微信网页版的聊天类应用,比如需要频繁更新页面数据(实时数据例如天气,电流电压,pm2.5等等这样类似的数据)的监控系统页面或股票看盘页面,比如服务器读取MySQL或者redis或者第三方的数据主动推送给浏览器客户端等等业务场景。我们通常采用如下几种技术:

(1)短轮询:前端老师利用ajax定期向服务器发起http请求,无论数据是否更新立马返回数据。这样存在的缺点就是,一方面如果后端数据木有更新,那么这一次http请求就是无用的,另一方面高并发情况下,短链接的频繁创建销毁,以及客户端数量过大造成过多无用的http请求,都会对服务器和带宽造成压力,短轮询只适用于客户端连接少,并发量不高的场景;

(2)长轮询:利用comet不断向服务器发起请求,服务器将请求暂时挂起,直到有新的数据的时候才返回,相对短轮询减少了请求次数得到了一定的优化,但是在高并发的场景下依然不适用;

(3)SSE:服务端推送(Server Send Event),在客户端发起一次请求后会保持该连接,服务器端基于该连接持续向客户端发送数据,从HTML5开始加入。

(4)Websocket:这是也是一种保持长连接的技术,并且是双向的,从HTML5开始加入,并非完全基于HTTP,适合于频繁和较大流量的双向通讯场景,是服务器推送消息功能的最佳实践。而实现websocket的最佳方式,就是netty

网上的很多netty搭建websocket的博文都不够全面,有很多问题都木有解决方式,我通过实际工作中的经验,把常遇到的问题总结了方法,下文会说到!

什么是websocekt呢?

websocket是一种在单个TCP连接上进行全双工通信的协议。也就是一种保持长连接的技术,并且是双向的。

websocket协议本身是构建在http协议之上的升级协议,客户端首先向服务器端去建立连接,这个连接本身就是http协议只是在头信息中包含了一些websocket协议的相关信息,一旦http连接建立之后,服务器端读到这些websocket协议的相关信息就将此协议升级成websocket协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

简单理解,就是一种通讯协议,重点是websocket的实现方式–netty。

什么是netty呢?

3.1 socket

(1)网络编程本质就是说两个设备之间信息的发送与接收,通过操作相应API调度计算机硬件资源,并且利用管道(网线)进行数据交互的过程。相关技术点像ISO七层模型,TCP三次握手/四次挥手等网络编程的基础不再赘述。

(2)而socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket发起系统调用操作系统内核,我们才能使用TCP/IP协议。

(3)我们经常说的I/O,在计算机中指Input/Output,即输入输出,实质上IO分为两种,一种是磁盘IO,磁盘上的数据读取到用户空间,那么这次数据转移操作其实就是一次I/O操作,也就是一次文件I/O。一种是网络IO,当一个客户端和服务端之间相互通信,交互我们称之为网络io(网络通讯)

3.2 Java IO模型

有BIO(同步阻塞IO)、NIO(同步非阻塞IO)、AIO(异步IO),netty就是一个NIO的高性能的框架。

(1)BIO:同步阻塞IO模型,适用于连接数目比较少且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,服务器实现模式为一个连接一个线程,即客户端有连 接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造 成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器)。

(2)NIO:同步非阻塞IO模型,适用于连接数据多且连接比较短的架构,如聊天服务器,弹幕系统,服务器间通讯等;服务器实现模式为一个线程处理多个连接(一个请求一个线程),包含Selector 、Channel 、Buffer三大组件。

selector选择器:用一个线程处理多个客户端的连接,就会使用到selector选择器,selector用于监听多个通道上是否有事件发生(比如连接请求,数据到达等),如果有事件发生,便获取事件然后针对于每个事件进行相应的处理,因此可以使用单个线程就可以监听多个客户端通道。

channel通道:Channel管道和Java IO中的Stream(流)是差不多一个等级的。只不过Stream是单向的,譬如:InputStream, OutputStream.而Channel是双向的,同时进行读写数据,而流只能读或者写。可以实现异步读写数据,可以从缓冲区读数据,也可以写数据到缓冲区。

buffer缓冲区:Buffer本质上是一个可以读写的内存块,可以理解成容器对象,底层是有一个数组,通过buffer实现非阻塞机制,该对象提供了一组方法,可以轻松的使用内存块,缓冲区对象内置了一些机制,能够跟踪和记录缓冲区的状态变化情况。Channel提供了从文件,网络读取数据的通道,但是读取和写入的数据必须经过buffer。

(3)AIO:异步IO模型,使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分 调用OS参

  • 10
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值