HSF用户指南

HSF(High-speed Service Framework)是阿里的高速服务框架,用于搭建高性能、分布式服务。本文详细介绍了HSF的背景、发展历程、基本结构、部署环境以及服务的编写、发布、调用等过程,涵盖了HSF-OPS的查询和测试服务功能。此外,还阐述了HSF的路由规则、归组规则、同机房规则、服务鉴权等内容,帮助开发者从0到1掌握HSF的使用和问题排查。
摘要由CSDN通过智能技术生成

用户指南

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

​ 这个手册会从快速跑HSF程序开始入手,然后介绍HSF的相关组件、HSF的服务端和客户端的配置、HSF服务的调用方式和HSF服务的发布方式、软负载体系的介绍和规则配置的讲解,最后介绍了如何通过日志和FAQ文档去自主排查问题。

希望这个小册子可以帮助你从0到1掌握HSF的使用和基本概念和具备自主排查问题的能力,有疑问的地方可以在下方评论,并且欢迎您进行文档的建设。

背景

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

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

可以看到ORM框架(仅做数据层共享)在应用数很少时,复杂度最低,但是当应用数一旦过千,复杂度程指数级攀升。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运维平台支持使用归组、路由以及同机房等规则对客户端发起的调用进行干预,使客户端调用变得更加智能。

发展历程

2007年的淘宝是一个单体应用架构,光用堆机器的方式已经无法支撑业务增长,所以采用应用拆分的方式来满足业务增长需求。

应用拆分离不开RPC框架,而HSF的出现就承担了这个角色,从1.1版本仅为了解决分布式调用的简陋RPC框架,到最新的2.2版本一个高性能、易扩展的SOA框架,HSF的主要发展历程如下表:
在这里插入图片描述

基本结构

HSF功能结构上分为6个部分,分别是:服务消费方、服务提供方、地址注册中心、持久化配置中心、元数据存储中心和HSF运维平台(HSF 控制台),它们组合在一起可以提供全功能的分布式服务,其中必须的是服务消费方、服务提供方和地址注册中心,上述功能结构的描述如下表:
在这里插入图片描述
在阿里巴巴集团内部:

地址注册中心的角色是由 ConfigServer 承担的

持久化配置中心的角色是由 Diamond 承担的

元数据存储中心的角色是由 Redis 承担的

HSF 控制台的角色是由 HSFOPS 承担的

上述HSF功能结构之间的关系如下图所示:

从上图可以看到,服务提供方在启动后会向地址注册中心发布地址,服务消费方根据服务名向地址注册中心订阅服务地址,当服务地址推送到服务消费方后,服务消费方就可以从地址列表中选择一个地址发起RPC调用。服务提供方在发布地址的同时会将服务元信息发布到元数据存储中心,HSF控制台通过访问元数据存储中心向使用者展示服务的详情,同时HSF控制台还可以通过持久化配置中心和地址注册中心客户端查询服务信息和规则信息。

部署环境

HSF是SOA框架,目的是连接起服务提供方和服务消费方,框架本身是无状态的,而整个服务框架的状态信息是依靠地址注册中心和持久化配置中心。

软件环境分为:日常、预发和生产三种,如果只有一种,生产环境的数据在日常线下就会被访问和操作,这是不允许的,而环境的分类就需要依靠状态信息分开存储,也就是环境的区分依赖于地址注册中心和持久化配置中心(软负载体系)的区分。简单的说,每个环境下都会有一套地址注册中心和持久化配置中心,而HSF框架都是一样的。

在不同环境中,它们之间关系如下图所示:

可以看到地址注册中心和持久化配置中心是相互隔离的,做项目或者需求时,会遵循从日常、预发和线上的顺序发布应用,而在某个环境中进行操作和排查问题时,需要使用部署在对应环境的HSF控制台或者软负载产品(地址注册中心和持久化配置中心)。

编写服务端

服务开始于接口的定义,我们首先定义一个接口。一般会将接口定义在一个工程中,它会打成一个jar包,发布到maven仓库中。服务端实现这些接口,然后发布对应的服务,而消费端通过依赖这个jar包,透过HSF远程调用到服务端。

以下示例项目可以在hsf-guide中找到

服务接口定义
先定义一个OrderService,它在hsf-guide-api这个工程中。

public interface OrderService {
   
    /**
     * <pre>
     * 根据订单id查询一笔订单
     *
     * </pre>
     *
     * @param id 订单id
     * @return 如果查询不到返回null
     */
    OrderModel queryOrder(Long id);
}

这个工程将会打包成为hsf-guide-api.jar,未来需要调用这个接口的消费方,可以通过依赖这个jar包完成远程调用,比如依赖一个maven坐标即可。

<dependency>
    <groupId>com.alibaba.middleware</groupId>
    <artifactId>hsf-guide-api</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

