preface
The quickest way to learn a technical framework is to integrate it into a project and experience its capabilities. And in the process, you step in a lot of holes. And the process of pit drainage is another enhancement of ability.
We’ve written a series of articles on Nacos, and with the introduction of “Learning Nacos? Let’s Get it Up and running,” we’ve already got Nacos Server up and running.
In this article, we will learn how to integrate Nacos into the Spring Cloud project and demonstrate two forms of invocation between nacOS-based microservices.
Integration and Versioning
To demonstrate this example, you first need to run the Nacos Server. Two microservices are built at the same time: the Provider and the Consumer. Verification is then performed by calling the two services together with looking at the registration information in Nacos Server.
As we know, Nacos is part of the Spring Cloud Alibaba family of components. So, one thing to keep in mind before you integrate is to make sure that the Spring Cloud, Spring Boot, and Spring Cloud Alibaba versions are consistent. Otherwise, something strange happens.
Release information can be found at spring. IO /projects/sp…
Here, the version of Spring Boot is 2.4.2, Spring Cloud uses 2020.0.0 and Spring Cloud Alibaba uses 2021.1. If you are using other versions, be sure to make comparisons.
Nacos service provider
Depend on the configuration
Create project Spring-cloud-alibaba-nacos-provider1, add version limit to define dependency in POM file:
< properties > < Java version > 1.8 < / Java version > < spring - the boot. Version > 2.4.2 < / spring - the boot. Version > < spring - cloud version > 2020.0.0 < / spring - cloud. Version > < cloud - alibaba. Version > 2021.1 < / cloud - alibaba. Version > </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>Copy the code
Then add the dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
Copy the code
In the operating system, the use of the actuator is a health check package, and the use of nacos-Discovery is a service discovery package.
The configuration file
Provider add configuration (application.yml)
Server: port: 8081 Spring: Application: name: user-service-provider Cloud: nacos: Discovery: server-addr: 127.0.0.1:8848Copy the code
The default IP address and port number of the Nacos Server are 127.0.0.1:8848. Name is used to specify the name of the service that consumers can register to make requests.
Business code
Before writing the business code, let’s take a look at the provider’s startup class:
// Different versions, Lower versions require explicit @enableDiscoveryClient annotation // @enableDiscoveryClient @SpringBootApplication Public Class NacosProviderApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderApplication.class, args); }}Copy the code
Note in the comments section above that the @enableDiscoveryClient annotation is no longer required for this release, while a corresponding annotation is required for earlier versions.
Create a new UserController service:
@RestController @RequestMapping("/user") public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); @getMapping ("/getUserById") public UserDetail getUserById(Integer userId) {logger.info(" Query user information, userId={}", userId); UserDetail detail = new UserDetail(); if (userId == 1) { detail.setUserId(1); detail.setUsername("Tom"); } else { detail.setUserId(2); detail.setUsername("Other"); } return detail; }}Copy the code
The entity class UserDetail used is:
public class UserDetail { private Integer userId; private String username; // omit getter/setter}Copy the code
Then start the service and check Nacos Server to see that it has been successfully registered.
Nacos serves consumers
The creation of a consumer is basically the same as the creation of a provider, except that the related functions are invoked.
Gen project
Create Spring Boot project Spring-Cloud-Alibaba-nacos-consumer1, poM dependency is basically the same as provider, but need to add two dependencies on it:
<! - consumer need extra load balancing dependence - > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-loadbalancer</artifactId> </dependency> <! - based on Feign framework called - > < the dependency > < groupId > org. Springframework. Cloud < / groupId > <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>Copy the code
Loadbalancer is used for service call load balancing. If you do not add this dependency, the following will occur during the call:
java.net.UnknownHostException: User - the provider at java.net.AbstractPlainSocketImpl.connect (AbstractPlainSocketImpl. Java: 196) ~ [na: 1.8.0 comes with _271] the at Java.net.SocksSocketImpl.connect SocksSocketImpl. Java: (394) ~ [na: 1.8.0 comes with _271] at java.net.Socket.connect (606) Socket. Java: ~ [na: 1.8.0 comes with _271] at java.net.Socket.connect (Socket. Java: 555) ~ [na: 1.8.0 comes with _271]Copy the code
Openfeign is used to implement microservice invocation based on feIGN framework, that is, to make the invocation between services more convenient. This framework is optional, and you don’t need its dependency if you want to make calls based on RestTemplate.
The configuration file
Consumer add Configuration (application.yml) :
spring: application: name: user-service-consumer cloud: nacos: discovery: server-addr: 127.0.0.1:8848 # Name of the microservice that the consumer is going to access (the microservice provider that successfully registered with nacOS) service-URL: nacos-user-service: http://user-service-providerCopy the code
Likewise, server-addr specifies the address and port to register Nacos Server. The service-URL defined in the configuration uses the service name of the service provider user-service-provider.
Business code
With regard to the annotation on the startup class, as with the provider, the @enableDiscoveryClient annotation depends on the version being used.
Create a UserController:
@RestController
@RequestMapping("/order")
public class UserController {
@Resource
private UserFeignService userFeignService;
@Resource
private RestTemplate restTemplate;
@Value("${service-url.nacos-user-service}")
private String userProvider;
@GetMapping("getUserInfo")
public UserDetail getUserInfo() {
int userId = 1;
ResponseEntity<UserDetail> result = restTemplate.getForEntity(userProvider + "/user/getUserById?userId=" + userId, UserDetail.class);
return result.getBody();
}
@GetMapping("getUserInfo1")
public UserDetail getUserInfoByFeign() {
return userFeignService.getUserById(2);
}
}
Copy the code
Two types of requests are shown in the code above, where the injected RestTemplate and getUserInfo methods are a group, and the injected UserFeignService and getUserInfoByFeign methods are a group. The former is based on RestTemplate mode, while the latter is based on Feign framework pattern.
RestTemplate: instantiate RestTemplate
@Configuration public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }}Copy the code
Note that the @loadBalanced annotation is used, and the RestTemplateCustomizer adds an interceptor to the RestTemplate marked @loadBalance, The interceptor transforms the request URI to determine which ServiceInstance ServiceInstance should be requested. If this annotation is missing, the exception mentioned above is also reported.
The corresponding UserFeignService for the Feign-based pattern is as follows:
@feignClient (name = "user-service-provider") public interface UserFeignService {/** * call @param userId based on the Feign interface User ID * @return UserDetail */ @getMapping (value = "/user/getUserById") UserDetail getUserById(@requestParam Integer) userId); }Copy the code
Where @FeignClient specifies the name of the invoked microservice through the name attribute, and the methods defined below correspond to the provider’s interface.
Start the service and check the registration status of Nacos Server.
results
At this point, two URL addresses are requested locally:
http://localhost:8080/order/getUserInfo
http://localhost:8080/order/getUserInfo1
Copy the code
Access, can return the result successfully:
// getUserInfo1 {"userId": 1, "username": "Tom"}Copy the code
At this point, the Spring Cloud integration Nacos example demonstration is complete, the complete source code address: github.com/secbr/sprin… .
summary
After the above examples, we successfully integrated Nacos into the Spring Cloud. Relatively speaking, the whole process is relatively simple, in practice, the only thing you need to pay attention to is the version problem. The content and usage of Spring Cloud vary greatly with different versions. Please refer to the official documentation.
About the blogger: Author of the technology book SpringBoot Inside Technology, loves to delve into technology and writes technical articles.
Public account: “program new vision”, the blogger’s public account, welcome to follow ~
Technical exchange: Please contact the weibo user at Zhuan2quan