目录

2.5.5 DHCP服务

2.5.6 Linux Network NameSpace

2.5.7 VLAN网络

2.5.8 Routing

2.5.9 VXLAN网络

2.5.10 L2 Population

2.5.11 Security Group

2.5.12  Neutron FWaaS

2.5.13 Neutorn LBaaS

至此linux-bridge部分实现neutron网络暂告一段落,后续具体细节部分再针对性的讲解!


2.5.5 DHCP服务

Neutron 提供 DHCP 服务的组件是 DHCP agent。DHCP agent 在网络节点运行上,默认通过 dnsmasq 实现 DHCP 功能。

DHCP agent 的配置文件位于 /etc/neutron/dhcp_agent.ini。(正常来说一般不需要什么特殊配置)

  • dhcp_driver:使用 dnsmasq 实现 DHCP。
  • interface_driver:使用 linux bridge 连接 DHCP namespace interface。

dnsmasq 是一个提供 DHCP 和 DNS 服务的开源软件。一般一个dnsmasp进程对应一个network,可以为该network内开启了dhcp服务的所有subnet提供服务。DHCP agent 会为每个 network 创建一个目录 /opt/stack/data/neutron/dhcp/,用于存放该 network 的 dnsmasq 配置文件。

dnsmasq 重要的启动参数:(1)--dhcp-hostsfile:存放 DHCP host 信息的文件,dnsmasq 从该文件获取 host 的 IP 与 MAC 的对应关系。 /opt/stack/data/neutron/dhcp/xxx(对应某个netwrok)/host下记录着DHCP、所有VM的Interface信息;(2)--interface:指定提供 DHCP 服务的 interface。dnsmasq 会在该 interface 上监听 instance 的 DHCP 请求;

2.5.6 Linux Network NameSpace

每个 namespace 都有自己独立的网络栈,包括 route table,firewall rule,network interface device 等。Neutron 通过 namespace 为每个 network 提供独立的 DHCP 和路由服务,从而允许租户创建重叠的网络。如果没有 namespace,网络就不能重叠,这样就失去了很多灵活性。

每个 dnsmasq 进程都位于独立的 namespace, 命名为 qdhcp-<network id>(每个dnsmasq进程又对应一个network)。ip netns list 命令可以列出所有的namespace。主机本身也有一个 namespace,叫 root namespace,拥有所有物理和虚拟 interface device。物理 interface 只能位于 root namespace。

        veth pair:解决了dhcp的interface(tap设备)无法直接与 root namespace 中的 bridge 设备连接。dhcp的ns设备与tap设备被称为一对veth pair,用来将dhcp的namespace连接到root namespace 中的 bridge 设备,可以通过 ip netns exec <network namespace name> <command>管理 namespace。连接关系如下图所示:

一台VM实例创建并启动dhcp获取到ip的过程如下:

  1. 在dashboard上创建VM时,neutron会给VM分配一个port,该port包含ip/mac信息,这些信息会自动同步到dnsmasq的host文件,同时compute节点会给创建的VM分配该port对应的mac地址;
  2. VM开机启动,发出 DHCP DISCOVER 广播,该广播消息在整个对应的network中(subnet的tap设备)都可以被收到;
  3. dhcp广播报文到达DHCP的tap设备,然后传送给veth pair另一端ns设备。dnsmasq在ns设备上面进行侦听,dnsmasq收到其dhcp discover于是对比自己的host文件发现有对应项(应该是通过mac对比),从而将对应的ip地址、掩码、地址租期信息返回给VM;
  4. VM发送 DHCPREQUEST 消息确认接受此 DHCPOFFER;
  5. dnsmasq 发送确认消息 DHCPACK,整个过程结束;

2.5.7 VLAN网络

vlan网络是待tag的网络类型,在实际应用中有较多使用。由于vlan数量有限制(4096),因此不能无限创建vlan。VM通过tap设备连接到对应的网桥上,网桥另一端连接网卡的子接口,数据流量到网卡子接口会被打上vlan tag并传送给网卡主接口,从而实现宿主机上vlan的网络隔离。(一个宿主机网卡可以有多个网卡子接口)

执行vi /etc/neutron/plugins/ml2/ml2_conf.ini配置文件,在ML2中将网络类型修改为vlan,定义标签default,指定普通用户创建网络的vlan范围(admin用户可以使用任意自己指定的vlan),并将标签与物理网卡对应起来。修改如下:(配置完成后重启neutron服务生效)

