zoukankan      html  css  js  c++  java
  • 《分布式服务框架原理与实践》读书笔记之第三章 通信框架

    感谢作者,受益匪浅,根据读书过程,进行的整理以便日后再来看。

    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还提供了零拷贝、内存池等性能相关的特性。
  • 相关阅读:
    asp.net保存网上图片到服务器
    一个强大的jquery分页插件
    JS全屏漂浮广告、移入光标停止移动
    使用C#类向数据库添加数据的例子源码
    pip安装报错Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-e_k8hq6a/pynacl/
    mycat启动报Unable to start JVM: No such file or directory (2)【转】
    pt-table-checksum校验与pt-table-sync修复数据【转】
    linux网卡参数NM_CONTROLLED【转】
    pt-table-checksum解读【转】
    pt-table-checksum报错Skipping chunk【转】
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608432.html
Copyright © 2011-2022 走看看