业务代码实现
一般意义上,对于业务代码的实现不会耦合上任何框架的约束,对于一个接口的实现一般工程模块会与下图相似。

可以看到对于OrderService的实现OrderServiceImpl,它使用使用spring jdbc来进行数据库操作,配置文件分为biz.xml、dao.xml和datasource.xml,里面分别定义了OrderService以及OrderDAO和数据源。

public class OrderServiceImpl implements OrderService {
   
    @Autowired
    private OrderDAO orderDAO;

    @Override
    public OrderModel queryOrder(Long id) {
   
        return orderDAO.queryOrder(id);
    }
}

可以看到对于订单的查询非常简单,只是调用DAO进行查询一下返回就好。整个过程没有一点其他框架的影子(除了Spring),非常简单且容易测试(使用spring-test可以方便的进行单元测试)。直到这里还没有涉及到HSF,原因是我们希望你的api和业务实现能够足够的干净和少依赖,只有这样一个本地服务才能够更加安全可靠的转换成为一个分布式服务。

发布服务

当服务编写好了,就可以将服务发布出去,让其他客户端调用到当前机器。

服务发布首先需要进行配置,配置是将一个本地的普通服务转变为分布式服务的前提条件。在配置阶段能够感受到HSF对于服务提供方所提出的语义要求和约束。

API形式配置HSF服务
发布HSF服务可以通过HSFApiProviderBean来完成,该过程只需要做一次,该对象比较重,建议缓存起来。

// ---------------------- 装配 -----------------------//
// [设置] HSF服务发布逻辑
HSFApiProviderBean hsfApiProviderBean = new HSFApiProviderBean();
// [设置] 发布服务的接口
hsfApiProviderBean.setServiceInterface("com.alibaba.middleware.hsf.guide.api.service.OrderService");
// [设置] 服务的实现对象
hsfApiProviderBean.setTarget(target);
// [设置] 服务的版本
hsfApiProviderBean.setServiceVersion("1.0.0");
// [设置] 服务的归组
hsfApiProviderBean.setServiceGroup("HSF");
// [设置] 服务的响应时间
hsfApiProviderBean.setClientTimeout(3000);
// [设置] 服务传输业务对象时的序列化类型
hsfApiProviderBean.setPreferSerializeType("hessian2");
// ---------------------- 发布 -----------------------//
// [发布] HSF服务
hsfApiProviderBean.init();

HSFApiProviderBean构建完成后,设置这个服务的接口名,能够让订阅方根据接口进行订阅,同时来自远端的请求也能够找到本机的具体实现。随后设置了服务的版本与归组,服务通过接口名、版本和归组来确定一个服务实例。可以用maven中对于一个坐标的定位(GAV)来理解这个概念。然后我们将HSFApiProviderBean与具体的服务实现进行绑定,也就是setTarget(Object obj)方法。

基本配置属性表:
在这里插入图片描述
Spring配置HSF服务
Spring框架是在应用中广泛使用的组件,如果不想通过API的形式配置HSF服务,可以使用Spring XML的形式进行配置,上述例子中的API配置等同于如下XML配置:

<bean class="com.taobao.hsf.app.spring.util.HSFSpringProviderBean" init-method="init">
    <!--[设置] 发布服务的接口-->
    <property name="serviceInterface" value="com.alibaba.middleware.hsf.guide.api.service.OrderService"/>
    <!--[设置] 服务的实现对象 target必须配置[ref],为需要发布为HSF服务的spring bean id-->
    <property name="target" ref="引用的BeanId"/>
    <!--[设置] 服务的版本-->
    <property name="serviceVersion" value="1.0.0"/>
    <!--[设置] 服务的归组-->
    <property name="serviceGroup" value="HSF"/>
    <!--[设置] 服务的响应时间-->
    <property name="clientTimeout" value="3000"/>
    <!--[设置] 服务传输业务对象时的序列化类型-->
    <property name="preferSerializeType" value="hessian2"/>
</bean>

注解配置HSF服务
SpringBoot广泛使用的今天,使用注解装配SpringBean也成为一种选择,HSF也支持使用注解进行配置,用来发布服务。

首先是在项目中增加依赖starter。

<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>pandora-hsf-spring-boot-starter</artifactId>
</dependency>

然后将@HSFProvider配置到实现的类型上,上述例子中的API配置等同于如下注解配置:

注意是com.alibaba.boot.hsf.annotation.HSFProvider,不是com.taobao.hsf.app.spring.util.annotation.HSFProvider

@HSFProvider(serviceInterface = OrderService.class, serviceGroup = "HSF", serviceVersion = "1.0.0", clientTimeout = 3000)
public class OrderServiceImpl implements OrderService {
   
    @Autowired
    private OrderDAO orderDAO;