[ml2]
type_drivers = vlan
tenant_network_types = vlan
......[ml2_type_vlan]
network_vlan_ranges =  default:1:4094

例如:创建2个vlan网络,同一个vlan内的vm可以相互通信,不同vlan内的vm是不能互相通信,若要使跨vlan通信就必须进行三层互通,这就涉及到Routing功能。对于相同网络vlan网络其在控制节点和计算节点的网桥名称都是一样的,可以从下图看出:

2.5.8 Routing

Neutron 的路由服务是由 l3 agent 提供的。 除此之外,l3_agent 通过 iptables 提供 firewall 和 floating ip 服务。

配置文件为 /etc/neutron/l3_agent.ini,如果 mechanism driver 是 linux bridge,则需要将interface_driver改为BridgeInterfaceDriver;若mechanism driver是OVS,则需要将interface_driver改为OVSInterfaceDriver。l3_agent运行在控制节点或者网络节点上。

当创建完成一个vrouter后,底层网桥会给vrouter的接口分配一个tap设备,TAP设备上不配置ip地址,l3 agent 会为每个 router 创建了一个 namespace(router 对应的 namespace 命名为 qrouter-<router id>。),通过 veth pair 与 TAP 相连,然后将 Gateway IP 配置在位于 namespace 里面的 veth interface 上,从而实现三层网络通信。网络架构如下图所示。

  • 可以通过ip netns 查看 namespace;
  • ip netns exec <namespace name> ip a查看namespace的veth interface地址配置;

讲到这里,需要思考一个问题?为什么vrouter不直接在tap设备上配置网关地址,而是要在namespace的veth接口上配置?-----答案是:在vrouter多做一层namespace可以起到各个租户之间的网络重叠的作用(每个namespace单独一张路由表),而直接在tap设备上配置IP相当于在root的namespace上添加subnet网段的路由(宿主机操作系统上加路由,查的是宿主机的全局路由表),这样的路由时没办法工作的。这个功能在某些特定场合下很重要。

既然已经通过vrouter实现了跨vlan网络的vm通信,那么如果实现vlan网络与外部网络通信呢?这里的外部网络是指的租户网络以外的网络。租户网络是由 Neutron 创建和维护的网络。外部网络不由 Neutron 创建,是已经存在的物理网络,一般都是flat型或者vlan型。

/etc/neutron/plugins/ml2/ml2_conf.ini 配置如下:

若是flat类型网络,需要如下配置:

若是vlan类型网络,则进行如下配置:

       在dashboard页面上创建完外部网络并关联vrouter后,会对应创建外部网络的网桥和tap设备,同时也会在vrouter对应的namespace中创建对应于tap设备的veth设备。vrouter 的每个 interface 在 namespace 中都有对应的 veth。如果 veth 用于连接租户网络,命名格式为 qr-xxx,比如 qr-d568ba1a-74 和 qr-e17162c5-00。如果 veth 用于连接外部网络,命名格式为 qg-xxx,比如 qg-b8b32a88-03。整体网络架构如下:

当数据包从 router 连接外网的接口 qg-xxx发出的时候,会做一次 Source NAT,即将包的源地址修改为 router 的外网接口地址,这样就能够保证目的端能够将应答的包发回给 router,然后再转发回源端 instance。可以通过iptables命令查看SNAT的相关规则:

ip netns exec 对应router的namespace iptables -t nat -S

SNAT主要是作为内部VM访问外部网络使用,单外部网络无法直接访问内部VM,此时就需要浮动ip来进行DNAT的转换

浮动ip必须要知道的几件事:

  • floating IP 提供静态 NAT 功能,建立外网 IP 与 instance 租户网络 IP 的一对一映射;
  • floating IP 是配置在 router 提供网关的外网 interface 上的,而非 instance 中;
  • router 会根据通信的方向修改数据包的源或者目的地址(这句话意思是对于内访外,则修改数据包源地址为float ip;对于外访内,则修改数据包的目的ip为真实VM的ip);

2.5.9 VXLAN网络

前期讲了flat 网络、vlan网络、local网络,还剩下VXLAN网络和GRE网络,这两种都是Overlay网络。overlay network 是指建立在其他网络上的网络。overlay network 中的节点可以看作通过虚拟(或逻辑)链路连接起来的,不需要关心底层的物理链路。vxlan网络相对于vlan有很强的灵活性和扩展性,主要提现在以下几个方面:

  1. 支持更多的二层网段。vlan的使用12 bit标记vlan ID,最多支持4094个VLAN;Vxlan则用24bit标记vlan ID,最多能支持到 16777216二层网段;
  2. 能更好的利用现有网络途径。vlan网络通过STP进行防环,一半路径被block;VXLAN则直接用MAC in UDP进行封装,利用三层网络进行转发;
  3. 避免物理交换机 MAC 表耗尽。由于采用隧道机制,TOR (Top on Rack) 交换机无需在 MAC 表中记录虚拟机的信息。(现在交换机的MAC规格都很大,不是啥问题)

