Brief introduction:Proprietary cloud traditional HSF upgrade Pandora Boot development

In this best practice, we analyze the disadvantages of traditional HSF applications and the advantages of upgrading to Pandora Boot development. HSF code and Pandora Boot code will be combined to explain how to upgrade traditional HSF applications to Pandora Boot development.

Background information

The disadvantage of HSF development application is that HSF needs to use the specified Ali-Tomcat container, and also needs to add the SAR packet extension in the Ali-Tomcat container, which is very invasive to the user’s running environment. HSF develops applications that ultimately run in the form of WAR packages, which do not conform to the lightweight application concept of microservice design. And development process injection beans need to write more XML file configuration.

The advantage of Pandora Boot is that it relies on the container Pandora and does not require Ali-Tomcat. The Pandora Boot development is also compatible with full HSF functionality, while seamlessly integrating with Spring Boot. So using Pandora Boot can also introduce Spring Boot to provide out-of-the-box dependency templates. Quick, agile development of Spring framework applications, enjoy the convenience of development.

The application developed by Pandora Boot finally runs in the form of FatJar package, and the Pandora environment can also be directly started in the IDE, and the efficiency of development and debugging will be greatly improved. The Pandora Boot injected Bean is annotated, which also reduces the complicated XML configuration file preparation and improves the development efficiency.

Because there is a need for HSF applications to be upgraded to PandoraBoot development among traditional customers, this best practice will describe the development of traditional HSF applications and PandoraBoot applications in detail to improve agile development and scalability of monolithic microservice applications.

HSF environment introduction and preparation

Product components

  • Ali-Tomcat is a container that services run on in EDAS, supports the Servlet 3.0 specification, and supports WebSockets. It includes a series of core functions such as publishing, subscribing, calling chain tracking and so on.
  • Pandora is a lightweight isolation container-taobao-hsf.sar, which is used to isolate dependencies between WebApp and middleware, as well as between middleware, and to achieve separation of deployment and application.
  • Diamond is a widely used configuration center in Taobao, which provides persistent management and dynamic configuration push service. The configuration published by the application is saved through persistent storage, independent of the publisher’s life cycle.
  • The dynamic configuration push is the core function of Diamond. There are many application scenarios in Taobao, such as dynamic switching and capacity expansion of database, operational system switch configuration change and so on.
  • ConfigServer (Lightweight Registry) : mainly used for publishing and subscribing non-persistent data, data lifecycle and TCP connection lifecycle binding, product architecture based on publishing and subscribing model and decentralized master design, to ensure the scalability of the system, high availability. In the Group, we provide address discovery services for distributed messaging system Notify and distributed RPC framework HSF in the main scenarios.

The basic structure

HSF structure is divided into six parts, which together can provide full-featured distributed services, respectively:

  • Service consumer: consumes the service provided by the service provider. The service consumer subscribes to the service through the address registry and initiates the call according to the subscribed address information. The address registry does not participate in the call as a bypass.
  • Service provider: an application instance that truly provides service function realization in the service framework. In order to guarantee the high availability of service provision, it is generally deployed in a cluster and addresses are published to the address registry at the same time.
  • Address registry: it accepts the address published by the service provider. When the service consumer subscribes according to the service, it will push the address information to the service consumer. The registry is the intermediary of the service information and provides the ability of service discovery
  • Persistence Configuration Center: The persistent configuration center is used to store various governance rules of HSF services. HSF clients will subscribe various service governance rules to the persistent configuration center during startup, such as routing rules, grouping rules, weight rules, etc., so as to intervene in the location logic of the calling process according to the rules.
  • Metadata Storage Center: Metadata refers to information such as the list of methods and parameter structures associated with HSF services. Metadata does not affect the invocation process of HSF, so metadata storage centers are not required. However, considering the convenience of service operation and maintenance, the HSF client will report the metadata to the metadata storage center at startup, so as to provide the metadata for service operation and maintenance
  • HSF operation and maintenance platform (HSF console) : HSF console provides users with a series of service operation and maintenance functions by accessing address registry ConfigServer, persistence configuration center Diamond, metadata storage center Redis, including service query, service governance rule management, service testing, service Mock, stand-alone operation and maintenance, etc. It aims to improve the efficiency of HSF service research and development and the convenience of operation and maintenance.

