Netty的使用主要是在网络交互中,在框架使用Netty的有 DUBBO 、RocketMQ 、 vertx 、Lettuce 等等,在其他方面主要用来作为IOT服务的后端,采用Java作为后端服务器,Netty作为网络框架交互. 下面分享一下在IOT服务方面维护Netty服务器的一些问题.
这里总结一下在维护过程中遇到的一些问题
总体逻辑图
Netty服务是使用Tomcat/SpringBoot来进行启动的. 所以存在3个端口。分别是Tomcat的http端口,RPC服务的暴露端口,Netty的监听端口.
问题
- 服务网关
硬件机器启动时从网关获取实际的Netty服务器IP和端口,或者之后链接到Netty服务器,这个动作建议作为一个日志上传到服务器,不然一旦出现获取端口但是不链接服务器的情况,后端同学会比较懵逼,也可以避免后端返回错误IP:PORT的情况。
- Netty服务日志
Netty服务器的日志不太好看,尤其是在Netty服务比较多的情况下,找起来特别麻烦. 建议将日志写入到ES,排查文件比较方便,需要注意ES写入的日志索引.
- Netty发布时端口处理
Netty发布时需要单独占用一个端口对外提供服务,平时看起来没有什么问题,但是在迁移的时候就会出现问题. 白名单/服务注册等等,比较好的解决方法是划一个port段,都可以作为作为白名单,服务启动时随机注册一个即可.
- Netty服务暴露
对外提供的服务是通过RPC来实现的,暴露服务很简单,但是在开发服务中引用的时候就比较麻烦了,因为硬件只会去连一台服务器,因此要找到对应的服务才行,这样一来就是一台服务一个版本,水平扩容和迁移的时候特别头大,现在我想的解决方法是:
不通过RPC进行服务暴露,而是通过HTTP进行暴露,这样以来只要将Netty服务的IP和Tomcat端口暴露出去即可,调用方直接通过Http进行调用. 简洁明了,初期可能需要点时间,但这是值得的.
服务注册可以是Zookeeper,也可以是Nacos, 都可以,看团队Hold住那个即可. Mac地址和Netty服务但映射,这里可以使用持久化MySQL,也可以使用Memcache/Redis去做,我个人认为缓存要好一点. 其实本质上没有太大但区别.
- 开放服务
每一台机器只能链接到一台Netty服务上,这样在开放服务上也要根据机器到MAC地址找到Netty暴露到服务,这里到设计一定好非常的非常的健壮,可以支撑Netty水平拓展的情况,支持随时随地迁移.
- 协议设计
协议的设定有简单的,也有复杂的,简单的就是魔数+length+data,复杂的有RocketMQ的传输协议,较为复杂,但是可以兼容到几乎所有到拓展情况. 协议的设定一定要简洁的同时要满足业务,不要在乎一个字节/几个字节,这些都是小事. 代码的可读性放在第一位,很多比特位反而影响代码的可读性.
- 硬件
软件出现Bug比较好解决,但是一旦硬件出现了Bug就比较麻烦了,我们第一时间接触不到,只能在软件层面做缝缝补补的话一般只会带来更大的Bug. 所以在测试的时候需要针对硬件做全面的测试
解决方案
目前我遇到的业务中,基本上使用Netty作为后端长链接服务的都是有状态的项目,这个状态体现在netty端口的注册上,以及TCP长链接的唯一性。
由于这写问题限制了下行消息的发送必须要找到与硬件机器建立TCP长链接的服务器才行,这里就引入了路由。
解决的方案目前想到了一个,就是将有状态转化为无状态,Netty端口注册是不可避免的,不过他是无状态的,在路由上可以使用MQ广播来避免路由寻址的问题。
如果硬件和我链接了,我就发出去,如果没有和我链接,我就丢弃。
ARP协议在上层协议上的应用?
总结
这个只是暂时遇到的一些问题,后续有再补充.