必会框架 - RPC与ORM(下)

接上篇

详解 Netty

下面我们来看 Netty 相关的知识点,如下图所示。

Netty

特点

如上图左侧所示,首先了解 Netty 的特点。

●Netty 是一个高性能的异步事件驱动的 NIO 框架,它对消息的处理采用串行无锁化设计,提供了对 TCP、UDP 和文件传输的支持。

●Netty 内置了多种 encoder 和 decoder 实现来解决 TCP 粘包问题。

●Netty 处理消息时使用了池化的缓冲池 ByteBufs,提高性能。

●结合内存零 copy 机制,减少了对象的创建,降低了 GC 的压力。

主要概念

需要掌握 Netty 中的一些对象概念,比如将 Socket 封装成 Channel 对象,在 Channel 读写消息时,使用 ChannelHandler 对消息进行处理,一组 Handler 顺序链接组成 ChannelPipeline 的责任链模式。一个 Channel 产生的所有事件交给一个单线程的 EventLoop 事件处理器来进行串行处理。而 Bootstrap 对象的主要作用是配置整个 Netty 程序串联起各个组件,是一个 Netty 应用的起点。

零内存复制

要了解 Netty 的内存零 copy 技术。包括使用堆外内存来避免在 Socket 读写时缓冲数据在堆外与堆内进行频繁复制;使用 CompositeByteBuf 来减少多个小的 buffer 合并时产生的内存复制;使用 FileRegion 实现文件传输的零拷贝等。

粘包与半包

要了解 TCP 协议下粘包与半包等产生原因,知道 Netty 提供的多个 decoder 是用什么方式解决这个问题的。例如 FixedLengthFrameDecoder 用来解决固定大小数据包的粘包问题、LineBasedFrameDecoder 适合对文本进行按行分包、DelimiterBasedFrameDecoder 适合按特殊字符作为分包标记的场景、LengthFieldBasedFrameDecoder 可以支持复杂的自定义协议分包等等。

Netty3 和 Netty4

简单了解一下 Netty3 和 Netty4 的区别,其中主要的就是两个版本的线程处理模型完全不同, Netty4 处理得更加优雅。其他的以 Netty4 的特点为主即可。

线程模型

Netty 线程模型采用“服务端监听线程”和“IO 线程”分离的方式,如下图,左侧 Boss 线程组负责监听事件,创建 Socket 并绑定到 Worker 线程组。

在这里插入图片描述
Worker 线程组负责 IO 处理。线程组由 EventLoopGroup 实现,其中包含了多个 EventLoop 事件处理器,每个 EventLoop 包含一个处理线程。通常情况下在 NIO 非阻塞模式下,Netty 为每个 Channel 分配一个 EventLoop,并且它的整个生命周期中的事件都由这个 EventLoop 来处理。一个 EventLoop 可以绑定多个 Channel。

如上图右侧所示,EventLoop 的处理模型,Netty4 中 Channel 的读写事件都是由 Worker 线程来处理。请求处理中最主要的就是 ChannelPipeline,其中包含了一组 ChannelHandler。这些 Handler 组成了责任链模式,依次对 Channel 中的消息进行处理。一般接收消息时,Pipeline 处理完成会把消息提交到业务线程池进行处理,当业务线程处理完成时,会封装成 Task,提交回 Channel 对应的 EventLoop 来写回返回值。

详解 RPC

RPC 是远程过程调用的简写,RPC 与 HTTP 一样都可以实现远程服务的调用,但是使用方式上有很大的区别。它能够像使用本地方法一样调用远程的方法。

交互流程

如下图所示,来看 RPC 的交互流程。图中绿色的模块是 RPC 中最主要的三个角色。左边的是 Client 端,就是请求的发起方,也可以叫作 Consumer 或者 Referer。右边的模块是 Server 端,就是提供服务实现的一方,也叫作 Provider。

在这里插入图片描述
为了保持较高的性能,Client 端一般都是直接请求远端的 Server 节点。因此,RPC 框架需要自动的服务注册与发现的能力,上方的绿色的注册中心就是用来动态维护可用服务节点信息的模块。

图中的箭头代表交互流程。当 Server 提供服务时,向注册中心注册服务信息,告诉注册中心可以提供哪些服务。同时与注册中心保持心跳或者维持长链接,来维持 Server 可用状态,具体方式与注册中心的实现有关,例如 ZK 使用长链接推送方式而 Consul 使用心跳方式。

如上图所示,当 Client 需要使用服务时,会先向注册中心订阅服务,获得可用的 Server 节点,并保存在 Client 本地。当 Server 节点发生变更时会通知 Client 更新本地 Server 节点信息。Client 按某种负载均衡策略直接请求 Server 使用服务。注意:注册中心只参与服务节点的注册与变更通知,并不会参与具体请求的处理。

另外一般的 RPC 框架都提供了完整的服务治理能力,因此会有额外的管理模块和信息采集模块来监控、管理服务。如图中灰色的模块所示。

开源框架

来看三款比较有特色的主流 RPC 框架,如下图所示。

