This topic describes how to develop RESTful applications in High-Speed Service Framework (HSF) and implement service registration and discovery. Enterprise Distributed Application Service (EDAS) supports native Spring Cloud applications. Therefore, we recommend that new users do not use HSF to develop RESTful applications.

Background information

For more information about how to develop applications in the native Spring Cloud framework, see Implement service registration and discovery.

Service registration and discovery

This topic provides a simple example on how to develop RESTful applications and implement service registration and discovery in an on-premises environment.

Download the demo source code sc-vip-server and sc-vip-client.

  1. Create a service provider.
    The service provider provides a simple echo service and registers itself with the service registry.
    1. Create a RESTful application project named sc-vip-server.
    2. Add the required dependencies to the pom.xml file.
          <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>1.5.8.RELEASE</version>
              <relativePath/>
          </parent>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-vipclient</artifactId>
                  <version>1.3</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-pandora</artifactId>
                  <version>1.3</version>
              </dependency>
          </dependencies>
      
          <dependencyManagement>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.cloud</groupId>
                      <artifactId>spring-cloud-dependencies</artifactId>
                      <version>Dalston.SR4</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
              </dependencies>
          </dependencyManagement>

      If you do not want to set parent of the project to spring-boot-starter-parent, you can add dependencyManagement and set scope=import to manage dependencies.

      <dependencyManagement>
                  <dependencies>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-dependencies</artifactId>
                          <version>1.5.8.RELEASE</version>
                          <type>pom</type>
                          <scope>import</scope>
                      </dependency>
                  </dependencies>
      </dependencyManagement>
    3. Create a service provider application, in which the @EnableDiscoveryClient annotation enables service registration and discovery for the application.
      @SpringBootApplication
          @EnableDiscoveryClient
          public class ServerApplication {
      
              public static void main(String[] args) {
                  PandoraBootstrap.run(args);
                  SpringApplication.run(ServerApplication.class, args);
                  PandoraBootstrap.markStartupAndWait();
              }
          }
    4. Create EchoController to provide a simple echo service.
      @RestController
          public class EchoController {
              @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
              public String echo(@PathVariable String string) {
                  return string;
              }
          }
    5. Configure the application name and the listener port number in the application.properties file in the resources directory.
      spring.application.name=service-provider
      server.port=18081
  2. Create a service consumer.
    In this example, a service consumer is created to call the service provider by using RestTemplate, AsyncRestTemplate, and FeignClient.
    1. Create a RESTful application project named sc-vip-client.
    2. Add the required dependencies to the pom.xml file.
      <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>1.5.8.RELEASE</version>
              <relativePath/>
          </parent>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-vipclient</artifactId>
                  <version>1.3</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-pandora</artifactId>
                  <version>1.3</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-feign</artifactId>
              </dependency>
          </dependencies>
      
          <dependencyManagement>
              <dependencies>
                  <dependency>
                      <groupId>org.springframework.cloud</groupId>
                      <artifactId>spring-cloud-dependencies</artifactId>
                      <version>Dalston.SR4</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
              </dependencies>
          </dependencyManagement>

      FeignClient is used in this example for demonstration. Compared with the service provider sc-vip-server, the pom.xml file contains the spring-cloud-starter-feign dependency.

    3. Enable service registration and discovery for sc-vip-client. This is the same as sc-vip-server. Compared with sc-vip-server, you must also add the following two annotations to use RestTemplate, AsyncRestTemplate, and FeignClient:
      • Add the @LoadBalanced annotation to combine RestTemplate and AsyncRestTemplate with the service discovery.
      • Use the @EnableFeignClients annotation to activate FeignClient.
        @SpringBootApplication
            @EnableDiscoveryClient
            @EnableFeignClients
            public class ConsumerApplication {
        
                @LoadBalanced
                @Bean
                public RestTemplate restTemplate() {
                    return new RestTemplate();
                }
        
                @LoadBalanced
                @Bean
                public AsyncRestTemplate asyncRestTemplate(){
                    return new AsyncRestTemplate();
                }
        
                public static void main(String[] args) {
                    PandoraBootstrap.run(args);
                    SpringApplication.run(ConsumerApplication.class, args);
                    PandoraBootstrap.markStartupAndWait();
                }
        
            }
    4. Configure the service name and the HTTP request of the HTTP method before you use FeignClient of EchoService. In the sc-vip-server project, set the service name to service-provider.
      @FeignClient(name = "service-provider")
          public interface EchoService {
              @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
              String echo(@PathVariable("str") String str);
          }
    5. Create a controller for call testing.
      @RestController
      public class Controller {
         @Autowired
         private RestTemplate restTemplate;
         @Autowired
         private AsyncRestTemplate asyncRestTemplate;
         @Autowired
         private  EchoService echoService;
         @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
         public String rest(@PathVariable String str) {
             return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
         }
         @RequestMapping(value = "/echo-async-rest/{str}", method = RequestMethod.GET)
         public String asyncRest(@PathVariable String str) throws Exception{
             ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.
                     getForEntity("http://service-provider/echo/"+str, String.class);
             return future.get().getBody();
         }
         @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
         public String feign(@PathVariable String str) {
             return echoService.echo(str);
         }
      }
      Code description:
      • /echo-rest/ calls the service from the service provider by using RestTemplate.
      • /echo-async-rest/ calls the service from the service provider by using AsyncRestTemplate.
      • /echo-feign/ calls the service from the service provider by using FeignClient.
    6. Configure the application name and the listener port number.
      spring.application.name=service-consumer
      server.port=18082
  3. Perform on-premises development and debugging.
    1. Start a light-weight configuration center.
      Before you perform on-premises development and debugging, start a light-weight configuration center. The light-weight configuration center provides a light-weight version of EDAS service registration and service discovery. For more information, see Start the light-weight configuration registry.
    2. Start the application.
      • Start the application in an integrated development environment (IDE)

        To start the application in an IDE, set the -Dvipserver.server.port=8080 startup parameter in VM options and start the application by calling the main method. This parameter is added only when the application is deployed in an on-premises environment and the light-weight configuration center is used. When the application is deployed to EDAS, remove this parameter. Otherwise, the application cannot be normally released or subscribed to.

        The light-weight configuration center and the application are deployed on different instances and their configurations must be added to the hosts file. For more information, see Start the light-weight configuration registry.

      • Start the application by using FatJar
        1. Add the FatJar packaging plug-in.

          To package the pandora-boot project into a FatJar package by using Maven, add the following plug-in to pom.xml. To prevent conflicts with other packaging plug-ins, do not add other plug-ins to the plugin field in build.

          <build>
              <plugin>
                  <groupId>com.taobao.pandora</groupId>
                      <artifactId>pandora-boot-maven-plugin</artifactId>
                      <version>2.1.9.1</version>
                      <executions>
                         <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                         </execution>
                       </executions>
              </plugin>
          </build>
        2. After you add the plug-in, run the mvn clean package command in the home directory of the project to create a FatJar package in the desired directory.
        3. Start the application by running the following Java command:
          java -Dvipserver.server.port=8080 -Dpandora.location=/Users/{$username}/.m2/repository/com/taobao/pandora/taobao-hsf.sar/dev-SNAPSHOT/taobao-hsf.sar-dev-SNAPSHOT.jar  -jar sc-vip-server-0.0.1-SNAPSHOT.jar
          Note The path specified in -Dpandora.location must be a full path that is placed before sc-vip-server-0.0.1-SNAPSHOT.jar.
      Start the service consumer and call the service provider. The calls are successful. Develop RESTful applications in HSF and deploy them to EDAS
  4. Troubleshoot FAQ.
    • Why am I unable to enable service discovery by using AsyncRestTemplate?

      You can enable service discovery by using AsyncRestTemplate only in Spring Cloud Dalston and later versions. For more information, see Pull requests.

    • What can I do if the FatJar packaging plug-in conflicts with other plug-ins?

      To prevent conflicts with other packaging plug-ins, do not add other plug-ins to the plugin field in build.

    • Can I add taobao-hsf.sar to a package?

      Yes, you can add taobao-hsf.sar to a package. However, we recommend that you do not add it to a package.

      You can modify pandora-boot-maven-plugin by setting excludeSar to false so that taobao-hsf.sar is automatically added to the package during packaging.
      <plugin>
          <groupId>com.taobao.pandora</groupId>
          <artifactId>pandora-boot-maven-plugin</artifactId>
          <version>2.1.9.1</version>
          <configuration>
          <excludeSar>false</excludeSar>
          </configuration>
             <executions>
                 <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                  </execution>
          </executions>
      </plugin>
      This way, the package can be started without configuring the address of pandora-boot-maven-plugin.
      java -jar  -Dvipserver.server.port=8080 sc-vip-server-0.0.1-SNAPSHOT.jar

      Restore the configuration to exclude taobao-hsf.sar before you deploy the application to EDAS.

