Springboot+Nacos项目

news/2025/3/9 10:48:27/文章来源:https://www.cnblogs.com/chengdanally/p/18605861

微服务

微服务(Microservices)是一种软件架构风格,他区别与单体架构,将拆分为多个小型的、独立的服务,每个服务都可以独立开发、部署和维护。这些服务通过轻量级的API进行通信。

Nacos简述

Nacos 用于发现、配置和管理微服务。nacos有2个核心功能,一个是注册中心,一个是配置中心。这里Nacos学习就是围绕着注册中心和配置中心2个核心功能展开的。

  • 注册中心的重点
    服务的注册:将服务注册到Nacos上
    服务的发现:找到相关的服务,使用RPC组件完成服务的调用

  • 配置中心的重点
    发现配置
    获取配置

当前是以Naocs2.4.3版本学习总结的。

Spring Boot整合Nacos步骤

服务版本说明:

官网链接:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明

添加依赖:

    //    nacos依赖引入implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.0.5.0'implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.0.5.0'

在resources目录下增加bootstrap.yml文件

spring:application:name: springboot_democloud:nacos:config:file-extension: ymlserver-addr: 127.0.0.1:8848enabled: truediscovery:server-addr: 127.0.0.1:8848enabled: true

启动服务后在浏览器访问http://127.0.0.1:8848/nacoss查看下

服务已经注册到Nacos上了

增加测试用例直接调用接口注册服务