在这里插入图片描述
Dubbo 是阿里开源的 RPC 框架,提供完善的服务治理能力,可以快速为 Java 服务提供 RPC 能力。Dubbo 提供了随机、轮询、最少调用优先等多种负载均衡策略,提供对 ZK 等多种注册中心等支持,能够自动完成服务的注册与发现。Dubbo 提供可视化的管理后台,方便对服务状态进行监控和管理。Dubbo 的数据通信默认使用我 Netty 来实现,拥有非常不错的性能。

微博开源的轻量级服务治理框架 Motan。Motan 的特点是轻量级,提供强大灵活的扩展能力,Motan 提供了多语言支持,目前支持 Java、PHP、Lua、Golang 等多语言交互,目前 Python 和 C++ 的客户端也在研发中。Motan 通过 Agent 代理方式,实现了的跨语言 ServiceMesh 的支持。ServiceMesh 被誉为下一代微服务,在课时 10 还会重点介绍。Motan Java 版本的通信层也是通过 Netty 来实现的,基于 TCP 的私有协议进行通信。

Google 开源的 gRPC。gRPC 默认使用 Protobuf 进行消息序列化,非常适合多语言服务之间进行交互。虽然 gRPC 本身支持的服务治理能力并不强,但拥有非常灵活的插件扩展能力,可以方便的实现自定义的服务治理能力。gRPC 基于 HTTP2 协议,能够支持链接复用,并且提供了流式调用能力,也支持从服务端进行推送消息的能力。

详解 MyBatis

特点

下面我们来看 ORM 框架 MyBatis,它的知识结构图如下所示。首先要了解它的特点,可以和 Hibernate 来对比进行理解。

在这里插入图片描述
MyBatis 的优点:

1.MyBatis 是原生SQL,不像 Hibernate 的 HQL 需要额外的学习成本;

2.MyBatis 的 SQL 语句与代码进行了解耦合,这与 Hibernate 是一致的;

3.MyBatis 功能简单,学习成本比较低,使用的门槛也非常低,可以快速上手;

4.MyBatis SQL调优比较灵活,而 Hibernate,SQL 语句是自动生成的,当有复杂语句需要进行优化时就比较难处理。

MyBatis 的缺点:

1.相比 Hibernate 这样的全自动 ORM 框架,不能自动生成 SQL 语句,编写 SQL 的工作量比较大,尤其是字段多、关联表多的情况下;

2.另外一个缺点就是 SQL 语句依赖于具体数据库,导致数据库迁移性差,而 Hibernate 则拥有良好的数据库可移植性。

缓存

MyBatis 提供了两级缓存。MyBatis 的一级缓存的存储作用域是 Session,会对同一个 Session 中执行语句的结果进行缓存,来提高再次执行时的效率。MyBatis 内部通过 HashMap 实现存储缓存,一级缓存是默认开启的。

MyBatis 的二级缓存的作用域是一个 Mapper 的 namespace,在同一个 namespace 中查询 SQL 时可以从缓存中获取数据。二级缓存能够跨 SqlSession 生效,并且可自定义存储源,比如 Ehcache。MyBatis 的二级缓存可以设置剔除策略、刷新间隔、缓存数量等参数来进行优化。

应用

●MyBatis 提供 #{} 的变量占位符,来支持 SQL 预编译,防止 SQL 注入。

●获取自增主键的 id 可以通过 keyProperty 配置和使用 selectKey 两种方式来实现。

●要记住动态 SQL 常用的几个标签,例如 foreach、where、if、choose、trim 等等。

主要对象

需要理解 MyBatis 的主要对象有哪些,它们的作用是什么,举例如下。

●SqlSessionFactory 是用来创建 SqlSession 的工厂类,一个 SqlSessionFactory 对应配置文件中的一个环境,也就是一个数据库配置。

●对数据库的操作必须在 SqlSession 中进行,SqlSession 非线程安全,每一次操作完数据库后都要调用 Close 对其进行关闭。

●SqlSession 通过内部的 Executor 来执行增删改查操作。

●StatementHandler 用来处理 SQL 语句预编译,设置参数等。

●ParameterHandler 用来设置预编译参数。

●ResultSetHandler 用来处理结果集。

●TypeHandler 进行数据库类型和 JavaBean 类型的互相映射。

插件机制

MyBatis 的插件机制是通过拦截器组成责任链来对 Executor、StatementHandler、ParameterHandler、ResultSetHandler 这四个作用点进行定制化处理。另外可以了解一下基于插件机制实现的 PageHelper 分页插件。

处理流程

如下图所示,MyBatis 的处理流程。

在这里插入图片描述
在执行 SQL 时,首先会从 SqlSessionFactory 中创建一个新的 SqlSession。

SQL 语句是通过 SqlSession 中的 Executor 来执行,Executor 根据 SqlSession 传递的参数执行 query() 方法,然后创建一个 StatementHandler 对象,将必要的参数传递给 StatementHandler,由 StatementHandler 来完成对数据库的查询。

StatementHandler 调用 ParameterHandler 的 setParameters 方法,把用户传递的参数转换成 JDBC Statement 所需要的参数, 调用原生 JDBC 来执行语句。

最后由 ResultSetHandler 的 handleResultSets 方法将 JDBC 返回的 ResultSet 结果集转换成对象集,并逐级返回结果,完成一次 SQL 语句执行。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Andrew.J

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值