Distributed tracing

You can modify your RESTful application in an on-premises environment and connect the application to EagleEye of EDAS to enable distributed tracing.

To reduce development costs and make development efficient, EDAS provides the EagleEye component for distributed tracing. After the EagleEye tracking point is configured in the code, you can use the distributed tracing feature of EDAS without considering log collection, analysis, and storage.

Download the demo source code service1 and service2.

Connect to EagleEye

  1. Configure the internal repository path of EDAS in Maven.
    The packages related to Pandora Boot Starter are published in the internal repository of EDAS. Therefore, you must configure the internal repository path in the settings.xml configuration file of Maven V3.x or later. For more information, see Configure the internal repository path and the light-weight configuration center of EDAS.
  2. Modify the code.
    You can connect RESTful applications to EagleEye of EDAS by performing the following steps:
    1. Add the following public settings to the pom.xml file:
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-eagleeye</artifactId>
                  <version>1.3</version>
              </dependency>
      
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-pandora</artifactId>
                  <version>1.3</version>
              </dependency>
    2. Modify the code in the main function.
      The following code shows the original content of the main function:
      public static void main(String[] args) {
          SpringApplication.run(ServerApplication.class, args);
      }
      The following code shows the main function after modification:
      public static void main(String[] args) {
          PandoraBootstrap.run(args);
          SpringApplication.run(ServerApplication.class, args);
          PandoraBootstrap.markStartupAndWait();
      }
    3. Add the FatJar packaging plug-in.
      To package the pandora-boot project into a FatJar package by using Maven, add the following plug-in to pom.xml.

      To prevent conflicts with other packaging plug-ins, do not add other plug-ins to the plugin field in build.

      <build>
          <plugins>
          <plugin>
              <groupId>com.taobao.pandora</groupId>
              <artifactId>pandora-boot-maven-plugin</artifactId>
              <version>2.1.9.1</version>
              <executions>
              <execution>
                  <phase>package</phase>
                  <goals>
                  <goal>repackage</goal>
                  </goals>
                  </execution>
              </executions>
          </plugin>
          </plugins>
      </build>

      After you complete the preceding three steps, you do not need to set up a collection and analysis system and can directly use the EDAS distributed tracing feature.