Environment preparation process steps

Before you start developing, you need to prepare the following basics:

  1. JDK base runtime environment: properly install JDK 7+ and properly configure the JAVA\_HOME environment variable.
  2. Maven project: Add the WAR package and HSF development build dependencies.
  3. Developing IDE: Eclipse or IDEA is recommended.
  4. Eclipse configuration: Tomcat4e plug-in +Pandora configuration.
  5. Idea: Configure AliTomcat+Pandora.
  6. Lightweight Configuration Center: Publish and subscribe to HSF services.

Pandora Boot environment introduction and preparation

Product components

  • Pandora: A lightweight isolation container -taobao-hsf.sar, which is used to isolate dependencies between webapps and middleware, as well as between middleware, to achieve separation of deployment and application.
  • Lightweight configuration and registry: developers can use the lightweight configuration and registry locally to realize application registration, discovery and configuration management, and complete application development and testing. After the local development of the application is hosted on the EDAS service, EDAS built-in registration and configuration center, so the registration and configuration functions can still be used normally.

The basic structure

HSF structure is divided into six parts, which together can provide full-featured distributed services, respectively:

  • Service consumer: consumes the service provided by the service provider. The service consumer subscribes to the service through the address registry and initiates the call according to the subscribed address information. The address registry does not participate in the call as a bypass.
  • Service provider: an application instance that truly provides service function realization in the service framework. In order to guarantee the high availability of service provision, it is generally deployed in a cluster and addresses are published to the address registry at the same time.
  • Address registry: it accepts the address published by the service provider. When the service consumer subscribes according to the service, it will push the address information to the service consumer. The registry is the intermediary of the service information and provides the ability of service discovery
  • Persistence Configuration Center: The persistent configuration center is used to store various governance rules of HSF services. HSF clients will subscribe various service governance rules to the persistent configuration center during startup, such as routing rules, grouping rules, weight rules, etc., so as to intervene in the location logic of the calling process according to the rules.
  • Metadata Storage Center: Metadata refers to information such as the list of methods and parameter structures associated with HSF services. Metadata does not affect the invocation process of HSF, so metadata storage centers are not required. However, considering the convenience of service operation and maintenance, the HSF client will report the metadata to the metadata storage center at startup, so as to provide the metadata for service operation and maintenance
  • HSF operation and maintenance platform (HSF console) : HSF console provides users with a series of service operation and maintenance functions by accessing address registry ConfigServer, persistence configuration center Diamond, metadata storage center Redis, including service query, service governance rule management, service testing, service Mock, stand-alone operation and maintenance, etc. It aims to improve the efficiency of HSF service research and development and the convenience of operation and maintenance.

Environment preparation process steps

Before you start developing, you need to prepare the basics:

  1. JDK base runtime environment: properly install JDK 7+ and properly configure the JAVA\_HOME environment variable.
  2. Maven environment and build Pandora Boot Maven project: add FatJar package and Pandora Boot development compile dependencies.
  3. Developing IDE: Eclipse or IDEA is recommended.
  4. Eclipse configuration: Pandora Boot application main function automatically loads the Pandora container.
  5. Idea configuration: Start Pandora Boot application main function to automatically load the Pandora container.
  6. Lightweight Registration and Configuration Center: Registration, discovery, and configuration management for Pandora Boot applications.

HSF development process and flow chart

Development process node:

  1. Service Interface: HSF’s service is based on the interface implementation. The interface needs to be pre-defined and designed at service design time. Producers will implement the interface to provide concrete implementations to provide services, and consumers will subscribe as services based on this interface.
  2. Service Producer: The Producer will implement the previously defined service interface to provide the implementation. In addition to the code implementation work, since HSF is implemented based on the Spring Framework, the XML file that the service publishes needs to be redefined.
  3. Service consumer: The consumer uses the service based on the interface, and there are two steps required for the specific invocation
    1. Pandora Boot’s configuration file defines a Bean using the annotation @hsfconsumer.
    2. Remove the Bean from Spring’s context when in use.

