Parent project
Create a maven project l-cloud-alibaba, delete the src directory and modify POM The XML content is as follows:
<?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.codelong</groupId> <artifactId>l-cloud-alibaba</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <modules> <!-- Common module--> <module>cloud-common</module> <module>cloud-nacos-register</module> <module>cloud-nacos-consumer</module> </modules> <properties> <java.version>1.8</java.version> <encoding>UTF-8</encoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <!-- Third party dependent version--> <lombok.version>1.18.20</lombok.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- Third party dependent version--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
In order to facilitate me to put some public dependencies and code, we create a cloud common module, POM The XML content is as follows:
<?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> <parent> <artifactId>l-cloud-alibaba</artifactId> <groupId>com.codelong</groupId> <version>1.0.0</version> </parent> <packaging>jar</packaging> <artifactId>cloud-common</artifactId> <name>common</name> <description>Common module</description> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> </dependencies> </project>
Then on COM codelong. Create a result. Under the base package Java and codeandmsg Java represents unified response content encapsulation and status code encapsulation respectively
Result.java
import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.io.Serializable; /** * Responder encapsulation * * @param <T> * @author codelong * @since 1.0 */ @JsonInclude(JsonInclude.Include.NON_NULL) @Slf4j @Data public class Result<T> implements Serializable { /** * Status code */ private int status; /** * news */ private String message; /** * data */ private T data; private boolean success; private long timestamp; public Result() { this.timestamp = System.currentTimeMillis(); } private Result(int status, String message, boolean success) { this(); this.status = status; this.message = message; this.success = success; } private Result(int status, String message, boolean success, T data) { this(status, message, success); this.data = data; } private Result(CodeAndMsg codeAndMsg, boolean success) { this(); this.status = codeAndMsg.getCode(); this.message = codeAndMsg.getMessage(); this.success = success; } private Result(CodeAndMsg codeAndMsg, boolean success, T data) { this(codeAndMsg, success); this.data = data; } /** * Create a successful response */ public static <T> Result<T> success(int status, String message) { return new Result<T>(status, message, true); } public static <T> Result<T> success(CodeAndMsg codeAndMsg) { return new Result<T>(codeAndMsg, true); } public static <T> Result<T> success(int status, String message, T data) { return new Result<T>(status, message, true, data); } public static <T> Result<T> success(CodeAndMsg codeAndMsg, T data) { return new Result<T>(codeAndMsg, true, data); } /** * Create failed response */ public static <T> Result<T> fail(int status, String message) { return new Result<T>(status, message, false); } public static <T> Result<T> fail(CodeAndMsg codeAndMsg) { return new Result<T>(codeAndMsg, false); } }
CodeAndMsg.java
/** * Status code set * * @author codelong * @since 1.0 */ public enum CodeAndMsg { /** * Operation successful **/ RC100(100, "Request succeeded"), /** * operation failed **/ RC999(999, "operation failed"), /** * Service current limiting **/ RC200(200, "Service open current limiting protection,Please try again later!"), /** * service degradation **/ RC201(201, "Service enable degradation protection,Please try again later!"), /** * Hot spot parameter current limiting **/ RC202(202, "Hot spot parameter current limiting,Please try again later!"), /** * System rules are not met **/ RC203(203, "System rules do not meet requirements,Please try again later!"), /** * Authorization rule failed **/ RC204(204, "Authorization rule failed,Please try again later!"), /** * access_denied **/ RC403(403, "Exception when anonymous users access resources without permission"), /** * access_denied **/ RC401(401, "Exception when an authenticated user accesses an unauthorized resource"); /** * Custom status code **/ private final int code; /** * Custom description **/ private final String message; CodeAndMsg(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } }
Create microservices
Here, we use cloud Nacos register and cloud Nacos consumer to simulate the invocation between microservices.
Create cloud Nacos register micro service
Create a sub module cloud Nacos register under the parent module.
pom. The XML content is as follows:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>l-cloud-alibaba</artifactId> <groupId>com.codelong</groupId> <version>1.0.0</version> </parent> <artifactId>cloud-nacos-register</artifactId> <name>register-service</name> <description>Service provider</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Then create a RegisterController class under the controller package and provide an interface for consumers to call. The contents of RegisterController are as follows:
import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("provider") public class RegisterController { @Value("${server.port}") String port; @GetMapping("{message}") public String hello(@PathVariable String message) { return String.format("%s from %s", message, port); } }
Modify application YML file, as follows:
server: port: 8001 # Service port number spring: application: name: provider-service # Service name, which is also the micro service ID registered in the micro service by default cloud: nacos: server-addr: 127.0.0.1:8848 # Specify the address of the Nacos registry username: nacos # The user name of the nacos server. The default is nacos password: nacos # The password of the nacos server. The default is nacos
Create cloud Nacos consumer micro service
Create a sub module cloud Nacos consumer under the parent module.
pom. The XML content is as follows:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>l-cloud-alibaba</artifactId> <groupId>com.codelong</groupId> <version>1.0.0</version> </parent> <artifactId>cloud-nacos-register</artifactId> <name>register-service</name> <description>Service provider</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Then create a RegisterController class under the controller package and provide an interface for consumers to call. The contents of RegisterController are as follows:
import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("provider") public class RegisterController { @Value("${server.port}") String port; @GetMapping("{message}") public String hello(@PathVariable String message) { return String.format("%s from %s", message, port); } }
Modify application YML file, as follows:
server: port: 8001 # Service port number spring: application: name: provider-service # Service name, which is also the micro service ID registered in the micro service by default cloud: nacos: server-addr: 127.0.0.1:8848 # Specify the address of the Nacos registry username: nacos # The user name of the nacos server. The default is nacos password: nacos # The password of the nacos server. The default is nacos
Create cloud Nacos consumer micro service
Create a sub module cloud Nacos consumer under the parent module.
pom. The XML content is as follows:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>l-cloud-alibaba</artifactId> <groupId>com.codelong</groupId> <version>1.0.0</version> </parent> <artifactId>cloud-nacos-consumer</artifactId> <name>consumer-service</name> <description>Serving consumers</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Then create a ConsumerController class under the controller package and provide an interface to call the above services. The contents of ConsumerController are as follows:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("consumer") public class ConsumerController { @Resource private RestTemplate restTemplate; @GetMapping("/{message}") public String hello(@PathVariable String message) { // Key point: replace the original IP: port with the service name, and RestTemplate will automatically use the Ribbon to query the list of available provider service instances before communication // Then select the node instance according to the load balancing strategy return restTemplate.getForObject(String.format("http://provider-service/provider/%s", message), String.class); } }
Then create a ConsumerConfigure configuration class under the configure package, inject RestTemplate and add @ LoadBalanced annotation to support Ribbon load balancing:
import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ConsumerConfigure { @Bean @LoadBalanced // Enables RestTemplate objects to automatically support Ribbon load balancing public RestTemplate restTemplate() { return new RestTemplate(); } }
Modify application YML file, as follows:
server: port: 9001 # Service port number spring: application: name: consumer-service # Service name, which is also the micro service ID registered in the micro service by default cloud: nacos: server-addr: 127.0.0.1:8848 # Specify the address of the Nacos registry username: nacos # The user name of the nacos server. The default is nacos password: nacos # The password of the nacos server. The default is nacos logging: level: root: debug # For the convenience of reading the log, it is only opened during development, not officially
Setting logging to debug level here is to make it easy to see the log of load balancing calls.
The final project structure is as follows
Start providers and consumers
Start the cloud Nacos register and cloud Nacos consumer projects respectively
Log in to the Nacos console to view the list of services:
You can see that both services are registered. Then visit the browser: http://localhost:9001/consumer/nacos :
If the call is successful, the service discovery is successful.
Test load balancing
As shown in the figure below, right-click ProviderApplication and select Copy Configuration
Then fill in the relevant contents as shown in the figure below:
Then start the service you just copied
Log in to the Nacos console and check the service list. It is found that there are two instances of the provider
Then visit many times: http://localhost:9001/consumer/nacos , you can see that the requests are balanced (the default is polling algorithm):
Nacos registry configuration
Configuration item | Key | Default value | explain |
---|---|---|---|
Server address | spring.cloud.nacos.discovery.server-addr | The IP and port of the Nacos server listener | |
Service name | spring.cloud.nacos.discovery.service | ${spring.application.name} | Current service name |
Service grouping | spring.cloud.nacos.discovery.group | Set the group in which the service is located | |
weight | spring.cloud.nacos.discovery.weight | 1 | Value range: 1 to 100. The higher the value, the greater the weight |
adapter name | spring.cloud.nacos.discovery.network-interface | If no IP address is specified, the registered IP address is the IP address of the network card. If it is not specified, the IP address of the first network card will be used by default. | |
Registered IP address | spring.cloud.nacos.discovery.ip | Highest priority | |
Registered port | spring.cloud.nacos.discovery.port | -1 | By default, it is not configured and will be detected automatically |
Namespace | spring.cloud.nacos.discovery.namespace | One of the common scenarios is the separation and isolation of registrations in different environments, such as the isolation of resources (such as configuration and service) between development and test environments and production environments. | |
AccessKey | spring.cloud.nacos.discovery.access-key | When going to alicloud, a cloud account name on alicloud | |
SecretKey | spring.cloud.nacos.discovery.secret-key | When you want to go to alicloud, you need a cloud account password on alicloud | |
Metadata | spring.cloud.nacos.discovery.metadata | Using Map format configuration, users can customize some metadata information related to services according to their own needs | |
Log file name | spring.cloud.nacos.discovery.log-name | ||
Cluster name | spring.cloud.nacos.discovery.cluster-name | DEFAULT | Configured as Nacos cluster name |
Access point | spring.cloud.nacos.discovery.endpoint | The entry domain name of a service in the region. Through this domain name, you can dynamically get the server address | |
Is Ribbon integrated | ribbon.nacos.enabled | true | Generally, it can be set to true |
Enable the Nacos Watch | spring.cloud.nacos.discovery.watch.enabled | true | You can set it to false to turn off the watch |
At the end of the article, the author sorted out a lot of materials for you! Including Java core knowledge points + a full set of architect learning materials and videos + first-line large factory interview classic + interview resume template + java architecture practical e-book and so on!
All free to share with you, if you need friends Just download it here , verification code: csdn