博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
闪电侠 Netty 小册里的骚操作
阅读量:6419 次
发布时间:2019-06-23

本文共 3249 字,大约阅读时间需要 10 分钟。

前言

即使这是一本小册,但基于“不提笔不读书”的理念,仍然有必要总结一下。此小册对于那些“硬杠 Netty 源码 却不曾在千万级生产环境上使用实操”的用户非常有用。当然,对那些没有 Netty 编程经验的人来说,更为有用。

放个小册地址:

再次强烈推荐,一碗黄焖鸡/半杯 Luckin coffee/一包炫赫门 的价钱,可以让你学会使用 Java 界的 epoll 进行多路复用网络编程,不能说是不划算的 :)

本文标题含有“骚操作”,为什么这么说呢?

作者是某团某评基础架构部技术专家,长期负责后台千万级别的推送系统,而这些推送系统自然是长连接实现的。可以想象,作者的这些实践经验不可谓不好用,纵然看过源码,提过 issue,本人也觉得这些操作非常好用,非常骚气。

开始

我们挑重点讲,虽然对于强迫症来讲,每一节都有笔记才是最吼的!

1 服务端启动流程

1. 通过给 bind 方法添加监听器,用以自动绑定递增端口。算骚操作吧?2. attr 方法,为每条连接增加属性,能够实现全单例模式哟3. childOption 方法,关于 TCP连接的优化,SO_KEEPALIVE 底层心跳,TCP_NODELAY 延迟发送,SO_BACKLOG 等待队列

2 客户端启动流程

1. 还是通过监听器实现重试,但是是 connect 返回的 future,且重实间隔时间左移 1 位增加(性能优化,不使用乘二 ,优秀)。2. 重试不在主线程,而是使用 bootstrap.config().group().schedule 搞定时任务,和我想的不一样。优秀3. 客户端需要 CONNECT_TIMEOUT_MILLIS 属性

3 客户端与服务端双向通信

1.客户端在 channelActive 立刻搞事情,嗯,rpc 通信通常也会做一些处理,例如打印客户端ip之类的。

4 客户端与服务端通信协议编解码(扩展较多)

emm,这个其实就是自定义应用层协议。1. 4 字节魔数校验,例如 dubbo 就使用0xdabb进行校验,Java 字节码也使用 0xcafebabe 校验字节码。2.  版本号肯定需要的3. 序列化算法,肯定也需要的4. 指令,肯定也是需要的,不过,也可以使用别的方式。5. 后面的数据长度,也是需要的,方便拆包。其实这里可以参照 RPC 协议来看,这里更像一个简化的 RPC 协议。一般 RPC 框架首先获取协议类型,根据这个协议类型得到协议处理器,然后再处理(一个端口处理多个协议的场景)。生产级别的 RPC 通常较为复杂,以 SOFABolt 为例,需要以下字段:1. 协议版本2. 请求类型,即指令(Request,Response, oneway)3. 指令版本4. RequestID 负责数据对应5. 序列号器6. 协议开关(例如 CRC 校验,安全校验)7. 响应码,约定异常,简化异常8. 类名长度,Java rpc 框架必备9. 请求头长度(参照 http header)10. 请求体长度(参照http body)11. 类名12. 业务请求头内容(一般是 Map,SOFABolt 支持自定义,SOFARPC 里面藏着是否泛化调用等信息)13. 业务请求体内容(一般就是个Request对象或 Response对象,里面包含约定的属性,例如参数,返回值,超级多,SOFARPC 有个属性类 RemotingConstants,这里都有)14. CRC 校验码(金融场景必备)

5 实现客户端与服务端收发消息

1. 使用 hannel.attr(Attributes.LOGIN).set(true) 绑定登录标识方便哟

6 构建客户端与服务端 pipeline

1. 常用的 ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter 但是需要强转哦,麻烦,   建议使用 SimpleChannelInboundHandler (还帮你释放内存哟)。2. 不使用 MessageToByteEncoder ,可以自己编解码哦,虽然麻烦点

