When multiple Spring Cloud microservices need to discover and call each other, a centralized service registry eliminates hardcoded endpoints and enables dynamic routing. Microservices Engine (MSE) provides a managed Nacos registry that handles service discovery and configuration management -- you configure the registry endpoint in your application, and it registers automatically on startup.
This guide walks through building a provider and a consumer, registering both with an MSE Nacos registry, and verifying end-to-end service calls.
Prerequisites
Before you begin, make sure that you have:
Maven installed with environment variables configured
An MSE Nacos instance. See Create an instance.
A namespace. See Create a namespace. This guide uses the default
Publicnamespace.
If you access the MSE Nacos registry over the Internet, both the provider and consumer must have Internet access. Add their public IP addresses to the registry's whitelist. See Configure a public IP address whitelist.
Step 1: Build the provider
Create a Spring Cloud application that exposes a REST endpoint and registers with the MSE Nacos registry as a service provider.
1. Create a Maven project
Create a Maven project named nacos-service-provider.
2. Add dependencies
Add the following to the pom.xml file. This example uses Spring Boot 2.1.4.RELEASE with Spring Cloud Greenwich.SR1.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!-- Nacos service discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>The Spring Cloud Alibaba version must match the Spring Cloud release:
| Spring Cloud version | Spring Cloud Alibaba version | Status |
|---|---|---|
| Greenwich | 2.1.1.RELEASE | Active |
| Finchley | 2.0.1.RELEASE | Active |
| Edgware | 1.5.1.RELEASE | Discontinued |
Spring Cloud Edgware is discontinued. Do not use it for new applications.
3. Create the application class
Create a package named com.aliware.edas under src/main/java. Add the following class named ProviderApplication.
The @EnableDiscoveryClient annotation enables service registration and discovery.
package com.aliware.edas;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}4. Create a REST controller
In the same com.aliware.edas package, create a class named EchoController that maps GET requests to /echo/{string} and returns the path variable.
package com.aliware.edas;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EchoController {
@RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
public String echo(@PathVariable String string) {
return string;
}
}5. Configure the Nacos registry endpoint
Create a file named application.properties under src/main/resources:
spring.application.name=service-provider
server.port=18081
spring.cloud.nacos.discovery.server-addr=mse.XX.nacos.mse.aliyuncs.com:8848
# To use a custom namespace, uncomment the following line:
# spring.cloud.nacos.discovery.namespace=<namespace-id>Replace mse.XX.nacos.mse.aliyuncs.com with your MSE Nacos instance's public endpoint. To find this value, open the MSE console, navigate to Microservices Registry > Instances, and locate the endpoint on the instance details page.
If you use an MSE ZooKeeper or Eureka registry instead of Nacos, replace the registry configuration accordingly. See Usage notes.
6. Verify provider registration
Run the
mainmethod of ProviderApplication to start the provider.Log in to the MSE console and select a region in the top navigation bar.
In the left-side navigation pane, choose Microservices Registry > Instances. Click the instance name.
Choose Service Management > Services.
On the Services page, confirm that
service-provideris listed.
Step 2: Build the consumer
Create a Spring Cloud application that calls the provider using RestTemplate and FeignClient, and registers with the same MSE Nacos registry.
1. Create a Maven project
Create a Maven project named nacos-service-consumer.
2. Add dependencies
Add the following to the pom.xml file. Compared to the provider, the consumer adds spring-cloud-starter-openfeign for declarative REST calls.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!-- Nacos service discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Declarative REST client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>3. Create the FeignClient interface
Create a package named com.aliware.edas under src/main/java. Add an interface named EchoService with the @FeignClient annotation pointing to service-provider.
package com.aliware.edas;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(name = "service-provider")
public interface EchoService {
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
String echo(@PathVariable("str") String str);
}4. Create the application class
In the same package, create a class named ConsumerApplication with the following annotations:
@EnableDiscoveryClient-- enables service registration and discovery@EnableFeignClients-- enables FeignClient@LoadBalancedon theRestTemplatebean -- integrates RestTemplate with service discovery for client-side load balancing
package com.aliware.edas;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}5. Create a test controller
In the same package, create a class named TestController that exposes two endpoints -- one using RestTemplate and one using FeignClient -- to demonstrate both service discovery methods.
package com.aliware.edas;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@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-feign/{str}", method = RequestMethod.GET)
public String feign(@PathVariable String str) {
return echoService.echo(str);
}
}6. Configure the Nacos registry endpoint
Create a file named application.properties under src/main/resources:
spring.application.name=service-consumer
server.port=18082
spring.cloud.nacos.discovery.server-addr=mse.XX.nacos.mse.aliyuncs.com:8848
# To use a custom namespace, uncomment the following line:
# spring.cloud.nacos.discovery.namespace=<namespace-id>Replace mse.XX.nacos.mse.aliyuncs.com with your MSE Nacos instance's public endpoint, as described in Step 1, sub-step 5.
If you use an MSE ZooKeeper or Eureka registry instead of Nacos, replace the registry configuration accordingly. See Usage notes.
7. Verify consumer registration
Run the
mainmethod of ConsumerApplication to start the consumer.Log in to the MSE console and select a region in the top navigation bar.
In the left-side navigation pane, choose Microservices Registry > Instances. Click the instance name.
Choose Service Management > Services.
On the Services page, confirm that
service-consumeris listed.
Step 3: Test service calls
With both applications running, verify that the consumer can discover and call the provider.
Linux, UNIX, or macOS:
curl http://127.0.0.1:18082/echo-rest/rest-rest
curl http://127.0.0.1:18082/echo-feign/feign-restWindows: Open a browser and navigate to the following URLs:
http://127.0.0.1:18082/echo-rest/rest-resthttp://127.0.0.1:18082/echo-feign/feign-rest
Expected output for the RestTemplate endpoint:
rest-restExpected output for the FeignClient endpoint:
feign-restIf both responses match, the consumer has discovered and called the provider through the MSE Nacos registry.
FAQ
Services do not appear in the MSE console after registration
By default, the public IP address whitelist is set to 127.0.0.1/32, which blocks all external access. Add the public IP addresses of your provider and consumer machines to the whitelist. See Configure a public IP address whitelist.
Which Spring Cloud versions does MSE support?
| Spring Cloud version | Spring Cloud Alibaba version | Status |
|---|---|---|
| Greenwich | 2.1.1.RELEASE | Active |
| Finchley | 2.0.1.RELEASE | Active |
| Edgware | 1.5.1.RELEASE | Discontinued |
Spring Cloud Edgware is discontinued. Do not use it for new applications.