如何用Netty写一个高性能的分布式服务框架?( 二 )


 

  • 消息派发器
  • FutureGroup
 
4 泛化调用
 
  • Object $invoke(String methodName , Object... args)
  • parameterTypes[]
 
5 序列化/反序列化
 
协议 header 标记 serializer type , 同时支持多种 。
 
6 可扩展性
 
Java SPI:
 
  • java.util.ServiceLoader
  • META-INF/services/com.xxx.Xxx
 
7 服务级别线程池隔离
 
要挂你先挂 , 别拉着我 。
 
8 责任链模式的拦截器
 
太多扩展需要从这里起步 。
 
9 指标度量(Metrics)
 
10 链路追踪
 
OpenTracing
 
11 注册中心
 
12 流控(应用级别/服务级别)
 
要有能方便接入第三方流控中间件的扩展能力 。
 
13 Provider线程池满了怎么办?
如何用Netty写一个高性能的分布式服务框架?

文章插图
 
14 软负载均衡
 
1)加权随机 (二分法 , 不要遍历)
如何用Netty写一个高性能的分布式服务框架?

文章插图
 
2)加权轮训(最大公约数)
如何用Netty写一个高性能的分布式服务框架?

文章插图
 
3)最小负载
 
4)一致性 hash (有状态服务场景)
 
5)其他
 
注意:要有预热逻辑 。
 
15 集群容错
 
1)Fail-fast
 
2)Failover
 
异步调用怎么处理?
 
  • Bad
 
如何用Netty写一个高性能的分布式服务框架?

文章插图
 
  • Better
 
如何用Netty写一个高性能的分布式服务框架?

文章插图
 
3)Fail-safe
 
4)Fail-back
 
5)Forking
 
6)其他
 
16 如何压榨性能(Don’t trust it , Test it)
 
1)ASM 写个 FastMethodAccessor 来代替服务端那个反射调用
如何用Netty写一个高性能的分布式服务框架?

文章插图
 
2)序列化/反序列化
 
在业务线程中序列化/反序列化 , 避免占用 IO 线程:
 
  • 序列化/反序列化占用数量极少的 IO 线程时间片 。
 
  • 反序列化常常会涉及到 Class 的加载 , loadClass 有一把锁竞争严重(可通过 JMC 观察一下) 。
 
选择高效的序列化/反序列化框架:
 
  • 如kryo/protobuf/protostuff/hessian/fastjson/…
 
选择只是第一步 , 它(序列化框架)做的不好的 , 去扩展和优化之:
 
  • 传统的序列化/反序列化+写入/读取网络的流程:java对象--> byte[] -->堆外内存 / 堆外内存--> byte[] -->java对象 。
 
  • 优化:省去 byte[] 环节 , 直接 读/写 堆外内存 , 这需要扩展对应的序列化框架 。
 
  • String 编码/解码优化 。
 
  • Varint 优化:多次 writeByte 合并为 writeShort/writeInt/writeLong 。
 
  • Protostuff 优化举例:UnsafeNioBufInput 直接读堆外内存/UnsafeNioBufOutput 直接写堆外内存 。
 
3)IO 线程绑定 CPU
 
4)同步阻塞调用的客户端和容易成为瓶颈 , 客户端协程:
 
  • Java层面可选的并不多 , 暂时也都不完美 。
 
name
description
kilim
编译期间字节码增强
quasar agent
动态字节码增强
ali_wisp
ali_jvm 在底层直接实现
 
5)Netty Native Transport & PooledByteBufAllocator:
 
  • 减小GC带来的波动 。
 
6)尽快释放 IO 线程去做他该做的事情 , 尽量减少线程上下文切换 。
 
四 Why Netty?
 
1 BIO vs NIO


推荐阅读