物联网,车联网netty服务器springboot支持图形化源码

先转发,加关注后私信“netty源码”即可免费获取源码

基于netty4,protoBuff的netty心跳服务器支持鉴权、断线重连、其他业务模块开发、支持图形化实时监控,可直接投入生产

Netty心跳服务器

Springboot2.0.8集成 netty4 ,使用protobuf作为ping的数据交换,比json更加的小巧,占用数据量更小,可用于任何第三方应用做心跳监控

应用场景

比如公司可以使用的一种业务场景是这样的: 现有多台服务器,有a业务的 有b业务的 有c业务的 有d业务项目等等,有时候用户量大或者其他因素,这些服务器down掉了,大多数情况都是基于运维监控报警的,但是由于项目都是多台机器部署同一个项目,项目挂了后centos主机并不能很快检查出来,一般时间会比较长在半小时之内,甚至有的时候是用户来打电话告知项目down掉了,这对公司来说影响多么的大。 挂上了项目心跳后,可以实时看到100多台机器的实时ping值是否正常,当然你也可以通过定时请求http接口来判断是否应用正常,熟知http接口的请求耗费资源,使用本项目的ping或者其他鉴权,protobuff基本上消耗网路开销非常的小,响应快,netty的长连接上线下立马感知,性能稳定好。

物联网,车联网netty服务器springboot支持图形化源码

物联网,车联网netty服务器springboot支持图形化源码

物联网,车联网netty服务器springboot支持图形化源码

开发环境

  • JDK8+
  • IntelliJ IDEA
  • springboot 2.0.8.RELEASE
  • Netty4.1.6.Final
  • protobuf-java3.3.0
  • Redis
  • Thymeleaf模板
  • Echarts图表
  • Tomcat8.5

项目说明

  1. 已完成功能
  • 客户端授权验证(基于protoBuff)
  • 心跳检测(基于protoBuff)
  • 断线重连
  • 计算ping值(支持到微秒)
  • 其他子业务模块(架子已搭进去)
  • 为了方便测试,项目已经支持跨域访问

说明

Netty是一个NIO客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化并简化了TCP和UDP套接字服务器等网络编程。 “快速简便”并不意味着最终的应用程序会受到可维护性或性能问题的影响。Netty经过精心设计,具有丰富的协议,如FTP,SMTP,HTTP以及各种二进制和基于文本的传统协议。因此,Netty成功地找到了一种在不妥协的情况下实现易于开发,性能,稳定性和灵活性的方法。4x(推荐,稳定,jdk1.6+)

几个常见的类

  • ServerBootstrap

netty服务器的帮助类

  • NioEventLoopGroup

处理I/O操作的多线程事件循环相当于一组线程池,服务器一般需要指定两个NioEventLoopGroup,一个作为监控tcp连接的,一个作为处理io事件的,前者默认1个线程就可以,后者最好是cpu核心数的2倍 客户端用一个就够了

  • NioServerSocketChannel

主要是server端接收建立SocketChannel用的

  • NioSocketChannel

主要是客户端接收SocketChannel用的

  • ChannelInboundHandlerAdapter

可以重写的各种事件处理程序方法,包括channelRead()、exceptionCaught()等方法

  • SimpleChannelInboundHandler

可以重写的各种事件处理程序方法,包括channelRead0()方法 这个可以跟指定的消息类型比上面的,如果自定义的消息类型用这个稍微多一点

  • ChannelPipeline

存放各种处理器,包括解码器,编码器等自定义处理器,idleStateHandler一定要放在第一个,传送数据时,编码器和解码器一定要放在前面,这个加载是分顺序的

  • ChannelHandlerContext

ChannelHandlerContext的writeAndFlush和ChannelHandlerContext.channel().writeAndFlush()是有区别的 前者是从当前hanler从后往前找OutputboundHandler,然后交给它执行的,后者是从最后一个开始执行handler的,最常见就是写错pipeline中的顺序后,客户端或服务器发消息就收不到了

  • ChannelInitializer

客户端和服务器都要用这个的SocketChannel,初始化的时候,加载ChannelPipeline

  • Bootstrap

客户端的连接帮助类

  • idleStateHandler

Netty 可以使用 IdleStateHandler 来实现连接管理,当连接空闲时间太长(没有发送、接收消息)时则会触发一个事件,我们便可在该事件中实现心跳机制

基本以上的几个类就可以满足日常的80%需求了,剩下就是书写各自的业务

心跳服务器实现详细过程

  1. 客户端网络空闲5秒没有进行写操作是,进行发送一次ping心跳给服务端;用自定义的消息格式类,其中包含验证auth、ping、pong等类型来代表不同的业务,首次连接时候在ChannelInboundHandlerAdapter中可以建立连接,客户端会发送一次auth类型的授权信息(用户名+盐值密码),服务器收到后作出校验响应,只有收到服务器的auth_ack响应客户端才能做出连接,否则断开当前链接,释放链路;
  2. 客户端如果在下一个发送ping心跳周期来临时,还没有收到服务端pong的心跳应答,则失败心跳计数器加1;
  3. 每当客户端收到服务端的pong心跳应答后,失败心跳计数器清零;
  4. 如果连续超过3次没有收到服务端的心跳回复,则断开当前连接,在5秒后进行重连操作,直到重连成功,否则每隔5秒又会进行重连;
  5. 服务端网络空闲状态到达10秒后,服务端心跳失败计数器加1;
  6. 只要收到客户端的ping消息,服务端心跳失败计数器清零;
  7. 服务端连续3次没有收到客户端的ping消息后,将关闭链路,释放资源,等待客户端重连;

心跳相关验证

当客户端超过三次没有收到服务器pong,客户端主动断开当前channel连接,重连服务器

物联网,车联网netty服务器springboot支持图形化源码

当服务器超过三次没有收到客户端ping,服务器主动断开当前客户端的channel连接

物联网,车联网netty服务器springboot支持图形化源码

ping值设计过程

ping值是基于客户端来的,即客户端发送ping之后,会先记录当前的时间(默认单位是ms),支持微秒的方法,当客户端再次收到响应后,记录当前时间a,因为数据传输双方时间是相同的,所以拿当前时间b-a,再除以2就是ping值了。然后把这个ping值,记录到redis中去。这里使用的是 System.currentTimeMillis(),用new Date().getTime()时间会出错,不知道为啥?看源码是一样的逻辑不大理解

起初是基于服务器计时的,但是服务器和客户端不可能在一台主机上,导致时间存在偏差,ping值就不准确了。 存到redis主要是为了使echarts访问最近几次的ping状态。起初想做成websocket的,但是这样的话,第一次进来当前页面数据会不全,而且不好日后做历史ping的统计

物联网定制开发


物联网,车联网netty服务器springboot支持图形化源码


物联网,车联网netty服务器springboot支持图形化源码

先转发,加关注后私信“netty源码”即可免费获取源码


分享到:


相關文章: