Contents

中间件

Contents

中间件

Arthas

Arthas统计方法耗时的原理是什么?

Arthas在统计方法耗时时,使用了字节码插桩技术。它会在需要监控的方法中插入代码,在方法执行前记录开始时间,在方法执行完毕后记录结束时间,并计算两者的差值得到方法执行时间。这个过程就是字节码插桩的经典应用之一。

相比传统的基于AspectJ等框架实现AOP的方式,Arthas的动态插装能力更强,支持无侵入式的监控。

字节码插桩

Java字节码插桩技术是指在编译期或运行期,通过修改Java字节码的方式,向代码中插入额外的代码,它可以在不改变Java源代码的情况下,对Java应用程序的运行时行为进行监控、调试、分析和优化等。例如实现性能监控、代码覆盖率检测、代码安全扫描等。

字节码插桩技术通常包括以下几个步骤:

- 生成目标类的字节码,这可以通过Java编译器(如javac)或其他工具(如AspectJ)完成。

- 解析字节码,识别需要插桩的代码区域(如方法、循环、异常处理等)。

- 插入额外的字节码,这些字节码通常是通过编写Java代码来实现的,并通过字节码生成库(如ASM、Javassist等)生成对应的字节码。

- 将修改后的字节码重新写回到磁盘或内存中,以便后续使用。

假设我们需要对一个Java方法进行性能监控,我们可以在方法的入口和出口处分别插入计时器,来统计方法的执行时间。这可以通过以下代码实现:

Dubbo

如何实现像本地方法一样调用远程方法的?

Dubbo 实现像本地方法一样调用远程方法的核心技术是动态代理。Dubbo 使用 JDK 动态代理或者字节码增强技术,生成一个代理类,该代理类实现了本地接口,具有本地接口的所有方法。在调用本地接口方法时,会通过代理类的 invoke 方法将请求转发到远程服务提供者上。

生成代理类,Dubbo 在启动时会扫描配置文件(注解)中指定的服务接口,并根据服务接口生成一个代理类。这个代理类实现了服务接口,并且在调用服务接口的方法时,会将参数封装成请求消息,然后通过网络传输给服务提供方。

网络通信,Dubbo 支持多种通信协议,包括 Dubbo 协议、HTTP 协议、Hessian 协议等。在配置文件中指定了要使用的通信协议后,Dubbo 会根据协议的不同,选择不同的序列化方式,将请求消息序列化成二进制流并发送给服务提供方。

负载均衡,Dubbo 支持多种负载均衡算法,包括轮询、随机、加权随机、最小活跃数等。在客户端发起调用时,Dubbo 会根据负载均衡算法选择一台服务提供方进行调用。

远程服务执行,当客户端发起远程调用后,服务提供方接收到请求后,会根据请求中的服务接口名和方法名,找到对应的实现类和方法,并将请求消息反序列化成参数列表,最终调用服务实现类的方法,并将执行结果序列化成响应消息返回给客户端。

Dubbo实现服务调用的过程是什么样的?

Dubbo的整体架构中,有多个角色,分别是服务提供者,服务调用者以及服务注册中心。一次完整的服务调用过程其实要分为服务注册、服务发现和服务调用三个过程。

https://cdn.nlark.com/yuque/0/2023/png/5378072/1680876975737-834e5838-87be-4e86-a742-4ba1af792819.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_32%2Ctext_SmF2YSA4IEd1IDk%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10

1、服务注册:服务提供者在启动时,会向注册中心注册自己提供的服务,并将服务相关的信息(如服务名称、版本号、IP地址、端口号、协议、权重等)一并注册。Dubbo支持多种注册中心,包括ZooKeeper、Redis、Multicast、Simple等。一旦服务注册成功,服务提供者就可以等待服务调用请求的到来。

2、服务发现:服务调用者在启动时,需要向注册中心订阅自己所需的服务,注册中心会将服务提供者列表返回给服务调用者。当过程中,如果服务提供者列表发生变化,那么Dubbo会通知客户端进行变更。

3、服务调用:服务调用者需要根据负载均衡策略选择一个服务提供者,之后,就可以发送服务调用请求了。Dubbo支持多种通信协议和序列化方式。Dubbo客户端将调用请求序列化成二进制数据,并使用网络协议发送给服务提供者,服务提供者将调用请求反序列化后,调用目标方法并将结果序列化成二进制数据返回给服务调用者。在整个调用过程中

Dubbo会对服务调用进行监控,包括调用次数、调用时间、响应时间、异常次数、异常信息等,以便于服务提供者和服务调用者进行故障排查和性能调优。

Dubbo支持哪些调用协议?