    @Override
    public OrderModel queryOrder(Long id) {
   
        return orderDAO.queryOrder(id);
    }
}

通过HSF-OPS查询服务

在完成 HSF 服务的发布之后,我们可以通过 HSF 运维系统(HSF-OPS)查询已发布的服务,从而验证服务发布的正确性,并获取服务的相关信息。

服务查询
访问 HSFOPS 的服务查询页面,准备进行服务查询:

日常环境:http://hsf.alibaba.net/hsfops/serviceSearch.htm?envType=daily
预发环境:http://hsf.alibaba-inc.com/hsfops/serviceSearch.htm?envType=pre
线上环境:http://hsf.alibaba-inc.com/hsfops/serviceSearch.htm?envType=online
HSFOPS 支持多种维度的服务查询能力,包括根据服务名查询,根据IP查询,以及根据应用名查询:

服务名:根据服务的 DataId(接口名:版本号)查询服务是否存在
IP:查询指定 IP 提供的服务 或 消费的服务
应用名:查询指定应用提供的服务列表。

注意:
根据 “应用名” 查询服务
查询结果中的 “应用名” 属性
是从 redis 中读取的 缓存 信息,而非 configserver 中的实时发布数据,因此会出现不准确的情况,但并不会影响 HSF 服务的正常调用。
若应用已经正确的配置了 -Dproject.name=yourAppName JVM 参数,则只需耐心等待缓存刷新即可(最迟1小时)。

服务详情
通过 HSFOPS 查询到发布的服务后,点击 “详情” 按钮即可查看服务的详情信息,包括:

  • 服务所属的应用信息
  • 服务提供方、消费方的 IP 列表
  • 服务的方法列表(元数据)

通过HSF-OPS测试服务

在通过 HSF 运维系统(HSF-OPS)的服务查询功能确认服务发布成功后,我们可以通过 “服务测试” 功能快速的发起一次服务调用,验证 HSF 服务中的业务逻辑。

HSF服务测试问题汇总

  • http://gitlab.alibaba-inc.com/middleware-container/hsf-guide/issues/78347
    选择测试方法
    访问 HSFOPS 的服务测试页面,准备进行服务测试:

  • 日常环境:http://hsf.alibaba.net/hsfops/testpage/testPage.htm?envType=daily

  • 预发环境:http://hsf.alibaba-inc.com/hsfops/testpage/testPage.htm?envType=pre

  • 线上环境:http://hsf.alibaba-inc.com/hsfops/testpage/testPage.htm?envType=online

进入服务测试页面后,首先查询需要测试的服务,点击 “选择测试方法” 按钮查看服务的方法列表;在服务的方法列表中,找到需要测试的方法,点击 “测试” 进入方法测试页面。

注意:

服务测试功能具有权限控制,并按照应用级别进行鉴权:

  • 日常:全部登录用户可调用
  • 预发:仅服务所属应用的 AppOps、开发负责人、测试负责人 可调用
  • 线上:仅服务所属应用的 AppOps
    可调用

编辑方法参数
进入最终的测试页面后,默认会展示出服务方法的参数格式,在 json 编辑器中,按需输入服务调用参数,并点击 “测试” 按钮,就完成了一次服务测试调用。

调用结果、服务提供方 IP、traceId 等信息会在页面下方的测试结果区域给出。

注意:

  • HSFOPS 的服务测试采用 HSF 泛化调用机制,对 DTO 的 “干净” 程度要求比较高,要有标准的 getters 和 setters,并且尽量不要在其中放置业务逻辑
  • 对于一些复杂参数的编辑,需要增、删属性字段时,可以切到 code 模式操作

编写调用端

服务提供方应用发布,并且客户端Jar包发布到maven仓库中后,服务消费方就可以调用了。

服务调用与服务的发布过程基本对称,需要对服务进行配置,但是在配置前还是需要先依赖服务提供方发布在maven仓库中的客户端jar包。

依赖客户端Jar包
首先需要询问服务提供方合适的客户端Jar包maven坐标,本文示例中类似如下配置:

<dependency>
    <groupId>com.alibaba.middleware</groupId>
    <artifactId>hsf-guide-api</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

API形式配置HSF服务
消费HSF服务可以通过HSFApiConsumerBean来完成,该过程只需要做一次,该对象比较重,包括获取到的HSF代理,建议缓存起来。

其实在HSF内部HSFApiConsumerBean对服务的配置也是缓存起来的,也就是说如果堆一个订阅的服务有多次配置,只有第一次配置会生效

// ---------------------- 装配 -----------------------//
// [设置] HSF服务订阅逻辑
HSFApiConsumerBean hsfApiConsumerBean = new HSFApiConsumerBean();
// [设置] 订阅服务的接口
hsfApiConsumerBean.setInterfaceName("com.alibaba.middleware.hsf.guide.api.service.OrderService"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值