vxlan报文封装格式如下:

VXLAN Tunnel Endpoint(VTEP)

VXLAN 使用 VXLAN tunnel endpoint (VTEP) 设备处理 VXLAN 的封装和解封。每个 VTEP 有一个 IP interface,配置了一个 IP 地址。VTEP 使用该 IP 封装 Layer 2 frame,并通过该 IP interface 传输和接收封装后的 VXLAN 数据包。VTEP既可以是软件设备(OpenvSwitch)也可以是硬件交换机,VTEP之间建立VXLAN隧道。VXLAN 独立于底层的网络拓扑;反过来,两个 VTEP 之间的底层 IP 网络也独立于 VXLAN。可以用一张图描述数据包在vxlan网络中的传输过程(具体细节就不再阐述,很简单,可以在单独去研究一下vxlan网络架构):

目前比较成熟的 VTEP 软件实现包括:1. 带 VXLAN 内核模块的 Linux;2. Open vSwitch。第一种方式如下,第二种方式待后续讲解openvSwitch时详细说明。

  • 1. Linux vxlan 创建一个 UDP Socket,默认在 8472 端口监听。
  • 2. Linux vxlan 在 UDP socket 上接收到 vxlan 包后,解包,然后根据其中的 vxlan ID 将它转给某个 vxlan interface,然后再通过它所连接的 linux bridge 转给虚机。
  • 3. Linux vxlan 在收到虚机发来的数据包后,将其封装为多播 UDP 包(同一个vxlan的都会收到),从网卡发出

vxlan网络的配置

需要在 /etc/neutron/plugins/ml2/ml2_conf.ini 设置 vxlan network 相关参数:

[ml2]
type_drivers = vlan,vxlan
tenant_network_types = vxlan
mechanism_drivers = linuxbridge,l2population
extension_drivers = port_security[ml2_type_vxlan]
vni_ranges = 1:10000

还需要在ml2_conf.ini中设置vtep:

控制节点/网络节点:

计算节点上同样设置,local_ip即为VTEP的ip地址。注意:作为准备工作,这两个 VTEP IP 需要提前配置到节点的 eth1 上,Neutron 并不会帮我们分配这个 IP。并且,值得注意的是,vxlan网络配置中不会特意配置vxlan标签与网卡的对应关系,它是通过VTEP IP来找到要从哪块网卡出去的。

此时通过 brctl show可以知道底层网络的架构,相比于vlan网络而言,没有eth1.100这种子接口的概念,而是直接用vxlan interface来表示(linuxbridge、vxlan-100、eth1网卡可以对应起来,还会针对这个子网创建了一个DHCP的tap设备,也是连接该linuxbridge),可以ip -d link show dev vxlan-100(创建的vxlan网络名)查看vxlan interface的详细配置。架构如下图:

同一个vxlan内,同一个节点上,VM之前通过linuxbridge就可以直接通信,若是跨节点间,则是通过宿主机间vxlan隧道到达另一主机。

以上vxlan网络只是针对同一个二层网络内进行通信,对于跨vxlan以及vxlan网络到外部网络的通信也是需要依靠vrouter与浮动ip来实现,原理和vlan网络是类似的,此处不再继续阐述。

2.5.10 L2 Population

vxlan组网得环境就是一个大二层网络,如果避免在这种大二层网络中的广播报文占用带宽,就需要L2 Population来解决这个问题。L2 Population 是用来提高 VXLAN 网络 Scalability (可以理解为高效运转)

如下图,VM A要想去访问其他HOST上的同vxlan的节点时会发送arp广播报文,这样整个网络环境里会存在大量的arp广播报文,从而占用网络带宽。此时L2 Population的出现解决了这个问题。

L2 Population可以让HOST开启一个ARP Proxcy的功能,本地的arp广播报文则由本地HOST主机直接响应其arp请求,并使得VTEP能够预先获知 VXLAN 网络的相关信息:(1)VM的IP/MAC信息;(2)VM--VTEP的对应关系。如下图:

