Nacos在spring boot的使用
说明:本文章是自己在学习spring boot中使用Nacos服务注册和发现时记录的当做笔记了,有什么不对的欢迎指正。
当你来搜索spring boot中使用nacos的时候就应该知道nacos是什么了,这里就不多废话了,直接看下面的使用吧
1、服务注册:
步骤:
1、去官网安装nacos并且启动nacos service.
成功的页面如下:
进入里面的的网页可以看到如下界面:
2、建立spring boot项目引入相关依赖jar包
<!-- spring boot 核心依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!-- spring boot测试依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<!-- nacos注册依赖--><dependency><groupId>com.alibaba.boot</groupId><artifactId>nacos-discovery-spring-boot-starter</artifactId><version>0.2.12</version></dependency></dependencies>
3、使项目启动自动注册到服务中心
1、通过配置实现(更推荐,下面的案例也是写yml文件来配置)
server:port: 8081ip: localhost
spring:application:name: userserver
nacos:discovery:# 设置自动注册,默认是falseauto-register: true# nacos server的ip和端口server-addr: localhost:8848
启动项目后可以在nacos server看的如下界面,已经注册到了服务中心
2、写配置类(依然需要在配置文件中设置nacos server的ip和端口)
package com.example.config;import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;import javax.annotation.PostConstruct;/*** Created by IntelliJ IDEA.** @Author : wlh* @create 2023/1/18 18:15*/
@Configuration
public class NacosRegisterConfig {// 服务名称@Value("${spring.application.name}")private String applicationName;// 服务的端口号@Value("${server.port}")private Integer port;// 服务ip地址@Value("${server.ip}")private String ip;@NacosInjectedprivate NamingService namingService;// @PostConstruct 在依赖注入完成时执行注解的方法@PostConstructpublic void register() throws NacosException {namingService.registerInstance(applicationName,ip,port);}
}
然后在启动类上写上注解@EnableNacosDiscovery。执行后一样的可以在nacos server里面看到注册的服务。
但是需要注意的是:使用配置文件的形式在启动类上是不需要@EnableNacosDiscovery注解的,用了反而注册不上
2、服务发现和调用:
1、获取服务:
使用NamingService对象的selectOneHealthyInstance(“服务名称”);获取一个服务,参数是服务名称。这个方法的作用是根据参数获取对应的服务,如果有多个(集群时)会自己去调用一个(要不是随机的,要不是轮询调度)。
2、远程调用:
RestTemplate对象的方法能够实现远程调用
getForObject — optionsForAllow 分为一组,这类方法是常规的 Rest API(GET、POST、DELETE 等)方法调用;
exchange:接收一个 RequestEntity 参数,可以自己设置 HTTP method,URL,headers 和 body,返回 ResponseEntity;
execute:通过 callback 接口,可以对请求和返回做更加全面的自定义控制。
如下:
public UserDto queryById(Integer id) throws NacosException {User user = userMapper.selectById(id);UserDto userDto = new UserDto();userDto.setId(user.getId());userDto.setName(user.getName());userDto.setMoney(user.getMoney());// 获取服务Instance logserver = namingService.selectOneHealthyInstance("logserver");String url = String.format("http://%s:%d/userLog/queryByUserId/"+id,logserver.getIp(),logserver.getPort());// 通过restTemplate对象进行跨模块请求数据List list = restTemplate.getForObject(url, List.class);userDto.setUserLogs(list);return userDto;}
3、完整案例
需求:写两个服务,一个user服务,一个user_log服务,在user服务获取用户信息时我们需要调用user_log服务来获取对应用户的日志列表。
数据库数据准备
表1:user
表2:user_log
user服务:
引入依赖:
<groupId>ikiku.space</groupId>
<artifactId>user-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user_server</name>
<description>user_server</description>
<?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>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.1</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>
<!-- spring boot 核心依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!-- spring boot测试依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<!-- mysql驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
<!-- mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency>
<!-- mybatis代码生成器依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency>
<!-- 模板--><!-- https://mvnrepository.com/artifact/org.freemarker/freemarker --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency>
<!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
<!-- swager注解依赖--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency>
<!-- nacos注册依赖--><dependency><groupId>com.alibaba.boot</groupId><artifactId>nacos-discovery-spring-boot-starter</artifactId><version>0.2.12</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
yml文件
server:# 端口port: 8081# ipip: localhost
spring:application:name: userserver #服务的名称# 连接数据库的数据源datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql://localhost:3306/db2?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
nacos:discovery:
# 自动注册auto-register: true# nacos服务地址server-addr: localhost:8848
controller层:
package com.example.controller;import com.alibaba.nacos.api.exception.NacosException;
import com.example.dto.UserDto;
import com.example.service.UserLogService;
import com.example.service.UserService;
import jdk.nashorn.internal.ir.ReturnNode;
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;/*** <p>* 前端控制器* </p>** @author wlh* @since 2023-01-18*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/query/{id}")public UserDto queryById(@PathVariable("id") Integer id) throws NacosException {return userService.queryById(id);}
}
config层
package com.example.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;/*** Created by IntelliJ IDEA.** @Author : wlh* @create 2023/1/18 17:20*/
@Configuration
public class NacosConfig {// 注入RestTemplate对象@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
service层
package com.example.service;import com.alibaba.nacos.api.exception.NacosException;
import com.example.dto.UserDto;
import com.example.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;/*** <p>* 服务类* </p>** @author wlh* @since 2023-01-18*/
public interface UserService extends IService<User> {// 根据id获取用户信息和日志列表UserDto queryById(Integer id) throws NacosException;
}
service实现类
package com.example.service.impl;import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.example.dto.UserDto;
import com.example.entity.User;
import com.example.entity.UserLog;
import com.example.mapper.UserMapper;
import com.example.service.UserLogService;
import com.example.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.util.List;/*** <p>* 服务实现类* </p>** @author wlh* @since 2023-01-18*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Resourceprivate UserMapper userMapper;@Autowiredprivate RestTemplate restTemplate;@NacosInjectedprivate NamingService namingService;@Overridepublic UserDto queryById(Integer id) throws NacosException {User user = userMapper.selectById(id);UserDto userDto = new UserDto();userDto.setId(user.getId());userDto.setName(user.getName());userDto.setMoney(user.getMoney());// 获取服务Instance logserver = namingService.selectOneHealthyInstance("logserver");String url = String.format("http://%s:%d/userLog/queryByUserId/"+id,logserver.getIp(),logserver.getPort());// 通过restTemplate对象进行夸模块请求数据List list = restTemplate.getForObject(url, List.class);userDto.setUserLogs(list);return userDto;}
}
mapper层
package com.example.mapper;import com.example.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;/*** <p>* Mapper 接口* </p>** @author wlh* @since 2023-01-18*/
public interface UserMapper extends BaseMapper<User> {}
实体类
user类
package com.example.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;/*** <p>* * </p>** @author wlh* @since 2023-01-18*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("user")
@ApiModel(value = "User对象", description = "")
public class User implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty("主键")@TableId(value = "id", type = IdType.AUTO)private Integer id;@ApiModelProperty("姓名")@TableField("name")private String name;@ApiModelProperty("账户余额")@TableField("money")private BigDecimal money;}
UserLog类
package com.example.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;/*** <p>* * </p>** @author wlh* @since 2023-01-18*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("user_log")
@ApiModel(value = "UserLog对象", description = "")
public class UserLog implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;@TableField("message")private String message;@TableField("time")private LocalDateTime time;@TableField("user_id")private Integer userId;}
dto用于定义数据传输模板
package com.example.dto;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.example.entity.UserLog;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;/*** Created by IntelliJ IDEA.** @Author : wlh* @create 2023/1/18 17:12*/
@Data
public class UserDto implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty("主键")private Integer id;@ApiModelProperty("姓名")private String name;@ApiModelProperty("账户余额")private BigDecimal money;@ApiModelProperty("日志列表")private List<UserLog> userLogs;
}
user_log服务
引入依赖
<?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>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>ikiku.space</groupId><artifactId>log_server</artifactId><version>0.0.1-SNAPSHOT</version><name>log_server</name><description>log_server</description><properties><java.version>8</java.version></properties><dependencies><!-- spring boot 核心依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- spring boot测试依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- mysql驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!-- mybatis代码生成器依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency><!-- freemarker模板--><!-- https://mvnrepository.com/artifact/org.freemarker/freemarker --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency><!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
<!-- swagger注解依赖--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency>
<!-- nacos注册依赖--><dependency><groupId>com.alibaba.boot</groupId><artifactId>nacos-discovery-spring-boot-starter</artifactId><version>0.2.12</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
controller层
package com.example.controller;import com.example.entity.UserLog;
import com.example.service.UserLogService;
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;import java.util.List;/*** <p>* 前端控制器* </p>** @author wlh* @since 2023-01-18*/
@RestController
@RequestMapping("/userLog")
public class UserLogController {@Autowiredprivate UserLogService userLogService;@GetMapping("/queryByUserId/{id}")public List<UserLog> getLog(@PathVariable("id") Integer id){return userLogService.queryById(id);}
}
config层暂时不需要,如果需要跨模块访问其他的模块时,在写的和user服务里面的一样即可
yml配置
server:port: 8082ip: localhost
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql://localhost:3306/db2?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=falseapplication:name: logserver
nacos:discovery:auto-register: trueserver-addr: localhost:8848
service层
package com.example.service;import com.example.entity.UserLog;
import com.baomidou.mybatisplus.extension.service.IService;import java.util.List;/*** <p>* 服务类* </p>** @author wlh* @since 2023-01-18*/
public interface UserLogService extends IService<UserLog> {List<UserLog> queryById(Integer id);
}
service实现类层
package com.example.service.impl;import com.example.entity.UserLog;
import com.example.mapper.UserLogMapper;
import com.example.service.UserLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;/*** <p>* 服务实现类* </p>** @author wlh* @since 2023-01-18*/
@Service
public class UserLogServiceImpl extends ServiceImpl<UserLogMapper, UserLog> implements UserLogService {@Resourceprivate UserLogMapper userLogMapper;@Overridepublic List<UserLog> queryById(Integer id) {return userLogMapper.queryByUserId(id);}
}
mapper层
package com.example.mapper;import com.example.entity.UserLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;import java.util.List;/*** <p>* Mapper 接口* </p>** @author wlh* @since 2023-01-18*/
public interface UserLogMapper extends BaseMapper<UserLog> {@Select("select * from user_log where user_id = #{id}")List<UserLog> queryByUserId(@Param("id") Integer id);
}
实体类层
package com.example.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;/*** <p>* * </p>** @author wlh* @since 2023-01-18*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("user_log")
@ApiModel(value = "UserLog对象", description = "")
public class UserLog implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;@TableField("message")private String message; @TableField("time")private LocalDateTime time;@TableField("user_id")private Integer userId;}
postman测试验证正确性
nacos服务中心
postman 发起请求测试
Nacos在spring boot的使用相关推荐
- Nacos 2.0的Spring Boot Starter来了!
随着Nacos2.0成熟稳定,Nacos-spring-boot发布0.1.10.0.2.10两个核心版本,全面支持了Nacos2.0,同时支持自动识别配置类型注入能力,修复了高并发场景下数据一致性问 ...
- Nacos(六)之Spring Boot集成
转载自 Nacos Spring Boot 快速开始 本文主要面向 Spring Boot 的使用者,通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务发现. 关于 Naco ...
- 彻夜怒肝!Spring Boot+Sentinel+Nacos高并发已撸完,快要裂开了!
很多人说程序员是最容易实现财富自由的职业,也确实,比如字节 28 岁的程序员郭宇不正是从普通开发一步步做起的吗? 回归行业现状,当开发能力可以满足公司业务需求时,拿到超预期的 Offer 并不算难.最 ...
- Nacos Spring Boot 快速开始
Nacos Spring Boot 快速开始 本文主要面向 Spring Boot 的使用者,通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务发现. 关于 Nacos Spr ...
- Spring Boot整合Nacos时遇到 java.lang.IllegalStateException: Context has been already given a name 的解决办法
问题概述 在进行项目开发过程中,通过Spring Boot整合Alibaba Nacos的服务注册与发现和配置中心时,遇到个梗,启动时打印出一串错误日志信息 " Failed to rena ...
- Spring Boot 构建war 部署到tomcat下无法在Nacos中注册服务
文章目录 1. 问题 2. 分析 3. 解决方案 1. 问题 使用Nacos作为注册中心的Spring Boot项目,以war包形式部署到服务器上,启动项目发现该服务无法在Nacos中注册. 2. 分 ...
- MyBatis-Plus,搭配 Spring Boot 使用,一篇就够了
以下文章来源方志朋的博客,回复"666"获面试宝典 MyBatis-plus 是一款 Mybatis 增强工具,用于简化开发,提高效率.下文使用缩写 mp来简化表示 MyBatis ...
- Spring Boot 和Apache Kafka的集成
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 1. 引言 Apache Kafka 是一个分布式的.容错 ...
- 如何让Spring Boot 的配置 “动” 起来?
前言 对于微服务而言配置本地化是个很大的鸡肋,不可能每次需要改个配置都要重新把服务重新启动一遍,因此最终的解决方案都是将配置外部化,托管在一个平台上达到不用重启服务即可一次修改多处生效的目的. 但是对 ...
最新文章
- MIT最新报告:完全无人驾驶仍需10年,马斯克:特斯拉已经实现
- 独家 | 手把手教你从有限的数据样本中发掘价值(附代码)
- Mysql学习之order by的工作原理
- Linux网络编程--聊天室客户端程序
- rust盖错了怎么拆除_细说Rust错误处理
- Docker 安装 ES 7.7.0 及 Head、Kibana、IK分词器、Logstash、Filebeat 插件
- python输入框输入提交_python文本文件处理和用户输入
- SurfaceGo配置轻量级LaTeX写作环境(MiKTeX)
- mysql之delete删除记录后数据库大小不变
- java懒汉,[Java教程]java 懒汉式
- Python设置显示屏分辨率
- System Verilog 语法1
- 身体健康是第一生产力 --- 我看央视主持人李咏早逝
- 【一文读懂】python 中的 numpy.reshape(a, newshape, order=‘C‘) 详细说明及实例讲解
- 在代码里面如何使用workman
- 啃下这些Framework技术笔记,专题解析
- 使用stream将List转换为用逗号拼接的字符串
- cocos2dx-setUserData
- Oracle 19c VLDB and Partitioning Guide 第5章:管理和维护基于时间的信息 读书笔记
- Firefly-rk3288 开发板Linux系统编译