HSF

产品简介

产品概述

HSF(High-speed Service Framework),高速服务框架,阿里巴巴内部人士广泛性使用的分布式RPC服务器框架。

HSF作为阿里巴巴的基础中间件,联通不同的业务系统,解耦系统间的实现依赖。HSF从分布式应用的层面,统一了服务的发布/调用方式,从而帮助用户可以方便、快速的开发分布式应用,以及提供或使用公共功能模块。为用户屏蔽了分布式领域的各种复杂技术细节,如:远程通讯、序列化实现、性能损耗、同步/异步调用方式的实现等。

产品架构

HSF作为一个纯客户端架构的RPC框架,本身是没有服务器集群的,所有的HSF服务调用都是服务消费方(Consumer)和服务提供方(Provider)点对点进行的。然而,为了实现整套分布式服务体系,HSF还需要依赖以下外部系统
hsf/hsf.png

地址注册中心

HSF依赖注册中心进行服务发现,如果没有注册中心,HSF只能完成简单的点对点调用。因为作为服务提供端,没有办法将自己的服务信息对外发布,让外界知晓;作为服务消费端,可能已经知道需要调用的服务,但是无法获取能够提供这些服务的机器。而注册中心就是服务信息的中介,提供服务发现的能力。

在阿里巴巴集团内部,地址注册中心的角色是由ConfigServer承担的。

持久化配置中心

持久化的配置中心用于存储HSF服务的各种治理规则,HSF客户端在启动的过程中会向持久化配置中心订阅各种服务治理规则,如路由规则、归组规则、权重规则等,从而根据规则对调用过程的选址逻辑进行干预。

在阿里巴巴集团内部,持久化配置中心的角色是由Diamond承担的。

元数据存储中心

元数据是指HSF服务对应的方法列表以及参数结构等信息,元数据不会对HSF的调用过程产生影响,因此元数据存储中心也并不是必须的。但考虑到服务运维的便捷性,HSF客户端在启动时会将元数据上报到元数据存储中心,以便提供给服务运维使用。

在阿里巴巴集团内部,元数据存储中心的角色是由Redis承担的。

HSF控制台

  1. HSF控制台通过打通地址注册中心ConfigServer、持久化配置中心Diamond、元数据存储中心Redis,为用户提供了一系列服务运维功能,包括服务查询、服务治理规则管理、服务测试、服务Mock、单机运维等,旨在提供HSF服务研发的效率、运维的便捷性。

在阿里巴巴集团内部,HSF控制台的角色由HSFOPS承担

产品功能

HSF作为分布式RPC服务框架,支持多种服务的调用方式。

同步调用

HSF客户端默认以同步调用的方式消费服务,客户端代码需要同步等待返回结果。

异步调用

对于服务调用的客户端来说,并不是所有的HSF服务都需要同步等待返回结果的。对于这些服务,HSF提供异步调用的形式,让客户端不必同步阻塞在HSF调用操作上。HSF的异步调用,有2种:

  • Future调用:客户端在需要调用的返回结果时,通过HSFResponseFuture.getResponse(int timeout)主动获取结果
  • Callback调用:Callback调用利用HSF内部提供的回调机制,当指定的HSF服务消费完毕拿到返回结果时,HSF框架会回调用户实现的HSFResponseCallBack接口,客户端通过回调通知的方式获取结果。

泛化调用

对于一般的HSF调用来说,HSF客户端需要依赖服务的二方包,通过依赖二方包中的API进行编程调用,获取返回结果。而泛化·调用不需要依赖服务的二方包,从而发起HSF调用,获取返回结果的方式。在一些平台型的产品中,泛化调用的方式可以有效减少平台型产品的二方包依赖,实现系统的轻量级运行。

HTTP调用

HSF支持将服务以HTTP的形式暴露出来,从而支持非java语言的客户端以HTTP协议进行服务调用。

调用链路Filter扩展

HSF内部设计了调用过滤器,并且能够主动发现用户的调用过滤器扩展点,将其集成到HSF调用链路中,使扩展能够方便的对HSF进行扩展处理。

产品优势

高性能的网络通信

  • 在网络通信层面,HSF采用开源的高性能、异步事件驱动的NIO框架Netty作为网络通信框架。
  • 在协议层面,HSF2.x做了大量优化,使用了更适用RPC场景的RPCRemoting协议替换了HSF1.x中的TBRemoting协议,性能有了大幅度提高。目前,HSF在物理机上的压测数据约为30wQPS。

无入侵的代理服务

HSF利用了java语言的代理机制,将协议封装、选址、远程调用等一系列RPC逻辑进行了封装,对用户透明。用户在使用HSF进行远程调用时,只要进行简单的Spring配置,就可以专注于自己的业务逻辑,编码方式与本地调用没有任何区别。