那么此时另一个问题又来了,VTEP 是如何提前获知 IP -- MAC -- VTEP 相关信息的呢?答案如下:

  1. Neutron 知道每一个 port 的状态和信息; port 保存了 IP,MAC 相关数据。
  2. instance 启动时,其 port 状态变化过程为:down -> build -> active。
  3. 每当 port 状态发生变化时,Neutron 都会通过 RPC 消息通知各节点上的 Neutron agent,使得 VTEP 能够更新 VM 和 port 的相关信息。

从而每个VTEP都知道了其他(VTEP)HOST上都有哪些VM,这样就大大减少了网络中arp广播报文的带宽占用。

L2 Population的配置参见vxlan中的相关部分。需要在 /etc/neutron/plugins/ml2/ml2_conf.ini 设置 mechanism_drivers = linuxbridge,l2population,l2_population = Ture;

可以通过bridge fdb show dev vxlan-100(vxlan名称)查看节点上的 forwarding database(保存的其他VTEP的地址以及其他VM的MAC);

2.5.11 Security Group

Neutron 为 instance 提供了两种管理网络安全的方法:安全组(Security Group)和虚拟防火墙。安全组的原理是通过 iptables 对 instance 所在计算节点的网络流量进行过滤。虚拟防火墙则由 Neutron Firewall as a Service(FWaaS)高级服务提供。其底层也是使用 iptables,在 Neutron Router 上对网络包进行过滤。

“default” 安全组有四条规则,其作用是:允许所有外出(Egress)的流量,但禁止所有进入(Ingress)的流量。创建VM时如果没有选择其他安全组,则默认强制使用default安全组。安全组功能可理解就是白名单的服务。具体可以在节点上iptables-save 命令查看相关规则,iptables 的规则是应用在 Neutron port 上的,也就是VM的虚拟网卡TAP设备上。

总结下来,安全组特性如下:

  1. 通过宿主机上 iptables 规则控制进出 instance 的流量。
  2. 安全组作用在 instance 的 port 上。
  3. 安全组的规则都是 allow,不能定义 deny 的规则。
  4. instance 可应用多个安全组叠加使用这些安全组中的规则。

2.5.12  Neutron FWaaS

Firewall as a Service(FWaaS)是 Neutron 的一个高级服务。用户可以用它来创建和管理防火墙,在 subnet 边界上对 layer 3 和 layer 4 的流量进行过滤。FWaaS 有三个重要概念:Firewall、Policy 和 Rule。

  • Firewall:租户能够创建和管理的逻辑防火墙资源。Firewall 必须关联某个 Policy,因此必须先创建 Policy。
  • Firewall Policy:Policy 是 Rule 的集合,Firewall 会按顺序应用 Policy 中的每一条 Rule。
  • Firewall Rule:Rule 是访问控制规则,由源与目的子网 IP、源与目的端口、协议、allow 或 deny 动作组成。

防火墙与安全组的区别。可以理解为防火墙的最小作用单元是subnet级别的防护,而安全组则是针对instance的防护。 /etc/neutron/fwaas_driver.ini 文件中设置 FWaaS 使用的 driver:(新版防火墙没有这个driver配置)

还需要在 /etc/neutron/neutron.conf  中启用 FWaaS plugin:

具体可以通过 ip netns <namespace名称> iptables-save查看对应router的防火墙规则状态。最后,FWaaS 用于加强 Neutron 网络的安全性,与安全组可以配合使用,防火墙与安全组的异同点总结如下:

相同点:

  • 1. 底层都是通过 iptables 实现。

不同点:

  • 1. FWaaS 的 iptables 规则应用在 router 上,保护整个租户网络;安全组则应用在虚拟网卡上,保护单个 instance。
  • 2. FWaaS 可以定义 allow 或者 deny 规则;安全组只能定义 allow 规则。

2.5.13 Neutorn LBaaS

LBaaS 有三个主要的概念: Pool Member,Pool 和 Virtual IP。

  1. Pool Member:Pool Member 是 layer 4 的实体,拥有 IP 地址并通过监听端口对外提供服务。
  2. Pool:Pool 由一组 Pool Member 组成。
  3. Virtual IP:Virtual IP 也称作 VIP,是定义在 load balancer 上的 IP 地址

OpenStack Neutron 目前默认通过 HAProxy 软件来实现 LBaaS。 HAProxy 是一个流行的开源 load balancer。 Neutron 也支持其他一些第三方 load balancer。实现方式如下图所示:

配置LB:(最新版本的配置可能与下面有差异,按官网最新版本安装步骤来)

/etc/neutron/services/loadbalancer/haproxy/lbaas_agent.ini。定义 interface_driver:

interface_driver 的作用是设置 load balancer 的网络接口驱动,可以有两个选项:

Linux Bridge

interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver

Open vSwitch


interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver

/etc/neutron/neutron.conf 中设置启用 LBaaS plugin:

在 /etc/neutron/neutron_lbaas.conf 中设置 service provider:

除了默认的 HAProxy,Neutron 也支持第三方 provider,比如 radware,VMWareEdge 等等。

LB的几种负载分担算法:

  • ROUND_ROUBIN:如果采用 round robin 算法,load balancer 按固定的顺序从 pool 中选择 member 相应 client 的连接请求。这种方法的不足是缺乏机制检查 member 是否负载过重。有可能出现某些 member 由于处理能力弱而不得不继续处理新连接的情况。
  • LEAST_CONNECTIONS:如果采用 least connections 算法,load balancer 会挑选当前连接数最少的 pool  member。这是一种动态的算法,需要实时监控每个 member 的连接数量和状态。
  • SOURCE_IP:如果采用 source IP 算法,具有相同 sourSession Persistencece IP 的连接会被分发到同一个 pool member。source IP 算法对于像购物车这种需要保存状态的应用特别有用;

Session Persistence(会话保持):

  • SOURCE_IP:这种方式与前面 load balance 的 SOURCE_IP 效果一样。初始连接建立后,后续来自相同 source IP 的 client 请求会发送给同一个 member;
  • HTTP_COOKIE:当 client 第一次连接到 VIP 时,HAProxy 从 pool 中挑选出一个 member。当此 member 响应请求时,HAProxy 会在应答报文中注入命名为 “SRV” 的 cookie,这个 cookie 包含了该 member 的唯一标识。client 的后续请求都会包含这个 “SRV” cookie。HAProxy 会分析 cookie 的内容,并将请求转发给同一个 member。HTTP_COOKIE 优于 SOURCE_IP,因为它不依赖 client 的 IP。
  • APP_COOKIE:app cookie 依赖于服务器端应用定义的 cookie。比如 app 可以通过在 session 中创建 cookie 来区分不同的 client。HAProxy 会查看报文中的 app cookie,确保将包含 app cookie 的请求发送到同一个 member。

Key Pairs

对于一些登陆密码随机的image,可以使用key pairs的功能来进行免密登陆。 通过ssh-keygen  -t rsa -f xx.key生成 Key Pair,会生成两个文件一个是xx.key。另一个是xx.key.pub。其中 cloud.key.pub 是公钥,需要添加到 instance 的 ~/.ssh/authorized_keys 文件中。 cloud.key 是私钥,用于访问 instance。将公钥cloud.key.pub的内容复制到openstack导入界面中即可,完成导入。然后就可以通过ssh -i指定私钥进行登陆VM了。

健康检查      

需要注意,在LB中配置健康检查的目的是周期性探测WEB Server的活动状态,防止server挂了业务流还持续往故障机器发送;

Neutron中LB的底层实现原理

对于每创建一个pool地址池,Neutron 都会创建新的 namespace qlbaas-xxx,该 namespace 对应我们创建的 pool “web servers”。其命名格式为 qlbaas-< pool ID>。对于每一个 pool,Neutron 都会启动一个 haproxy 进程提供 load balancering 功能。也就是说:一个pool地址池-----namespace-----一个haprocxy进程。haproxy 配置文件保存在 /opt/stack/data/neutron/lbaas/< pool ID>/conf 中。

总结一下:(1)LBaaS 为租户提供了横向扩展应用的能力,租户之间是隔离的。(2)租户可以将外部请求 balancing 到多个 instance 上,并通过 monitor 实现应用的高可用。

至此linux-bridge部分实现neutron网络暂告一段落,后续具体细节部分再针对性的讲解!

