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

Posted 漫谈Java架构

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用Netty写一个高性能的分布式服务框架相关的知识,希望对你有一定的参考价值。

提纲


  1. 什么是Netty? 能做什么?

  2. 贴近日常生活, 先设计一个服务框架

  3. RPC的一些Features&好的实践

  4. 如何压榨性能

  5. Why Netty? (延伸: Netty --> NIO --> Linux Epoll一些实现细节)


什么是Netty? 能做什么?


  • Netty是一个致力于创建高性能网络应用程序的成熟的IO框架

  • 相比较与直接使用底层的Java IO API, 你不需要先成为网络专家就可以基于Netty去构建复杂的网络应用

  • 业界常见的涉及到网络通信的相关中间件大部分基于Netty实现网络层

设计一个分布式服务框架

  • Architecture

  • 远程调用的流程



    以上流程对方法调用者是透明的, 一切看起来就像本地调用一样


    重要概念: RPC三元组 <ID, Request, Response>


    • 启动服务端(服务提供者)并发布服务到注册中心

    • 启动客户端(服务消费者)并去注册中心订阅感兴趣的服务

    • 服务端收到收到并反序列化请求信息, 根据<group, providerName, version>从本地服务字典里查找到对应providerObject, 再根据<methodName, args[]>通过反射调用指定方法, 并将方法返回值序列化为字节数组返回给客户端

    • 客户端收到响应信息再反序列化为Java对象后由Proxy返回给方法调用者


  • 远程调用客户端图解

    若是netty4.x的线程模型, IO Thread(worker) —> Map<InvokeId, Future>代替全局Map能更好的避免线程竞争

  • 远程调用服务端图解

    重要概念: RPC三元组 <ID, Request, Response>

  • 远程调用传输层图解

    左图为客户端, 右图为服务端

  • 设计传输层协议栈



协议头


协议体

  • metadata: <group, providerName, version>

  • methodName

  • parameterTypes[]

    真的需要?

    • Java方法静态分派规则参考JLS <Java语言规范> $15.12.2.5 Choosing the Most Specific Method 章节

    • 有什么问题?

    • 能解决吗?

    1. 反序列化时ClassLoader.loadClass()潜在锁竞争

    2. 协议体码流大小

    3. 泛化调用多了参数类型

  • args[]

  • 其他: traceId, appName…

一些Features&好的实践&压榨性能

  • 创建客户端代理对象

    • 注意拦截toString, equals, hashCode等方法避免远程调用

    • jdk proxy/javassist/cglib/asm/bytebuddy

    • 集群容错 —> 负载均衡 —> 网络

    • Proxy做什么?

    • 有哪些创建Proxy的方式?

    • 要注意的:

    • 推荐的(bytebuddy):

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

  • 优雅的同步/异步调用

    • 先往上翻再看看'远程调用客户端图解'

    • 再往下翻翻看看Failover如何处理更好

    • 思考下如何拿到future?

  • 单播/组播

    • 消息派发器

    • FutureGroup

  • 泛化调用

    • Object $invoke(String methodName, Object... args)

    • parameterTypes[]

  • 序列化/反序列化(协议header标记serializer type, 同时支持多种)

  • 可扩展性

    • -java.util.ServiceLoader

    • -META-INF/services/com.xxx.Xxx

    • Java SPI

  • 服务级别线程池隔离

    • 要挂你先挂, 别拉着我

  • 责任链模式的拦截器

    • 太多扩展需要从这里起步

  • 指标度量(Metrics)

  • 链路追踪

    • OpenTracing

  • 注册中心

  • 流控(应用级别/服务级别)

    • 要有能方便接入第三方流控中间件的扩展能力

  • Provider线程池满了怎么办?

  • 软负载均衡

    要有预热逻辑

    • 加权随机 (二分法, 不要遍历)

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

    • 加权轮训(最大公约数)

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

    • 最小负载

    • 一致性hash(有状态服务场景)

    • 其他