前言:之前写了在boot中集成nacos的博客,现在顺便学习一下在cloud里面集成nacos,也就有了这份笔记
一、了解nacos的概念
官网概念:
Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台 。
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
二、集成步骤
1、下载安装并启动nacos服务
下载链接:https://github.com/alibaba/nacos/releases
选择对应的版本压缩包即可
直接解压即可,可以看到如下文件
启动方法:参考官网
进入bin目录,执行,对应的命令即可
注意:-m standalone是单机模式,不加则为集群模式,这里我们选择单机模式。还有就是我win11系统用win的系统命令报错,win11是 .\startup.cmd -m standalone
启动后可以查看
2、在Spring cloud进行集成
我们通过在名为test的服务项目中调用userserver服务里面的服务来测试服务注册和远程调用
(1)创建父工程cloud
空的maven项目或者boot项目,之后我们删除工程中的其他文件,只留部分,如下
父工程pom文件
<?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>
<!-- 改为pom打包方式,可以让子工程集成,便于管理,
后面更改相关版本就不用去挨个找一个一个改了-->
<packaging>pom</packaging>
<!-- spring boot父依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 这个父组件的域id、工程名、版本-->
<groupId>ikiku.space</groupId>
<artifactId>cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 整个cloud工程的依赖版本管理-->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<mysql-connector.version>8.0.28</mysql-connector.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.18.12</lombok.version>
<velocity-engine-core.version>2.2</velocity-engine-core.version>
<spring-cloud.version>2020.0.5</spring-cloud.version>
<mybatis-plus-boot-starte.version>3.5.2</mybatis-plus-boot-starte.version>
<mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
<springfox-swagger-ui.version>2.9.2</springfox-swagger-ui.version>
<springfox-swagger2.version>2.9.2</springfox-swagger2.version>
</properties>
<!-- dependencyManagement 里只是声明依赖并不实现引入,
因此子项目需要显示的声明需要用的依赖。-->
<dependencyManagement>
<dependencies>
<!--Spring Cloud Alibaba 的版本信息-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2021.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud 的版本信息-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- swagger注解依赖-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger-ui.version}</version>
</dependency>
<!-- Spring cloud官方提供的客户端负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
(2)创建子工程(user服务–Spring boot项目)作为提供服务
pom文件
<?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>
<!-- 继承父工程的pom-->
<parent>
<groupId>ikiku.space</groupId>
<artifactId>cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>ikiku.space</groupId>
<artifactId>user_server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user_server</name>
<description>user_server</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<!-- nacos注册服务依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- spring boot核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mp的代码生成器依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus-generator.version}</version>
</dependency>
<!-- boot整合mybatis-plus的依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-boot-starte.version}</version>
</dependency>
<!-- 代码生成器的模板依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml文件配置
# 数据库连接配置
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/db2?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos服务中心的地址
application:
name: userserver #注册到服务中心的服务名称
server:
port: 8081 #端口号
controller层
package com.example.controller;
import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
* Created by IntelliJ IDEA.
*
* @Author : wlh
* @create 2023/1/17 21:06
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/get/{id}")
public User getById(@PathVariable("id") Integer id){
User user = userService.getUserById(id);
return user;
}
}
service层
接口
package com.example.service;
import com.example.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author 王先生
* @since 2023-01-18
*/
public interface UserService extends IService<User> {
User getUserById(Integer id);
}
实现类
package com.example.service.impl;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* <p>
* 服务实现类
* </p>
*
* @author 王先生
* @since 2023-01-18
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Resource
private UserMapper userMapper;
@Override
public User getUserById(Integer id) {
User user = userMapper.selectById(id);
return user;
}
}
mapper层
package com.example.mapper;
import com.example.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author 王先生
* @since 2023-01-18
*/
public interface UserMapper extends BaseMapper<User> {
}
实体类
package com.example.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author 王先生
* @since 2023-01-18
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="User对象", description="")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "账户余额")
private BigDecimal money;
}
启动类
package com.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
@SpringBootApplication // Spring boot启动注解
@EnableDiscoveryClient // 自动注册
@MapperScan("com.example.mapper") // MP的包扫描
@RefreshScope // 开启自动刷新配置管理
public class UserServerApplication {
public static void main(String[] args) {
SpringApplication.run(UserServerApplication.class, args);
}
}
启动后,查看nacos服务结果:可以看到我们的userser服务已经注册上去了
(3)创建test工程来拉取配置和远程调用服务(resttemplate)
由于用于测试,就不写其他层了,直接在controller层实现。
pom文件
<?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>
<groupId>ikiku.space</groupId>
<artifactId>cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>ikiku.space</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test_server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- nacos注册服务依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 配置管依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- spring boot核心依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mp的代码生成器依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus-generator.version}</version>
</dependency>
<!-- boot整合mybatis-plus的依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-boot-starte.version}</version>
</dependency>
<!-- 代码生成器的模板依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
yml配置文件
server:
port: 8080
spring:
application:
name: testserver
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 设置注册中心地址
controller
package com.example.controller;
import com.example.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.PropertySource;
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;
/**
* Created by IntelliJ IDEA.
*
* @Author : wlh
* @create 2023/1/18 12:34
*/
@RestController
@RequestMapping("/test2")
@RefreshScope
public class Test2 {
// 我自己注入了一个RestTemplate 对象在spring 容器中
@Autowired
private RestTemplate restTemplate;
// 调用远程user服务
@GetMapping("/get/{id}")
public User get(@PathVariable("id") Integer id){
// 格式为:http://注册到服务中心的服务名称/请求
User forObject = restTemplate.getForObject("http://userserver/user/get/" + id, User.class);
return forObject;
}
}
(4)最后的测试结果:
注册了两个服务
去postman测试是否能够远程调用:
图一发请求到test服务中返回了在user服务中的数据
图二:直接发送请求到user服务中
最后测试是正确的,这就是Spring cloud集成nacos实现服务注册、发现和调用的方法。后续还会记录集成中实现配置管理(包括配置拉取,共享等)