@SpringBootTest
class SpringbootDemo2ApplicationTests {@Testvoid contextLoads() throws Exception {NamingService namingService = NamingFactory.createNamingService("127.0.0.1:8848");// 将服务注册到nacos上namingService.registerInstance("nacos.test.1", "11.11.11.11", 8888, "test");Thread.sleep(Integer.MAX_VALUE);}

客户端注册服务到Nacos上逻辑:

是使用这个方法
namingService.registerInstance("nacos.test.1", "11.11.11.11", 8888, "test");

将当前服务信息存到Map集合里,然后调用接口(/nacos/v1/ns/instance),将服务信息发给nacos

public class NacosNamingService implements NamingService {@Overridepublic void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {// 生成实例对象,填充ip,端口,和服务名Instance instance = new Instance();instance.setIp(ip);instance.setPort(port);instance.setWeight(1.0);instance.setClusterName(clusterName);registerInstance(serviceName, groupName, instance);}@Overridepublic void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {// 判断是否是临时实例if (instance.isEphemeral()) {BeatInfo beatInfo = new BeatInfo();// 拼接服务名 groupName@@serviceNamebeatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));beatInfo.setIp(instance.getIp());beatInfo.setPort(instance.getPort());beatInfo.setCluster(instance.getClusterName());beatInfo.setWeight(instance.getWeight());beatInfo.setMetadata(instance.getMetadata());beatInfo.setScheduled(false);beatInfo.setPeriod(instance.getInstanceHeartBeatInterval());// 心跳检测服务beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);}// 调用api注册服务信息serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);}}
public class NamingProxy {public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}",namespaceId, serviceName, instance);final Map<String, String> params = new HashMap<String, String>(9);params.put(CommonParams.NAMESPACE_ID, namespaceId);params.put(CommonParams.SERVICE_NAME, serviceName);params.put(CommonParams.GROUP_NAME, groupName);params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());params.put("ip", instance.getIp());params.put("port", String.valueOf(instance.getPort()));params.put("weight", String.valueOf(instance.getWeight()));params.put("enable", String.valueOf(instance.isEnabled()));params.put("healthy", String.valueOf(instance.isHealthy()));params.put("ephemeral", String.valueOf(instance.isEphemeral()));params.put("metadata", JSON.toJSONString(instance.getMetadata()));reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.POST);}}

启动当前Springboot程序如何将服务注册到Nacos上呢?

首先nacos-discovery依赖包里面有个文件spring.factories,内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,\com.alibaba.cloud.nacos.ribbon.RibbonNacosAutoConfiguration,\com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,\com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,\com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,\com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration

启动过程中会加载这些配置类,实例化需要的bean

查看NacosServiceRegistryAutoConfiguration配置类,注册流程是在NacosServiceRegistry里开始做的

@Configuration
@EnableConfigurationProperties
@ConditionalOnNacosDiscoveryEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,AutoServiceRegistrationAutoConfiguration.class,NacosDiscoveryAutoConfiguration.class })
public class NacosServiceRegistryAutoConfiguration {// 生成NacosServiceRegistry类型的bean,注入到容器中@Beanpublic NacosServiceRegistry nacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {return new NacosServiceRegistry(nacosDiscoveryProperties);}......}

注册本地服务

在com.alibaba.cloud.nacos.registry.NacosServiceRegistry#register里调用namingService.registerInstance方法,最后调用http接口,将服务信息注册到nacos上。
这个入口怎么进来呢?
是在启动springboot项目时,在其中spring生命周期里,getLifecycleProcessor().onRefresh();做的。
NacosAutoServiceRegistration继承了AbstractAutoServiceRegistration抽象类,在执行listener监听器那里做的,去注册本地的服务。实现了AbstractAutoServiceRegistration的register接口(org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration#register)

public abstract class AbstractAutoServiceRegistration<R extends Registration>implements AutoServiceRegistration, ApplicationContextAware, ApplicationListener<WebServerInitializedEvent> {@Override@SuppressWarnings("deprecation")public void onApplicationEvent(WebServerInitializedEvent event) {bind(event);}@Deprecatedpublic void bind(WebServerInitializedEvent event) {ApplicationContext context = event.getApplicationContext();if (context instanceof ConfigurableWebServerApplicationContext) {if ("management".equals(((ConfigurableWebServerApplicationContext) context).getServerNamespace())) {return;}}this.port.compareAndSet(0, event.getWebServer().getPort());this.start();}public void start() {if (!isEnabled()) {if (logger.isDebugEnabled()) {logger.debug("Discovery Lifecycle disabled. Not starting");}return;}if (!this.running.get()) {this.context.publishEvent(new InstancePreRegisteredEvent(this, getRegistration()));register();if (shouldRegisterManagement()) {registerManagement();}this.context.publishEvent(new InstanceRegisteredEvent<>(this, getConfiguration()));this.running.compareAndSet(false, true);}}protected void register() {this.serviceRegistry.register(getRegistration());}
}
public class NacosServiceRegistry implements ServiceRegistry<Registration> {private static final Logger log = LoggerFactory.getLogger(NacosServiceRegistry.class);private final NacosDiscoveryProperties nacosDiscoveryProperties;private final NamingService namingService;public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {this.nacosDiscoveryProperties = nacosDiscoveryProperties;this.namingService = nacosDiscoveryProperties.namingServiceInstance();}@Overridepublic void register(Registration registration) {if (StringUtils.isEmpty(registration.getServiceId())) {log.warn("No service to register for nacos client...");return;}String serviceId = registration.getServiceId();String group = nacosDiscoveryProperties.getGroup();Instance instance = getNacosInstanceFromRegistration(registration);try {// 这里将服务注册到nacos上namingService.registerInstance(serviceId, group, instance);log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,instance.getIp(), instance.getPort());}catch (Exception e) {log.error("nacos registry, {} register failed...{},", serviceId,registration.toString(), e);// rethrow a RuntimeException if the registration is failed.// issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132rethrowRuntimeException(e);}}}

总结:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/854295.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入聊聊asyncPromise

正文 最近在学习JavaScript里的async、await异步,对于其中的Promise状态以及背后的Js引擎实际运行状态不大理解且很感兴趣,因此花了一点时间仔细研究了一下。 从Example说起 const createImg = function (path) {return new Promise((resolve, reject) => {const img = do…

[OS] 计算机资源虚拟化技术

1 定义:计算机资源虚拟化服务器虚拟化主要通过软件技术将物理服务器的硬件资源抽象化,创建多个独立的虚拟服务器环境。2 虚拟化技术方向 以下是一些常见的服务器虚拟化方式和工具: 基于hypervisor的虚拟化Hypervisor技术: 也称为虚拟机监视器(Virtual Machine Monitor,VMM…

C#调用Python代码的方式(二),以PaddleOCR-GUI为例

前言 前面介绍了在C#中使用Progress类调用Python脚本的方法,但是这种方法在需要频繁调用并且需要进行数据交互的场景效果并不好,因此今天分享的是C#调用Python代码的方式(二):使用pythonnet调用Python代码。 pythonnet介绍 Python.NET 是一个包,为 Python 程序员提供了与…

在线教育系统厂家电话

为了方便您直接对接相关业务,下面提供几个在线教育相关企业的联系电话,请自行选择合适的服务商联系。若想直接获取更多信息或定制化的产品方案,请拨打以下联系电话:- 顺企网在线教育直播软件开发平台联系人:张生;联系方式:电话 15989102540(说明您来自顺企网,可获得优…

如何解决Git合并冲突?

讲个故事先: 一个晴朗的日子,Alex 把远程版本库的修改拉到他的本地版本库。 他修改了名为 abc.txt 的文件,将其暂存(staged),提交(committed),最后推送(pushed)回远程版本库。 同时,Tina 不知道 Alex 对abc.txt文件的修改,在该文件的 相同区域 做了一些修改,并尝…

MongoDB备份脚本

#!/bin/bash #backup MongoDB #mongodump命令路径 DUMP=/home/mongodb/bin/mongodump #临时备份目录 OUT_DIR=/home/mongodb_bak/mongodb_bak_now #备份存放路径 TAR_DIR=/home/mongodb_bak/mongodb_bak_list #获取当前系统时间 DATE=`date +%Y_%m_%d` #数据库账号 DB_USER=roo…

SQL Server创建用户一直提示用户已存在的解决办法

背景:复制的老数据库,创建账号onlyread时,一直提示数据库里有这个用户名。报错如下:“用户、组或角色onlyread在当前数据库中已存在。”解决方法: 1. 查询数据库,是否有这个用户 -- 查询是否存在指定的用户、组或者角色 SELECT * FROM sys.database_principals WHERE na…

jquery目录树插件

file-explore是一款简单的jquery目录树插件。它使用嵌套的无序列表作为目录树的结构,结合font-awesome图标可以制作出非常漂亮的jquery目录树效果。在线预览 下载使用方法 在页面中引入file-explore.css和font-awesome文件,以及jquery和file-explore.js文件。<link rel=&…

SQL Server的数据库备份与还原

数据库备份分类 备份分类完全备份:(常用方式)备份整个数据库,包含用户表、系统表、索引、视图和存储过程等所有数据库对象。 因而,占用不少时间和空间,这种方式不建议太频繁,一般一周一次。差异备份:也叫增量备份。它不使用事务日志,相反,它使用整个数据库的一种新映…

vue-实现组件是否显示还是隐藏

比如我们在home页面需要这个标签在city页面不需要这个标签我们可以在router里面添加meta属性在需要的组件页面导入route实力获取meta属性的值

教育行业办公软件排行榜揭晓!J 人备考该选谁?

在教育领域,高效的办公软件对团队协作和个人学习意义重大。尤其对于 J 人,其偏好秩序与规划,可视化团队协作办公软件能助其在教育教培团队运作和个人公考备考中精准把控进程。本文将盘点 6 款此类软件,助力相关人士做出合适选择。 一、板栗看板 板栗看板是教育办公软件中的…