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

RPC 源码解析~Apache Dubbo

解析 RPC(远程过程调用)的源码可以帮助你深入理解其工作原理和实现细节。为了更好地进行源码解析,我们选择一个流行的 RPC 框架——Apache Dubbo 作为示例。Dubbo 是一个高性能、轻量级的开源 Java RPC 框架,广泛应用于企业级应用中。

Dubbo的优劣势

优势
  1. 高性能:

    • Dubbo 使用 Netty 作为底层通信框架,支持高并发场景下的高效通信。
    • 支持多种序列化方式(如 Hessian2, Kryo, FST 等),可以根据需要选择最合适的序列化方案以提升性能。
  2. 丰富的功能:

    • 提供多种负载均衡策略(如 RandomLoadBalance, RoundRobinLoadBalance 等)。
    • 内置了服务降级、熔断和限流机制,增强了系统的健壮性。
    • 支持多协议(如 Dubbo 协议, HTTP 协议等),灵活适应不同的应用场景。
  3. 良好的生态系统:

    • 拥有成熟的社区支持和丰富的文档资源。
    • 可与 Spring Boot 和 Spring Cloud 等主流框架无缝集成,简化开发流程。
  4. 细粒度控制:

    • 提供详细的配置选项,允许开发者对每个服务进行精细化管理。
    • 支持服务分组、版本控制等功能,便于维护和升级。
  5. 强大的监控能力:

    • 内置了监控中心,可以实时查看服务的调用情况和性能指标。
    • 支持与其他监控系统(如 Prometheus, Grafana)集成,实现全面的监控解决方案。
劣势
  1. 依赖复杂:

    • Dubbo 依赖较多,引入时可能需要额外配置多个组件(如注册中心、序列化库等)。
    • 学习曲线相对陡峭,初学者需要一定时间掌握其复杂的配置和使用方法。
  2. 扩展性有限:

    • 尽管 Dubbo 提供了插件机制,但相对于一些现代微服务框架(如 Spring Cloud),其扩展性和灵活性稍显不足。
    • 对于某些特定需求,可能需要自行开发插件或中间件来满足。
  3. 生态整合难度:

    • 虽然可以与 Spring Boot 和 Spring Cloud 集成,但在某些高级特性上可能存在兼容性问题。
    • 相比 Spring Cloud 生态更为丰富和成熟,Dubbo 的第三方组件和支持程度略逊一筹。
  4. 社区活跃度:

    • 虽然 Dubbo 社区活跃,但由于近年来 Spring Cloud 的崛起,部分开发者更倾向于使用后者。
    • 新的功能更新速度相对较慢,不如 Spring Cloud 快速迭代。

解析目标

我们将逐步解析 Dubbo 的核心组件和流程,包括但不限于以下部分:

  1. 服务注册与发现:如何将服务注册到注册中心,并从注册中心发现可用的服务。
  2. 代理机制:客户端和服务端如何通过动态代理来透明地进行远程调用。
  3. 序列化:数据在网络传输过程中如何被序列化和反序列化。
  4. 负载均衡:客户端如何根据不同的策略选择合适的服务提供者。
  5. 通信协议:底层网络通信是如何实现的,包括 Netty 等网络框架的应用。

准备工作

在开始解析之前,请确保你已经具备以下条件:

  1. Java 开发环境:安装 JDK 8 或更高版本。
  2. Git 工具:用于克隆 Dubbo 源码仓库。
  3. IDE:推荐使用 IntelliJ IDEA 或 Eclipse。
  4. Maven:用于构建和管理依赖。

克隆 Dubbo 源码

首先,克隆 Dubbo 的 GitHub 仓库到本地:

bash

git clone https://github.com/apache/dubbo.git
cd dubbo

构建 Dubbo 源码

使用 Maven 构建 Dubbo 源码:

bash

mvn clean install -DskipTests=true

核心组件解析

1. 服务注册与发现

Dubbo 使用 ZooKeeper 作为默认的注册中心。以下是服务注册和发现的核心流程。

服务注册

当服务提供者启动时,会将其元数据注册到注册中心。主要涉及 RegistryProtocolZookeeperRegistry 类。

  • RegistryProtocol: 负责处理服务注册和订阅逻辑。
  • ZookeeperRegistry: 实现了具体的注册中心操作,如连接 ZooKeeper 并执行注册。

关键代码位置:

  • dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/RegistryProtocol.java
  • dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java

核心方法:

  • export(Invoker<T> invoker): 导出服务并注册到注册中心。
  • doRegister(URL url): 执行实际的注册操作。

示例代码:

java

@Override
public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {URL registryUrl = getRegistryUrl(originInvoker);// 创建注册器实例Registry registry = getRegistry(registryUrl);final URL providerUrl = getProviderUrl(originInvoker, registryUrl);// 向注册中心注册服务final URL registeredProviderUrl = getRegisteredProviderUrl(providerUrl, registryUrl);ProviderModel providerModel = new ProviderModel(providerUrl.getServiceKey(), originInvoker, providerUrl);ApplicationModel.registerProvider(providerModel);registry.register(registeredProviderUrl);// 订阅 override 数据registry.subscribe(getSubscribedOverrideUrl(providerUrl), event -> {if (logger.isDebugEnabled()) {logger.debug("Notify urls for subscribe url " + event.getUrl() + ", urls: " + event.getUrls());}Map<String, String> notifiedUrls = new HashMap<>();if (CollectionUtils.isNotEmpty(event.getUrls())) {event.getUrls().forEach(url -> notifiedUrls.put(url.getServiceKey(), url.toFullString()));}refreshOverrideAndInvoker(providerUrl, notifiedUrls);});exporterMapLock.lock();try {ExporterChangeableWrapper<T> exporter = new ExporterChangeableWrapper<>(originInvoker, null);exporters.put(originInvoker, exporter);return exporter;} finally {exporterMapLock.unlock();}
}
服务发现

当服务消费者启动时,会从注册中心订阅服务提供者的地址列表。主要涉及 RegistryProtocolZookeeperRegistry 类。

  • RegistryProtocol: 处理订阅逻辑,并生成服务代理。
  • ZookeeperRegistry: 监听注册中心的变化,并通知消费者。

关键代码位置:

  • dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/RegistryProtocol.java
  • dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperRegistry.java

核心方法:

  • refer(Class<T> type, URL url): 引用远程服务并创建代理对象。
  • doSubscribe(URL url, NotifyListener listener): 执行实际的订阅操作。

示例代码:

java

@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, mapLocalHost(url.getParameter(Constants.REGISTER_IP_KEY, NetUtils.getLocalHost())), 0,type.getName(), url.getParameters());// 设置检查是否延迟暴露if (!Constants.YES_VALUE.equals(url.getParameter(Constants.LAZY_CONNECT_KEY))) {checkWhetherMetadataCenterExist(subscribeUrl);List<URL> urls = registryCache.get(subscribeUrl);if (urls != null && !urls.isEmpty()) {// 如果存在直接返回StaticDirectory<T> directory = new StaticDirectory<>(subscribeUrl, toInvokers(urls));doRefer(subscribeUrl, directory);return cluster.join(directory);}}// 创建动态目录DynamicDirectory<T> directory = new DynamicDirectory<>(subscribeUrl, registry, directoryFactory, false);directory.buildRouterChain(subscribeUrl);directory.setConsumerUrl(subscribeUrl);directoryList.add(directory);registry.subscribe(subscribeUrl, new CacheListener(directory, url));// 创建集群Invoker<T> clusterInvoker = cluster.join(directory);providersModel.setClusterInvoker(clusterInvoker);return clusterInvoker;
}
2. 代理机制

Dubbo 使用动态代理来简化远程调用的过程。主要涉及 ProxyFactoryJavassistProxyFactory 类。

  • ProxyFactory: 定义了代理工厂接口。
  • JavassistProxyFactory: 实现了具体的代理创建逻辑。

关键代码位置:

  • dubbo-common/src/main/java/org/apache/dubbo/common/proxy/ProxyFactory.java
  • dubbo-proxy/dubbo-proxy-javassist/src/main/java/org/apache/dubbo/common/proxy/javassist/JavassistProxyFactory.java

核心方法:

  • getProxy(Invoker<?> invoker): 获取服务代理对象。
  • getInvoker(T proxy, Class<T> type, URL url): 将代理对象转换为 Invoker。

示例代码:

java

@Override
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}@Override
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {// TODO Wrapper cannot handle this scenario at this moment.throw new UnsupportedOperationException("Not supported.");
}
3. 序列化

Dubbo 支持多种序列化方式,如 Hessian2, Kryo, FST 等。主要涉及 Serialization 和具体序列化类。

  • Serialization: 定义了序列化接口。
  • Hessian2Serialization: 实现了 Hessian2 序列化的具体逻辑。

关键代码位置:

  • dubbo-common/src/main/java/org/apache/dubbo/common/serialize/Serialization.java
  • dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2Serialization.java

核心方法:

  • serialize(URL url, OutputStream output): 返回序列化对象。
  • deserialize(URL url, InputStream input): 返回反序列化对象。

示例代码:

java

@Override
public ObjectOutput serialize(URL url, OutputStream out) throws IOException {Hessian2ObjectOutputStream hessian2os = new Hessian2ObjectOutputStream(out);com.caucho.hessian.io.SerializerFactory serializerFactory = getSerializerFactory(url);if (serializerFactory != null) {hessian2os.setSerializerFactory(serializerFactory);}return new CompatibleObjectOutput(hessian2os);
}@Override
public ObjectInput deserialize(URL url, InputStream is) throws IOException {Hessian2ObjectInputStream hessian2is = new Hessian2ObjectInputStream(is);com.caucho.hessian.io.DeserializerFactory deserializerFactory = getDeserializerFactory(url);if (deserializerFactory != null) {hessian2is.setDeserializerFactory(deserializerFactory);}return new CompatibleObjectInput(hessian2is);
}
4. 负载均衡

Dubbo 提供多种负载均衡策略,如 RandomLoadBalance, RoundRobinLoadBalance 等。主要涉及 LoadBalance 和具体策略类。

  • LoadBalance: 定义了负载均衡接口。
  • RandomLoadBalance: 实现了随机负载均衡的具体逻辑。

关键代码位置:

  • dubbo-cluster/src/main/java/org/apache/dubbo/rpc/loadbalance/LoadBalance.java
  • dubbo-cluster/src/main/java/org/apache/dubbo/rpc/loadbalance/RandomLoadBalance.java

核心方法:

  • select(List<Invoker<T>> invokers, URL url, Invocation invocation): 选择合适的 Invoker。

示例代码:

java

@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {int length = invokers.size(); // Number of providersint totalWeight = 0; // The sum of weightsboolean sameWeight = true; // Every provider has the same weight?for (int i = 0; i < length; i++) {int weight = getWeight(invokers.get(i), invocation);totalWeight += weight; // Sumif (sameWeight && i > 0 && weight != getWeight(invokers.get(i - 1), invocation)) {sameWeight = false;}}if (totalWeight > 0 && !sameWeight) {// If (not every provider has the same weight & at least one provider's weight>0), select randomly based on totalWeight.int offset = ThreadLocalRandom.current().nextInt(totalWeight);// Return a invoker based on the random value.for (int i = 0; i < length; i++) {Invoker<T> invoker = invokers.get(i);offset -= getWeight(invoker, invocation);if (offset < 0) {return invoker;}}}// If all providers have the same weight value or totalWeight=0, return evenly.return invokers.get(ThreadLocalRandom.current().nextInt(length));
}
5. 通信协议

Dubbo 支持多种通信协议,如 Dubbo 协议, HTTP 协议等。主要涉及 Transporter 和具体协议类。

  • Transporter: 定义了通信接口。
  • NettyTransporter: 实现了基于 Netty 的通信逻辑。

关键代码位置:

  • dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Transporter.java
  • dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java

核心方法:

  • bind(URL url, ChannelHandler handler): 绑定服务器端口。
  • connect(URL url, ChannelHandler handler): 连接到服务器。

示例代码:

@Override
public Server bind(URL url, ChannelHandler handler) throws RemotingException {return new NettyServer(url, handler);
}@Override
public Client connect(URL url, ChannelHandler handler) throws RemotingException {return new NettyClient(url, wrapChannelHandler(url, handler));
}

示例项目

为了更好地理解上述解析内容,我们可以创建一个简单的 Dubbo 示例项目,包含服务提供者和消费者。

1. 创建服务接口

定义一个简单的服务接口:

UserApi.java:

java

package com.example.dubbo.service;public interface UserApi {String sayHello(String name);
}
2. 实现服务提供者

实现服务接口并启动服务提供者:

UserServiceImpl.java:

java

package com.example.dubbo.provider;import com.example.dubbo.service.UserApi;
import org.apache.dubbo.config.annotation.DubboService;@DubboService(version = "1.0.0")
public class UserServiceImpl implements UserApi {@Overridepublic String sayHello(String name) {return "Hello, " + name;}
}

ProviderApplication.java:

java

package com.example.dubbo.provider;import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@EnableDubbo(scanBasePackages = "com.example.dubbo.provider")
public class ProviderApplication {public static void main(String[] args) {SpringApplication.run(ProviderApplication.class, args);}
}

application.properties:

