分布式服务框架原理与实践之 通信框架

憧憬 2018-08-05

1.技术点

1.1 长连接还是短连接?

长连接更加省资源,长连接只有在首次创建或者链路重连才会创建链路,实现多消息复用同一个链路、

1.2 采用BIO还是NIO、?

采用nio,因为nio的多路复用技术,Selector可以管理多个通道Channel,nio的非阻塞更加高效、

1.3 自己研制还是选择开源nio框架

netty已经经过诸多项目的考验,并且API层对底层进行了细节隐藏,更加便捷;

netty解决了java 传统nio的bug;

2.功能设计

2.1服务端的设计

原则:1.服务端只提供上层的API,不与任何协议绑定。

2.服务端提供给用户的API尽量的屏蔽底层的通信细节,防止底层变更引起级联变 更。

3.功能不在于全面,而在于可扩展。

2.2客户端设计:

1.第一步创建Bootstrap实例。

2.初始化TCP链接参数,设置编解码handler和其他业务handler,

3.connect方法发起异步TCP连接操作;

connect为异步链接,程序不会等待。TCP是否连接可以通过返回的ChannelFuture对象来通知连接结果。(同步等待:wait后notify,会有InterruptionException;注册监听器:等待操作完成后异步通知)

4.采用连接监听器的方式,异步通知结果;

5.服务端返回TCP握手应答,矽统回调监听器操作完成接口。

6.操作完成接口中实现的逻辑,通知客户端连接操作完成。

分布式服务框架原理与实践之 通信框架

3.可靠性设计

3.1 链路有效性检测

当前流行的做法是:心跳检测

心跳检测的机制:

1.TCP层面:TCP的Keep-Alive;它的作用域是整个TCP协议栈;

2.协议层:主要是长连接连接协议中,例如SMPP协议。

3.应用层:通过各个业务与产品通过约定方式定时给对方发送信条消息。

心跳检测的目的:

确认当前的链路是可用的。

不同的协议,心跳机制:

1.ping-pong型心跳:请求-响应型,一方发出ping,收到信息后立即回复pong;

2.ping-ping型心跳:双方按照约定定时想对方发送ping;属于双向心跳。

心跳检测策略:

1.心跳超时:连续N次未检测到对方发送来的ping或者pong信息,则认为链路失效;

2.心跳失败:读取或者发送消息的时候发生了I/o异常;

无论是超时还是失败,都要关闭链路,并且有客户端发起重连,保证恢复正常。

Netty心跳检测利用链路空闲检测机制实现的,空闲机制分为:

1.读空闲:链路持续时间t没有读取任何消息

2.写空闲:链路持续时间t没有发送消息

3.读写空闲:链路持续时间t没有读或者写消息

Netty默认读写空闲机制;利用netty提供的链路空闲检测机制,可以非常灵活的实现链路空闲时的有效性检测;

3.2 断连重连机制

利用netty的CloseChannel,可以方便的检测链路状态,一旦链路关闭,则可以重连。

3.3 消息缓存重发

我们调用发送消息接口的时候,消息并没真正写入Socket中,而是先放入了nio框架的消息发送队列中,由Reactor线程扫描待发送的消息队列,异步的发送给通信对方;遗憾的是 消息队列中挤压部分消息而此时链路断开,这部分消息就会丢失,netty和mina都没有对 消息缓存和重新发送 进行提供,需要自己封装实现。

基于netty如下:

1)、调用ChannelHandlerContext的write()方法时候,返回ChannelFuture对象,我们在ChannelFuture中注册发送结果监听Listener;

2)、在listener的operationComplete方法中判断操作结果,如果操作不成功,将之前发送的消息添加到重发队列;

3)、链路重连成功之后,根据策略,将缓存队列中的消息重新发送出去。

3.4 资源优雅释放

netty提供了相应的接口和类库进行资源优雅释放

优雅释放:

java优雅停机是通过注册jdk的shutdownHook来实现;当系统受到退出指令的时候,首先标记系统处于退出状态,不再接收新消息,然后积压的信息处理完最后资源回收接口调用销毁资源,最后线程退出执行。

一般优雅退出有时间限制,例如30s。如果还未处理完强制执行kill -9 pid

分布式服务框架原理与实践之 通信框架

4 性能设计

4.1 性能差:

1.网络传输问题

BIO通信模型,服务端为请求的线程生成不能与并发访问呈线性关系,所以会发生句柄溢出,线程堆栈溢出等,

2.序列化性能差

Java序列化机制是java内部的一种对象编解码机制,无法跨语言使用;

相较于其他开源序列化框架,java序列化后的码流太大,不利于传输或者存储。

序列化性能差,CPU占有率高

3.线程模型问题

同步阻塞I/O,tcp每个链接占一个线程,阻塞导致线程无法及时释放,导致性能下降;

4.2 通信性能三原则:

1.传输:NIO、 BIO、 AIO

2.协议:相较于公有协议,内部私有协议往往性能被设计的更优。

3.线程:Reactor线程模型的不用,对性能影响很大。

分布式服务框架原理与实践之 通信框架

4.3 高性能之道

1)、异步非阻塞通信

netty的I/O线程NioEventLoop由于聚合了多路复用器Selector,可以同时处理很多SocketChannel,这就解决了传统同步阻塞IO一个连接一个线程的模型,架构性能、伸缩性得到了提升。

2)、高效的I/O线程模型

netty支持Reactor单线程模型、Reactor多线程模型、主从Reactor多线程模型

3)、高性能的序列化框架

netty默认提供google的Protobuf的二进制序列化框架。

同时,netty还提供了零拷贝、内存池等性能相关的特性。

想要学习Dubbo框架、zookeper基本原理、redis分布式缓存、JVM性能优化,Nginx+apache+Tomcat集群部署、大数据hadoop,Hbase实时计算spark、storm、数据分析分词和权重等核心技术;需要的可以关注之后私信哈,记得要点赞转发噢!!!

相关推荐