Figure 1. Flow chart

Develop HSF applications

Background information

  1. Seamless Compatibility: HSF is seamlessly compatible with Spring, and standard usage uses Spring’s XML configuration.
  2. Standard Schema: Provides HSF :provider and HSF :consumer standard XML format.
  3. Code non-intrusive: When developed using XML, the code does not need to be aware of the HSF framework, and only the EDAS-SDK needs to be introduced into the POM.
  4. Frames are separated from the WAR package: The final WAR input does not need to include the HSF framework, which is provided in AliTomcat+Pandora mode.

You need to build the HSF Maven project by following these steps:

  1. Build the Maven project. After creating the Maven project, define the dependencies to add EDAS-SDK and Spring in the pom.xml file.
<dependencies> <! > <dependency> < grouppid >javax.servlet</ grouppid > <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> <! > <dependency dependency> < grouppid >com.alibaba.edas</ grouppid > <artifactId>edas-sdk</artifactId> The < version > 1.5.4 < / version > < / dependency > < / dependencies >
  1. Add the Maven packaging plug-in for the HSF application to the pom.xml file.
<build> <finalName>itemcenter</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> < artifactId > maven -- the compiler plugin < / artifactId > < version > 3.1 < / version > < configuration > < source > 1.6 < / source > <target>1.6</target> </configuration> </plugin> </plugins> </build>

Define the service interface

The HSF service is called based on the interface. After the SayHello interface is defined, the producer will use this interface to implement the specific service, and the consumer will subscribe to the service based on this interface, so the interface is usually defined in a project, which will be published into a JAR into the Maven repository. The following is the public module EdasDemo-API interface definition code:

package com.edas.demo;
public interface Sayhello {
    public String sayHello();
    public String sayHello(String name);
}

Write the HSF service provider

  1. Writing HSF Provider Services In addition to building the HSF Maven project, the service provider needs to introduce a common module project dependency in the pom.xml file.
< the dependency > < groupId > com. Edas. Demo < / groupId > < artifactId > edasdemo - API < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > </dependency>
  1. The service provider implements the interface to provide a concrete service and then publishes the corresponding service.
package com.edas.demo; Public class SayHelloImpl implements SayHello {public String SayHello () {System.out.println(" Info: implements "); return "Hello!" ; } public String SayHello (String Name) {return "hello "+name; }}
  1. Spring configures HSF services in HSF-provider-beans.xml.
<? The 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 id="sayHelloProvider" interface="com.edas.demo </hsf:provider> </beans>

Write HSF service consumers

  1. Writing a consumer service In addition to building the HSF Maven project, the service consumer needs to introduce the dependency of the common module project in the pom.xml file.
< the dependency > < groupId > com. Edas. Demo < / groupId > < artifactId > edasdemo - API < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > </dependency>
  1. Spring configures HSF services in HSF-consumer-beans.xml.
<? The 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>
  1. Write the code SayHelloServlet that the service consumer invokes the service provider based on the interface.
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()); 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); }}

Develop HSF asynchronous calls

The asynchronous call

For the client, not all HSF services need to wait for the server to return the result synchronously. For these scenarios, HSF provides an asynchronous way to call, so that the client does not have to block on the HSF operation synchronously. An asynchronous call is made to the HSF service, and the result of the call is the default value returned. The actual result is retrieved either in HSFResponseFuture or in the callback function.

Futrue asynchronous call

HSF integrates seamlessly with the Spring framework and can be configured for Future asynchronous calls using Spring XML.

<bean id="orderService" class="com.taobao.hsf.app.spring.util.HSFSpringConsumerBean"> <property name="interfaceName" Value = "com. Alibaba. Middleware. The HSF. Guide. API. The service. The OrderService" / > < property name = "version" value = "1.0.0" / > < property name="group" value="HSF"/> <! --[Settings] Interface to subscribe service --> <property name="asyncallMethods"> <list> <value>name:queryOrder; type:future</value> </list> </property> </bean>

