This article explains the following aspects:
1. Nacos service discovery principle
2. Spring cloud service collaboration process
3. Build nacos server
4. Build the nacos service discovery client
5. Data model of nacos service discovery
1. The principle of nacos service discovery
There are two microservices A and B. A calls B, so how does A call B? We can call through http request. You can also use rpc to call.
No matter what method is used, A needs to know B's address and port number. So how does A know B's address and port? As shown above:
1. When service B starts, it will register with the service discovery center and tell him what my ip and port number are? This should also be an interface call to notify the service discovery center.
2. When the service A starts, the service discovery center will also be registered, tell him, what is my ip and port number? At the same time, the service discovery center will tell me the ip and port number of the currently registered service. Pass here An interface request and parameter return can be achieved.
3. After getting the ip and port of service B, you can call service B next.
2. Spring cloud service collaboration process
We need to develop based on the spring cloud ecological environment. So, let's first understand the service writing process of spring cloud
I won't talk about registration and discovery before, as mentioned above, there are two more things here, one is Ribbon, the other is feign.
Ribbon is a load balancer, and Feign is a remote call, which automatically makes http requests.
2.1 Service load balancing - Ribbon
Client Service A needs to call instance 1 and instance 2 of ServiceB. So which instance of ServiceB should be called? To use Ribbon load balancing, it depends on what kind of algorithm is used. You can use a polling algorithm, or other algorithms, such as a weighted algorithm
There are two kinds of load balancing: server load balancing, client load balancing
-
Server-side load balancing
Maintain a list of available service instances in load balancing. When a client request comes, the load balancing server will select one from the list of available service instances to process the client request according to a certain configured rule (load balancing algorithm) , This is the server-side load balancing, such as Nginx. Load balancing is performed through nginx, the client sends the request value Nginx, and nginx uses the load balancing algorithm to select one among multiple servers for access.
-
Client load balancing
Next, the ribbon we are going to talk about belongs to client load balancing. There will be a list of service instance addresses on the ribbon client. Before sending the request, select a service instance through the load balancing algorithm, and then access it. This is the client End load balancing. That is, load balancing algorithm distribution is performed on the client.
The caller of the service can be understood as a client.
Load balancing algorithm:
You can modify the default load balancing strategy in the spring boot configuration in the following way
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">account-service.ribbon.NFLoadBalanceRuleClassName=com.netflix.loadBalancer.RandomRule</pre>
Among them: account-service: is the name of the called service. The following components are fixed.
2.2 Calling the interface between services---Feign
Feign is the call of the server http interface.
Feign can help us call httpApi more quickly and elegantly. It turns out that when we call http requests, we need to use RestTemplate, transfer domain name and port number, and make http calls. After using feign, we no longer need to use RestTemplate to simulate requests, feign The corresponding interface can be found by the service name. We don't need to splice the address + port, and provide a simple and convenient operation.
Instructions:
1. Define an interface in Service B
2. Declare the feign client
Create a new class and declare it as an interface of type FeignClient. Specify the name of the service to be called. Then specify the interface. So when calling, you can automatically find the corresponding project interface through the service name, + interface.
Three. Build nacos server
The previous section has been built here (Address: https://www.cnblogs.com/ITPower/articles/12630193.html ), at the end of the service, we built a nacos cluster
Four. Build the nacos service discovery client
Because for service discovery, many configurations are common, so we build a parent project and add all common configurations to it.
4.1 Build the parent project.
Create a maven factory and import the jar package. The pom file is as follows
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;"><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lxl.www</groupId>
<artifactId>parent-discovery</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 这是一个父类工程, 所以, 需要设置打包类型为pom -->
<packaging>pom</packaging>
<properties>
<project.build.sourceEncodding>UTF-8</project.build.sourceEncodding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 这里我们使用的是alibaba的spring cloud -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project></pre>
4.2 Create a service provider, that is, a producer.
Create a subproject under the parent project. We have to do three things
1. Modify the pom file, introduce service discovery, feign, and spring boot web
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;"><dependencies>
<!-- 引入服务发现的包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 定义接口访问, 引入spring boot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 服务之间http调用, 引入feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies></pre>
2. Add application.yml configuration file
Specify the service port number, the address of the nacos service
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">server:
port: 56010 spring:
application:** name: productor
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848** **#nacos的服务器地址**
logging:
level:
root: info
org.springframework: info</pre>
3. Define a startup class to start a new spring boot project
Need to add two introductions. One is to enable service discovery, the other is to enable feign
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">package com.lxl.www.nacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import javax.swing.*;
**@SpringBootApplication** **// 引入服务发现
@EnableDiscoveryClient
// 使用feign接口调用
@EnableFeignClients** public class ProductorApplication { public static void main(String[] args) {
SpringApplication.run(ProductorApplication.class, args);
}
}</pre>
4. Define a controller, write an interface
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">package com.lxl.www.nacos.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/productor") public class ProductorController {
@GetMapping("/service") public String service() {
System.out.println("provider invoke"); return "provider invoke";
}
}</pre>
5. Start the program and view the service registration list in nacos
The final project structure is as follows:
4.3 Create a service consumer.
The first 3 steps are the same as creating a service producer
Create a subproject under the parent project. We have to do three things
1. Modify the pom file, introduce service discovery, feign, and spring boot web
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;"><dependencies>
<!-- 引入服务发现的包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 定义接口访问, 引入spring boot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 服务之间http调用, 引入feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies></pre>
2. Add application.yml configuration file
Specify the service port number, the address of the nacos service
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">server:
port: 56010 spring:
application:
**name: consumer**
cloud:
** nacos:
discovery:
server****-addr: 127.0.0.1:8848** **#nacos的服务器地址**
logging:
level:
root: info
org.springframework: info</pre>
3. Define a startup class to start a new spring boot project
Need to add two introductions. One is to enable service discovery, the other is to enable feign
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">package com.lxl.www.nacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients; **@SpringBootApplication** **// 引入服务发现
@EnableDiscoveryClient
// 使用feign接口调用
@EnableFeignClients** public class CustomerApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args); } }</pre>
4. Productor producer remote agent definition
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">package com.lxl.www.nacos.feign.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "productor") public interface ProductorFeign {
@GetMapping("/productor/service")
String service();
}</pre>
5. Call productor's interface through feign
<pre style="color: rgb(0, 0, 0); font-family: "Courier New"; font-size: 12px; margin: 5px 8px; padding: 5px;">package com.lxl.www.nacos.controller;
import com.lxl.www.nacos.feign.client.ProductorFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/") public class ConsumerController {
@Autowired private ProductorFeign productorFeign;
@GetMapping("consumer") public String cunsumer() {
String service = productorFeign.service();
System.out.println(service); return service;
}
}</pre>
6. Start the service, check the nacos client, and call the interface test
Two question services have been registered on nacos production
At the same time call the interface, you can get the content returned by the productor.
4.4 Spring Cloud's default load balancing method-polling
We can test the load balancing strategy of the service by starting multiple services.
1. Modify the start port number of productor to a dynamic port number. The purpose is to dynamically configure the port number when starting up and start the cluster
2. Modify configuration, add dynamic port number
Set the dynamic port number in the vm options configuration to -Dport=56010, 56011. Click the copy button to add an application, and then after configuring the parameters, start two applications.
3. View the startup effect in the nacos console
We see that the productor of nacos has two service instances. Click details to view specific service instance information:
4. Call the consumer's interface, access the productor, and use the polling load balancing algorithm by default
http://localhost:56020/consumer
Five. Data model of nacos service discovery
The registration discovery of nacos is a three-layer model: service-cluster-instance. As shown below:
The outermost layer of nacos is the service. The innermost layer is multiple instances. Multiple instances form a service cluster.
5.1 Namespace
Namespaces are not only suitable for configuration management, but also for service discovery. One of the common scenarios of namespaces is the configuration isolation of different environments. For example, the isolation of development, generation, and test environment resources.
Productor started two instances, click on the details to enter, you can see that he is a cluster. There are two instances in the cluster.
5.2 Service.
Under the namespace, there are various services. For example, what we defined above is under the public namespace, and two services are defined. One is the productor and the other is the consumer.
Services have service names and instances. **When calling remotely, you need to specify the service name.**
5.3 Examples
The example is based on network protocol communication, so there must be an ip: port number
5.4 Meta information
Click on an instance in and group-->Edit, you can see the following page, you can set meta information
So what is the meta information? Each server may set its own personalized information. This is the metadata information of each server
5.5 Practical operation---Specify the namespace of the cluster as dev
Just add a namespace to the configuration.
We can also modify the name of the cluster. The default name of the cluster is DEFAULT. We will modify it to default here. In the console dev namespace, you can see that the service customer is started.