Java 网络编程最佳实践

2017年12月20日23:19:12 发表评论 304

  1. 通信层

  • 直接使用最成熟的网络框架,如 Netty
  • 单连接 & 连接复用 & 长连接
    • 建议提前设计心跳机制
    • 集群较小,长连接无需开启心跳
    • 如果网络情况比较复杂,建议开启心跳。如有防火墙,会将连接清掉且不会向客户端发送 RST 信令,导致长连接变成一个脏连接

  1. 线程模型

如果采用了 Netty 这样的框架,线程模型基本已经决定了,但是 Netty 只需负责 IO 处理,需要提供额外的业务线程池负责处理业务请求。

  • 序列化过程在业务线程中处理
  • 请求/响应包多个批量从 IO 线程交给业务线程处理
  • 服务端线程池需要有保护策略
    • 框架层面的 RejectExcetpion
    • 业务层面的限流策略
  • 需要定时打印线程池大小,方便性能分析

  1. 序列化

  • 全站都是 Java 系

为了以后能让其它语言更好的交互,协议设计越扁平越好,切忌将整个协议类对象序列化,仅整个序列化方法参数对象列表及返回值对象。

  • 全站各种语言百花齐放

可以考虑直接使用 Protobuf 或者 msgpack 这样的跨语言的序列化协议,但我个人没使用经验。

  1. 容灾

  • 必须要有超时时间,分布式环境下无超时机制对整体环境影响非常大
  • 需要有连接隔离机制(根据请求量、错误率等)

  1. 故障定位

  • 客户端发送、服务端接收均需要打印日志,日志必须要有的几个字段:
    • 时间戳
    • 唯一ID: 由于客户端和服务端的请求量较大,所以需要有唯一 ID 能够将客户端日志和服务端请求串起来
    • IP 信息
    • 如下:
      • client:time,unique-id,server-ip
      • server:time,unique-id,client-ip
  • 提供较好的方式打印网络层日志
    • 经常会发生客户端有请求日志,但是服务端没有接收日志的情况
    • 这个时候无法判断是客户端出错还是服务端出错,可以提供 debug 日志打印网络层的请求日志

weinxin
微信公众号
分享IT信息技术、北海生活的网站。提供北海本地化的信息技术服务。
连线北海

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: