RPC 详解

一、简介

RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议,允许程序在不同的计算机上执行过程或服务。RPC 使得开发者能够像调用本地函数一样调用远程服务,简化了网络编程的复杂性。使得开发者能够专注于业务逻辑,而不必过多关注底层的网络通信细节。

二、工作原理

  1. 客户端调用:客户端程序调用一个本地的代理(Stub),这个代理的功能是模拟远程过程的调用。
  2. 参数打包:代理将调用的参数打包(序列化),将其转换为可以通过网络传输的格式。这一过程通常称为“编码”或“序列化”。
  3. 发送请求:代理通过网络将请求发送到远程服务器。这个请求包含了要调用的函数名和参数。
  4. 服务器接收请求:远程服务器上的代理(Stub)接收到请求后,进行解码(反序列化),将参数转换回原始格式。
  5. 执行过程:服务器的代理调用实际的服务端过程,并将结果返回给代理。
  6. 结果返回:服务器的代理将结果打包并发送回客户端。
  7. 客户端接收结果:客户端的代理接收到结果后进行解码,并将结果返回给原始调用的客户端程序。

三、优缺点

优点:

  • 透明性:开发者可以像调用本地函数一样调用远程服务,简化了分布式系统的开发。
  • 语言无关性:RPC 可以在不同的编程语言之间进行通信,只要双方遵循相同的协议。
  • 高效性:通过使用序列化和网络传输,RPC 可以高效地进行远程调用。

缺点:

  • 网络延迟:由于涉及网络通信,RPC 调用的延迟通常高于本地调用。
  • 错误处理:网络问题可能导致调用失败,开发者需要处理这些异常情况。
  • 安全性:远程调用可能面临安全风险,需要采取适当的安全措施。

四、常见RPC框架

一、gRPC