Asynchronous Callback

Spring XML is used to configure Callback asynchronous calls.

<bean id="CallHelloWorld" class="com.taobao.hsf.app.spring.util.HSFSpringConsumerBean"> <property name="interfaceName" Value = "com. Alibaba. Middleware. The HSF. Guide. API. The service. The 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>

Develop HSF generalization calls

Background information

Instead of relying on a normal invocation of a business client JAR package, you need to rely on a two-sided package, using a specific GenericService interface, and pass in the method name, method signature, and parameter values to call the service. Generalization invocation is more suitable for some gateway applications, where HSFOPS service testing also relies on generalization invocation functionality.

Configure HSF services in API form

Set HSFConsumerBean, with Generic set to True, to indicate that the client ignores exceptions that do not load the interface.

HSFApiConsumerBean hsfApiConsumerBean = new HSFApiConsumerBean(); hsfApiConsumerBean.setInterfaceName("com.alibaba.middleware.hsf.guide.api.service.OrderService"); HsfApiConsumerBean. SetVersion (" 1.0.0 "); hsfApiConsumerBean.setGroup("HSF"); . / / [set] generalization configuration hsfApiConsumerBean setGeneric (" true "); hsfApiConsumerBean.init(true); / / using generic interface to get the agent GenericService genericOrderService = (GenericService) hsfApiConsumerBean. GetObject (); / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- call -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- / / / / [call] HSF generalization call, return the result of the map types. Map orderModelMap = (Map) genericOrderService.$invoke("queryOrder", new String[] { Long.class.getName() }, new Object[] { 1L });

The GenericService provides the $invoke method that contains the name of the actual method called, the input type, and the parameters so that the server can find the modified method. Since there are no API JARs that depend on the server, the parameters passed in, if they are custom DTOs, need to be converted to a Map type that the client can serialize.

Spring configures the HSF service

As described above, HSF services can be configured via APIs, as well as Spring XML.

<bean id="CallHelloWorld" class="com.taobao.hsf.app.spring.util.HSFSpringConsumerBean"> <! - [set] subscription service interface - > < property name = "interfaceName" value = "com. Alibaba. Middleware. The HSF. Guide. API. The service. The OrderService" / > <! - [set] version of the service - > < property name = "version" value = "1.0.0" / > <! > <property name="group" value="HSF"/> <property name="generic" value="true"/> </bean>

Invocation context

Background information

The request context includes attributes related to the one-time call, such as the address of the call, the application name of the caller, timeout, and other attributes, as well as custom data passed by the user outside the parameters defined by the interface.

Sets and gets the context of this call

Com. Taobao. HSF. Util. RequestCtxUtil provide set and get the invocation context of static method, based on the ThreadLocal, getXXX XXX will be attributes from the current operation remove ThreadLocal variables, A single call to the current thread only.

Table 1. Client

The name of the describe
setRequestTimeout() Sets the timeout for a single invocation
setUserId() Set the userId of the unitary service for this invocation (you need to configure this method in the generalized invocation)
getProviderIp() Gets the IP of the [last] called server
setTargetServerIp(String ip) Sets the target server IP for the next invocation by the current thread (this IP must be included in the address list of the service provided in memory)
setDirectTargetServerIp(String targetIp) Sets the target server IP for the next call from the current thread (bypassing the registry and ignoring the in-memory address list)

Table 2. Server side

The name of the describe
getClientIp() The server gets the caller’s IP
getAppNameOfClient() The server gets the application name of the caller
isHttpRequest() HTTP call or not
getHttpHeader(String key) Gets the header property of the HTTP request

Pass the custom request context

RPCContext provides a way to pass additional data to the server without modifying the interface. The argument can be a custom DO or a primitive type. Make sure the opposite end also has the corresponding type and can be serialized.

  1. Pass the custom context development example to import the following dependencies in the Maven project you build.
<dependency>
    <groupId>com.taobao.hsf</groupId>
    <artifactId>hsf-feature-context</artifactId>
</dependency>
  1. Set the context before the client initiates the call.
