Develop RESTful applications in the HSF framework and implement service registration and discovery. Because SAE now supports native Spring Cloud applications, this development method is not recommended for new users.
Background information
To learn how to develop services using the native Spring Cloud framework, see and Host Spring Cloud applications in SAE.
Service registration and discovery
This section walks you through developing a local RESTful application with service registration and discovery.
- Create a service provider.
This service provider exposes a simple echo service and registers itself with the service registry.
- Create a RESTful application project named sc-vip-server.
- 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 the project's parent to
spring-boot-starter-parent, you can add adependencyManagementsection and setscope="import"to manage the 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> - Create the service provider application. Use the @EnableDiscoveryClient annotation to enable service registration and discovery.
@SpringBootApplication @EnableDiscoveryClient public class ServerApplication { public static void main(String[] args) { PandoraBootstrap.run(args); SpringApplication.run(ServerApplication.class, args); PandoraBootstrap.markStartupAndWait(); } } - Create an 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; } } - In the application.properties file in the resources directory, configure the application name and listening port.
spring.application.name=service-provider server.port=18081
- Create a service consumer.
This example creates a service consumer that calls the service provider using RestTemplate, AsyncRestTemplate, and FeignClient.
- Create a RESTful application project named sc-vip-client.
- 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>This example uses FeignClient for demonstration. Unlike the service provider (sc-vip-server), the consumer's pom.xml file includes an additional
spring-cloud-starter-feigndependency. - To use RestTemplate, AsyncRestTemplate, and FeignClient, you must also enable service registration and discovery (as you did for sc-vip-server) and add the following two configurations.
- Add the @LoadBalanced annotation to integrate RestTemplate and AsyncRestTemplate with service discovery.
- Add 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(); } }
- Before you use the FeignClient for EchoService, you must configure the service name and map the method to the corresponding HTTP request. In the sc-vip-server project, the service name is configured as service-provider.
@FeignClient(name = "service-provider") public interface EchoService { @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET) String echo(@PathVariable("str") String str); } - Create a Controller to test the service calls.
@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); } }The code implements three endpoints for testing:/echo-rest/: Verifies the call to the service provider using RestTemplate./echo-async-rest/: Verifies the call to the service provider using AsyncRestTemplate./echo-feign/: Verifies the call to the service provider using FeignClient.
- Configure the application name and listening port.
spring.application.name=service-consumer server.port=18082
- Develop and debug locally.
- Start the lightweight configuration center.
For local development and debugging, use the lightweight configuration center. It provides a lightweight version of the server-side service registration and discovery component used by and SAE. For more information, see Start the lightweight configuration and registration center.
- Start the application.
- Start from an IDE
To start the application from your IDE, add the
-Dvipserver.server.port=8080VM option and then run the main method. Note: This parameter is required only for local development with the lightweight configuration center. You must remove this parameter when you deploy the application to or SAE. Otherwise, the application may fail to publish or subscribe to services.If the lightweight configuration center and your application are on different machines, configure host bindings. For more information, see Start the lightweight configuration and registration center.
- Start from a FatJar
- Add the FatJar packaging plug-in.
To package the pandora-boot project into a FatJar using Maven, add the following plug-in to your pom.xml file. To avoid conflicts, do not add other FatJar plug-ins to the <plugins> section of the build configuration.
<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> - After you add the plug-in, run the
mvn clean packagecommand in the project's root directory. The FatJar file is generated in thetargetdirectory. - Start the application using a 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.jarNote The path specified by-Dpandora.locationmust be an absolute path and must be placed before the-jarargument.
- Add the FatJar packaging plug-in.
Start the services and call the endpoints. The output shows that all calls are successful.→ ~ curl http://localhost:18082/echo-rest/rest-test rest-test% → ~ curl http://localhost:18082/echo-async-rest/async-rest-test async-rest-test% → ~ curl http://localhost:18082/echo-feign/feign-test feign-test% - Start from an IDE
- Start the lightweight configuration center.
- Troubleshoot common issues.
- AsyncRestTemplate cannot connect to service discovery.
Support for service discovery using AsyncRestTemplate was added in Spring Cloud Dalston. You must use this version or a later version. For more information, see this pull request.
- Conflicts with the FatJar packaging plug-in.
To avoid conflicts, do not add other FatJar plug-ins to the <plugins> section of the build configuration.
- Can I include taobao-hsf.sar in the package?
Yes, but this is not recommended.
You can modify the pandora-boot-maven-plugin configuration by settingexcludeSartofalse. This automatically includes taobao-hsf.sar in the package.<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, you can start the application without configuring the Pandora location.java -jar -Dvipserver.server.port=8080 sc-vip-server-0.0.1-SNAPSHOT.jarBefore deploying the application to or SAE, restore the default configuration to exclude the SAR package.
- AsyncRestTemplate cannot connect to service discovery.