Distributed tracing example

To demonstrate how to use the distributed tracing feature, two application demos are used in this example: service1 and service2.

service1 works as an entrance and provides services for the following three demonstration scenarios:

  • /rest/ok for normal callsDistributed tracing example rest_ok
  • /rest/delay for calls that have a long delayDistributed tracing example rest_delay
  • /rest/error for calls that have exceptionsDistributed tracing example rest_error
  1. Deploy an application.
    The collection and analytics features of EagleEye are built on top of EDAS. To demonstrate how to perform trace queries, deploy service1 and service2 to EDAS first. For more information, see the following topics:
  2. View the trace information.
    To view the trace information after the applications are deployed, familiarize yourself with the corresponding methods for calling service1 in the three demonstration scenarios. You can run the curl http://{$ip:$port}/rest/ok command. You can also use tools, such as Postman, or directly call the methods in your browser. To observe the response, we recommend that you call the methods in script mode multiple times. Then, perform the following steps to view the trace information:
    • Log on to the EDAS console and find the application that you have deployed.
    • In the left-side navigation pane, choose Application Monitoring > Interface Call.
    • On the Interface Call page, view the trace information.
  3. Demonstrate on other clients.
    EagleEye implements automatic tracking for RestTemplate, AsyncRestTemplate, and FeignClient in /echo-rest/{str}, /echo-async-rest/{str}, and /echo-feign/{str} of service1. You can view the trace information in the same way after you call them.
  4. More information
    • Automatic tracking

      EagleEye of EDAS automatically tracks requests of the RestTemplate, AsyncRestTemplate, and FeignClient calls. In the future, more components will support automatic tracking.

    • AsyncRestTemplate

      AsyncRestTemplate must modify the automatic tracking configuration during the class instantiation phase. Therefore, the eagleEyeAsyncRestTemplate object must be injected to enable the distributed tracing feature. By default, this object supports service discovery.

      @Autowired
      private AsyncRestTemplate eagleEyeAsyncRestTemplate;
    • FatJar packaging plug-in

      To create the pandora-boot project as a FatJar package in Maven, add the packaging plug-in of pandora-boot-maven-plugin to pom.xml. To prevent conflicts with other packaging plug-ins, do not add other plug-ins to the plugin field in build.