gRPC(Google Remote Procedure Call)是一个高性能、开源和通用的远程过程调用(RPC)框架,由Google开发。它基于HTTP/2协议,支持多种编程语言,旨在简化微服务之间的通信。

  • 语言支持:多种编程语言,包括(C++, Java, Python, Go, C#, Node.js)等。
  • 主要特性:
    • 高性能:使用HTTP/2,支持多路复用、流控和头压缩,能够提高网络效率和降低延迟。
    • IDL(接口定义语言):使用Protocol Buffers(protobuf)作为接口定义语言,允许开发者定义服务和消息格式,具有良好的跨语言兼容性。
    • 流式传输:支持四种类型的服务方法:单向 RPC、服务器流式 RPC、客户端流式 RPC 和双向流式 RPC,适合不同的应用场景。
    • 负载均衡和故障恢复:内置了负载均衡和故障恢复机制,能够提高系统的可用性和可靠性。
    • 安全性:支持TLS加密,确保数据在传输过程中的安全性。
示例代码:

下面使用gRPC实现一个Java客户端调用Python服务端的示例,包括服务定义、服务实现和客户端调用。主要有以下几个步骤:

  1. 定义gRPC服务:使用Protocol Buffers(.proto文件)定义服务和消息。
  2. 生成代码:使用protoc编译器生成Java和Python代码。
  3. 实现Python服务端:编写Python代码来实现gRPC服务。
  4. 实现Java客户端:编写Java代码来调用Python服务。
(1)定义 gRPC 服务

首先,需要定义一个 gRPC 服务。创建一个 .proto 文件,例如:example.proto:

syntax = "proto3";package example;// 定义请求消息
message HelloRequest {string name = 1;
}// 定义响应消息
message HelloResponse {string message = 1;
}// 定义服务
service Greeter {rpc SayHello(HelloRequest) returns (HelloResponse);
}
(2)生成代码

使用protoc编译器生成Java和Python代码。确保已经安装了protoc和相应的gRPC插件。

  • 生成Python代码
    python -m grpc_tools.protoc -I. --python_out=./python_out --grpc_python_out=./python_out helloworld.proto-I.:指定 proto 文件的搜索路径。
    --python_out=./python_out:指定生成的 Python 代码输出目录。
    --grpc_python_out=./python_out:指定生成的 gRPC Python 代码输出目录。
    
  • 生成Java代码
    protoc --java_out=./java_out --grpc_out=./java_out --plugin=protoc-gen-grpc-java=path/to/protoc-gen-grpc-java  helloworld.proto--java_out=./java_out:指定生成的 Java 代码输出目录。
    --grpc_out=./java_out:指定生成的 gRPC 代码输出目录。
    --plugin=protoc-gen-grpc-java=path/to/protoc-gen-grpc-java:指定 gRPC Java 插件的路径。
    

生成的代码将会在指定的输出目录中。对于 Java,通常会生成以下文件:

  • GreeterGrpc.java
  • HelloRequest.java
  • HelloResponse.java

对于 Python,通常会生成以下文件:

  • example_pb2.py
  • example_pb2_grpc.py
(3)实现Python服务端

在 Python 中,使用生成的代码来实现 gRPC 服务,创建一个名为server.py的文件,内容如下:

import grpc
from concurrent import futures
import time# 导入生成的python代码
import example_pb2
import example_pb2_grpc// 定义一个ExampleService类,继承自 example_pb2_grpc.ExampleServiceServicer,这意味着它实现了 gRPC 服务的基本功能
class ExampleService(example_pb2_grpc.ExampleServiceServicer):/*** SayHello 是一个 RPC 方法,接收两个参数:* request: 包含客户端发送的数据,通常是一个包含请求字段的对象。* context: 提供与请求相关的上下文信息,例如元数据、取消请求等。* 方法返回一个 HelloResponse 对象,该对象是通过 example_pb2 模块定义的。*/def SayHello(self, request, context):return example_pb2.HelloResponse(message=f"Hello, {request.name}!")def serve():// 创建一个 gRPC 服务器,使用线程池执行器,最大工作线程数为 10server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))// 将 ExampleService 的实现添加到服务器example_pb2_grpc.add_ExampleServiceServicer_to_server(ExampleService(), server)// 服务器监听所有可用的网络接口,端口为 50051server.add_insecure_port('[::]:50051')// 启动服务器server.start()print("Server is running on port 50051...")try:while True:# 运行一天time.sleep(86400)  except KeyboardInterrupt:# 停止服务器server.stop(0)if __name__ == '__main__':serve()
(4)实现Java客户端

在Java中,使用生成的代码来实现客户端,创建一个名为Client.java的文件,内容如下:

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;# 导入生成的Java代码
import example.ExampleServiceGrpc;
import example.HelloRequest;
import example.HelloResponse;public class Client {public static void main(String[] args) {// 创建一个 gRPC 管道,连接到本地的 50051 端口ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051).usePlaintext()  // 使用明文传输,不加密.build();  // 构建管道// 创建一个阻塞式的存根,用于调用 ExampleService 服务ExampleServiceGrpc.ExampleServiceBlockingStub stub = ExampleServiceGrpc.newBlockingStub(channel);// 构建请求HelloRequest request = HelloRequest.newBuilder().setName("World").build();// 通过存根发送请求并接收响应HelloResponse response = stub.sayHello(request);// 打印从服务器接收到的响应消息System.out.println("Response from server: " + response.getMessage());// 关闭管道channel.shutdown();}
}
二、Thrift

Thrift 是一个开源的跨语言服务开发框架,最初由 Facebook 开发,旨在简化不同编程语言之间的服务调用。

  • 语言支持:多种编程语言,包括(Java、C++、Python、PHP、Ruby、Go)等。
  • 主要特性:
    • 高效的序列化:Thrift 提供了高效的二进制序列化机制,能够快速地将数据结构转换为字节流,适合高性能的网络通信。
    • 灵活的接口定义:Thrift 使用一种简单的接口定义语言(IDL)来定义服务和数据结构,开发者可以通过 Thrift 编译器生成相应语言的代码。
    • 多种传输和协议:Thrift 支持多种传输方式(如 TCP、HTTP)和协议(如二进制协议、JSON 协议),可以根据需求选择合适的组合。
    • 服务治理:Thrift 提供了服务注册和发现的功能,方便管理和调用分布式服务。
示例代码:

下面使用Thrift实现一个Java客户端调用Python gRPC服务端的示例。主要涉及以下几个步骤,包括定义服务、生成代码、实现服务端和客户端。

(1)定义服务

首先,创建一个IDL(Interface Definition Language)文件,主要用于定义服务接口和数据结构,以便在不同编程语言之间进行高效的远程过程调用(RPC)。例如下面创建的example.thrift文件中主要包含以下几部分:

  • 命名空间:使用 namespace 关键字定义不同编程语言的命名空间。
  • 结构体:使用 struct 定义数据结构,字段使用 类型 名称 的格式,并且每个字段都有一个唯一的 ID(数字)。
  • 服务:使用 service 定义服务接口,服务中的每个方法可以定义输入参数和返回值。
namespace py example  // Python 命名空间
namespace java example  // Java 命名空间// 定义一个简单的结构
struct User {1: i32 id,          // 用户 ID2: string name,     // 用户名3: string email     // 用户邮箱
}// 定义一个服务
service ExampleService {// 创建用户void createUser(1: User user),// 获取用户信息User getUser(1: i32 id),// 更新用户信息void updateUser(1: User user),// 删除用户void deleteUser(1: i32 id)
}
(2)生成代码

使用Thrift编译器生成Java和Python代码,生成Python和Java的代码,分别在 gen-py 和 gen-java 目录下。在已经安装了Thrift编译器的情况下,可以使用以下命令:

thrift --gen py example.thrift
thrift --gen java example.thrift
(3)实现Python服务端

在Python中实现服务端。创建一个文件 server.py:

from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from example import ExampleService
from example.ttypes import Userclass ExampleServiceHandler:def __init__(self):self.users = {}def createUser(self, user):self.users[user.id] = userdef getUser(self, id):return self.users.get(id)def updateUser(self, user):if user.id in self.users:self.users[user.id] = userdef deleteUser(self, id):if id in self.users:del self.users[id]if __name__ == '__main__':handler = ExampleServiceHandler()processor = ExampleService.Processor(handler)transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)tfactory = TTransport.TBufferedTransportFactory()pfactory = TBinaryProtocol.TBinaryProtocolFactory()server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)print("Starting the server...")server.serve()
(4)实现Java客户端