RPCContext rpcContext = RPCContext.getClientContext();
rpcContext.putAttachment("tetantId", "123");
orderService.queryOrder(1L);
  1. Within the server-side business method, get the context.
RPCContext rpcContext = RPCContext.getServerContext();
String myContext = (String)rpcContext.getAttachment("tetantId");

Configuration serialization

The process of serialization is to convert Java objects into Byte arrays for transmission across the network, and deserialization converts the Byte arrays into Java objects.

Serialization mode configuration

The serialization of HSF supports Java, Hessian, Hessian2, JSON, Kyro, and Hessian2. The default is Hessian2. The comparison and configuration of these serialization methods (HSFapiProviderBean is configured only on the server side) are shown in the following table:

Serialization mode Maven rely on configuration compatibility performance
hessian2 <artifactId>hsf-io-serialize-hessian2</artifactId> setPreferSerializeType(“hessian2”) good good
java <artifactId>hsf-io-serialize-java</artifactId> setPreferSerializeType(“java”) The best general
fastjson <artifactId>hsf-io-serialize-json</artifactId> setPreferSerializeType(“json”) good good
kryo <artifactId>hsf-io-serialize-kryo</artifactId> setPreferSerializeType(“kryo”) general The best

Configure HSF services in API form

HSFApiProviderBean hsfApiProviderBean = new HSFApiProviderBean();
hsfApiProviderBean.setPreferSerializeType("hessian2");

Spring configures the HSF service

The Spring Framework is a widely used component in applications. If you don’t want to configure HSF services via an API, you can configure them using Spring XML. The API configuration in the above example is equivalent to the following XML configuration:

<bean class="com.taobao.hsf.app.spring.util.HSFSpringProviderBean" init-method="init"> <! - [set] publishing service interface - > < property name = "serviceInterface" value = "com. Alibaba. Middleware. The HSF. Guide. API. The service. The OrderService" / > <! The target object must be configured [ref] for the Spring bean id that needs to be published as HSF service --> <property name="target" ref=" referenced BeanId"/> <! - [set] version of the service - > < property name = "serviceVersion" value = "1.0.0" / > <! --[set] serviceGroup --> <property name="serviceGroup" value="HSF"/> <! > <property name="clientTimeout" value="3000"/> <! PreferSerializeType ="preferSerializeType" value="hessian2"/> </bean>

timeout

Background information

All requests for network calls need to be timed out. The default timeout for HSF is 3000ms. Both the client and the server can set the timeout. By default, the client’s configuration is preferred. If the client is not configured, the server’s timeout configuration is used. When setting the timeout on the server side, it needs to take into account the execution time of the service itself, plus the time of serialization and network communication. Therefore, it is recommended that the server configure a default time for each service. Of course, the client can also configure the timeout according to its own business scenarios. For example, some front-end applications need users to see the results quickly, so the timeout can be set a little smaller.

Client timeout configuration

There are two ways to configure client timeouts:

  • HSF service configuration API form, configure HSFapIconumerBean ClientTimeout property, the unit is ms, we set the interface timeout is 1000ms, the queryOrder method is 100ms, the code is as follows:
HSFApiConsumerBean consumerBean = new HSFApiConsumerBean(); / / interface level timeout configuration consumerBean. SetClientTimeout (1000); //xxx MethodSpecial methodSpecial = new MethodSpecial(); methodSpecial.setMethodName("queryOrder"); / / the method level timeout configuration, prior to the interface configuration methodSpecial. Overtime setClientTimeout (100); consumerBean.setMethodSpecials(new MethodSpecial[]{methodSpecial});
  • Spring configures HSF services. The API configuration in the example above is equivalent to the following XML configuration:
<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>

Server timeout configuration

There are also two different ways to configure server-side timeouts:

  • HSF service configuration API form, configure HSFapiProviderBean ClientTimeout property, the unit is ms, code is as follows:
HSFApiProviderBean providerBean = new HSFApiProviderBean(); / / interface level timeout configuration providerBean. SetClientTimeout (1000); //xxx MethodSpecial methodSpecial = new MethodSpecial(); methodSpecial.setMethodName("queryOrder"); / / the method level timeout configuration, prior to the interface configuration methodSpecial. Overtime setClientTimeout (100); providerBean.setMethodSpecials(new MethodSpecial[]{methodSpecial});
  • Spring configures HSF services. The API configuration in the example above is equivalent to the following XML configuration:
<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>

Server-side thread pool configuration

HSF server thread pool is mainly divided into IO thread and business thread, in which the IO thread model is used in the Netty Reactor network model.

Default thread pool configuration

The server thread pool is used to execute business logic. The default core size of the thread pool is 50, the Max size is 720, and keepAliveTime is 500s. Queues use a synchronousQueue, there is no cache queue, and user requests do not pile up. When all the threads in the server Thread pool (720) are processing the request, the new request is rejected immediately and the Thread Pool is Full exception is returned. This can be configured using the following VM parameter (-D parameter).

  • Thread pool minimum configuration: -dhsf.server.min.poolSize
  • Maximum configuration for thread pool: -dhsf.server.max.poolsize
  • Thread the survival time of convergence: – Dhsf. Server thread. Keepalive.

Service thread pool configuration

For slow services with high concurrency, you can configure the thread pool separately to avoid consuming too many business threads and affecting the invocation of other services in your application. You can configure HSF applications in one of two ways:

  • Configuring HSF applications in API form:
HSFApiProviderBean hsfApiProviderBean = new HSFApiProviderBean(); / /... hsfApiProviderBean.setCorePoolSize("50"); hsfApiProviderBean.setMaxPoolSize("200");
  • Spring configuration HSF application:
<bean class="com.taobao.hsf.app.spring.util.HSFSpringProviderBean" init-method="init"> <! - [set] publishing service interface - > < property name = "serviceInterface" value = "com. Alibaba. Middleware. The HSF. Guide. API. The service. The OrderService" / > <property name="corePoolSize" value="50" /> <property name="maxPoolSize" value="200" /> </bean>

Pandora Boot development process

Development process node:

  1. Service Interface: Pandora Boot’s service is based on an interface implementation that needs to be pre-defined and designed at service design time. Producers will implement this interface to provide concrete implementations to provide services, and consumers will subscribe to this interface as a service.
  2. Service Producer: The producer will implement the previously defined service interface to provide the implementation, in addition to the work of the code implementation, so it needs to redefine the annotation @HSFProvider configuration for the service publication as the service provider.
  3. Service consumer: The consumer uses the service based on the interface. There are two steps for the specific invocation:
    1. Spring’s configuration file defines a Bean using tags.
    2. Remove the Bean from Spring’s context when in use.

Develop the Pandora Boot application

Build Pandora Boot Maven project

  1. Build the Maven project. After creating the Maven project, configure the private server address of EDAS and the plug-in private server address in the pom. XML file.
<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>
  1. Build the Maven project. After creating the Maven project, define the version to add Pandora Boot and Spring Boot dependencies in the pom.xml file.
< the properties > < spring - the boot. Version > 2.1.6. RELEASE < / spring - the 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>
  1. Add Pandora Boot and Spring Boot development dependencies to pom.xml.
<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 > < the dependency > < the groupId > IO. Springfox < / groupId > < artifactId > springfox - swagger2 < / artifactId > < version > 2.6.1 < / version > < / dependency > </dependencies>
  1. Add the Maven packaging plug-in for the Pandora Boot application to the pom.xml file.
<build> <plugins> <plugin> <groupId>com.taobao.pandora</groupId> <artifactId>pandora-boot-maven-plugin</artifactId> The < version > 2.1.11.8 < / version > < executions > < execution > < phase > package < / phase > < goals > < goal > repackage < / goal > < / goals > </execution> </executions> </plugin> </plugins> </build>
  1. Configure the application name and listening port number in the application.properties file under the project directory Resources.
Spring. The application. The name = HSF - the provider for server port = 8082 spring. (HSF) version = 1.0.0 spring. The HSF. Timeout = 1000
  1. Add the main function entry for service startup.
