当前位置: 首页 > news >正文

【Spring Boot 与 Spring Cloud 深度 Mape 之三】服务注册与发现:Nacos 核心实战与原理浅析

【Spring Boot 与 Spring Cloud 深度 Mape 之三】服务注册与发现:Nacos 核心实战与原理浅析

#SpringCloudAlibaba #Nacos #服务注册 #服务发现 #服务治理 #微服务 #SpringBoot #Java

系列衔接:在前两篇 [【深度 Mape 之一】 和 [【深度 Mape 之二】] 中,我们分别掌握了 Spring Boot 的核心应用构建能力,并理解了微服务架构的演进以及 Spring Cloud 解决分布式挑战的宏伟蓝图。现在,我们将踏入 Spring Cloud 核心组件的实战领域。本文作为系列的第三篇,将聚焦于微服务架构中的基石——服务注册与发现,并重点讲解如何使用当前主流且功能强大的 Nacos 作为注册中心,替代日渐老旧的 Eureka,并将其与 Spring Boot 应用无缝集成。

摘要:在动态的微服务环境中,服务实例的地址(IP、端口)会因部署、扩缩容而频繁变化。服务消费者如何准确、实时地找到服务提供者?这便是服务注册与发现机制要解决的核心问题。本文将深入探讨服务发现的必要性,介绍 Nacos 作为现代化服务发现解决方案的优势及其核心概念。我们将通过详细的步骤和代码示例,手把手教你如何部署 Nacos Server、如何在 Spring Boot 应用(服务提供者和服务消费者)中集成 Nacos Discovery,并最终实现基于服务名的动态调用。


本文目标

  • 深刻理解在微服务架构中引入服务注册与发现的必要性。
  • 了解 Nacos 作为服务发现组件的核心概念(Namespace, Group, Service, Instance)。
  • 掌握 Nacos Server 的单机模式部署与控制台基本使用。
  • 熟练配置 Spring Boot 应用(提供者/消费者)接入 Nacos 实现服务注册。
  • 掌握服务消费者如何通过 Nacos 发现服务实例并进行调用(使用 @LoadBalanced RestTemplate)。

一、 为何需要服务注册与发现?告别硬编码的噩梦

想象一个没有服务注册中心的微服务世界:

  • 服务 A 需要调用服务 B。服务 A 的开发者需要知道服务 B 当前部署的所有实例的 IP 地址和端口号。
  • 这些地址可能会因为重新部署、服务器故障、弹性伸缩(增加或减少实例)而改变。
  • 每次服务 B 的地址列表发生变化,服务 A 的配置都需要手动更新并重新部署。
  • 如果服务 B 有多个实例,服务 A 还需要自己实现负载均衡逻辑来分发请求。

这种 硬编码静态配置 的方式在动态、大规模的微服务环境中是完全不可行的,会导致配置维护困难、系统脆弱、无法自动适应环境变化。

服务注册与发现机制 就是为了解决这个问题:

  1. 服务注册 (Service Registration):服务提供者(如服务 B)在启动时,将自己的网络地址(IP、端口、服务名等元数据)注册到一个中心化的 服务注册中心 (Service Registry)。同时,它会定期向注册中心发送“心跳”表明自己还活着。
  2. 服务发现 (Service Discovery):服务消费者(如服务 A)在需要调用服务 B 时,向服务注册中心询问:“服务名叫 B 的可用实例有哪些?” 注册中心返回当前存活的服务 B 实例列表。
  3. 健康检查 (Health Check):注册中心会定期检查已注册服务的健康状况(或由服务实例主动上报心跳)。如果某个实例长时间没有心跳或健康检查失败,注册中心会将其从可用列表中剔除,防止消费者调用到故障实例。

通过这种机制,服务间的依赖关系从具体的网络地址解耦为对 服务名 的依赖,实现了服务的动态发现和高可用。

二、 Nacos 闪亮登场:现代化的服务发现与配置中心

Nacos (Naming and Configuration Service) 是阿里巴巴开源的一款功能丰富的平台,用于构建云原生应用。它不仅仅是一个服务注册中心,还集成了分布式配置管理动态 DNS 服务

为何选择 Nacos (相较于 Eureka)?

  • 功能更全面:同时支持服务发现和配置管理,减少了需要引入的中间件数量。
  • 更好的性能与可用性:支持 AP (最终一致性) 和 CP (强一致性) 模式切换(服务发现通常用 AP,配置管理可能需要 CP),底层通信机制更优。
  • 更友好的控制台:提供了易于使用的 Web UI,方便查看服务、配置、集群状态等。
  • 社区活跃,持续发展:阿里巴巴主导,社区活跃,迭代速度快。而 Eureka 已进入维护模式。
  • 支持多种服务类型:支持基于 API、DNS、RPC 的服务发现。

Nacos 服务发现核心概念:

  • Namespace (命名空间):用于进行租户隔离或环境隔离(如开发环境、测试环境、生产环境)。不同的 Namespace 之间的服务、配置默认是隔离的。默认 Namespace 是 public
  • Group (分组):可以将不同的服务或配置划分到同一个组内,实现逻辑上的分类。默认 Group 是 DEFAULT_GROUP
  • Service (服务):一个逻辑上的服务单元,通常对应一个微服务的 spring.application.name
  • Instance (实例):一个服务下的具体运行实例,包含 IP、端口、权重、健康状态、元数据等信息。
  • Cluster (集群):Nacos 实例可以属于某个集群,用于逻辑或物理上的划分(如杭州集群、上海集群)。默认 Cluster 是 DEFAULT
  • Health Check (健康检查):Nacos 支持多种健康检查机制(客户端上报心跳、服务端探测 TCP/HTTP 端口),以确保服务实例的可用性。

理解这些概念有助于我们后续的配置和管理。

三、 Nacos Server 部署:快速启动本地开发环境

对于本地开发和测试,我们可以快速部署一个单机版的 Nacos Server。

1. 下载 Nacos Server:

访问 Nacos 的 GitHub Release 页面:https://github.com/alibaba/nacos/releases

下载最新稳定版的 nacos-server-x.x.x.tar.gz (Linux/macOS) 或 .zip (Windows)。

2. 解压并启动:

解压下载的文件。进入 nacos/bin 目录。

  • Linux/macOS:
    # 启动单机模式 (-m standalone)
    sh startup.sh -m standalone
    
  • Windows:
    # 启动单机模式 (-m standalone)
    cmd startup.cmd -m standalone
    

启动成功后,你会看到类似 Nacos started successfully in stand alone mode. 的日志。

3. 访问 Nacos 控制台:

打开浏览器,访问 http://localhost:8848/nacos

默认用户名和密码都是 nacos

登录后,你可以在左侧菜单看到 “服务管理” -> “服务列表”,目前应该是空的。

生产环境提示:生产环境强烈建议使用集群模式部署 Nacos,并通常需要配置外部数据源(如 MySQL)来持久化数据。具体请参考 Nacos 官方文档。

四、 服务提供者:向 Nacos 注册服务

现在,我们创建一个简单的 Spring Boot 应用作为服务提供者,并将其注册到 Nacos。

1. 创建 Spring Boot 项目 (例如 nacos-provider-demo)

使用 Spring Initializr 创建一个 Maven 项目,添加 Spring Web 依赖。

2. 添加 Nacos Discovery 依赖

修改 pom.xml,引入 Spring Cloud Alibaba 的 BOM 和 Nacos Discovery Starter:

<properties><java.version>1.8</java.version><!-- 确保 Spring Boot 版本与 Spring Cloud Alibaba 版本兼容 --><spring-boot.version>2.6.14</spring-boot.version><spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version><!-- Spring Cloud 版本也需要兼容 --><spring-cloud.version>2021.0.8</spring-cloud.version>
</properties><dependencyManagement><dependencies><!-- 引入 Spring Cloud BOM --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- 引入 Spring Boot BOM --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!-- 引入 Spring Cloud Alibaba BOM --><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></dependencies>
</dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Nacos 服务发现 Starter --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- 建议添加 Actuator 以便 Nacos 进行更准确的健康检查 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
</dependencies>

注意: 请根据你选择的 Spring Boot 版本,查找并使用兼容的 Spring Cloud Alibaba 和 Spring Cloud 版本。版本兼容性至关重要!

3. 配置 application.yml

src/main/resources 下创建 application.yml (或 .properties):

server:port: 8081 # 服务端口号spring:application:name: nacos-provider-service # !! 服务名称,将注册到 Nacos !!cloud:nacos:discovery:server-addr: localhost:8848 # Nacos Server 地址# namespace: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # 指定命名空间 ID (可选, 默认为 public)# group: MY_GROUP # 指定分组 (可选, 默认为 DEFAULT_GROUP)# cluster-name: HZ # 指定集群名称 (可选, 默认为 DEFAULT)# Actuator 配置 (可选,用于健康检查)
management:endpoints:web:exposure:include: 'health' # 至少暴露 health 端点endpoint:health:show-details: always
  • spring.application.name 是必须的,它定义了服务在 Nacos 中的名称。
  • spring.cloud.nacos.discovery.server-addr 指定 Nacos Server 的地址。

4. 创建一个简单的 REST Controller

package com.example.nacosproviderdemo;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.RestController;import java.util.HashMap;
import java.util.Map;@RestController
public class ProviderController {@Value("${server.port}")private String serverPort;// 模拟一个简单的接口@GetMapping("/provider/echo/{message}")public Map<String, String> echo(@PathVariable String message) {Map<String, String> response = new HashMap<>();response.put("message", "Received: " + message);response.put("fromPort", serverPort);return response;}
}

5. 启动应用并验证注册

运行 NacosProviderDemoApplication

启动完成后,回到 Nacos 控制台 (http://localhost:8848/nacos),刷新 “服务列表”。你应该能看到名为 nacos-provider-service 的服务,并且实例数量为 1。点击服务名可以查看实例详情,包括 IP、端口、健康状态等。

五、 服务消费者:发现并调用服务

现在,我们创建另一个 Spring Boot 应用作为服务消费者,它将通过 Nacos 发现 nacos-provider-service 并调用其接口。

1. 创建 Spring Boot 项目 (例如 nacos-consumer-demo)

同样使用 Spring Initializr 创建,添加 Spring Web 依赖。

2. 添加 Nacos Discovery 和 LoadBalancer 依赖

修改 pom.xml,引入与 Provider 相同的 BOM 配置,并添加依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Nacos 服务发现 Starter --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- Spring Cloud LoadBalancer 用于客户端负载均衡 (替代 Ribbon) --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
</dependencies>

注意: 我们引入了 spring-cloud-starter-loadbalancer。虽然 Ribbon 仍然可以通过 Nacos Discovery 传递依赖进来,但 Spring Cloud 官方推荐使用 Spring Cloud LoadBalancer 作为新的客户端负载均衡器。

3. 配置 application.yml

server:port: 8082 # 消费者端口号spring:application:name: nacos-consumer-service # 消费者自己的服务名cloud:nacos:discovery:server-addr: localhost:8848 # Nacos Server 地址

消费者也需要配置 Nacos 地址和自己的 spring.application.name,以便自己也能被发现(如果需要)或进行管理。

4. 配置 @LoadBalanced RestTemplate

为了方便地使用服务名进行调用并自动实现负载均衡,我们需要配置一个带有 @LoadBalanced 注解的 RestTemplate Bean。

创建一个配置类:

package com.example.nacosconsumerdemo.config;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 RestTemplateConfig {@Bean@LoadBalanced // !! 核心注解:启用 Spring Cloud LoadBalancer 的能力 !!public RestTemplate restTemplate() {return new RestTemplate();}
}

@LoadBalanced 注解会拦截 RestTemplate 的请求,通过 LoadBalancerClient (由 spring-cloud-starter-loadbalancer 提供) 从 Nacos 获取目标服务(根据 URL 中的服务名)的实例列表,并根据负载均衡策略(默认为轮询)选择一个实例,将请求的 URL 替换为实际的 IP 和端口,最后才真正发出 HTTP 请求。

5. 创建 Consumer Controller 调用 Provider

package com.example.nacosconsumerdemo;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.RestController;
import org.springframework.web.client.RestTemplate;import java.util.Map;@RestController
public class ConsumerController {// 注入带有 @LoadBalanced 注解的 RestTemplate@Autowiredprivate RestTemplate restTemplate;// 定义要调用的服务提供者名称private final String PROVIDER_SERVICE_URL = "http://nacos-provider-service"; // !! 使用服务名 !!@GetMapping("/consumer/call/echo/{message}")public Map<String, String> callProviderEcho(@PathVariable String message) {// 使用服务名 + 路径 调用提供者接口String requestUrl = PROVIDER_SERVICE_URL + "/provider/echo/" + message;System.out.println("Requesting URL: " + requestUrl);// 发起 GET 请求,期望返回 Map 类型// RestTemplate 会自动进行服务发现和负载均衡Map<String, String> result = restTemplate.getForObject(requestUrl, Map.class);System.out.println("Received response: " + result);return result;}
}

关键点:调用 URL 时,主机名部分直接使用在 Nacos 中注册的 服务名 (nacos-provider-service),而不是具体的 IP 和端口。RestTemplate (因为 @LoadBalanced) 会自动处理这一切。

6. 启动并测试

  • 确保 Nacos Server 和 nacos-provider-demo (端口 8081) 正在运行。
  • 启动 nacos-consumer-demo (端口 8082)。

访问消费者的接口:http://localhost:8082/consumer/call/echo/HelloNacos

观察 nacos-consumer-demo 的控制台输出,你应该能看到它请求了 http://nacos-provider-service/provider/echo/HelloNacos,并收到了来自 nacos-provider-demo (端口 8081) 的响应。

浏览器会显示类似:

{"message": "Received: HelloNacos","fromPort": "8081"
}

负载均衡测试 (可选):
你可以修改 nacos-provider-demoserver.port (例如改为 8083),然后启动第二个 Provider 实例。再次访问消费者的接口多次,你会发现响应中的 fromPort 会在 8081 和 8083 之间轮流切换,证明了负载均衡在生效。

六、 Nacos 健康检查机制简介

Nacos 通过健康检查来判断服务实例是否可用。主要方式:

  1. 客户端心跳 (推荐):Nacos 客户端(集成在你的 Spring Boot 应用中)会定期向 Nacos Server 发送心跳包,告知自己还存活。如果 Server 在一定时间内(可配置)未收到心跳,则认为实例不健康。这是默认且推荐的方式。
  2. 服务端探测:Nacos Server 主动探测实例的 TCP 端口或 HTTP 接口(如 Actuator 的 /actuator/health)。这需要服务端能访问到客户端实例。

当 Spring Boot 应用集成了 spring-boot-starter-actuator 后,Nacos 客户端通常会利用 Actuator 的 /actuator/health 端点信息来上报更准确的健康状态给 Nacos Server。

七、 总结与展望

本文我们深入实践了使用 Nacos 作为服务注册中心的核心流程:

  1. 理解了服务注册与发现对于动态微服务环境的必要性。
  2. 了解了 Nacos 的核心概念并成功部署了单机版 Nacos Server。
  3. 通过 spring-cloud-starter-alibaba-nacos-discovery,将服务提供者注册到了 Nacos。
  4. 配置了 @LoadBalanced RestTemplate,使服务消费者能够基于 服务名 动态发现并调用提供者,同时实现了客户端负载均衡。

至此,我们解决了微服务间“如何找到彼此”的问题。但这仅仅是服务调用的第一步。直接使用 RestTemplate 拼接 URL 仍然有些繁琐,且缺乏类型安全。

在下一篇文章【深度 Mape 之四】中,我们将学习更优雅、更强大的服务间调用方式——使用声明式 REST 客户端 OpenFeign,它将使远程调用如同调用本地方法一样简单,敬请期待!


你在使用 Nacos 或其他注册中心时遇到过什么问题?或者对服务发现有什么更深的理解?欢迎在评论区分享讨论!

相关文章:

【Spring Boot 与 Spring Cloud 深度 Mape 之三】服务注册与发现:Nacos 核心实战与原理浅析

【Spring Boot 与 Spring Cloud 深度 Mape 之三】服务注册与发现&#xff1a;Nacos 核心实战与原理浅析 #SpringCloudAlibaba #Nacos #服务注册 #服务发现 #服务治理 #微服务 #SpringBoot #Java 系列衔接&#xff1a;在前两篇 [【深度 Mape 之一】 和 [【深度 Mape 之二】] 中…...

JS实现动态点图酷炫效果

实现目标 分析问题 整个图主要是用canvas实现&#xff0c;其中难点是将线的长度控制在一定范围内、并且透明度随长度变化。 前置知识 canvas绘制点、线、三角形、弧形 // 点ctx.moveTo(this.x, this.y);ctx.arc(this.x, this.y, this.r,0, 2 * Math.PI, false);ctx.fillStyle …...

使用ModbusRTU读取松下测高仪的高度

使用C#通过Modbus RTU读取松下测高仪高度 1. 准备工作 1.1 硬件连接 确保松下测高仪支持Modbus RTU协议(需查阅设备手册确认)。通过RS-485或RS-232接口连接设备与计算机,可能需要USB转串口适配器。确认通信参数(波特率、数据位、停止位、奇偶校验),常见设置为:9600波特…...

SQL Server从安装到入门一文掌握应用能力。

本篇文章主要讲解,SQL Server的安装教程及入门使用的基础知识,通过本篇文章你可以快速掌握SQL Server的建库、建表、增加、查询、删除、修改等基本数据库操作能力。 作者:任聪聪 日期:2025年3月31日 一、SQL Server 介绍: SQL Server 是微软旗下的一款主流且优质的数据库…...

Ubuntu上给AndroidStudio创建桌面图标

最近使用了Ubuntu开发了&#xff0c;默认的android studio没有桌面图标&#xff0c;还是很不方便&#xff0c;每次都要cd到bin目录启动studio.sh。 步骤1&#xff1a;cd /usr/share/applications linux系统里面&#xff0c;所有的应用启动入口都在 /usr/share/applications …...

HarmonyOS:ComposeTitleBar 组件自学指南

在日常的鸿蒙应用开发工作中&#xff0c;我们常常会面临构建美观且功能实用的用户界面的挑战。而标题栏作为应用界面的重要组成部分&#xff0c;它不仅承载着展示页面关键信息的重任&#xff0c;还能为用户提供便捷的操作入口。最近在参与的一个项目里&#xff0c;我就深深体会…...

C# System.Net.Dns 使用详解

总目录 前言 在网络编程中&#xff0c;域名系统&#xff08;DNS&#xff09;是互联网的核心组成部分之一&#xff0c;它将人类可读的域名转换为机器可用的IP地址。在.NET框架中&#xff0c;System.Net.Dns类提供了一组静态方法&#xff0c;用于执行与DNS相关的操作。本文将详细…...

Spring-事务属性

1.隔离属性 数据库对于隔离属性的支持 隔离属性的值MySQLOracle ISOLATION.READ_COMMITTED √ √ ISOLATION.REPEATABLE_READ√ISOLATION.SERIALIZABLE√√ Oracle不支持REPEATABLE_READ值 如何解决不可重复度 采用的多版本比对的方式 解决不可重复读 默认隔离属性 ISO…...

“上云入端” 浪潮云剑指组织智能化落地“最后一公里”

进入2025年&#xff0c;行业智能体正在成为数实融合的核心路径。2025年初DeepSeek开源大模型的横空出世&#xff0c;通过算法优化与架构创新&#xff0c;显著降低算力需求与部署成本&#xff0c;推动大模型向端侧和边缘侧延伸。其开源策略打破技术垄断&#xff0c;结合边缘计算…...

Docker 的实质作用是什么

Docker 的实质作用是什么 目录 Docker 的实质作用是什么**1. Docker 的实质作用****2. 为什么使用 Docker?****(1)解决环境一致性问题****(2)提升资源利用率****(3)简化部署与扩展****(4)加速开发与协作****3. 举例说明****总结**Docker 的实质是容器化平台,核心作用…...

WEB安全--文件上传漏洞--白名单绕过

一、MIME类型&#xff08;Content-Type&#xff09;绕过 原理&#xff1a;在我们不能绕过白名单后缀限制时&#xff0c;如果后端检测的是文件类型&#xff08;数据包中的Content-Type字段&#xff09;&#xff0c;那我们可以利用合法类型替换 示例&#xff1a;在上传,php后缀…...

Mac 本地化部署 dify

Macbook 本地化部署 dify 目录 Macbook 本地化部署 dify安装dockerdocker下载地址 安装dify下载dify到本地github可能遇到的问题: github打开超时在本地解压dify.zip文件本地化部署docker部署可能遇到的问题: 部署超时登录体验 dify 安装docker docker下载地址 根据电脑芯片选…...

MySQL和navicat日常使用记录

navicat界面上之前跟localhost连接的数据库可以直接点开了 这里有excel导入的地方 然后添加文件&#xff0c;选则文件是哪个&#xff0c;勾选excel的表是哪个&#xff0c;根据实际情况定义一些附加选项&#xff0c;注意时间格式&#xff0c;下一步下一步&#xff0c;然后选择主…...

linux进程信号 ─── linux第27课

在 Linux 系统中&#xff0c;信号&#xff08;Signals&#xff09; 是一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;用于通知进程发生了某种事件或请求进程执行特定操作。 你怎么能识别信号呢&#xff1f;识别信号是内置的&#xff0c;进程识别信号&#xff0c;是…...

云安全之k8s未授权漏洞总结

一、k8s介绍 全称是 kubernetes&#xff0c;是谷歌在2014年推出的一种开源容器编排系统&#xff0c;后来捐赠给了云原生计算基金会&#xff08;CNCF&#xff09;。因将k后面的8个字母进行缩写后&#xff0c;被广泛简称为K8s。随着容器技术的发展&#xff0c;面临着容器数量庞大…...

博客学术汇测试报告

Author&#xff1a;MTingle major:人工智能 Build your hopes like a tower! 目录 一.项目简介 二.开发技术 三.测试用例设计 四.自动化测试代码 common包 博客编辑 博客列表 登录页面 未登录测试 主函数 五.性能测试 六.测试总结 一.项目简介 该项目是一款基于 S…...

揭秘:父子组件之间的传递

基础知识 组件与组件之间有三大方面的知识点&#xff1a; 子组件通过props defineProps&#xff08;{}&#xff09;接收父组件传递到参数和方法&#xff1b;子组件可以通过定义 emit 事件&#xff0c;向父组件发送事件&#xff1b;父组件调用子组件通过defineExpose 导出的方法…...

leetcode 169.Majority Element

这道题虽然简单&#xff0c;但适合用来练习各种解法。《剑指offer》5.2节 面试题29与此题一样&#xff0c;并且给出了leetcode官方题解未给出的快速选择的解法。 方法一、用哈希表解决 class Solution { public:int majorityElement(vector<int>& nums) {unordered…...

魔改chromium——基础环境搭建

谷歌chromium环境要求详细文档 软件和环境要求&#xff0c;必须安装&#xff0c;硬性要求 系统环境&#xff1a;Windows 10&#xff0c;内存最小8GB&#xff0c;推荐16GB&#xff0c;NTFS格式磁盘最少100GB空间Git版本&#xff1a;安装最新版本即可&#xff0c;Git桌面端下载…...

[网络_1] 因特网 | 三种交换 | 拥塞 | 差错 | 流量控制

目录 一、网络、互连网与因特网 二、因特网发展 三、因特网的组成与功能 四、计算机网络的分类 五、因特网的标准化与意义 一、三种传输方式&#xff1a;电路交换 vs 报文交换 vs 分组交换 1. 电路交换&#xff08;Circuit Switching&#xff09;——像“打电话” 2. 报…...

android 何如查找内网设备 IP

前沿 最近在与嵌入式设备打交道,需要对设备进行配网。发现 UpnP 服务不稳定,经常收不到设备的信息。就想着能不能通过内网查找到 IP 后,直接与设备通信,不停的请求设备信息。 1.Android 端通过 UDP 组播(Multicast)查找设备 如果嵌入式设备支持 UDP 组播,Android 端可…...

Oracle数据库数据编程SQL<3.5 PL/SQL 存储过程(Procedure)>

存储过程(Stored Procedure)是 Oracle 数据库中一组预编译的 PL/SQL 语句集合&#xff0c;存储在数据库中并可通过名称调用执行。它们是企业级数据库应用开发的核心组件。 目录 一、存储过程基础 1. 存储过程特点 2. 创建基本语法 3. 存储过程优点 4. 简单示例 二、没有…...

六级词汇量积累day13

commend 表扬 exhaust 耗尽&#xff0c;用尽 weary 疲惫的&#xff0c;劳累的 fatigue 疲惫&#xff0c;劳累 obese 臃肿的&#xff0c;肥胖的 adopt 采纳&#xff0c;收养 adapt 适应 accomplish 完成&#xff0c;实现 accomplishment 成就 achieve 实现&#xff0c;完成 achi…...

蓝桥杯15届JAVA_A组

将所有1x1转化为2x2 即1x1的方块➗4 然后计算平方数 记得-1 2 import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter;public class Main{static BufferedReader in new BufferedReader(new In…...

OpenCV图像输入输出模块imgcodecs(imwrite函数的用法)

《OpenCV计算机视觉开发实践&#xff1a;基于Python&#xff08;人工智能技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 3.2.3 imwrite保存图片 函数imwrite可以用来输出图像到文件&#xff0c;其声明如下&#xff1a; imwrite(filename,…...

win 远程 ubuntu 服务器 安装图形界面

远程结果&#xff1a;无法使用docker环境使用此方法 注意要写IP和:数字 在 ubuntu 服务器上安装如下&#xff1a; # 安装 sudo apt-get install tightvncserver # 卸载 sudo apt purge tightvncserver sudo apt autoremove#安装缺失的字体包&#xff1a; sudo apt update s…...

地下管线三维建模软件工具MagicPipe3D V3.6.1

经纬管网建模系统MagicPipe3D&#xff0c;基于二维矢量管线管点数据本地离线参数化构建地下管网三维模型&#xff08;包括管道、接头、附属设施等&#xff09;&#xff0c;输出标准3DTiles、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、…...

vue子组件生命周期的执行顺序

在 Vue 中&#xff0c;子组件的生命周期钩子函数的执行顺序受父组件的影响&#xff0c;通常遵循**“先创建子组件&#xff0c;后创建父组件&#xff1b;先销毁父组件&#xff0c;后销毁子组件”**的原则。 1. 组件创建&#xff08;挂载&#xff09;阶段 当父组件挂载时&#x…...

【含文档+PPT+源码】基于微信小程序的在线考试与选课教学辅助系统

项目介绍 本课程演示的是一款基于微信小程序的在线考试与选课教学辅助系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统…...

树莓派超全系列文档--(17)树莓派配置显示器

树莓派配置显示器 显示支持 HDMI 显示器设置分辨率和旋转手动设置分辨率和旋转确定显示设备名称设置自定义分辨率设置自定义旋转 控制台分辨率和旋转 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 显示 要配置 Raspberry Pi 使用非默认显示模式…...

python将pdf文件转为图片,如果pdf文件包含多页,将转化的多个图片通过垂直或者水平合并成一张图片

要将PDF文件转换为图片&#xff0c;并将多页PDF垂直合并成一张图片&#xff0c;可以使用PyMuPDF&#xff08;也称为fitz&#xff09;库来读取PDF文件&#xff0c;并使用Pillow库来处理和合并图片。以下是一个示例代码&#xff0c;展示了如何实现这个功能&#xff1a; 首先&…...

JVM基础原理

JVM是一个虚拟化的计算机&#xff0c;它可以执行Java字节码文件&#xff08;.class文件&#xff09;&#xff0c;实现Java程序跨平台的特性。JVM负责将Java程序的字节码翻译成具体操作系统的机器码&#xff0c;从而能够在不同的平台上运行。JVM的核心原理涉及以下几个重要方面 …...

Miniforge3高效管理 Python环境:2025年最新实践指南

Miniforge3 高效管理 Python 环境:2025 年最新实践指南 在现代开发中,灵活高效地管理 Python 环境至关重要。Miniforge3 作为一款轻量级 Conda 管理工具,不仅默认采用更新更快的 conda-forge 软件源,还对 ARM 架构(例如 Apple M1/M2/M3)有着出色的适配性。相比于传统的 …...

31天Python入门——第17天:初识面向对象

你好&#xff0c;我是安然无虞。 文章目录 面向对象编程1. 什么是面向对象2. 类(class)3. 类的实例关于self 4. 对象的初始化5. __str__6. 类之间的关系继承关系组合关系 7. 补充练习 面向对象编程 1. 什么是面向对象 面向对象编程是一种编程思想,它将现实世界的概念和关系映…...

困于环中的机器人

************* c topic: 1041. 困于环中的机器人 - 力扣&#xff08;LeetCode&#xff09; ************* Inspect the topic first. And it looks really familiar with another robot topic. 657. 机器人能否返回原点 - 力扣&#xff08;LeetCode&#xff09;https://lee…...

阿里 FunASR 开源中文语音识别大模型应用示例(准确率比faster-whisper高)

文章目录 Github官网简介模型安装非流式应用示例流式应用示例 Github https://github.com/modelscope/FunASR 官网 https://www.funasr.com/#/ 简介 FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端…...

spring boot前后端开发上传文件时报413(Request Entity Too Large)错误的可能原因及解决方案

可能原因及解决方案 1. Spring Boot默认文件大小限制 原因&#xff1a;Spring Boot默认单文件最大为1MB&#xff0c;总请求体限制为10MB。解决方案&#xff1a; 在application.properties中配置&#xff1a;spring.servlet.multipart.max-file-size10MB # 单文件最大 spring…...

Transformer:破局山地暴雨预测的「地形诅咒」--AI智能体开发与大语言模型的本地化部署、优化技术

极端降雨预测的技术痛点与边缘破局 1. 传统预警系统的三重瓶颈‌ ‌延迟致命‌&#xff1a;WRF模式在1km分辨率下3小时预报耗时>45分钟&#xff0c;错过山洪黄金响应期 ‌地形干扰大‌&#xff1a;复杂地形区&#xff08;如横断山脉&#xff09;降水预测误差超50% ‌数据…...

游戏引擎学习第187天

看起来观众解决了上次的bug 昨天遇到了一个相对困难的bug&#xff0c;可以说它相当棘手。刚开始的时候&#xff0c;没有立刻想到什么合适的解决办法&#xff0c;所以今天得从头开始&#xff0c;逐步验证之前的假设&#xff0c;收集足够的信息&#xff0c;逐一排查可能的原因&a…...

05-02-自考数据结构(20331)- 动态查找-知识点

自考数据结构动态查找算法主要讲二叉树和平衡二叉树,但是感觉到了,就又续接了一部分,所以这篇备考的小伙伴着重看前两种就可以了。 知识拓扑 知识点介绍 二叉排序树(BST) 定义 二叉排序树(Binary Search Tree)又称二叉查找树,它或者是一棵空树,或者是具有下列性质的二…...

PyQt6实例_批量下载pdf工具_使用pyinstaller与installForge打包成exe文件

目录 前置&#xff1a; 步骤&#xff1a; step one 准备好已开发完毕的项目代码 step two 安装pyinstaller step three 执行pyinstaller pdfdownload.py&#xff0c;获取初始.spec文件 step four 修改.spec文件&#xff0c;将data文件夹加入到打包程序中 step five 增加…...

NVR接入录像回放平台EasyCVR视频融合平台城市/乡镇污水处理厂解决方案

一、方案背景 随着经济的快速发展和城市化的加快&#xff0c;城市污水排放量急剧增加&#xff0c;给城市环境和粮食安全带来了威胁。因此&#xff0c;污水处理厂的建设和高效运营成为对城市环境保护的重要任务。 目前&#xff0c;国内许多城市虽已建成污水处理系统&#xff0…...

Vue2 vs Vue3 生命周期全面对比:created 的进化与革新!!!

&#x1f3af; Vue2 vs Vue3 生命周期全面对比&#xff1a;created 的进化与革新 &#x1f525; 核心差异全景图 一、钩子函数命名与定位变化 1. 命名规范革新 Vue2 钩子Vue3 钩子 (Options API)Vue3 Composition APIbeforeCreate❌ 无setup() 替代created✅ 保留setup() 替代…...

Ubuntu 22.04安装MongoDB:GLM4模型对话数据收集与微调教程

在Ubuntu 22.04安装MongoDB Community Edition的教程请点击下方链接进行参考&#xff1a; 点击这里获取MongoDB Community Edition安装教程 今天将为大家带来如何微调GLM4模型并连接数据库进行对话的教程。快跟着小编一起试试吧~ 1. 大模型 ChatGLM4 微调步骤 1.1 从 github…...

并查集(Union-Find Set)课程笔记

目录 1. 并查集原理 2. 并查集的实现 3. 并查集应用 应用 1&#xff1a;省份数量问题 应用 2&#xff1a;等式方程的可满足性 1. 并查集原理 并查集用于处理需要将不同元素划分成若干不相交集合的问题。最开始时&#xff0c;每个元素都是单独的一个集合&#xff0c;随后根…...

算法刷题记录——LeetCode篇(1.4) [第31~40题](持续更新)

更新时间&#xff1a;2025-03-29 算法题解目录汇总&#xff1a;算法刷题记录——题解目录汇总技术博客总目录&#xff1a;计算机技术系列博客——目录页 优先整理热门100及面试150&#xff0c;不定期持续更新&#xff0c;欢迎关注&#xff01; 32. 最长有效括号 给你一个只包…...

【区块链安全 | 第十四篇】类型之值类型(一)

文章目录 值类型布尔值整数运算符取模运算指数运算 定点数地址&#xff08;Address&#xff09;类型转换地址成员balance 和 transfersendcall&#xff0c;delegatecall 和 staticcallcode 和 codehash 合约类型&#xff08;Contract Types&#xff09;固定大小字节数组&#x…...

一款超级好用且开源免费的数据可视化工具——Superset

认识Superset 数字经济、数字化转型、大数据等等依旧是如今火热的领域&#xff0c;数据工作有一个重要的环节就是数据可视化。 看得见的数据才更有价值&#xff01; 现如今依旧有多数企业号称有多少多少数据&#xff0c;然而如果这些数据只是呆在冷冰冰的数据库或文件内则毫无…...

android gradle一直编译不下来,可能是打开了gradle离线模式

gradle离线模式 当然&#xff0c;如果本地已经将gradle&#xff0c;lib都下载下来了&#xff0c;也可以打开这个离线模式&#xff0c;不然重启AS的时候可能会重新走一次下载流程...

(C语言)学生信息表(学生管理系统)(基于通讯录改版)(正式版)(C语言项目)

1.首先是头文件&#xff1a; //student.h //头文件//防止头文件被重复包含#pragma once//宏定义符号常量&#xff0c;方便维护和修改 #define ID_MAX 20 #define NAME_MAX 20 #define AGE_MAX 5 #define SEX_MAX 5 #define CLA_MAX 20 //定义初始最大容量 #define MAX 1//定义结…...