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 providers
    int totalWeight = 0; // The sum of weights
    boolean sameWeight = true; // Every provider has the same weight?
    for (int i = 0; i < length; i++) {
        int weight = getWeight(invokers.get(i), invocation);
        totalWeight += weight; // Sum
        if (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 {
    @Override
    public 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);
    }

    @Override
    public 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 进行服务开发和部署。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core - 配置系统之配置添加

ASP.NET Core - 配置系统之配置添加 2. 配置添加 2. 配置添加 配置系统可以读取到配置文件中的信息&#xff0c;那必然有某个地方可以将配置文件添加到配置系统中。之前的文章中讲到 ASP.NET Core 入口文件中&#xff0c;builder(WebApplicationBuilder 对象) 中有一个 Config…

C#中通道(Channels)的应用之(生产者-消费者模式)

一.生产者-消费者模式概述 生产者-消费者模式是一种经典的设计模式&#xff0c;它将数据的生成&#xff08;生产者&#xff09;和处理&#xff08;消费者&#xff09;分离到不同的模块或线程中。这种模式的核心在于一个共享的缓冲区&#xff0c;生产者将数据放入缓冲区&#x…

ArcSegment绘制及计算

ArcSegment绘制及计算 给定起始点、终止点和 bulge 值计算弧线中心点和半径&#xff0c;绘制ArcSegment。 import math def calculate_arc_center_and_radius(x1, y1, x2, y2, bulge):angle4*math.atan(bulge)# 计算弦中点mid_x (x1 x2) / 2mid_y (y1 y2) / 2# 计算弦长的…

【高可用自动化体系】自动化体系

架构设计的愿景就是高可用、高性能、高扩展、高效率。为了实现架构设计四高愿景&#xff0c;需要实现自动化系统目标&#xff1a; 标准化。 流程自助化。 可视化&#xff1a;可观测系统各项指标、包括全链路跟踪。 自动化&#xff1a;ci/cd 自动化部署。 精细化&#xff1a…

FakeLocation 1599 | 内部旧版

前言:FakeLocation又更新了,在某安上面看见一些&#xff0c;大概问题就是地图没了&#xff0c;然后有更难搞了 任务一 我们先去看看地图是怎么个事情 这里用的是百度地图就没有了哈 高德地图是有的 任务二 null 选择成功了&#xff0c;虽然是null 任务三 地图位置 虽然不显示了…

初识算法和数据结构P1:保姆级图文详解

文章目录 前言1、算法例子1.1、查字典&#xff08;二分查找算法&#xff09;1.2、整理扑克&#xff08;插入排序算法&#xff09;1.3、货币找零&#xff08;贪心算法&#xff09; 2、算法与数据结构2.1、算法定义2.2、数据结构定义2.3、数据结构与算法的关系2.4、独立于编程语言…

2025年华数杯国际赛B题论文首发+代码开源 数据分享+代码运行教学

176项指标数据库 任意组合 千种组合方式 14页纯图 无水印可视化 63页无附录正文 3万字 1、为了方便大家阅读&#xff0c;全文使用中文进行描述&#xff0c;最终版本需自行翻译为英文。 2、文中图形、结论文字描述均为ai写作&#xff0c;可自行将自己的结果发给ai&#xff0c…

CSS的小知识

一、子选择器 (>) 让 CSS 样式只作用于子级和孙级元素&#xff0c;而不影响其他元素 有>是只对其子级有效&#xff0c;子选择器只会影响直接的子级元素&#xff0c;而不会影响更深层次的孙级元素 无>时是对子级、孙级、曾孙级等所有后代都有效

【经管数据】ZF数字采购采购明细数据(2015.3-2024.3)

一、数据来源&#xff1a; 原始数据来源为ZF采购网。数据涵盖了自2015年3月至2024年3月的ZF数字采购合同明细&#xff0c;反映了数字化转型在政府采购中的应用情况。 二、参考文献&#xff1a; [1] 申志轩, 祝树金, 文茜, 等. ZF数字采购与企业数字化转型[J]. 数量经济技术经济…

【Linux】Mysql部署步骤

一、JDK安装配置 在home目录下执行命令&#xff1a;mkdir Jdk 1.将JDK 上传至该文件夹&#xff0c;有些终端工具可以直接上传文件&#xff0c;比如&#xff1a;MobaXterm 可以看到安装包已经上传上来了 2.直接安装 命令&#xff1a;rpm -ivh jdk-8u311-linux-x64.rpm 3.安装成…

虚拟同步机(VSG)Matlab/Simulink仿真模型

虚拟同步机控制作为原先博文更新的重点内容&#xff0c;我将在原博客的基础上&#xff0c;再结合近几年的研究热点对其内容进行更新。Ps&#xff1a;VSG相关控制方向的simulink仿真模型基本上都搭建出来了&#xff0c;一些重要的控制算法也完成了实验验证。 现在搭建出来的虚拟…

二分查找算法——点名

一.题目描述 LCR 173. 点名 - 力扣&#xff08;LeetCode&#xff09; 二.题目解析 有0~n-1这n个数&#xff0c;但是数组中只有n-1个数&#xff0c;我们要找到消失的那个数。 三.算法原理 1.哈希表 我们先创建一个n个数的哈希表并初始化为0&#xff0c;然后将数组中的数存放…

FIDO2密码钥匙与无密码认证:打造安全便捷的数字世界

在数字化时代&#xff0c;密码曾被视为网络安全的基石&#xff0c;但随着网络攻击手段日益复杂&#xff0c;传统的密码认证方法越来越无法抵御这些挑战。对于用户来说&#xff0c;登录密码不仅繁琐易忘&#xff0c;而且一旦泄露&#xff0c;往往会导致数据泄露&#xff0c;造成…

Jmeter进行http接口并发测试

目录&#xff1a; 1、Jmeter设置&#xff08;1&#xff09;设置请求并发数&#xff08;2&#xff09;设置请求地址以及参数&#xff08;3&#xff09;添加结果数 2、启动看结果 1、Jmeter设置 &#xff08;1&#xff09;设置请求并发数 &#xff08;2&#xff09;设置请求地址…

osg中实现模型的大小、颜色、透明度的动态变化

以博饼状模型为对象,实现了模型大小、颜色、透明度的动态变化。 需要注意的是一点: // 创建材质对象osg::ref_ptr<osg::Material> material = new osg::Material;material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0.0, 1.0, 0.0, 0.5));// 获取模型的…

VSCode使用纪要

1、常用快捷键 1&#xff09;注释 ctrl? 单行注释&#xff0c; altshifta 块注释&#xff0c; 个人测试&#xff0c;ctrl? 好像也能块注释 2&#xff09;开多个项目 可以先开一个新窗口&#xff0c;再新窗口打开另一个项目&#xff0c;这时就是同时打开多个项目了。 打开…

Jmeter 简单使用、生成测试报告(一)

一、下载Jmter 去官网下载&#xff0c;我下载的是apache-jmeter-5.6.3.zip&#xff0c;解压后就能用。 二、安装java环境 JMeter是基于Java开发的&#xff0c;运行JMeter需要Java环境。 1.下载JDK、安装Jdk 2.配置java环境变量 3.验证安装是否成功&#xff08;java -versio…

Linux 服务器挖矿木马防护实战:快速切断、清理与加固20250114

Linux 服务器挖矿木马防护实战&#xff1a;快速切断、清理与加固 引言 挖矿木马作为一种常见的恶意软件&#xff0c;对服务器资源和安全构成严重威胁。据安全机构统计&#xff0c;2023 年全球约 45%的 Linux 服务器遭受过挖矿木马攻击&#xff0c;平均每台被感染服务器每月造…

Linux Kernel 之十 详解 PREEMPT_RT、Xenomai 的架构、源码、构建及使用

概述 现在的 RTOS 基本可以分为 Linux 阵营和非 Linux 阵营这两大阵营。非 Linux 阵营的各大 RTOS 都是独立发展,使用上也相对独立;而 Linux 阵营则有多种不同的实现方法来改造 Linux 以实现实时性要求。本文我们重点关注 Linux 阵营的实时内核实现方法! 本文我们重点关注 …

计算机网络(四)——网络层

目录 一、功能 二、IP数据报分片 三、DHCP动态主机配置协议 四、网络地址转换&#xff08;NAT&#xff09;技术 五、无分类编址CIDR 六、ARP地址解析协议 七、ICMP网际控制报文协议 八、IPv4和IPv6的区别 九、IPv4向IPv6的两种过渡技术——双栈协议和隧道技术 十、路由…