@SpringBootApplication public class HSFProviderApplication {public static void main(String[] args) {// Pandora Boot Pandora container pandorabootstrap.run (args); SpringApplication.run(HSFProviderApplication.class, args); // Marks that the service has started and sets the thread wait. Prevent the container from exiting after the user's business code has finished running. PandoraBootstrap.markStartupAndWait(); }}

Write the Pandora Boot service provider

  1. For the service provider, the creation process is the same as the above steps to build the Pandora Boot Maven project, and the service interface EchoService needs to be defined to provide consumer subscriptions.
public interface EchoService {
    String echo(String string);
    String echoFuture(String str);
    String echoCallback(String str);
    String echoHSFMix(int id);
    String echoMQConsumer(String str);
}
  1. Create a concrete implementation class for the service provider, EchoServiceImpl, and publish the service as an annotation.
@HSFProvider(serviceInterface = EchoService.class, serviceGroup = "HSF", ServiceVersion = "1.0.0") public class EchoServiceImpl implements EchoService {@Autowired private 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) {// Produce SimpleMQ.sendMsg (id+""); return echoDao.findById(id).getUserName(); } public String echomQConsumer (String STR) {// Subscribe the message simplemQConsumer. Receive (); return str; }}

Write the Pandora Boot consumer service

  1. For the service consumer, the creation process is the same as the above steps to build the Pandora Boot Maven project, adding the interface defined by the service provider and copying it to the consumer service project.
public interface EchoService {
    String echo(String string);
    String echoFuture(String str);
    String echoCallback(String str);
    String echoHSFMix(int id);
    String echoMQConsumer(String str);
}
  1. Add consumer service configuration classes and business logic code.
Consumer service configuration class: @Configuration public class HSFConfig {// Injects an instance of the service consumer into the Spring Context using an annotation and calls @HSFConsumer(ClientTimeout = 3000, ServiceVersion = "1.0.0") private EchoService EchoService; } The consumer service implementation calls the HSF service provider: @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 = "fetch server return information a-> C") @RequestMapping(value = "/ HSF-echo ", method = RequestMethod.GET) public String echo(@RequestParam("str") String str) { return echoService.echo(str) + "\r\n";  } @apiOperation (value = "query database by ID for return information, rocketMQ writes information 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 subscription message 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 = "fetch version information ") @requestMapping (value = "/echo-version"), method = RequestMethod.GET) public String echoVersion() { return "This is pandora boot version 2" + "\r\n"; }}

Develop Pandora Boot asynchronous calls

For the client, not all HSF services need to wait for the server to return the result synchronously. For these scenarios, HSF provides a way to call asynchronously so that the client does not have to block on the HSF operation synchronously. An asynchronous call is made to the HSF service, and the result of the call is the default value returned. The actual result is retrieved either in HSFResponseFuture or in the callback function.

Futrue asynchronous call

  1. For the service provider, its creation process is consistent with the above steps to build the Pandora Boot Maven project. It needs to define the service interface EchoService to provide consumer subscription, and add the interface and implementation class for Future asynchronous invocation in EchoService.
public interface EchoService { String echoFuture(String str); } Interface implementation class:  @HSFProvider(serviceInterface = EchoService.class, serviceGroup = "HSF", ServiceVersion = "1.0.0") public class EchoServiceImpl implements EchoService {public String EchoForure (String STR) { return "welcome --" + str; }}
  1. For the service consumer, the creation process is the same as the above steps to build the Pandora Boot Maven project, and the Future asynchronous invocation code is written.
Configure HSF interface methods in the configuration class via annotations for asynchronous calls: //Future asynchronously calls @hsfConsumer (ServiceGroup = "HSF", ServiceVision = "1.0.0", futureMethods = "echoFuture") private EchoService echoService; Write Future asynchronous call code to expose the request to the outside:  @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); // Get the Future object in the context of the current call; Since the object is placed in a ThreadLocal, the Future object will be overwritten by subsequent calls in the same thread, so it should be fetched in time. HSFFuture hsfFuture = HSFResponseFuture.getFuture(); Try {System.out.println(HSFuture.getResponse (5000)); try {System.out.println(HSFuture.getResponse (5000)); } catch (Throwable throwable) { throwable.printStackTrace(); } return resp; }

Asynchronous Callback

  1. For the service provider, its creation process is the same as the above construction of Pandora Boot Maven. It needs to define the service interface EchoService to provide consumer subscription, and add the interface and implementation class of the asynchronous call Callback in EchoService.
public interface EchoService { String echoFuture(String str); } Interface implementation class:  @HSFProvider(serviceInterface = EchoService.class, serviceGroup = "HSF", ServiceVersion = "1.0.0") public class EchoServiceImpl implements EchoService {public String EchoForure (String STR) { return "welcome --" + str; }}
  1. For the service consumer, the creation process is the same as the above steps to build Pandora Boot Maven, and the Future asynchronous invocation code is written.
The annotation configures the HSF interface method as a callback call:  @AsyncOn(interfaceName = EchoService.class, methodName = "echoCallback") public class CallbackHandler implements HSFResponseCallback { public void onAppException(Throwable t) { t.printStackTrace(); } public void onapResponse (Object result) {return callback;} public void onapResponse (Object result) CallbackInvocationContext.getContext(); System.out.println(result.toString()); System.out.println(context); } public void onHSFException(HSFException e) { e.printStackTrace(); }} write asynchronous Callback code that exposes the request to the outside world:  @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; }

Develop Pandora Boot timeout Settings

Background information

HSF services are configured with annotations, SpringBoot is widely used today, and using annotations to assemble Spring beans is an option. HSF also supports configuring with annotations for subscribing to services.

Client annotation timeout configuration