openstack neutron网络插件学习(二)【linux-bridge实现】相关推荐

  1. openstack neutron网络插件学习(三)【Open vSwitch实现】

    目录 3.1 Open vSwitch 3.1.1 Open vSwitch配置 3.1.2 OVS中的网络设备类型 3.1.3 Local Network 3.1.4 Flat Network 3. ...

  2. python openstack vpc互通_深入浅出新一代云网络——VPC中的那些功能与基于OpenStack Neutron的实现(二)-带宽控制...

    在VPC功能实现第一篇中,简单介绍了一下VPC网络对租户间隔离能力的提升以及基于路由提供的一系列网络功能.在这一篇中,将继续介绍VPC网络中十分重要的一个内容:网络带宽的控制,共享以及分离. 首先是对 ...

  3. 您必须了解的4种OpenStack Neutron网络类型

    如果您托管的OpenStack虚拟实例需要网络连接,则必须创建一个网络. 有多种类型的网络,为了做出正确的选择,您至少需要了解两个非常重要的网络属性:" router:external&qu ...

  4. CUDA入门和网络加速学习(二)

    0. 简介 最近作者希望系统性的去学习一下CUDA加速的相关知识,正好看到深蓝学院有这一门课程.所以这里作者以此课程来作为主线来进行记录分享,方便能给CUDA网络加速学习的萌新们去提供一定的帮助. 1 ...

  5. neutron linux网络命令,OpenStack Neutron网络组件介绍(重要)

    列出已加载的扩展以验证进程成功启动:neutron-server openstack extension list --network +------------------------------- ...

  6. (47)LINUX应用编程和网络编程之二Linux文件属性

    Linux下的文件系统为树形结构,入口为/ 树形结构下的文件目录: 无论哪个版本的Linux系统,都有这些目录,这些目录应该是标准的.各个Linux发行版本会存在一些小小的差异,但总体来说,还是大体差 ...

  7. (*长期更新)软考网络工程师学习笔记——Linux操作系统中的vi/vim 编辑器详解

    目录 一.vi/vim概念 (一)vi/vim文本编辑器 (二)gedit文本编辑器 二.vi编辑器分类 三.屏幕编辑器 (一)命令模式 1.进入命令模式 2.命令模式下的常用操作 3.退出命令模式 ...

  8. .NET网络编程学习(二)

    System.Net.Sockets有很多类,其中最重要的就是Socket类. Socket类 public class Socket : IDisposable Socket 类为网络通信提供了一套 ...

  9. openstack第四章:neutron— 网络服务

    第四篇neutron- 网络服务 一.neutron 介绍:   Neutron 概述 传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备:而云环境下的网络已经变得非常复杂,特别是 ...

  10. openstack M 版 neutron网络组件基础入门

    在我们openstack学习当中,网络组件neutron无疑是令很多人很难理解的,可以说要深入理解 了neutron组件,你基本完成了openstack 60%的学习,存储方面只要不涉及到分布式,剩下 ...

最新文章

  1. 英文版PDF不能显示中文PDF文件的解决方法
  2. ISA2006英文版实验手册下载
  3. 自学前端的高效学习路线.avi
  4. tcp长连接和短连接的区别_TCP --- 连接
  5. 智能运维监管系统终端_什么系统能实现机房智能运维?
  6. 模式识别的几种基本算法
  7. 【Luogu P1878】舞蹈课
  8. alexa世界排名的登录及使用教材(转)
  9. Linux基础篇之DNS服务的部署
  10. 如何给视频添加水印logo?
  11. 文章《Deep Image Homography Estimation》
  12. Cocos2d-x 2.0.1 学习tests示例(一)Manual Transformation
  13. 来搞清楚CRC校验的原理和实现
  14. 读论文《DisenHAN: Disentangled Heterogeneous Graph Attention Network for Recommendation》
  15. 28款最好的数据恢复软件对比介绍
  16. 使用nodeJS写一个简单的小爬虫
  17. 闲鱼选品我使用的4个网站,附赠20个流量密码关键字!
  18. ClickHouse MySQL引擎
  19. 《科学伦理与学术规范》 课后习题_答案 2022春季
  20. Vjudge攻略——POJ1753

热门文章

  1. 计算机房的正常温度和湿度,什么是机房温度、湿度标准?
  2. 免备案二级不死域名制作教程大全
  3. tplink软件升级有用吗_新版tplink路由器固件升级_tplink软件升级方法-192路由网
  4. 全网最详细解释Keil-MDK中Code、RO-data、RW-data、ZI-data的含义
  5. deepin linux连接不上网络,把Deepin升级到15.8桌面版后无线上不了网的解决方法
  6. 肖博数学高考数学快速解题法及秒杀向量问题总结
  7. 【零基础】MT4量化入门三:写一个双均线指标
  8. 【与时俱进,智慧社区应运而生】
  9. 2022-2027年中国文化传媒行业市场调研及未来发展趋势预测报告
  10. 华为数据存储用户精英论坛,信心与合作的故事