dubbo支持多种协议,主要由以下几个:

  • 1、dubbo 协议 (默认)

  • 默认就是走dubbo协议的,基于hessian作为序列化协议,单一长连接,TCP协议传输,NIO异步通信,适合大并发小数据量的服务调用,以及消费者远大于提供者,传输数据量很小(每次请求在100kb以内),但是并发量很高。

  • 2、rmi 协议

  • 采用JDK标准的rmi协议实现,传输参数和返回参数对象需要实现Serializable接口,使用java标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输协议TCP。

  • 3、hessian 协议

  • 集成Hessian服务,基于HTTP通讯,采用Servlet暴露服务,Dubbo内嵌Jetty作为服务器时默认实现,提供与Hession服务互操作。

  • hessian序列化协议,多个短连接,同步HTTP传输,传入参数较大,提供者大于消费者,提供者压力较大,适用于文件的传输,一般较少用;

  • 4、http 协议

  • 基于Http表单提交的远程调用协议,使用Spring的HttpInvoke实现。

  • 5、webservice 协议

  • 基于WebService的远程调用协议,集成CXF实现,提供和原生WebService的互操作。

  • 6、thrift 协议

  • 当前 dubbo 支持的 thrift 协议是对 thrift 原生协议 的扩展,在原生协议的基础上添加了一些额外的头信息,比如 service name,magic number 等。

  • 7、memcached 协议

  • 基于 memcached实现的 RPC 协议。

  • 8、redis 协议

  • 基于 Redis实现的 RPC 协议。

  • 9、restful

  • 基于标准的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的简写)实现的REST调用支持

Dubbo服务发现与路由的概念有什么不同?

服务发现是指在Dubbo注册中心中查找提供某个服务的服务提供者,以便服务消费者可以调用它们。

Dubbo的注册中心可以是ZooKeeper、Redis等,服务提供者在启动时会将自己的地址信息注册到注册中心中,服务消费者在调用服务时会从注册中心中获取服务提供者的地址信息。

服务路由是指根据一定的规则将服务请求路由到指定的服务提供者上。Dubbo提供了多种路由策略,如随机路由、轮询路由、一致性哈希路由等。路由规则可以在Dubbo的配置文件中进行配置,也可以在运行时通过API进行动态修改。

因此,服务发现是获取服务提供者的地址信息,路由则是将服务请求路由到指定的服务提供者上。两者都是Dubbo中非常重要的概念,但是它们的作用是不同的。

Dubbo的缓存机制了解吗?

Dubbo提供了缓存机制,其主要作用是缓存服务调用的响应结果,减少重复调用服务的次数,提高调用性能。

Dubbo支持了服务端结果缓存和客户端结果缓存。

服务端缓存是指将服务端方法的返回结果缓存到内存中,以便下次请求时可以直接从缓存中获取结果,而不必再调用服务方法。服务端缓存可以提高响应速度和系统吞吐量。Dubbo提供了三种服务端缓存的实现方式:

  • LRU Cache: 使用基于LRU(最近最少使用)算法的缓存,当缓存空间满时,会将最近最少使用的缓存清除掉。
  • Thread Local Cache: 使用线程本地缓存,即每个线程都拥有一个缓存实例,缓存结果只对当前线程可见。
  • Concurrent Map Cache: 使用基于ConcurrentMap的缓存,支持并发读写,相对LRU Cache和Thread Local Cache来说,缓存效率更高。

客户端缓存是指客户端将调用远程服务方法的返回结果缓存到内存中,以便下次请求时可以直接从缓存中获取结果,而不必再调用远程服务方法。消费端缓存可以提高系统的响应速度和降低系统的负载。Dubbo提供了两种消费端缓存的实现方式:

  • LRU Cache: 使用基于LRU算法的缓存,当缓存空间满时,会将最近最少使用的缓存清除掉。
  • Thread Local Cache: 使用线程本地缓存,即每个线程都拥有一个缓存实例,缓存结果只对当前线程可见。

需要注意的是,缓存虽好用,使用需谨慎,过度依赖缓存可能会出现数据不一致的问题。

Elastic

ElasticSearch为什么快?

Elasticsearch是一个高性能、分布式搜索引擎,它之所以快,主要有以下几个原因:

  • 分布式存储:Elasticsearch使用分布式存储技术,将数据存储在多个节点上,从而减少单个节点的压力,提高整体性能。
  • 索引分片:Elasticsearch把每个索引划分成多个分片,这样可以让查询操作并行化,从而提高查询速度。
  • 全文索引:Elasticsearch使用了高效的全文索引技术,把文档转化成可搜索的结构化数据,使得搜索操作快速高效。
  • 倒排索引:Elasticsearch支持倒排索引这种数据结构,倒排索引将文档中的每个词与该词出现在哪些文档中进行映射,并存储这些信息。当搜索请求发生时,ES可以快速查找包含所有搜索词的文档,从而返回结果。
  • 索引优化:Elasticsearch通过索引优化技术,可以使查询速度更快。例如,它支持索引覆盖、索引下推等优化技术,使得查询速度更快。
  • 预存储结果:Elasticsearch在插入数据时,对数据进行预处理,把结果预存储到索引中,从而在查询时不需要再重新计算,提高查询速度。
  • 高效的查询引擎:Elasticsearch使用了高效的查询引擎,支持各种类型的查询,并对复杂查询提供了优化策略,从而提高查询速度。
  • 异步请求处理:ES使用了异步请求处理机制,能够在请求到达时立即返回,避免长时间的等待,提高用户体验。
  • 内存存储:ES使用了内存存储技术,能够在读写数据时大大减少磁盘访问次数,提高数据存储和查询效率。

总之,Elasticsearch快的原因在于它使用了各种高效的技术,使得数据存储、查询、处理都变得更加高效,从而实现了快速的搜索体验。