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还提供了零拷贝、内存池等性能相关的特性。
  • 相关阅读:
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
    Neo4j批量插入(Batch Insertion)
    嵌入式(Embedded)Neo4j数据库访问方法
    Neo4j 查询已经创建的索引与约束
    Neo4j 两种索引Legacy Index与Schema Index区别
    spring data jpa hibernate jpa 三者之间的关系
    maven web project打包为war包,目录结构的变化
    创建一个maven web project
    Linux下部署solrCloud
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608432.html
Copyright © 2011-2022 走看看