本次最佳实践 分析传统HSF应用的劣势及升级至Pandora Boot开发的优势。将结合HSF代码和Pandora Boot代码进行详解传统HSF应用如何升级至Pandora Boot开发。
背景信息??HSF开发应用的劣势在于HSF要使用指定的Ali-Tomcat容器 还需要在Ali-Tomcat等容器中加入sar包扩展 对用户运行环境的侵入性大。而HSF开发的应用程序最终以WAR包的形式运行 不符合微服务设计的轻量应用理念。并且开发过程注入Bean需要编写较多的xml文件配置。
而Pandora Boot开发应用的优势就在于依赖容器Pandora 不需要Ali-Tomcat。而且Pandora Boot开发也兼容了完整的HSF功能 同时与Spring Boot无缝集成。所以使用Pandora Boot的同时也可以引入Spring Boot提供开箱即用的依赖模板。快速、敏捷的开发Spring框架的应用程序 享受开发的便利。
Pandora Boot开发的应用最终以FatJar包的形式运行 并且Pandora环境也可以直接在IDE中启动 开发调试等效率将得到极大的提高。而Pandora Boot注入Bean通过注解的方式 也减少了繁杂的xml配置文件编写 提高开发效率。
因为在传统客户中有HSF应用升级至Pandora Boot开发的需求 所以针对客户的需要 本次最佳实践将详细描述传统HSF应用和PandoraBoot应用的开发 使单体微服务应用的敏捷开发及拓展性有所提高。
HSF环境介绍及准备产品组件Ali-Tomcat是EDAS中的服务运行依赖的一个容器 支持Servlet 3.0规范 支持WebSocket。包含服务的发布、订阅、调用链追踪等一系列的核心功能。Pandora是一个轻量级的隔离容器-taobao-hsf.sar 它用来隔离Webapp和中间件的依赖 也用来隔离中间件之间的依赖 并实现部署与应用分离。轻量级配置中心 Diamond 是淘宝内部广泛使用的配置中心 提供持久化管理和动态配置推送服务。应用方发布的配置会通过持久化存储保存 与发布者的生命周期无关。动态配置推送是Diamond的核心功能 在淘宝内部有很多应用场景 如数据库动态切换和扩容 业务系统开关配置运行时变更等。轻量级注册中心 ConfigServer 主要用于非持久数据的发布和订阅、数据的生命周期和TCP连接生命周期绑定、产品架构基于发布订阅模型和去中心无master设计 保证了系统的可扩展性、高可用。在集团内部主要场景为分布式消息系统Notify、分布式RPC框架HSF提供地址发现服务。基本结构HSF结构分为6个部分 共同组合在一起可以提供全功能的分布式服务 分别是
服务消费方 消费服务提供方提供的服务 服务消费者通过地址注册中心订阅服务 根据订阅到的地址信息发起调用 地址注册中心作为旁路不参与调用。服务提供方 在服务框架中真正提供服务功能实现的应用实例 为了保障服务提供的高可用性 一般均是集群部署 同时将地址信息发布到地址注册中心。地址注册中心 接受服务提供方发布的地址 当服务消费方根据服务进行订阅时 会将地址信息推送给服务消费方 注册中心就是服务信息的中介 提供服务发现的能力持久化配置中心 持久化的配置中心用于存储 HSF 服务的各种治理规则 HSF 客户端在启动的过程中会向持久化配置中心订阅各种服务治理规则 如路由规则、归组规则、权重规则等 从而根据规则对调用过程的选址逻辑进行干预。元数据存储中心 元数据是指 HSF 服务对应的方法列表以及参数结构等信息 元数据不会对 HSF 的调用过程产生影响 因此元数据存储中心也并不是必须的。但考虑到服务运维的便捷性 HSF客户端在启动时会将元数据上报到元数据存储中心 以便提供给服务运维使用HSF运维平台 HSF控制台 HSF 控制台通过打通地址注册中心 ConfigServer、持久化配置中心 Diamond、元数据存储中心Redis 为用户提供了一些列服务运维功能 包括服务查询、服务治理规则管理、服务测试、服务 Mock、单机运维等 旨在提高 HSF 服务研发的效率、运维的便捷性。环境准备流程步骤在进行开发前 需要准备以下基本内容
JDK基础运行环境 正确安装JDK 7 正确配置JAVA_HOME环境变量。MAVEN环境及构建HSF MAVEN工程 添加打war包与HSF开发编译依赖。开发IDE 推荐Eclipse或IDEA。Eclipse配置 Tomcat4e插件 Pandora配置。IDEA 配置AliTomcat Pandora。轻量级配置中心 HSF服务的发布与订阅。Pandora Boot环境介绍及准备产品组件Pandora 一个轻量级的隔离容器-taobao-hsf.sar 它用来隔离Webapp和中间件的依赖 也用来隔离中间件之间的依赖 也实现部署与应用分离。轻量级配置及注册中心 对于开发者可以在本地使用轻量级配置及注册中心实现应用的注册、发现与配置管理 完成应用的开发和测试。本地开发完应用托管到EDAS服务上 EDAS内置注册及配置中心 因此注册及配置功能仍然可以正常使用。基本结构HSF结构分为6个部分 共同组合在一起可以提供全功能的分布式服务 分别是
服务消费方 消费服务提供方提供的服务 服务消费者通过地址注册中心订阅服务 根据订阅到的地址信息发起调用 地址注册中心作为旁路不参与调用。服务提供方 在服务框架中真正提供服务功能实现的应用实例 为了保障服务提供的高可用性 一般均是集群部署 同时将地址信息发布到地址注册中心。地址注册中心 接受服务提供方发布的地址 当服务消费方根据服务进行订阅时 会将地址信息推送给服务消费方 注册中心就是服务信息的中介 提供服务发现的能力持久化配置中心 持久化的配置中心用于存储 HSF 服务的各种治理规则 HSF 客户端在启动的过程中会向持久化配置中心订阅各种服务治理规则 如路由规则、归组规则、权重规则等 从而根据规则对调用过程的选址逻辑进行干预。元数据存储中心 元数据是指 HSF 服务对应的方法列表以及参数结构等信息 元数据不会对 HSF 的调用过程产生影响 因此元数据存储中心也并不是必须的。但考虑到服务运维的便捷性 HSF客户端在启动时会将元数据上报到元数据存储中心 以便提供给服务运维使用HSF运维平台 HSF控制台 HSF 控制台通过打通地址注册中心 ConfigServer、持久化配置中心 Diamond、元数据存储中心Redis 为用户提供了一些列服务运维功能 包括服务查询、服务治理规则管理、服务测试、服务 Mock、单机运维等 旨在提高 HSF 服务研发的效率、运维的便捷性。环境准备流程步骤在进行开发前 需要准备一下基本内容
JDK基础运行环境 正确安装JDK 7 正确配置JAVA_HOME环境变量。MAVEN环境及构建Pandora Boot MAVEN工程 添加打FatJar包与Pandora Boot开发编译依赖。开发IDE 推荐Eclipse或IDEA。Eclipse配置 启动Pandora Boot应用主函数自动加载Pandora容器。IDEA配置 启动Pandora Boot应用主函数自动加载Pandora容器。轻量级注册及配置中心 Pandora Boot应用的注册、发现及配置管理。HSF开发流程及流程图开发流程节点 服务接口 HSF的服务基于接口实现 接口需在服务设计时预先定义设计好 生产者将实现该接口以提供具体的实现来提供服务 消费者也是基于此接口作为服务去订阅。服务生产者 生产者将实现之前定义的服务接口以提供具体实现 除了代码实现的工作之外 由于HSF是基于Spring框架来实现的 所以还需要再定义服务发布的XML文件。服务消费者 消费者基于接口使用服务 具体调用时需要做两个步骤Pandora Boot 的配置文件使用注解 HSFConsumer定义好一个 Bean。在使用的时候从 Spring 的 context 中将 Bean 取出。图 1.?流程图
开发HSF应用背景信息无缝兼容 HSF与Spring无缝兼容 标准用法使用Spring的xml配置。标准schema 提供hsf:provider hsf:consumer两个标准的xml格式。代码无侵入 使用xml方式开发时 代码不需要感知HSF框架 而且POM中只需要引入edas-sdk。框架与WAR包分离 最终输入的war 不需要包含HSF框架 HSF框架依赖AliTomcat Pandora方式提供。您需要按以下步骤构建HSF maven工程
构建maven工程 创建完maven工程后 在pom.xml文件中定义添加edas-sdk和spring的依赖。dependencies !-- 添加 servlet 的依赖 -- dependency groupId javax.servlet /groupId artifactId servlet-api /artifactId version 2.5 /version scope provided /scope /dependency dependency groupId org.springframework /groupId artifactId spring /artifactId version 2.5.6 /version type jar /type scope compile /scope /dependency !-- 添加 edas-sdk 的依赖 -- dependency groupId com.alibaba.edas /groupId artifactId edas-sdk /artifactId version 1.5.4 /version /dependency /dependencies在pom.xml文件中添加HSF应用的maven打包插件。
build finalName itemcenter /finalName plugins plugin groupId org.apache.maven.plugins /groupId artifactId maven-compiler-plugin /artifactId version 3.1 /version configuration source 1.6 /source target 1.6 /target /configuration /plugin /plugins /build定义服务接口
HSF服务基于接口实现调用 定义好接口Sayhello后 生产者将使用该接口实现具体的服务 消费者也基于此接口订阅服务 所以一般会将接口定义在一个工程中 它会打成一个jar包 发布到maven仓库中。下面是公共模块edasdemo-api接口定义代码
package com.edas.demo; public interface Sayhello { public String sayHello(); public String sayHello(String name); }编写HSF服务提供者编写HSF提供者服务除构建HSF maven工程外 服务提供者需要在pom.xml文件中引入公共模块工程的依赖。
dependency groupId com.edas.demo /groupId artifactId edasdemo-api /artifactId version 0.0.1-SNAPSHOT /version /dependency服务提供者实现接口提供具体的服务 然后发布对应的服务。
package com.edas.demo; public class SayhelloImpl implements Sayhello { public String sayHello() { System.out.println( INFO:执行一次Hello return Hello! public String sayHello(String name) { return 你好 name; }在hsf-provider-beans.xml中Spring配置HSF服务。
?xml version 1.0 encoding UTF-8 ? beans xmlns:xsi http://www.w3.org/2001/XMLSchema-instance xmlns:hsf http://www.taobao.com/hsf xmlns http://www.springframework.org/schema/beans xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.taobao.com/hsf http://www.taobao.com/hsf/hsf.xsd default-autowire byName bean id sayHello class com.edas.demo.SayhelloImpl / !-- 提供一个服务示例 -- hsf:provider id sayHelloProvider interface com.edas.demo.Sayhello ref sayHello version 1.0.0 /hsf:provider /beans编写HSF服务消费者编写消费者服务除构建HSF maven工程外 服务消费者需要在pom.xml文件中引入公共模块工程的依赖。
dependency groupId com.edas.demo /groupId artifactId edasdemo-api /artifactId version 0.0.1-SNAPSHOT /version /dependency在hsf-consumer-beans.xml中Spring配置HSF服务。
?xml version 1.0 encoding UTF-8 ? beans xmlns:xsi http://www.w3.org/2001/XMLSchema-instance xmlns:hsf http://www.taobao.com/hsf xmlns http://www.springframework.org/schema/beans xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.taobao.com/hsf http://www.taobao.com/hsf/hsf.xsd default-autowire byName !-- 消费一个服务示例 -- hsf:consumer id sayHello interface com.edas.demo.Sayhello version 1.0.0 /hsf:consumer /beans编写服务消费者基于接口调用服务提供者的代码SayhelloServlet。
public class SayhelloServlet extends HttpServlet { private static final long serialVersionUID 1L; public SayhelloServlet() { super(); * see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ApplicationContext ctx WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); // 根据 Spring 配置中的 Bean ID item 获取订阅到的服务 final Sayhello sayHello (Sayhello) ctx.getBean( sayHello Thread thread new Thread( new Runnable() { Override public void run() { while ( true ) { try { Thread.sleep(500l); System.out.println(sayHello.sayHello()); System.out.println(sayHello.sayHello( tom } catch ( Throwable e ) { e.printStackTrace(); thread.start(); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }开发HSF异步调用异步调用
对于客户端来说 并不是所有的HSF服务都需要同步等待服务端返回结果 对于这些场景 HSF提供异步调用的方式 让客户端不必同步阻塞在HSF操作上。在HSF服务发起异步调用 调用结果都是返回的默认值。而真正的结果要在HSFResponseFuture或者回调函数callback中获取。
Futrue异步调用HSF与Spring框架无缝集成 可以使用Spring XML的方式进行Future异步调用配置。
bean id orderService class com.taobao.hsf.app.spring.util.HSFSpringConsumerBean property name interfaceName value com.alibaba.middleware.hsf.guide.api.service.OrderService / property name version value 1.0.0 / property name group value HSF / !--[设置] 订阅服务的接口-- property name asyncallMethods list value name:queryOrder;type:future /value /list /property /beanCallback异步调用
使用Spring XML进行Callback异步调用配置。
bean id CallHelloWorld class com.taobao.hsf.app.spring.util.HSFSpringConsumerBean property name interfaceName value com.alibaba.middleware.hsf.guide.api.service.OrderService / property name version value 1.0.0 / property name group value HSF / property name asyncallMethods list !--name:methodName;type:future|callback-- value name:queryOrder;type:callback;listener:com.alibaba.middleware.hsf.CallbackHandler /value /list /property /bean开发HSF泛化调用背景信息
相对于依赖业务客户端Jar包的正常调用 需要依赖二方包 使用特定的GenericService接口 而传入需要调用的方法名 方法签名和参数值进行调用服务。泛化调用更适用于一些网关应用 其中hsfops服务测试也是依赖泛化调用功能。
API形式配置HSF服务将HSFConsumerBean 配置generic为true 标识客户端忽略加载不到接口的异常。
HSFApiConsumerBean hsfApiConsumerBean new HSFApiConsumerBean(); hsfApiConsumerBean.setInterfaceName( com.alibaba.middleware.hsf.guide.api.service.OrderService hsfApiConsumerBean.setVersion( 1.0.0 hsfApiConsumerBean.setGroup( HSF // [设置] 泛化配置 hsfApiConsumerBean.setGeneric( true hsfApiConsumerBean.init(true); //使用泛化接口获取代理 GenericService genericOrderService (GenericService) hsfApiConsumerBean.getObject(); // ---------------------- 调用 -----------------------// // [调用] 发起HSF泛化调用, 返回map类型的result。 Map orderModelMap (Map) genericOrderService.$invoke( queryOrder , new String[] { Long.class.getName() }, new Object[] { 1L });
GenericService提供的$invoke方法包含了真实调用的方法名、入参类型和参数 以便服务端找到改方法。由于没有依赖服务端的API jar包 传入的参数如果是自定义的DTO 需要转成客户端可以序列化的Map类型。
Spring配置HSF服务上面描述了通过API配置HSF服务 也可以通过Spring XML配置HSF服务。
bean id CallHelloWorld class com.taobao.hsf.app.spring.util.HSFSpringConsumerBean !--[设置] 订阅服务的接口-- property name interfaceName value com.alibaba.middleware.hsf.guide.api.service.OrderService / !--[设置] 服务的版本-- property name version value 1.0.0 / !--[设置] 服务的归组-- property name group value HSF / property name generic value true / /bean调用上下文背景信息
请求上下文包括一次性调用相关的属性 比如调用的地址 调用方的应用名 超时时间等属性和用户在接口定义的参数之外传递自定义的数据。
设置和获取本次调用上下文com.taobao.hsf.util.RequestCtxUtil提供设置和获取调用上下文的静态方法 基于ThreadLocal工作 getXXX操作会将XXX属性从当前ThreadLocal变量中remove掉 仅作用于当前线程的单次调用。
?表1. 客户端
名称描述setRequestTimeout()设置单次调用的超时时间setUserId()设置本次调用的单元化服务的userId 泛化调用中需要通过此方法配置 getProviderIp()获取【最近一次】调用的服务端的IPsetTargetServerIp(String ip)设置当前线程下一次调用的目标服务器IP 此IP必须包含在内存已提供服务的地址列表里 setDirectTargetServerIp(String targetIp)设置当前线程下一次调用的目标服务器IP 绕过注册中心 忽略内存里的地址列表表 2.?服务端
名称描述getClientIp()服务端获取调用方IPgetAppNameOfClient()服务端获取调用方的应用名isHttpRequest()是否是http调用getHttpHeader(String key)获取http请求的header属性RpcContext提供一种不修改接口 向服务端额外传递数据的方式。参数可以是自定义的DO或者基本类型。要保证对端也有该对应的类型 并且可以能够被序列化。
传递自定义上下文开发示例 在构建的Maven项目中导入下面依赖。dependency groupId com.taobao.hsf /groupId artifactId hsf-feature-context /artifactId /dependency客户端发起调用前 设置上下文。
RPCContext rpcContext RPCContext.getClientContext(); rpcContext.putAttachment( tetantId , 123 orderService.queryOrder(1L);服务端业务方法内 获取上下文。
RPCContext rpcContext RPCContext.getServerContext(); String myContext (String)rpcContext.getAttachment( tetantId配置序列化
序列化的过程是将JAVA对象转成byte数组在网络中传输 反序列化会将byte数组转成JAVA对象。
序列化方式配置序列化的选择需要考虑兼容性 性能等因素 HSF的序列化方式支持JAVA、hessian、hessian2、JSON、kyro 默认是hessian2。这些序列化方式的对比和配置 只在服务端配置HSFApiProviderBean 如下表所示
序列化方式maven依赖配置兼容性性能hessian2 artifactId hsf-io-serialize-hessian2 /artifactId setPreferSerializeType( hessian2 )好好java artifactId hsf-io-serialize-java /artifactId setPreferSerializeType( java )最好一般fastjson artifactId hsf-io-serialize-json /artifactId setPreferSerializeType( json )好好kryo artifactId hsf-io-serialize-kryo /artifactId setPreferSerializeType( kryo )一般最好HSFApiProviderBean hsfApiProviderBean new HSFApiProviderBean(); hsfApiProviderBean.setPreferSerializeType( hessian2Spring配置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的默认超时时间是3000ms。客户端和服务端都可以设置超时 默认优先采用客户端的配置 如果客户端没有配置 使用服务端的超时配置。在服务端设置超时时 需要考虑到业务本身的执行耗时 加上序列化和网络通讯的时间。所以推荐服务端给每个服务都配置个默认的时间。当然客户端也可以根据自己的业务场景配置超时时间 比如一些前端应用 需要用户快速看到结果 可以把超时时间设置小一些。
客户端超时配置客户端超时配置有以下两种方式
API形式配置HSF服务 配置HSFApiConsumerBean的clientTimeout属性 单位是ms 我们把接口的超时配置为1000ms 方法queryOrder配置为100ms 代码如下HSFApiConsumerBean consumerBean new HSFApiConsumerBean(); //接口级别超时配置 consumerBean.setClientTimeout(1000); //xxx MethodSpecial methodSpecial new MethodSpecial(); methodSpecial.setMethodName( queryOrder //方法级别超时配置 优先于接口超时配置 methodSpecial.setClientTimeout(100); consumerBean.setMethodSpecials(new MethodSpecial[]{methodSpecial});Spring配置HSF服务 上述例子中的API配置等同于如下XML配置
bean id CallHelloWorld class com.taobao.hsf.app.spring.util.HSFSpringConsumerBean property name clientTimeout value 1000 / property name methodSpecials list bean class com.taobao.hsf.model.metadata.MethodSpecial property name methodName value queryOrder / property name clientTimeout value 100 / /bean /list /property /bean服务端超时配置
服务端超时配置也有两种不同的方式
API形式配置HSF服务 配置HSFApiProviderBean的clientTimeout属性 单位是ms 代码如下HSFApiProviderBean providerBean new HSFApiProviderBean(); //接口级别超时配置 providerBean.setClientTimeout(1000); //xxx MethodSpecial methodSpecial new MethodSpecial(); methodSpecial.setMethodName( queryOrder //方法级别超时配置 优先于接口超时配置 methodSpecial.setClientTimeout(100); providerBean.setMethodSpecials(new MethodSpecial[]{methodSpecial});Spring配置HSF服务 上述例子中的API配置等同于如下XML配置
bean class com.taobao.hsf.app.spring.util.HSFSpringProviderBean init-method init property name clientTimeout value 1000 / property name methodSpecials list bean class com.taobao.hsf.model.metadata.MethodSpecial property name methodName value queryOrder / property name clientTimeout value 2000 / /bean /list /property /bean服务端线程池配置
HSF服务端线程池主要分为IO线程和业务线程 其中IO线程模型就是netty reactor网络模型中使用的。
默认线程池配置服务端线程池是用来执行业务逻辑的线程池 线程池默认的core size是50 max size是720 keepAliveTime 500s。队列使用的是SynchronousQueue 没有缓存队列 不会堆积用户请求。 当服务端线程池所有线程 720 都在处理请求时 对于新的请求 会立即拒绝 返回Thread pool is full异常。可以使用下面VM参数 -D参数 进行配置。
线程池最小配置 -Dhsf.server.min.poolsize。线程池最大的配置 -Dhsf.server.max.poolsize。线程收敛的存活时间 -Dhsf.server.thread.keepalive。服务线程池配置对于一些慢服务、并发高 可以为其单独配置线程池 以免占用过多的业务线程 影响应用的其他服务的调用 你可以通过以下两种方式配置HSF应用
API形式配置HSF应用HSFApiProviderBean hsfApiProviderBean new HSFApiProviderBean(); //... hsfApiProviderBean.setCorePoolSize( 50 hsfApiProviderBean.setMaxPoolSize( 200Spring配置HSF应用
bean class com.taobao.hsf.app.spring.util.HSFSpringProviderBean init-method init !--[设置] 发布服务的接口-- property name serviceInterface value com.alibaba.middleware.hsf.guide.api.service.OrderService / property name corePoolSize value 50 / property name maxPoolSize value 200 / /beanPandora Boot开发流程开发流程节点 服务接口 Pandora Boot 的服务基于接口实现 接口需在服务设计时预先定义设计好 生产者将实现该接口以提供具体的实现来提供服务 消费者也是基于此接口作为服务去订阅。服务生产者 生产者将实现之前定义的服务接口以提供具体实现 除了代码实现的工作之外 所以还需要再定义服务发布的注解 HSFProvider配置标识为服务提供者。服务消费者 消费者基于接口使用服务 具体调用时需要做两个步骤 Spring 的配置文件使用标签定义好一个Bean。在使用的时候从Spring的context中将Bean取出。开发Pandora Boot应用构建Pandora Boot maven工程构建maven工程 创建完maven工程后 在pom.xml文件中配置EDAS的私服库地址和插件私服库地址。
repositories repository id central /id url http://repo1.maven.org/maven2 /url releases enabled true /enabled /releases snapshots enabled true /enabled /snapshots /repository repository id edas-oss-central /id name taobao mirror central /name url http://edas-public.oss-example.aliyuncs.com/repository /url snapshots enabled true /enabled /snapshots releases enabled true /enabled /releases /repository /repositories pluginRepositories pluginRepository id central /id url http://repo1.maven.org/maven2 /url releases enabled true /enabled /releases snapshots enabled true /enabled /snapshots /pluginRepository pluginRepository id edas-oss-plugin-central /id url http://edas-public.oss-example.aliyuncs.com/repository /url snapshots enabled true /enabled /snapshots releases enabled true /enabled /releases /pluginRepository /pluginRepositories构建maven工程 创建完maven工程后 在pom.xml文件中定义添加pandora boot和spring boot依赖的版本。
properties spring-boot.version 2.1.6.RELEASE /spring-boot.version pandora-boot.version 2019-06-stable /pandora-boot.version /properties dependencyManagement dependencies dependency groupId org.springframework.boot /groupId artifactId spring-boot-dependencies /artifactId version ${spring-boot.version} /version type pom /type scope import /scope /dependency dependency groupId com.taobao.pandora /groupId artifactId pandora-boot-starter-bom /artifactId version ${pandora-boot.version} /version type pom /type scope import /scope /dependency /dependencyManagement在pom.xml添加pandora boot 和spring boot开发的依赖。
dependencies dependency groupId com.alibaba.boot /groupId artifactId pandora-hsf-spring-boot-starter /artifactId /dependency dependency groupId org.springframework.boot /groupId artifactId spring-boot-starter-web /artifactId /dependency dependency groupId org.slf4j /groupId artifactId jcl-over-slf4j /artifactId /dependency dependency groupId com.taobao.pandora /groupId artifactId pandora-boot-test /artifactId scope test /scope /dependency dependency groupId org.springframework.boot /groupId artifactId spring-boot-starter-test /artifactId /dependency dependency groupId org.springframework.boot /groupId artifactId spring-boot-starter-actuator /artifactId /dependency !-- Use Swagger UI for REST API test -- dependency groupId io.springfox /groupId artifactId springfox-swagger-ui /artifactId version 2.6.1 /version /dependency dependency groupId io.springfox /groupId artifactId springfox-swagger2 /artifactId version 2.6.1 /version /dependency /dependencies在pom.xml文件中添加pandora boot应用的maven打包插件。
build plugins plugin groupId com.taobao.pandora /groupId artifactId pandora-boot-maven-plugin /artifactId version 2.1.11.8 /version executions execution phase package /phase goals goal repackage /goal /goals /execution /executions /plugin /plugins /build在工程目录resources下的application.properties文件中配置应用名和监听端口号。
spring.application.name hsf-provider server.port 8082 spring.hsf.version 1.0.0 spring.hsf.timeout 1000添加服务启动的main函数入口。
SpringBootApplication public class HSFProviderApplication { public static void main(String[] args) { // 启动 Pandora Boot 用于加载 Pandora 容器 PandoraBootstrap.run(args); SpringApplication.run(HSFProviderApplication.class, args); // 标记服务启动完成,并设置线程 wait。防止用户业务代码运行完毕退出后 导致容器退出。 PandoraBootstrap.markStartupAndWait(); }编写Pandora Boot服务提供者对于服务提供者 其创建过程与以上构建Pandora Boot maven工程步骤一致外 需要定义服务接口EchoService提供给消费者订阅。
public interface EchoService { String echo(String string); String echoFuture(String str); String echoCallback(String str); String echoHSFMix(int id); String echoMQConsumer(String str); }创建服务提供者的具体实现类EchoServiceImpl 并通过注解方式发布服务。
HSFProvider(serviceInterface EchoService.class, serviceGroup HSF , serviceVersion 1.0.0 ) public class EchoServiceImpl implements EchoService { Autowired private EchoDao echoDao; Autowired private SimpleMQConsumer simpleMQConsumer; Autowired private SimpleMQProduce simpleMQProduce; public String echo(String str) { return hello -- str; public String echoFuture(String str) { return welcome -- str; public String echoCallback(String str) { return welcome -- str; public String echoHSFMix(int id) { //写消息 simpleMQProduce.sendMsg(id return echoDao.findById(id).getUserName(); public String echoMQConsumer(String str) { //订阅消息 simpleMQConsumer.receive(); return str; }编写Pandora Boot消费者服务对于服务消费者 其创建过程与以上构建Pandora Boot maven工程步骤一致 添加服务提供者定义的接口复制到消费者服务工程。
public interface EchoService { String echo(String string); String echoFuture(String str); String echoCallback(String str); String echoHSFMix(int id); String echoMQConsumer(String str); }添加消费者服务配置类及业务逻辑代码。
消费者服务配置类 Configuration public class HsfConfig { //通过注解的方式将服务消费者的实例注入到Spring的Context中,同步调用 HSFConsumer(clientTimeout 3000, serviceVersion 1.0.0 ) private EchoService echoService; 消费者服务实现调用HSF服务提供者 RestController RequestMapping(value /poc ) Api(description HSF-POC功能测试接口 ) public class ConsumerController { Autowired private EchoService echoService; NacosValue(value ${useLocalCache:false} , autoRefreshed true) private String useLocalCache; ApiOperation(value 获取服务者返回信息 A- C ) RequestMapping(value /hsf-echo , method RequestMethod.GET) public String echo( RequestParam( str ) String str) { return echoService.echo(str) \r\n ApiOperation(value 通过ID查询数据库获取返回信息、RocketMQ写信息 A- C ) RequestMapping(value /hsf-echo-mix , method RequestMethod.GET) public String echoHSFMix( RequestParam( id ) int id) { return echoService.echoHSFMix(id) \r\n ApiOperation(value RocketMQ订阅消息 A- C ) RequestMapping(value /hsf-echo-mq , method RequestMethod.GET) public String echoMQConsumer( RequestParam( str ) String str) { return echoService.echoMQConsumer(str) \r\n ApiOperation(value 获取版本信息 ) RequestMapping(value /echo-version , method RequestMethod.GET) public String echoVersion() { return This is pandora boot version 2 \r\n }开发Pandora Boot异步调用
对于客户端来说 并不是所有的HSF服务都是需要同步等待服务端返回结果的 对于这些场景 HSF提供异步调用的方式 让客户端不必同步阻塞在HSF操作上。在HSF服务发起异步调用 调用结果都是返回的默认值。而真正的结果要在HSFResponseFuture或者回调函数callback中获取。
Futrue异步调用对于服务提供者 其创建过程与以上构建Pandora Boot maven工程步骤一致外 需要定义服务接口EchoService提供给消费者订阅 在EchoService添加Future异步调用的接口及实现类。public interface EchoService { String echoFuture(String str); 接口实现类 HSFProvider(serviceInterface EchoService.class, serviceGroup HSF , serviceVersion 1.0.0 ) public class EchoServiceImpl implements EchoService { public String echoFuture(String str) { return welcome -- str; }对于服务消费者 其创建过程与以上构建Pandora Boot maven工程步骤一致外 编写Future异步调用代码。
在配置类通过注解配置HSF接口方法为异步调用 //Future异步调用 HSFConsumer(serviceGroup HSF , serviceVersion 1.0.0 , futureMethods echoFuture ) private EchoService echoService; 编写对外暴露请求的Future异步调用代码 RequestMapping(value /hsf-echo-future , method RequestMethod.GET) public String echoFuture( RequestParam( str ) String str) { String resp echoService.echoFuture(str) \r\n System.out.println(resp); //及时在当前调用上下文中 获取 future 对象 因为该对象是放在ThreadLocal中 同一线程中后续调用会覆盖future对象 所以要及时取出。 HSFFuture hsfFuture HSFResponseFuture.getFuture(); //这里才真正地获取结果 如果调用还未完成 将阻塞等待结果 5000ms是等待结果的最大时间 try { System.out.println(hsfFuture.getResponse(5000)); } catch (Throwable throwable) { throwable.printStackTrace(); return resp; }Callback异步调用对于服务提供者 其创建过程与以上构建Pandora Boot maven一致外 需要定义服务接口EchoService提供给消费者订阅 在EchoService添加Callback异步调用的接口及实现类。
public interface EchoService { String echoFuture(String str); 接口实现类 HSFProvider(serviceInterface EchoService.class, serviceGroup HSF , serviceVersion 1.0.0 ) public class EchoServiceImpl implements EchoService { public String echoFuture(String str) { return welcome -- str; }对于服务消费者 其创建过程与以上构建Pandora Boot maven步骤一致外 编写Future异步调用代码。
注解配置HSF接口方法为callback调用 AsyncOn(interfaceName EchoService.class, methodName echoCallback ) public class CallbackHandler implements HSFResponseCallback { public void onAppException(Throwable t) { t.printStackTrace(); public void onAppResponse(Object result) { //取 callback 调用时设置的上下文 Object context CallbackInvocationContext.getContext(); System.out.println(result.toString()); System.out.println(context); public void onHSFException(HSFException e) { e.printStackTrace(); 编写对外暴露请求的Callback异步调用代码 RequestMapping(value /hsf-echo-callback , method RequestMethod.GET) public String echoCallback( RequestParam( str ) String str) { String resp echoService.echoCallback(str) \r\n System.out.println(resp); return resp; }开发Pandora Boot超时设置背景信息
注解配置HSF服务 SpringBoot广泛使用的今天 使用注解装配SpringBean也成为一种选择 HSF也支持使用注解进行配置 用来订阅服务。
客户端注解超时配置首先在Maven项目pom.xml文件中添加依赖Starterdependency groupId com.alibaba.boot /groupId artifactId pandora-hsf-spring-boot-starter /artifactId /dependency通常一个HSF Consumer需要在多个地方使用 但并不需要在每次使用的地方都用 HSFConsumer来标记。只需要写一个统一个Config类 然后在其它需要使用的地方 直接 Autowired注入即可上述例子中的API配置等同于如下注解配置
HSFConsumer(clientTimeout 1000, methodSpecials HSFConsumer.ConsumerMethodSpecial(methodName queryOrder , clientTimeout 100 )) private OderService orderService;服务端注解超时配置首先在Maven项目pom.xml文件中添加依赖Starter
dependency groupId com.alibaba.boot /groupId artifactId pandora-hsf-spring-boot-starter /artifactId /dependency服务端注解配置HSF服务超时设置
HSFProvider(serviceInterface OrderService.class, clientTimeout 3000) public class OrderServiceImpl implements OrderService { Autowired private OrderDAO orderDAO; Override public OrderModel queryOrder(Long id) { return orderDAO.queryOrder(id); }开发Pandora Boot服务线程池配置背景信息
注解配置HSF服务 SpringBoot被广泛使用的今天 使用注解装配SpringBean也成为一种选择 HSF也支持使用注解进行配置 用来订阅服务。
首先在Maven项目pom.xml文件中添加依赖Starter。dependency groupId com.alibaba.boot /groupId artifactId pandora-hsf-spring-boot-starter /artifactId /dependency将 HSFProvider配置到实现的类型上 上述例子中的API配置等同于如下注解配置。
HSFProvider(serviceInterface OrderService.class, corePoolSize 50, maxPoolSize 200) public class OrderServiceImpl implements OrderService { Autowired private OrderDAO orderDAO; Override public OrderModel queryOrder(Long id) { return orderDAO.queryOrder(id); }
溢价 域名 的续费价格如何?通常来说,因为溢价域名的价值高于普通域名,所以溢...
在Python开发过程中,我们难免会遇到多重条件判断的情况的情况,此时除了用很多...
TIOBE 公布了 2021 年 3 月的编程语言排行榜。 本月 TIOBE 指数没有什么有趣的变...
想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区 https://...
本文转载自微信公众号「bugstack虫洞栈」,作者小傅哥 。转载本文请联系bugstack...
前言 统计科学家使用交互式的统计工具(比如R)来回答数据中的问题,获得全景的认...
近几年,互联网行业蓬勃发展,在互联网浪潮的冲击下,互联网创业已成为一种比较...
基本介绍 给定 n 个权值作为 n 个叶子节点,构造一颗二叉树,若该树的带权路径长...
背景 我们知道 如果在Kubernetes中支持GPU设备调度 需要做如下的工作 节点上安装...
本文转载自公众号读芯术(ID:AI_Discovery)。 这一刻你正在应对什么挑战?这位前...