强大的服务管控

HSF配套的控制台(HSFOPS)提供了丰富的服务管控功能,例如:

  • 服务查询:提供多种维度的服务查询功能,展示服务的实时状态。
  • 服务治理:提供多种服务治理的管理功能,如路由规则、归组规则、同机房规则、权重规则等,让用户通过配置服务治理规则,完成服务集群的管理、流量的划分。
  • 服务测试:提供快速测试、调用服务的能力,用户只需通过在页面上输入服务调用的参数,即可方便的完成一次HSF服务的调用,提升研发效率。
  • 服务Mock:提供HSF服务的Mock能力,使用时无需关注服务端是否存在,只需要在HSFOPS上配置好Mock规则,HSF客户端即可通过hsf-mock插件获取配置的Mock数据,并且对代码没有入侵。

应用场景

HSF诞生于阿里巴巴内部诸多系统进行服务化改造的诉求,也就是说HSF本身就是对应用服务化进行支撑的框架。一般意义上,一个公司的业务系统发展脉络基本都是类似的:从单个应用到多个应用,从本地调用到远程调用,随着发展需要对远程服务进行高效的资源管理,这个过程中,RPC框架解决了主要的技术问题。

因此,如果需要将应用进行服务化改造,将单个巨型应用拆分为多个职责分明的基础服务应用,进而将这些基础服务提供给更多的上层应用使用,那么,HSF将会是最佳选择。

背景

一般意义上,一个公司的业务系统发展脉络基本都是类似,从单体应用到多应用,从本地调用到远程调用,随着发展需要对远程服务进行高效的资源管理,这个过程是系统应用变化和复杂的应对之道。

每个应用都是解决不同的问题,应用数量的增加会导致复杂性的上升,当复杂性越高,整个系统接收变化的程度就越低,也代表开发成本、维护成本的攀升。如何在应用规模增大的同时,保证响应变化的迅捷,应用之间的沟通或调用方式是关键。

SOA在应用数量很少时,由于其技术复杂性导致其初始化复杂度较高,但是当应用数量快速攀升过万时,复杂度并不会显著提升,仍处于可控状态,同时复杂度表现又明显的优于单纯的RPC方案。

单体应用的问题

单体应用的主要问题是不同的业务相互纠缠在一起,面对快速发展的业务,这种业务开发模型和架构不利于业务发展,主要体现在以下方面:

  • 架构分化,分工不同的业务开发团队对于开发细节和实现方式在一段时间后一定有差别;
  • 开发效率,团队业务发展快慢区别导致发布的频度会不一样,团队之间需要相互配合和知会,导致效率低下
  • 可用性低,一个团队的严重问题导致单体应用挂掉,将影响到另一个团队,稳定性难以提升

分拆应用的好处

将不同的业务分拆到多个应用中,让不同的应用分别承担不同的功能,例如:商品应用承担商品信息的管理,会员应用承担会员核心业务的实现。分拆出来的功能分布到不同的系统后,就可以做到技术实现的多样性以及适合性,带来发布的自由度以及系统的稳定性会极大地提升。

经过演化,一个单体应用变成了一组复杂的分布式系统,而在一个应用中,相互调用直接在本地完成,而变成多个系统时,相互之间进行通信的方式就不能依赖本地,而必须走远程,因此一个高效、稳定的RPC框架就变得非常重要。

服务即资源

随着业务不断的发展,可以想象承担不同业务的应用雨后春笋般出现,每个应用都有很多服务。如果把 这些服务都理解为资源的话,对于资源的管理就变得愈发重要。在RPC框架刚开始使用时,可能只有几个应用,几十个服务,如果规模扩充到上万个应用,几十万个服务,RPC调用调用反而不是重头戏,而重要的是如何能高效的组织这些服务。

一般来说,需要(或最好能够具备)服务治理的能力:

  • 服务的方便检索,查询服务,包括服务的提供者与消费者信息;
  • 服务的快捷测试,提升分布式场景验证服务的便捷性;
  • 服务的路由,根据调用的服务名等运行时信息,服务消费方能够路由到对应的服务提供方指定机器上

这些特性都已经超越了一个普通RPC框架的范畴,而提供这些能力的RPC框架才能称之为SOA框架。

阿里SOA解决方案

阿里SOA解决方案–HSF(High-speed Service Framework),高速服务框架。该框架是阿里系主要采用的服务框架,其目的是作为桥梁联通不同的业务系统,解耦系统之间的实现依赖。其高速体现在底层的非阻塞I/O以及优秀的序列化机制上,实现了同步和异步调用方式,并且有一套软负载体系,实现分布式应用。HSF超越了普通的SOA解决方案,在以下几个方面有更加优秀的特性:

高性能的服务调用

低侵入,HSF基于Java接口完成透明的RPC调用,用户对服务是否在本地不做感知,不侵入用户代码。

高性能,HSF提供基于非阻塞I/O上的高性能调用,相同场景下与gRPC做了性能对比测试,超过gRPC约30%(达到41k的TPS)

多语言,多语言支持完善,提供了C++以及nodejs客户端,支持HTTP REST调用

大流量的场景应对

客户端负载均衡,HSF在客户端基于服务地址列表做负载均衡,不需要借助其他负载均衡设备,高效完成负载均衡工作。

多种选址策略,HSF客户端在调用时提供了多种选址策略,以服务端重启这个场景为例,HSF提供了基于可用地址的选址策略,当发现地址的链接不可用时,会暂时将该地址移出地址列表并尝试回复链接,这样既保证调用的平滑,又能使服务端机器在重启完成后对应的地址被加回地址列表。

上下线策略,HSF提供了优雅上下线的能力,保证服务在重启时对客户端的影响面减到最小,客户端调用在服务端重启时表现平滑。

全方位的服务治理

服务管理功能,HSF运维平台提供了服务查询、测试和Mock功能,支持用户通过服务名(一般是接口名)查询服务的提供者,或者通过输入参数对已有的服务进行调用测试。

规则管理功能,HSF运维平台支持使用归组、路由以及同机房等规则对客户端发起的调用进行干预,使客户端调用变得更加智能。

一次调用过程

HSF一次调用过程会从服务消费方发起,经过网络抵达服务提供方,再将服务提供方的结果通过网络携带回来,最终返回给用户。这个过程会涉及到多个线程交互,也会涉及到HSF中的不同领域对象。

hsf/hsf-diaoyong.png

作为服务消费方,在客户端线程(比如:tomcat线程)中首先会将用户的参数也就是请求对象进行序列化,将序列化之后的内容放置到请求通信对象中,请求通信对象对应的是HSF协议,它包含诸如请求Id等多个与请求对象无关的内容。请求通信对象会提交给I/O线程,在I/O线程中完成编码,最终发送到服务提供方,此时客户端线程会等待结果返回,处于等待状态。

服务提供方的I/O线程接收到二进制内容,解码后生成通信请求对象并将其递交给HSF服务端线程,在HSF服务端线程完成反序列化还原成请求对象,然后发起反射调用,得到结果,也就是响应对象。响应对象会在HSF服务端线程中完成序列化,并放置到通信响应对象。HSF服务端线程会将通信响应对象提交给I/O线程,在I/O线程中完成编码,最终发送回服务消费方。

服务消费方收到二进制内容,在I/O线程中完成解码,生成响应通信对象,并唤醒客户端线程,客户端线程会根据响应通信对象中的内容完成反序列化,最终拿到响应对象,一次远程调用结束。

异步调用

HSF的IO操作都是异步的,客户端同步调用的本质是做future.get(timeout)操作,等待服务端的结果返回,这里的timeout就是客户端响应的超时时间(默认3000ms)。默认的同步调用时序图如下所示:

对于客户端来说,并不是所有的HSF服务都是需要同步等待服务端返回结果的,对于这些服务,HSF提供异步调用的形式,让客户端不必同步阻塞在HSF操作上。异步调用在发起调用时,HSF服务的调用结果都是返回值的默认值,如返回值是int,则返回0,返回类型是Object,则会返回null。而真正的结果,是在HSFResponseFuture或回调函数(callback)中获得的。

Future异步调用

HSF发起调用后,用户可以在上下文中获取跟返回结果关联的HSFFuture对象,然后用户可以在任意时刻调用HSFFutrue.getResponse(timeout)获取服务端的返回结果。Futrue异步调用的时序图如下:

Callback异步调用

客户端配置为callback方式调用时,需要配置一个实现了HSFResponseCallback接口的listener,结果返回之后,HSF会调用HSFResponseCallback中的方法。时序图乳如下所示:

注意

回调函数是由单独的线程池(LinkBlockingQueue无限队列)来调用的,不要做太费时间的操作,避免影响其他请求的onAppResponse回调。callback线程默认的corePoolSize、maxPoolSize是机器cpu数目。

泛化调用

相对于需要依赖业务客户端jar包的正常调用,泛化调用,不需要依赖二方包,使用其特定的GenericService接口,传入需要调用的方法名、方法签名和参数值进行调用服务。泛化调用适用于一些网关应用(没办法依赖所有服务的二方包),其中hsfops服务测试也是依赖泛化调用功能。

注意

1、泛化调用,如果客户端没有接口类,路由规则默认不生效

2、泛化调用性能会比正常调用差