在Java中实现客户端。创建一个文件 Client.java:

import org.apache.thrift.TException;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.protocol.TBinaryProtocol;
import example.ExampleService;
import example.User;public class ExampleClient {public static void main(String[] args) {TTransport transport = new TSocket("127.0.0.1", 9090);try {transport.open();TBinaryProtocol protocol = new TBinaryProtocol(transport);ExampleService.Client client = new ExampleService.Client(protocol);// 创建用户User user = new User();user.setId(1);user.setName("Alice");user.setEmail("alice@example.com");client.createUser(user);// 获取用户信息User retrievedUser = client.getUser(1);System.out.println("Retrieved User: " + retrievedUser.getName());// 更新用户信息user.setEmail("alice_new@example.com");client.updateUser(user);// 删除用户client.deleteUser(1);} catch (TException x) {x.printStackTrace();} finally {transport.close();}}
}
三、Dubbo

Dubbo 是一个开源的高性能 Java RPC 框架,最初由阿里巴巴开发。它主要用于构建分布式服务,支持服务的注册、发现、调用和负载均衡等功能。Dubbo 以其高效、灵活和可扩展性而受到广泛欢迎,尤其是在微服务架构中。

  • 语言支持:Java
  • 主要特性:
    • 高性能:Dubbo 采用了高效的网络通信协议,能够处理大量的并发请求。
    • 服务治理:提供服务注册与发现、负载均衡、容错、限流等功能,帮助开发者管理微服务。
    • 多协议支持:支持多种协议(如 Dubbo、HTTP、REST、gRPC 等),可以根据需求选择合适的协议。
    • 扩展性:支持 SPI(Service Provider Interface)机制,允许用户自定义扩展。
    • 监控与管理:提供监控和管理工具,帮助开发者实时监控服务的状态和性能。
  • 组件
    • Provider:提供服务的应用。
    • Consumer:调用服务的应用。
    • Registry:服务注册中心,负责服务的注册与发现。
    • Monitor:监控中心,收集服务调用的统计信息。
示例代码:

通过将服务提供者和消费者同时注册到nacos注册中心后,直接在消费者服务中掉用提供者服务的接口。主要包含以下几步:

(1)环境准备
  • 一个能正常启动的提供者服务。
  • 一个能正常启动的消费者服务。
  • 一个能正常启动的Nacos 服务器。
(2)配置提供者服务
  1. 首先在提供者服务的 pom.xml 中添加以下依赖:

    <dependencies><!-- Dubbo 依赖 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>3.0.0</version> <!-- 请根据需要选择版本 --></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.0.0</version></dependency><!-- Nacos 依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.0</version> <!-- 请根据需要选择版本 --></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2.2.0</version></dependency>
    </dependencies>
    
  2. 然后在提供者服务的 src/main/resources/application.properties 中添加 Nacos 的配置:

    spring.application.name=dubbo-demo
    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    spring.cloud.nacos.config.server-addr=127.0.0.1:8848
    
  3. 在提供者服务中创建一个服务接口,例如 HelloService:

    package com.example.service;public interface HelloService {String sayHello(String name);
    }
    
  4. 实现服务接口,创建接口的实现类,使用@DubboService注解来定义这个服务是dubbo服务:

    package com.example.service.impl;import com.example.service.HelloService;
    import org.apache.dubbo.config.annotation.DubboService;@DubboService
    public class HelloServiceImpl implements HelloService {@Overridepublic String sayHello(String name) {return "Hello, " + name;}
    }
    
(3)配置消费者服务
  1. 首先在消费者服务的 pom.xml 中添加以下依赖:

    <dependencies><!-- Dubbo 依赖 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo</artifactId><version>3.0.0</version> <!-- 请根据需要选择版本 --></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.0.0</version></dependency><!-- Nacos 依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.0</version> <!-- 请根据需要选择版本 --></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2.2.0</version></dependency>
    </dependencies>
    
  2. 然后在消费者服务的 src/main/resources/application.properties 中添加 Nacos 的配置:

    spring.application.name=dubbo-consumer
    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    
  3. 使用 Dubbo 进行 RPC 调用,通过创建一个消费者类,并使用@DubboReference注解自动注入远程服务的代理对象来调用提供者服务的service:

    import org.apache.dubbo.config.annotation.DubboReference;
    import com.example.service.HelloService;
    import org.springframework.stereotype.Component;@Component
    public class HelloConsumer {@DubboReference // Dubbo 的注解,标识这是一个服务消费者private HelloService helloService;public void sayHello(String name) {String result = helloService.sayHello(name);System.out.println(result);}
    }
    
四、Spring Cloud

Spring Cloud 是一组工具和框架,旨在帮助开发者构建分布式系统,特别是微服务架构。在 Spring Cloud 中实现 RPC 调用通常可以通过使用 Spring Cloud OpenFeign 或 Spring Cloud Ribbon + Spring Cloud Eureka 来完成。

  • 语言支持:Java
  • 主要特性:
    • 服务注册与发现:Spring Cloud 提供了 Eureka 作为服务注册与发现的解决方案,并结合 Ribbon 或 Spring Cloud LoadBalancer,客户端可以在多个服务实例之间进行负载均衡。
    • 服务调用:通过Spring Cloud Feign 是一个声明式的 Web 服务客户端,可以简化 HTTP 请求的编写。传统的 RESTful 服务调用方式,可以使用RestTemplate 来进行 HTTP 请求。
    • 容错处理:Hystrix提供了熔断器模式的实现,能够在服务调用失败时快速返回默认值,防止服务雪崩。而Resilience4j作为 Hystrix 的替代品,提供了更轻量级的熔断、限流和重试机制。
    • API 网关:Spring Cloud Gateway提供了一个简单的 API 网关解决方案,可以路由请求到不同的微服务,并支持过滤器、负载均衡等功能。
    • 配置管理:Spring Cloud Config提供了集中式的配置管理,支持动态刷新配置,方便微服务的配置管理。
    • 链路追踪:Sleuth 和 Zipkin提供了分布式追踪的能力,可以追踪请求在微服务之间的流转,帮助开发者分析性能瓶颈和故障。
    • 安全性:Spring Security: 可以与 Spring Cloud 结合,提供安全认证和授权机制,保护微服务的访问。
    • 消息驱动:Spring Cloud Stream提供了基于消息中间件的微服务通信方式,支持多种消息中间件(如 RabbitMQ、Kafka),实现异步消息传递。
    • 监控与管理:Spring Boot Actuator: 提供了监控和管理微服务的功能,可以查看服务的健康状态、指标等。
示例代码:

下面使用 Spring Cloud OpenFeign 实现rpc跨服务调用:

(1)添加依赖

在 pom.xml 中添加 OpenFeign 的依赖。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
(2)启用 Feign 客户端

在主应用类上添加 @EnableFeignClients 注解。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableFeignClients
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
(3)定义 Feign 客户端

创建一个接口并使用 @FeignClient 注解。

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;@FeignClient(name = "service-name") // service-name 是要调用的服务名称
public interface MyFeignClient {@GetMapping("/api/resource/{id}") // 指定调用服务的接口地址Resource getResourceById(@PathVariable("id") Long id);
}
(4)使用 Feign 客户端

在服务中注入并使用 Feign 客户端。通过调用客户端接口中的方法,就会调用到该方法@GetMapping注解中对应的远程服务的接口。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate MyFeignClient myFeignClient;public Resource fetchResource(Long id) {return myFeignClient.getResourceById(id);}
}

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

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

相关文章

WHAT - React 富文本编辑器推荐

目录 1. Draft.js2. Slate.js3. Quill4. TinyMCE5. CKEditor6. react-quill7. TipTap8. Lexical React 生态中有许多优秀的开源富文本编辑器可供使用&#xff0c;以下是一些常用的选择&#xff1a; 1. Draft.js Draft.js 优点&#xff1a; 由 Facebook 开发和维护&#xff0…

php使用file_get_contents返回false

php使用file_get_contents返回false, 具体报错内容如下: failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request 解决方式1 : 使用curl 替换 file_get_contents 解决方式2 : 请检查请求网址中是否包含中文, 将中文部分进行urlencode function encodeChin…

国产GPU中,VLLM0.5.0发布Qwen2.5-14B-Instruct-GPTQ-Int8模型,请求返回结果乱码

概述 国产GPU: DCU Z100 推理框架&#xff1a; vllm0.5.0 docker容器化部署 运行如下代码&#xff1a; python -m vllm.entrypoints.openai.api_server --model /app/models/Qwen2.5-14B-Instruct-GPTQ-Int8 --served-model-name qwen-gptq --trust-remote-code --enforce…

WireShark速成

1.WireShark安装 官网&#xff1a; Wireshark Go Deep Kali Linux系统自带WireShark工具。 2.WireShark介绍 WireShark是一个网络包分析工具&#xff0c;该工具主要用于捕获网络数据包&#xff0c;并自动解析数据包&#xff0c;为用户显示数据包的详情信息&#xff0c;供…

算法-字符串-72.编辑距离

一、题目 二、思路解析 1.思路&#xff1a; 最少操作数——动态数组 res[i][j]:长度为i的字符串转化为长度为j字符串的最少操作 2.常用方法&#xff1a; 无 3.核心逻辑&#xff1a; 1.情况一&#xff1a;当word1为空&#xff0c;word2不为空时 for(int i0;i<size2;i){res[0…

uniapp-内部项目使用文档

uniapp-内部项目使用文档 目录 uniapp-内部项目使用文档阶段1自行实现内容&#xff1a;阶段1问题记录&#xff1a; 阶段2自行实现内容&#xff1a; 阶段3 APP项目介绍及规范阶段4 公共组件方法UseList 列表页面HooksListItem 列表项uni-load-more 列表加载更多组件CardTitle 列…

大模型在辅导场景的深度应用,猿辅导素养课推出启发性“AI作文通”

猿辅导集团旗下的飞象星球面向学校发布“飞象AI作文”&#xff0c;让教育大模型成为老师的AI批改助手、学生的写作助手。芥末堆注意到&#xff0c;猿辅导集团旗下的猿辅导素养课也推出了名为“AI作文通”的AI作文功能&#xff0c;已于7月正式大规模上线&#xff0c;在AI教育领域…

Node.js系统模块

【图书介绍】《Node.jsMongoDBVue.js全栈开发实战》-CSDN博客 《Node.jsMongoDBVue.js全栈开发实战&#xff08;Web前端技术丛书&#xff09;》(邹琼俊)【摘要 书评 试读】- 京东图书 (jd.com) 2.2.1 什么是系统模块 由于Node.js运行环境提供的API都是以模块化的方式进行开…

路由封装,连接导航router-link

路由的封装抽离&#xff1a; 所有路由配置堆在main.js中不合适&#xff0c;需将路由模块抽离出来&#xff0c;以便维护 将与路由相关信息提取到src文件夹下的router文件夹下的index.js文件中 在main.js中就只需要导入当前路由&#xff0c;并且注入到当前实例中&#xff0c;其他…

工业4.0下的IT网络与OT网络

https://zhuanlan.zhihu.com/p/498984722 随着“中国制造2025”的深入推进&#xff0c;制药行业以手工为主的传统生产方式正在被以“工业4.0 ”为核心的自动化生产方式逐步替代。 为了实现生产自动化&#xff0c;很多制药企业都引入了由PLC&#xff08;可编程逻辑控制器 &am…

Ubuntu压缩打包解压

ubuntu压缩打包 上图&#xff0c;压缩当前目录svn 为svn.tar.gaz&#xff0c;解压后再当前解压目录生成svn文件 在Ubuntu中&#xff0c;你可以使用tar命令来创建一个压缩包&#xff0c;或者使用zip命令来创建一个.zip压缩文件。以下是两种常见的压缩方法&#xff1a; 下图&am…

【FAQ】HarmonyOS SDK 闭源开放能力 —Remote Communication Kit

1.问题描述&#xff1a; DynamicDnsRule有没有示例&#xff1f;这个地址是怎么解析出来 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/remote-communication-rcp-0000001770911890#section8160554134811 解决方案&#xff1a; ‘DynamicDnsRule’&a…

记录c语言一些有趣的疑问

一些有趣的疑问 字符串栈数组调用字符串库API进行赋值么 char szStackStr[] "Hello World!";答案&#xff1a;使用机器指令进行硬编码 无限循环存在比较指令么 while(1) {printf("Hello World!\n"); }答案&#xff1a;while开始处&#xff0c;即使是没…

Master EDI 项目需求分析

Master Electronics 通过其全球分销网络&#xff0c;支持多种采购需求&#xff0c;确保能够为客户提供可靠的元件供应链解决方案&#xff0c;同时为快速高效的与全球伙伴建立合作&#xff0c;Master 选择通过EDI来实现与交易伙伴间的数据传输。 EDI为交易伙伴之间建立了一个安…

人脸识别之Python的人工智能研究(附学习资源)

1. 引言&#xff1a;人脸识别的意义与挑战 人脸识别技术已经在多个领域得到了广泛应用&#xff0c;包括手机解锁、公共安全监控、社交媒体、人机交互等。这项技术的普及不仅提高了生活的便利性&#xff0c;也为社会安全提供了有效的支持。然而&#xff0c;随着人脸识别技术的不…

时频转换 | Matlab梅尔频谱图Mel spectrogram一维数据转二维图像方法

目录 基本介绍程序设计参考资料获取方式 基本介绍 时频转换 | Matlab梅尔频谱图Mel spectrogram一维数据转二维图像方法 程序设计 clear clc % close all load 130.mat % 导入数据 x X130_DE_time; % 本数据只选择5120个点进行分析 x x(1:120000,:); fs 12000 ; % 数据…

Milvus向量数据库03-搜索理论

Milvus向量数据库03-搜索理论 1-ANN搜索 通过 k-最近邻&#xff08;kNN&#xff09;搜索可以找到一个查询向量的 k 个最近向量。kNN 算法将查询向量与向量空间中的每个向量进行比较&#xff0c;直到出现 k 个完全匹配的结果。尽管 kNN 搜索可以确保准确性&#xff0c;但十分耗…

STM32 出租车计价器系统设计(一) 江科大源码改写

STM32 出租车计价器系统设计 功能目标 驱动步进电机模拟车轮旋转&#xff0c;并实现调速功能。 设置车轮周长和单价&#xff0c;检测车轮转速和运转时间。 计算并显示行驶里程和价格。 硬件材料 28BYJ48 五线四相步进电机和 ULN2003 驱动板模块 测速传感器模块 嵌入式小系统…

顶顶通电话机器人开发接口对接大语言模型之实时流TTS对接介绍

大语言模型一般都是流式返回文字&#xff0c;如果等全部文字返回了一次性去TTS&#xff0c;那么延迟会非常严重&#xff0c;常用的方法就是通过标点符号断句&#xff0c;返回了一句话就提交给TTS。随着流TTS的出现&#xff0c;就可以直接把大模型返回的文字灌给流TTS&#xff0…

问题清除指南|AEROBLADE论文复现相关要点总结

前言&#xff1a;本篇博客总结本人在复现 CVPR 2024 论文 AEROBLADE 过程中遇到的一些问题及解决方案。 注&#xff1a;仅仅使用了论文github源码中的Quickstart部分。 论文链接&#x1f517;&#xff1a;AEROBLADE: Training-Free Detection of Latent Diffusion Images Using…