# Dubbo Application Info
dubbo.application.name=user-provider
dubbo.registry.address=zookeeper://localhost:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
3. 实现服务消费者

创建服务消费者并调用远程服务:

ConsumerApplication.java:

java

package com.example.dubbo.consumer;import com.example.dubbo.service.UserApi;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class ConsumerApplication implements CommandLineRunner {@DubboReference(version = "1.0.0")private UserApi userApi;public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Overridepublic void run(String... args) throws Exception {String result = userApi.sayHello("World");System.out.println(result); // Output: Hello, World}
}

application.properties:

# Dubbo Application Info
dubbo.application.name=user-consumer
dubbo.registry.address=zookeeper://localhost:2181

运行示例

  1. 启动 ZooKeeper: 确保 ZooKeeper 服务正在运行。如果没有安装,可以从 ZooKeeper 官网 下载并按照官方文档进行安装和启动。

  2. 启动服务提供者

bash

cd provider
mvn spring-boot:run

3.启动服务消费者

bash

cd consumer
mvn spring-boot:run

总结

通过对 Dubbo 源码的解析,我们深入了解了 RPC 框架的关键组成部分和工作原理,包括服务注册与发现、代理机制、序列化、负载均衡和通信协议。此外,我们还创建了一个简单的示例项目,展示了如何使用 Dubbo 进行服务开发和部署。

相关文章:

RPC 源码解析~Apache Dubbo

解析 RPC&#xff08;远程过程调用&#xff09;的源码可以帮助你深入理解其工作原理和实现细节。为了更好地进行源码解析&#xff0c;我们选择一个流行的 RPC 框架——Apache Dubbo 作为示例。Dubbo 是一个高性能、轻量级的开源 Java RPC 框架&#xff0c;广泛应用于企业级应用…...

VS Code--常用的插件

原文网址&#xff1a;VS Code--常用的插件_IT利刃出鞘的博客-CSDN博客 简介 本文介绍VS Code&#xff08;Visual Studio Code&#xff09;常用的插件。 插件的配置 默认情况下&#xff0c;插件会放到这里&#xff1a;C:\Users\xxx\.vscode\extensions 修改插件位置的方法 …...

深度学习 Pytorch 张量的索引、分片、合并以及维度调整

张量作为有序的序列&#xff0c;也是具备数值索引的功能&#xff0c;并且基本索引方法和python原生的列表、numpy中的数组基本一致。 不同的是&#xff0c;pytorch中还定义了一种采用函数来进行索引的方式。 作为pytorch中的基本数据类型&#xff0c;张量既具备了列表、数组的基…...

神州数码--制作wifi

防火墙: #ip vrouter trust-vr#router ospf 1#router-id 8.8.8.8#network 10.0.0.0/30 area 0.0.0.0#network 10.0.0.4/30 area 0.0.0.0#network 10.0.0.8/30 area 0.0.0.0 交换机&#xff1a; #vlan 10;50#ip add 192.168.10.1 255.255.255.0#int vlan 50#ip add 192.168.50.…...

Web前端开发技术之HTMLCSS知识点总结

学习路线 一、新闻网界面1. 代码示例2. 效果展示3. 知识点总结3.1 HTML标签和字符实体3.2 超链接、颜色描述与标题元素3.3 关于图片和视频标签&#xff1a;3.4 CSS引入方式3.5 CSS选择器优先级 二、flex布局1. 代码示例2. 效果展示3. 知识点总结3.1 span标签和flex容器的区别3.…...

客户案例:致远OA与携程商旅集成方案

一、前言 本项目原型客户公司创建于1992年,主要生产并销售包括糖果系列、巧克力系列、烘焙系列、卤制品系列4大类,200多款产品。公司具有行业领先的生产能力,拥有各类生产线100条,年产能超过10万吨。同时,经过30年的发展,公司积累了完善的销售网络,核心经销商已经超过1200个,超…...

【常见BUG】Spring Boot 和 Springfox(Swagger)版本兼容问题

???欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老…...

【Python】FastAPI入门

文章目录 第一节&#xff1a;FastAPI入门一、FastAPI框架介绍什么是ASGI服务&#xff08;WSGI&#xff09;1、补充Web开发1&#xff09;Web前端开发2&#xff09;Web后端开发 二、FastAPI安装1、安装Python虚拟环境2、安装FastAPI 三、第一个FastAPI案例1、访问接口和文档2、接…...

JavaScript系列(32)-- WebAssembly集成详解

JavaScript WebAssembly集成详解 &#x1f680; 今天&#xff0c;让我们深入了解JavaScript与WebAssembly的集成&#xff0c;这是一项能够显著提升Web应用性能的关键技术。 WebAssembly基础概念 &#x1f31f; &#x1f4a1; 小知识&#xff1a;WebAssembly&#xff08;简称W…...

wps数据分析000002

目录 一、快速定位技巧 二、快速选中技巧 全选 选中部分区域 选中部分区域&#xff08;升级版&#xff09; 三、快速移动技巧 四、快速录入技巧 五、总结 一、快速定位技巧 ctrl→&#xff08;上下左右&#xff09;快速定位光标对准单元格的上下部分双击名称单元格中…...

无降智o1 pro——一次特别的ChatGPT专业模式探索

这段时间和朋友们交流 ChatGPT 的使用心得&#xff0c;大家都提到一个很“神秘”的服务&#xff1a;它基于 O1 Pro 模型&#xff0c;能够在对话里一直保持相对高水平的理解和回复&#xff0c;不会突然变得“降智”。同时&#xff0c;整体使用还做了免折腾的网络设置——简单一点…...

前端:前端开发任务分解 / 开发清单

一、背景 前端开发过程中&#xff0c;好多任务同时开发&#xff0c;或者一个大的任务分解为若干个子任务进行开发&#xff0c;分解出去的很多内容容易记不清楚 / 不易过程管理&#xff0c;所以记录表格如下&#xff0c;方便开发同事&#xff0c;也辅助掌握整体开发情况。 二、…...

【Django自学】Django入门:如何使用django开发一个web项目(非常详细)

测试机器&#xff1a;windows11 x64 python版本&#xff1a;3.11 一、安装Django 安装步骤非常简单&#xff0c;使用pip安装就行 pip install django安装完成之后&#xff0c;python的 Scripts 文件夹下&#xff0c;会多一个 django-admin.exe (管理创建django项目的工具)。…...

面试经验分享-回忆版某小公司

说说你项目中数据仓库是怎么分层的&#xff0c;为什么要分层&#xff1f; 首先是ODS层&#xff0c;连接数据源和数据仓库&#xff0c;数据会进行简单的ETL操作&#xff0c;数据来源通常是业务数据库&#xff0c;用户日志文件或者来自消息队列的数据等 中间是核心的数据仓库层&a…...

WebSocket——推送方案选型

一、前言&#xff1a;为何需要服务端主动推送&#xff1f; 在现代应用中&#xff0c;很多功能都依赖于“消息推送”。比如&#xff1a; 小红点提醒&#xff1a;我们经常在手机应用里看到的一个小红点提示&#xff0c;表示有新的消息或任务需要我们关注。新消息提醒&#xff1…...

山石防火墙命令行配置示例

现网1台山石SG6000防火墙&#xff0c;配置都可以通过GUI实现。 但有一些配置在命令行下配置效率更高&#xff0c;比如在1个已有策略中添加1个host或端口。 下面的双引号可以不加 1 创建服务 1.1 单个端口 service "tcp-901"tcp dst-port 901 1.2 端口范围 servi…...

LLM - 大模型 ScallingLaws 的 C=6ND 公式推导 教程(1)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145185794 Scaling Laws (缩放法则) 是大模型领域中&#xff0c;用于描述 模型性能(Loss) 与 模型规模N、数据量D、计算资源C 之间关系的经验规律…...

Leetcode 983. 最低票价 动态规划

原题链接&#xff1a;Leetcode 983. 最低票价 class Solution { public:int mincostTickets(vector<int>& days, vector<int>& costs) {int n days.size();int last days[n - 1];int dp[last 1];map<int, int> mp;for (auto x : days)mp[x] 1;dp…...

Kafka——两种集群搭建详解 k8s

1、简介 Kafka是一个能够支持高并发以及流式消息处理的消息中间件&#xff0c;并且Kafka天生就是支持集群的&#xff0c;今天就主要来介绍一下如何搭建Kafka集群。 Kafka目前支持使用Zookeeper模式搭建集群以及KRaft模式&#xff08;即无Zookeeper&#xff09;模式这两种模式搭…...

springboot使用websocket

文章目录 一、概述1、简介 二、 使用1、引包2、配置处理器3、前端测试 一、概述 1、简介 简介略&#xff0c;附上官方文档&#xff0c;spring5和spring6的官方文档内容大致是一样的&#xff1a; https://docs.spring.io/spring-framework/docs/5.2.25.RELEASE/spring-framewo…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...