  1. First add the dependency Starter to the Maven project’s pom.xml file:
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>pandora-hsf-spring-boot-starter</artifactId>
</dependency>
  1. Usually an HSFConsumer needs to be used in more than one place, but it does not need to be marked with @HSFConsumer every time it is used. All you need to do is write a single Config class, and then inject it wherever necessary by @Autowired. The API configuration in the example above is equivalent to the following annotation configuration:
@HSFConsumer(clientTimeout = 1000, methodSpecials =
@HSFConsumer.ConsumerMethodSpecial(methodName = "queryOrder", clientTimeout = "100"))
private OderService orderService;

Server-side annotation timeout configuration

  1. First add the dependency Starter to the Maven project’s pom.xml file:
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>pandora-hsf-spring-boot-starter</artifactId>
</dependency>
  1. Configure HSF service timeout setting with server-side annotations:
@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); }}

Develop the Pandora Boot service thread pool configuration

Background information

HSF services are configured with annotations, SpringBoot is widely used today, and assembling Springbeans with annotations is an option. HSF also supports configuring with annotations for subscribing to services.

  1. Begin by adding a dependency Starter to the Maven project’s pom.xml file.
<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>pandora-hsf-spring-boot-starter</artifactId>
</dependency>
  1. Configure @HSFProvider to the type of implementation. The API configuration in the example above is equivalent to the following annotation configuration.
@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); }}

We are AliCloud Intelligence Global Technical Serving -SRE team. We are committed to becoming a technology-based, service-oriented engineering team to ensure the high availability of business systems. Provide professional and systematic SRE services to help customers make better use of the cloud, build a more stable and reliable business system based on the cloud, and improve business stability. We are looking forward to sharing more technologies to help enterprise customers get on the cloud and use the cloud well, so that customers can run more stable and reliable business on the cloud. You can scan the QR code below, join the circle of Ali Cloud SRE Technical College, and communicate with more people about the cloud platform.

Copyright Notice:The content of this article is contributed by Aliyun real-name registered users, and the copyright belongs to the original author. Aliyun developer community does not own the copyright and does not bear the corresponding legal liability. For specific rules, please refer to User Service Agreement of Alibaba Cloud Developer Community and Guidance on Intellectual Property Protection of Alibaba Cloud Developer Community. If you find any suspected plagiarism in the community, fill in the infringement complaint form to report, once verified, the community will immediately delete the suspected infringing content.