7 拆包粘包理论与解决方案

1. 常用拆包:固定长度,行拆包(有bug,我写过文章分析),分隔符,基于长度2. 最通用的就是基于长度,只要你的自定义协议中包含长度域字段,就可以使用3. LengthFieldBasedFrameDecoder 代替自己继承 ByteToMessageDecoder 哟。4. 对 LengthFieldBasedFrameDecoder 扩展一下,校验魔数关闭错误连接美滋滋。

8 channelHandler 的生命周期

1. 在 channelReadComplete 方法里执行 flush,批量刷新,性能提升美滋滋。2. channelActive 和 channelInActive 增减连接,RPC 都这么干

9 使用 channelHandler 的热插拔实现客户端身份校验

1. ctx.pipeline().remove(this) 删除没有必要的 handler 美滋滋2. handlerRemoved 回调美滋滋

10 客户端互聊原理与实现

1. Session 通过 channel.attr(Attributes.SESSION).set(session) 绑定连接美滋滋。2. channel.attr(Attributes.SESSION).set(null) 删除 session 美滋滋3. channel.attr(Attributes.SESSION).get() 美滋滋

11 群聊的发起与通知

1. ChannelGroup c = ChannelGroup channelGroup = new DefaultChannelGroup(ctx.executor()) 批量处理连接美滋滋2. channelGroup.writeAndFlush 批量写连接美滋滋

高能预警!!!!

12 牛逼的性能优化

1. 共享 handler2. 压缩 handler - 合并编解码器 —— MessageToMessageCodec3. 虽然有状态的 handler 不能搞单例,但是你可以绑定到 channel 属性上,强行单例4. 缩短事件传播路径—— 放 Map 里,在第一个 handler 里根据指令来找具体 handler。5. 更改事件传播源—— 用 ctx.writeAndFlush() 不要用 ctx.channel().writeAndFlush()6. 减少阻塞主线程的操作—— 使用业务线程池,RPC 优化重点7. 计算耗时,使用回调 Future

13 心跳和空闲检测

1. 空闲检测 IdleStateHandler 用起来很爽, channelIdle 和 userEventTriggered 都可以处理2. 定时心跳 ctx.executor().scheduleAtFixedRate 很优秀3. 通常空闲检测时间要比发送心跳的时间的两倍要长一些(3倍),这也是为了排除偶发的公网抖动,防止误判。美滋滋

总结

小小短文,无法尽数 Netty 精华,但对于新手来说,已经足够使用了。而我这里仅仅是做简单的阅读总结,更多的内容,还需要读者自己去研究小册,研究源码,研究 Netty 在 RPC 里的运用,方能成为 Netty 多路复用网络编程高手。

关于 RPC 里使用 Netty 的最佳范例,推荐蚂蚁金服开源框架 ,可以说是对 Netty 编程最佳实践的提炼,和此文相辅相成进行学习,可助汝纵横 Java 各种面试。

good luck!!!

转载于:https://www.cnblogs.com/stateis0/p/9784323.html

你可能感兴趣的文章
Oracle-01:基础命令小结
查看>>
创建用户配置文件
查看>>
New Concept English Two 31 85
查看>>
New Concept English three (29)
查看>>
2014年发生的一些事情
查看>>
hdu3709
查看>>
自定义对话框,时间日期对话框
查看>>
windows上apache+php+mysql环境部署
查看>>
cocos2dx——裁剪节点ClippingNode
查看>>
13. Intellij IDEA调试功能使用总结
查看>>
3. Spring Boot Servlet
查看>>
3n+1问题
查看>>
[FPGA] DE0_NANO eeprom i2C控制程式
查看>>
java 反射之获取泛型对象的所有字段与对应的值(包括父类的)
查看>>
js中修改标签的hidden属性
查看>>
2012年流行的安卓手机浏览器
查看>>
树莓派摄像头直播程序,非常希望有贡献者一起玩
查看>>
mysql 用drop和delete方法删除用户的区别(草稿)
查看>>
vs code插件
查看>>
less学习笔记四
查看>>