当前位置: 首页 > news >正文

Netty面试题(三)

文章目录

  • 前言
  • 一、如何选择序列化协议?
  • 二、Netty 的零拷贝实现?
  • 总结


前言

  1. 如何选择序列化协议?
  2. Netty 的零拷贝实现?

一、如何选择序列化协议?

具体场景
对于公司间的系统调用,如果性能要求在 100ms 以上的服务,基于 XML 的 SOAP 协议是一个值得考虑的方案

基于 Web browser 的 Ajax,以及 Mobile app 与服务端之间的通讯,JSON 协议是首选。对于性能要求不太高,或者以动态类型语言为主,或者传输数据载荷很小的的运用场景,JSON也是非常不错的选择。

对于调试环境比较恶劣的场景,采用 JSON 或 XML 能够极大的提高调试效率,降低系统开发成本。

当对性能和简洁性有极高要求的场景,Protobuf,Thrift,Avro 之间具有一定的竞争关系。
对于 T 级别的数据的持久化应用场景,Protobuf 和 Avro 是首要选择。如果持久化后的数据存储在 hadoop 子项目里,Avro 会是更好的选择。

对于持久层非 Hadoop 项目,以静态类型语言为主的应用场景,Protobuf 会更符合静态类型语言工程师的开发习惯。由于 Avro 的设计理念偏向于动态类型语言,对于动态语言为主的应用场景,Avro 是更好的选择。

如果需要提供一个完整的 RPC 解决方案,Thrift 是一个好的选择。
如果序列化之后需要支持不同的传输层协议,或者需要跨防火墙访问的高性能场景,Protobuf 可以优先考虑。
protobuf 的数据类型有多种:bool、double、float、int32、int64、string、bytes、enum、message。protobuf 的限定符:required: 必须赋值,不能为空、optional:字段可以赋值,也可以不赋值、repeated: 该字段可以重复任意次数(包括 0 次)、枚举;只能用指定的常量集中的一个值作为其值;

protobuf 的基本规则:每个消息中必须至少留有一个 required 类型的字段、包含 0 个或多个 optional 类型的字段;repeated 表示的字段可以包含 0 个或多个数据;[1,15]之内的标识号在编码的时候会占用一个字节(常用),[16,2047]之内的标识号则占用 2 个字节,标识号一定不能重复、使用消息类型,也可以将消息嵌套任意多层,可用嵌套消息类型来代替组。

protobuf 的消息升级原则:不要更改任何已有的字段的数值标识;不能移除已经存在的required 字段,optional 和 repeated 类型的字段可以被移除,但要保留标号不能被重用。新添加的字段必须是 optional 或 repeated。因为旧版本程序无法读取或写入新增的required 限定符的字段。

编译器为每一个消息类型生成了一个.java 文件,以及一个特殊的 Builder 类(该类是用来创建消息类接口的)。如:UserProto.User.Builder builder =
UserProto.User.newBuilder();builder.build();

Netty 中的使用:ProtobufVarint32FrameDecoder 是用于处理半包消息的解码类;ProtobufDecoder(UserProto.User.getDefaultInstance())这是创建的 UserProto.java 文件中的解码类;ProtobufVarint32LengthFieldPrepender 对 protobuf 协议的消息头上加上一个长度为32 的整形字段,用于标志这个消息的长度的类;ProtobufEncoder 是编码类将 StringBuilder 转换为 ByteBuf 类型:copiedBuffer()方法


二、Netty 的零拷贝实现?

Netty 的接收和发送 ByteBuffer 采用 DIRECT BUFFERS,使用堆外直接内存进行 Socket 读写,不需要进行字节缓冲区的二次拷贝。堆内存多了一次内存拷贝,JVM 会将堆内存Buffer 拷贝一份到直接内存中,然后才写入 Socket 中。ByteBuffer 由 ChannelConfig 分配,而 ChannelConfig 创建 ByteBufAllocator 默认使用 Direct Buffer

CompositeByteBuf 类可以将多个 ByteBuf 合并为一个逻辑上的 ByteBuf, 避免了传统通过内存拷贝的方式将几个小 Buffer 合并成一个大的 Buffer。addComponents 方法将 header与 body 合并为一个逻辑上的 ByteBuf, 这两个 ByteBuf 在 CompositeByteBuf 内部都是单
独存在的, CompositeByteBuf 只是逻辑上是一个整体

通过 FileRegion 包装的 FileChannel.tranferTo 方法 实现文件传输, 可以直接将文件缓冲区的数据发送到目标 Channel,避免了传统通过循环 write 方式导致的内存拷贝问题。

通过 wrap 方法, 我们可以将 byte[] 数组、ByteBuf、ByteBuffer 等包装成一个 Netty
ByteBuf 对象, 进而避免了拷贝操作。

Selector BUG:若 Selector 的轮询结果为空,也没有 wakeup 或新消息处理,则发生空轮询,CPU 使用率 100%,

Netty 的解决办法:对 Selector 的 select 操作周期进行统计,每完成一次空的 select 操作进行一次计数,若在某个周期内连续发生 N 次空轮询,则触发了 epoll 死循环 bug。重建
Selector,判断是否是其他线程发起的重建请求,若不是则将原 SocketChannel 从旧的
Selector 上去除注册,重新注册到新的 Selector 上,并将原来的 Selector 关闭。


总结

  1. 如何选择序列化协议?
  2. Netty 的零拷贝实现?
http://www.lryc.cn/news/170239.html

相关文章:

  • risc-v dv源代码分析
  • C语言基础语法复习07-c语言关键字的解释
  • 阿里巴巴全店商品采集教程,阿里巴巴店铺所有商品接口(详解阿里巴巴店铺所有商品数据采集步骤方法和代码示例)
  • Android 白天黑夜模式设置
  • FFMpeg zoompan 镜头聚焦和移动走位
  • 利用hutool工具类实现验证码功能
  • 前端面试题: 请解释什么是函数的作用域?
  • 华为云云服务器云耀L实例评测 | 华为云云服务器实例新品全面解析
  • Nginx配置SSL证书
  • 一,安卓aosp源码编译环境搭建
  • video 视频编解码一些debug方法
  • 中秋国庆假期——模板推荐
  • 【配代码演示】Cookie和Session的区别
  • 【Linux初阶】信号入门2 | 信号阻塞、捕捉、保存
  • 【已解决】:该该虚拟机似乎正在使用中。如果该虚拟机未在使用,请按“获取所有权(T)“按钮获取它的所有权。否则,请按“取消(C)“按钮以防损坏。
  • 系统架构常用的工具
  • 腾讯云2核4G服务器5M带宽 218元一年 优惠价格明细表
  • [C++ 网络协议] 多播与广播
  • IOS17正式版今日发布
  • 2560. 打家劫舍 IV
  • java web中部署log4j.xml
  • 【张兔兔送书第一期:考研必备书单】
  • 基于Spring Boot+ Vue的健身房管理系统与实现
  • ThreadLocal线程局部变量
  • C++ Primer (第五版)第一章习题部分答案
  • Python与GUI集成:零基础也能开发国际象棋游戏
  • SaaS软件能保证数据安全吗?
  • 方案:基于AI烟火识别与视频技术的秸秆焚烧智能化监控预警方案
  • phantomjs插件---实现通过链接生成网页截图
  • SpringBoot分页实现查询数据