关于OpenFlow协议的运行机制和实践分析(SDN)

目录

OpenFlow运行机制

1 OpenFlow信道建立

1.1 OpenFlow消息类型

 1.2 信道建立过程解析

2 OpenFlow消息处理

2.1 OpenFlow流表下发与初始流表

2.2 OpenFlow报文上送控制器

2.3 控制器回应OpenFlow报文

3 OpenFlow交换机转发

3.1 单播报文转发流程

OpenFlow的实践分析

1、实验目的:

2、实验环境:

3、基础实验要求:

4、进阶实验要求:


OpenFlow运行机制

1 OpenFlow信道建立

1.1 OpenFlow消息类型

        要了解OpenFlow信道的建立过程,首先需要了解OpenFlow协议目前支持的三种报文类型:

💡OpenFlow协议目前支持的三种报文类型:

1、Controller To Switch消息

2、异步(Asynchronous)消息

3、同步(Symmetric)消息

1、Controller To Switch消息

        由Controller发起、Switch接收并处理的消息。这些消息主要用于Controller对Switch进行状态查询和修改配置等管理操作,可能不需要交换机响应。

💡Controller To Switch的6种消息:

1、Features:用于控制器发送请求来了解交换机的性能,交换机必须回应该报文。

2、Modify-State:用于管理交换机的状态,如流表项和端口状态。该命令主要用于增加、删除、修改OpenFlow交换机内的流表表项,组表表项以及交换机端口的属性。

3、Read-State:用于控制器收集交换机各方面的信息,例如当前配置,统计信息等 。

4、Flow-Mod: Flow-Mod消息用来添加、删除、修改OpenFlow交换机的流表信息。Flow-Mod消息共有五种类型:ADD、DELETE、DELETE-STRICT、MODIFY、MODIFY-STRICT。

5、Packet-out:用于通过交换机特定端口发送报文 ,这些报文是通过Packet-in消息接收到的。通常Packet-out消息包含整个之前接收到的Packet-in消息所携带的报文或者buffer ID(用于指示存储在交换机内的特定报文)。这个消息需要包含一个动作列表,当OpenFlow交换机收到该动作列表后会对Packet-out消息所携带的报文执行该动作列表。如果动作列表为空,Packet-out消息所携带的报文将被OpenFlow交换机丢弃。

6、Asynchronous-Configuration:控制器使用该报文设定异步消息过滤器来接收其只希望接收到的异步消息报文,或者向OpenFlow交换机查询该过滤器。该消息通常用于OpenFlow交换机和多个控制器相连的情况。

2、异步(Asynchronous)消息

        由Switch发送给Controller,用来通知Switch上发生的某些异步事件的消息,主要包括Packet-in、Flow-Removed、Port-Status和Error等。例如,当某一条规则因为超时而被删除时,Switch将自动发送一条Flow-Removed消息通知Controller,以方便Controller作出相应的操作,如重新设置相关规则等。

💡异步消息具体包含以下几种类型:

1、Packet-in:转移报文的控制权到控制器。对于所有通过匹配流表项或者Table Miss后转发到Controller端口的报文均要通过Packet-in消息送到Controller。也有部分其他流程(如TTL检查等)也需要通过该消息和Controller交互。Packet-in既可以携带整个需要转移控制权的报文,也可以通过在交换机内部设置报文的Buffer来仅携带报文头以及其Buffer ID传输给Controller。Controller在接收到Packet-in消息后会对其接收到的报文或者报文头和Buffer ID进行处理,并发回Packet-out消息通知OpenFlow交换机如何处理该报文。

2、Flow-Removed:通知控制器将某个流表项从流表的移除。通常该消息在控制器发送删除流表项的消息或者流表项的定时器超时后产生。

3、Port-Status:通知控制器端口状态或设置的改变。

3、同步(Symmetric)消息

        顾名思义,同步(Symmetric)消息是双向对称的消息,主要用来建立连接、检测对方是否在线等,是控制器和OpenFlow交换机都会在无请求情况下发送的消息,包括Hello、Echo和Experimenter三种消息,这里我们介绍应用最常见的前两种:

💡 最常见的两种同步消息:

1、Hello:当连接启动时交换机和控制器会发送Hello交互。

2、Echo:用于验证控制器与交换机之间连接的存活,控制器和OpenFlow交换机都会发送Echo Request/Reply消息。对于接收到的Echo Request消息必须能返回Echo Reply消息。Echo消息也可用于测量控制器与交换机之间链路的延迟和带宽。

 1.2 信道建立过程解析

💡 OpenFlow控制器和交换机之间建立信道连接的基本过程:

1、OpenFlow交换机与OpenFlow控制器之间通过TCP三次握手过程建立连接,使用的TCP端口号为6633

2、TCP连接建立后,交换机和控制器就会互相发送hello报文。Hello报文负责在交换机和控制器之间进行版本协商,该报文中OpenFlow数据头的类型值为 0

3、功能请求(Feature Request):控制器发向交换机的一条OpenFlow 消息,目的是为了获取交换机性能,功能以及一些系统参数。该报文中OpenFlow 数据头的类型值为 5

4、功能响应(Feature Reply):由交换机向控制器发送的功能响应(Feature Reply)报文,描述了OpenFlow交换机的详细细节。控制器获得交换机功能信息后,OpenFlow协议相关的特定操作就可以开始了

5、Echo请求(Echo Request)和Echo响应(EchoReply)属于OpenFlow中的对称型报文,他们通常用于OpenFlow交换机和OpenFlow控制器之间的保活。通常echo请求报文中OpenFlow数据头的类型值为 2,echo响应的类型值为 3。不同厂商提供的不同设备中,echo请求和响应报文中携带的信息也会有所不同

1.3 信道连接断开模式

        当OpenFlow设备与所有Controller断开连接后,设备进入Fail Open模式。

💡OpenFlow设备存在两种Fail Open模式:

1、Fail Secure mode交换机:在该模式下的OpenFlow交换机,流表项继续生效,直到流表项超时删除。OpenFlow交换机内的流表表项会正常老化。

2、Fail Standalone mode交换机:所有报文都会通过保留端口Normal处理。即此时的OpenFlow交换机变成传统的以太网交换机。Fail Standalone mode只适用于OpenFlow-Hybrid交换机

        安全通道也有两种模式,不同模式下安全通道重连的机制不同。

 💡安全通道的两种模式:

1、并行模式:并行模式下,Switch允许同时与多个Controller建立连接,Switch与每个Controller单独进行保活和重连,互相之间不影响。当且仅当Switch与所有Controller的连接断开后,Switch才进入Fail Open状态。

2、串行模式:串行模式下,Switch在同一时刻仅允许与一个Controller建立连接。一旦与该Controller连接断开后,Switch并不会进入Fail Open状态,而是立即根据Controller的ID顺序依次尝试与Controller连接。如果与所有Controller都无法建立连接,则等待重连时间后,继续遍历Controller尝试建立连接。在三次尝试后,仍然没有成功建立连接,则Switch进入Fail Open状态。

2 OpenFlow消息处理

2.1 OpenFlow流表下发与初始流表

        OpenFlow流表下发分为主动和被动两种机制:

 💡OpenFlow流表下发的两种模式:

1、主动模式:Controller将自己收集的流表信息主动下发给网络设备,随后网络设备可以直接根据流表进行转发

2、被动模式下:网络设备收到一个报文没有匹配的FlowTable记录时,会将该报文转发给Controller,由后者进行决策该如何转发,并下发相应的流表。被动模式的好处是网络设备无需维护全部的流表,只有当实际的流量产生时才向Controller获取流表记录并存储,当老化定时器超时后可以删除相应的流表,因此可以大大节省交换机芯片空间。

   在实际应用中,通常是主动模式与被动模式结合使用

        当OpenFlow交换机和Controller建立连接后,Controller需要主动给OpenFlow交换机下发初始流表,否则进入OpenFlow交换机的报文查找不到流表项,就会做丢弃处理。这里的初始流表保证了OpenFlow的未知报文能够上送控制器。而后续正常业务报文的转发流表,则在实际流量产生时,由主动下发的初始流表将业务报文的首包上送给控制器后,触发控制器以被动模式下发。

        这里我们以H3C VCFC控制器给交换机下发的一个初始流表举例。

        前面我们了解到,OpenFlow流表是分级匹配的,通常按0表、1表、2表这样依次匹配过去,每个级别的表中则由优先级高的表项先进行匹配。

   如上图所示,0表优先级最高为65535的两条流表匹配到的是端口号为67、68的UDP报文,也就是DHCP报文,匹配动作为goto_table 1,剩下的其他所有报文也命中优先级最低为0的表项后goto_table 1。而在表1中,优先级最低的表项对应的动作为output controller,这保证了虚拟机的DHCP请求可以发送给控制器,由控制器作为网络中的DHCP Server,避免DHCP请求泛洪,同时还保证了交换机上所有未知的无流表匹配的报文都可以上送控制器,触发控制器被动下发流表给交换机指导转发。这里,我们把表1里优先级最低为0,匹配所有未知报文的表项叫做table-miss表项。

        我们在OpenFlow交换机上同样可以观察到初始流表,这里以H3C S6800交换机上的一个初始流表举例。上图中的这条表项匹配报文类型为以太网报文,UDP端口67、68说明匹配DHCP请求报文,动作为上送控制器:

2.2 OpenFlow报文上送控制器

        OpenFlow报文上送控制器详细过程如下:

 💡OpenFlow报文上送控制器的详细过程:

1、控制器和交换机建立连接事件是Packet-in事件发生的前提。

2、当OpenFlow交换机收到数据包后,如果明细流表中与数据包没有任何匹配条目,就会命中table-miss表项,触发Packet-in事件,交换机会将这个数据包封装在OpenFlow协议报文中发送至控制器。

3、一旦交换机触发了Packet-in事件,Packet-in报文就将发送至控制器。

  Packet-in数据头包括了:

  • 缓冲ID
  • 数据包长度
  • 输入端口
  • Packet-in的原因,分两种:
    • 0: 无匹配
    • 1: 流表中明确提到将数据包发送至控制器

2.3 控制器回应OpenFlow报文

        控制器收到Packet-in消息后,可以发送Flow-Mod消息向交换机写一个流表项。并且将Flow-Mod消息中的buffer_id字段设置为Packet-in消息中的buffer_id值。从而控制器向交换机写入了一条与数据包相关的流表项,并且指定该数据包按照此流表项的action列表处理。

        Controller根据报文的特征信息(如IP、mac等)下发一条新的流表项到OpenFlow交换机或者做其他处理之后下,发Packet-out消息动作为output到table,具体过程如下所示:

💡output到table的具体过程

1、控制器和交换机之间建立连接事件是Packet-out事件发生的前提;

2、控制器要发送数据包至交换机时,就会触发Packet-out事件将数据包发送至交换机。这一事件的触发可以看做是控制器主动通知交换机发送一些数据报文的操作。通常,当控制器想对交换机的某一端口进行操作时,就会使用Packet-out报文。

3、该数据包由控制器发往交换机,内部信息使用Packet-out,并由OpenFlow数据头封装。

💡OpenFlow Packet-out信息包括:

1、缓冲ID

2、入口端口编号

3、动作明细(添加为动作描述符)

4、输出动作描述符

5、VLAN VID动作描述符

6、VLAN PCP动作描述符

7、提取VLAN标签动作描述符

8、以太网地址动作描述符

9、IPv4地址动作描述符

10、IPv4 DSCP动作描述符

11、TCP/UDP端口动作描述

12、队列动作描述符

15、各厂商动作描述符

3 OpenFlow交换机转发

3.1 单播报文转发流程

        当OpenFlow交换机接收到Flow-Mod消息,生成流表后,就可以按照流表转发接收到的Packet-out报文了,过程举例如下:

        在本例中,OpenFlow 交换机需要转发一个从7.7.7.1到9.9.9.1的流量。当流量上送到OpenFlow交换机后,流量的第一个包会先进行Packet-in、Flow-Mod、Packet out的过程,之后同流量的报文就能匹配控制器已经下发的流表进行转发了。

3.2 组播报文转发

        当终端发出的组播报文到达OpenFlow交换机后,OpenFlow交换机Packet-in给控制器,控制器会为网络下发指导查询组表的流表,并进行流表与组表关联。交换机参考流表,引用组表进行转发。举例如下:

         上条流表的动作为引用组表4096,组表4096详细内容如下:

OpenFlow的实践分析

1、实验目的:

  • 能够运用 wireshark 对 OpenFlow 协议数据交互过程进行抓包;
  • 能够借助包解析工具,分析与解释 OpenFlow协议的数据包交互过程与机制。

2、实验环境:

  • VMware Workstion Pro 17
  • Ubuntu22.04 Desktop amd64,且完整安装了Mininet;

3、基础实验要求:

  1. 在Mininet可视化界面搭建如下拓扑;
  2. 完成相关IP地址的配置,实现主机与主机之间的IP通信;
  3. 使用抓包软件Wireshark获取控制器与交换机之间的通信数据包进行分析;

 

1、配置网段

2、修改各主机IP地址并保存为py脚本文件

 在Test-1.py最下放添加以下代码,不添加的话无法运行:

    CLI(net)
    net.stop()
if __name__ == '__main__':
    setLogLevel('info')
    myNetwork()

注意:net.stop()要和CLI(net)对齐,否则无法运行,因为在Python中对于代码的缩进有着极其严格的要求

3、先启动wireshark,再运行脚本

wireshark &

        & 这个符号的意思是:将本行命令的运行结果放在后台执行,不占用命令行,运行脚本文件时也就无需再多开启一个终端界面了

        运行wireshark &命令,并选择any模式进行抓包,开启另一个终端,命令行运行Test-1.py文件,运行pingall

python3 Test-1.py
pingall

4、过滤抓包结果,分析OpenFlow协议中交换机与控制器的消息交互过程

OFPT_HELLO 源端口6633 -> 目的端口38552,从控制器到交换机,控制器与交换机建立连接,使用的OpenFlow版本为1.0

也有源端口38552 -> 目的端口6633的,即交换机到控制器的另一个包,此处协议为openflow1.5,此时是交换机和控制器协商协议版本阶段,最后交换机向下兼容控制器的OpenFlow版本(1.0)

 OFPT_FEATURES_REQUEST 源端口6633 -> 目的端口38552,从控制器到交换机,控制器请求交换器的特征信息,使用的是OpenFlow 1.0版本

OFPT_SET_CONFIG 源端口6633 -> 目的端口38552,从控制器到交换机,控制器要求交换机按照所给出的信息进行配置

OFPT_PORT_STATUS 源端口49032 -> 目的端口6633,从交换机到控制器,当交换机端口发生变化时,交换机告知控制器相应的端口状态

OFPT_FEATURES_REPLY 源端口38552 -> 目的端口6633,从交换机到控制器,交换机告知控制器它的特征信息

OFPT_PACKET_IN 源端口38556 -> 目的端口6633,从交换机到控制器,交换机告知控制器有数据包进来,请求控制器指示

OFPT_PACKET_OUT 源端口6633 -> 目的端口38556,从控制器到交换机交换机告知控制器有数据包进来,控制器要求交换机按照所给出的action进行处理

OFPT_FLOW_MOD 源端口6633 -> 目的端口53712,从控制器到交换机,控制器对交换机进行流表的添加、删除、变更等操作(这里重新做了一下所以端口变了)

 从抓到的包协议字段可以看出,交换机与控制键建立通信时使用的是TCP协议

4、进阶实验要求:

        将抓包结果对照OpenFlow源码,了解OpenFlow主要消息类型对应的数据结构定义。相关数据结构可在openflow安装目录openflow/include/openflow当中的openflow.h头文件中查询到

1. HELLO

/* Header on all OpenFlow packets. */                                 `OpenFlow包的所有头部`
struct ofp_header {
     uint8_t version;    /* OFP_VERSION. */                            `版本`
     uint8_t type;       /* One of the OFPT_ constants. */             `类型`
     uint16_t length;    /* Length including this ofp_header. */       `头部长度`
     uint32_t xid;       /* Transaction id associated with this packet.
                            Replies use the same id as was in the request
                            to facilitate pairing. */                  `配对ID`

2. FEATURES_REQUEST

源码参数格式与HELLO相同,与上述ofp_header结构体中数据相同,不同的只有TYPE的值

3.SET_CONFIG

/* Switch configuration. */                                          `交换机配置
`
struct ofp_switch_config {
    struct ofp_header header;                                        `调用ofp_header `
    uint16_t flags;             /* OFPC_* flags. */                  `标签`
    uint16_t miss_send_len;     /* Max bytes of new flow that datapath should
                                   send to the controller. */        `数据路径应发送到控制器的新流的最大字节数`
};

4. PORT_STATUS

/* A physical port has changed in the datapath */        `数据路径中物理端口的更改`
struct ofp_port_status {
    struct ofp_header header;                            `调用ofp_header`
    uint8_t reason;          /* One of OFPPR_*. */       `发生原因`
    uint8_t pad[7];          /* Align to 64-bits. */     `将长度调整对其到64位`
    struct ofp_phy_port desc;
};

5. FEATURES_REPLY

struct ofp_switch_features {
    struct ofp_header header;                                                        `调用ofp_header`
    uint64_t datapath_id;   /* Datapath unique ID.  The lower 48-bits are for        `数据路径唯一 ID`
                               a MAC address, while the upper 16-bits are
                               implementer-defined. */

    uint32_t n_buffers;     /* Max packets buffered at once. */                       `一次缓冲的最大数据包数`

    uint8_t n_tables;       /* Number of tables supported by datapath. */             `数据路径支持的表数`
    uint8_t pad[3];         /* Align to 64-bits. */                                   `将长度调整对其到64位`

    /* Features. */                                                                   `特征`
    uint32_t capabilities;  /* Bitmap of support "ofp_capabilities". */               `支持"ofp_capabilities"`          
    uint32_t actions;       /* Bitmap of supported "ofp_action_type"s. */             `支持"ofp_action_type"`  

    /* Port info.*/                                                                   `端口信息`
    struct ofp_phy_port ports[0];  /* Port definitions.  The number of ports          `端口定义 端口数是从标头中的长度字段推断出来的`
                                      is inferred from the length field in
                                      the header. */
};
/* Description of a physical port */
struct ofp_phy_port {
    uint16_t port_no;
    uint8_t hw_addr[OFP_ETH_ALEN];
    char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */

    uint32_t config;        /* Bitmap of OFPPC_* flags. */
    uint32_t state;         /* Bitmap of OFPPS_* flags. */

    /* Bitmaps of OFPPF_* that describe features.  All bits zeroed if
     * unsupported or unavailable. */
    uint32_t curr;          /* Current features. */
    uint32_t advertised;    /* Features being advertised by the port. */
    uint32_t supported;     /* Features supported by the port. */
    uint32_t peer;          /* Features advertised by peer. */
};

6.PACKET_IN

有两种情况:

        1.交换机查找流表,发现没有匹配条目

enum ofp_packet_in_reason {
    OFPR_NO_MATCH,          /* No matching flow. */
    OFPR_ACTION             /* Action explicitly output to controller. */
};

        2.有匹配条目,对应的action是OUTPUT=CONTROLLER,固定收到向控制器发送包

 

struct ofp_packet_in {
    struct ofp_header header;
    uint32_t buffer_id;     /* ID assigned by datapath. */
    uint16_t total_len;     /* Full length of frame. */
    uint16_t in_port;       /* Port on which frame was received. */
    uint8_t reason;         /* Reason packet is being sent (one of OFPR_*) */
    uint8_t pad;
    uint8_t data[0];        /* Ethernet frame, halfway through 32-bit word,
                               so the IP header is 32-bit aligned.  The
                               amount of data is inferred from the length
                               field in the header.  Because of padding,
                               offsetof(struct ofp_packet_in, data) ==
                               sizeof(struct ofp_packet_in) - 2. */
};

7. PACKET_OUT

struct ofp_packet_out {
    struct ofp_header header;
    uint32_t buffer_id;           /* ID assigned by datapath (-1 if none). */
    uint16_t in_port;             /* Packet's input port (OFPP_NONE if none). */
    uint16_t actions_len;         /* Size of action array in bytes. */
    struct ofp_action_header actions[0]; /* Actions. */
    /* uint8_t data[0]; */        /* Packet data.  The length is inferred
                                     from the length field in the header.
                                     (Only meaningful if buffer_id == -1.) */
};

8. FLOW_MOD

struct ofp_flow_mod {
    struct ofp_header header;
    struct ofp_match match;      /* Fields to match */
    uint64_t cookie;             /* Opaque controller-issued identifier. */

    /* Flow actions. */
    uint16_t command;             /* One of OFPFC_*. */
    uint16_t idle_timeout;        /* Idle time before discarding (seconds). */
    uint16_t hard_timeout;        /* Max time before discarding (seconds). */
    uint16_t priority;            /* Priority level of flow entry. */
    uint32_t buffer_id;           /* Buffered packet to apply to (or -1).
                                     Not meaningful for OFPFC_DELETE*. */
    uint16_t out_port;            /* For OFPFC_DELETE* commands, require
                                     matching entries to include this as an
                                     output port.  A value of OFPP_NONE
                                     indicates no restriction. */
    uint16_t flags;               /* One of OFPFF_*. */
    struct ofp_action_header actions[0]; /* The action length is inferred
                                            from the length field in the
                                            header. */
};
struct ofp_action_header {
    uint16_t type;                  /* One of OFPAT_*. */
    uint16_t len;                   /* Length of action, including this
                                       header.  This is the length of action,
                                       including any padding to make it
                                       64-bit aligned. */
    uint8_t pad[4];
};

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

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

相关文章

解锁 JavaScript ES6:函数与对象的高级扩展功能

个人主页:学习前端的小z 个人专栏:JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! ES5、ES6介绍 文章目录 ES6函数扩展1 默认参数1.1 之前写法1.2 ES6 写法1.3 注意点 2 …

springboot kafka 提高拉取数量

文章目录 背景问题复现解决问题原理分析fetch.min.bytesfetch.max.wait.ms源码分析ReplicaManager#fetchMessages 背景 开发过程中,使用kafka批量消费,发现拉取数量一直为1,如何提高批量拉取数量,记录下踩坑记录。 问题复现 ka…

【设计模式】结构型-门面模式

前言 在软件开发中,设计模式是解决特定问题的经验总结,为开发者提供了一种可复用的解决方案。其中,门面模式(Facade Pattern)是一种结构型模式,旨在为复杂系统提供简化的接口,使客户端与系统之…

GPT-4o(OpenAI最新推出的大模型)

简介:最近,GPT-4o横空出世。对GPT-4o这一人工智能技术进行评价,包括版本间的对比分析、GPT-4o的技术能力以及个人感受等。 方向一:对比分析 GPT-4o(OpenAI最新推出的大模型)与GPT-4之间的主要区别体现在响应…

微服务学习Day8

文章目录 Sentinel雪崩问题服务保护框架Sentinel配置 限流规则快速入门流控模式流控效果热点参数限流 隔离和降级FeignClient整合Sentinel线程隔离(舱壁模式)熔断降级 授权规则及规则持久化授权规则自定义异常结果持久化 Sentinel 雪崩问题 服务保护框架…

SpringBoot打war包并配置外部Tomcat运行

简介 由于其他原因,我们需要使用SpringBoot打成war包放在外部的Tomcat中运行,本文就以一个案例来说明从SpringBoot打war包到Tomcat配置并运行的全流程经过 环境 SpringBoot 2.6.15 Tomcat 8.5.100 JDK 1.8.0_281 Windows 正文 一、SpringBoot配置打war包 第一步&a…

怎么通过互联网远程控制电脑?

远程访问又称为网络远程控制,它使用户能够通过互联网连接两台设备以解决问题。进行控制的电脑称为控制端,被控制的电脑则称为被控端。在远程访问过程中,控制端电脑掌握整个连接的操作。远程控制软件会捕获被控端电脑的操作,并在主…

JS数组怎么去重?| JavaScript中数组去重的14种方法

目录 一、利用for循环嵌套去重 二、利用splice() for循环嵌套(ES5中最常用) 三、利用indexOf() for循环去重 四、利用sort() for循环去重 五、利用includes() for循环去重(ES7) 六、利用Object键值对及其hasOwnProperty…

521源码网-免费网络教程-Cloudflare使用加速解析-优化大陆访问速度

Cloudfalre 加速解析是由 心有网络 向中国大陆用户提供的公共优化服务 接入服务节点: cf.13d7s.sit 接入使用方式类似于其它CDN的CNAME接入,可以为中国大陆用户访问Cloudflare网络节点大幅度加速,累计节点130 如何接入使用 Cloudflare 加速解析&#…

LabVIEW中进行步进电机的位置控制

在LabVIEW中进行步进电机的位置控制,通常涉及以下几个关键步骤:设置硬件、配置通信、编写控制算法和实施反馈控制。以下是一个详细的介绍。 硬件设置 步进电机:选择合适的步进电机,根据负载和应用需求选择适当的步数和转矩。 驱…

Kafka broker的新增和剔除(服役与退役)

说明:集群现有broker:node1,node2,node3三个,broker.id分别为0,1,2 已有两个topic:products、cities 1、退役(Kafka集群中减少一个服务器broker2) 退役后要保证剩下的服务器数量大于等于备份数&#xff0c…

SpringBoot+layui实现Excel导入操作

excel导入步骤 第三方插件引入插件 效果图 (方法1)代码实现(方法1)Html代码( 公共)下载导入模板 js实现 (方法1)上传文件实现 效果图(方法2)代码实现&#xf…

智慧医院物联网建设-统一管理物联网终端及应用

近年来,国家卫健委相继出台的政策和评估标准体系中,都涵盖了强化物联网建设的内容。物联网建设已成为智慧医院建设的核心议题之一。 作为医院高质量发展的关键驱动力,物联网的顶层设计与网络架构设计规划,既需要结合现代信息技术的…

AI炒股-批量爬取网易财经的要闻板块

工作任务和目标&#xff1a;批量爬取网易财经的要闻板块 在class"tab_body current"的div标签中&#xff1b; 标题和链接在&#xff1a;<a href"https://www.163.com/dy/article/J2UIO5DD051188EA.html">华为急需找到“松弛感”</a> 第一步&…

linux磁盘满了,如何查找大文件清除?

将整个Linux中文件按照文件大小排序&#xff0c;从大到小排序 只显示前100条数据 命令&#xff1a; find / -type f -exec du -h {} | sort -rh | head -n 100结果&#xff1a;

Llama改进之——分组查询注意力

引言 今天介绍LLAMA2模型引入的关于注意力的改进——分组查询注意力(Grouped-query attention,GQA)1。 Transformer中的多头注意力在解码阶段来说是一个性能瓶颈。多查询注意力2通过共享单个key和value头&#xff0c;同时不减少query头来提升性能。多查询注意力可能导致质量下…

联芸科技偏高的关联交易:业绩波动性明显,海康威视曾拥有一票否决

《港湾商业观察》施子夫 5月31日&#xff0c;上交所上市审核委员会将召开2024年第14次审议会议&#xff0c;届时将审议联芸科技&#xff08;杭州&#xff09;股份有限公司招股书&#xff08;以下简称&#xff0c;联芸科技&#xff09;的首发上会事项。 据悉&#xff0c;此次系…

php反序列化学习(3)

1、session 当session_start()被调用或者php.ini中session.auto_start为1时&#xff0c;php内部调用会话管理器&#xff0c;访问用户session被序列化后&#xff0c;存储到指定目录&#xff08;默认为/tmp&#xff09;。 漏洞产生&#xff1a;写入格式与读取格式不一致 处理器…

C# 代码配置的艺术

文章目录 1、代码配置的定义及其在软件工程中的作用2、C# 代码配置的基本概念和工具3、代码配置的实践步骤4、实现代码配置使用属性&#xff08;Properties&#xff09;使用配置文件&#xff08;Config Files&#xff09;使用依赖注入&#xff08;Dependency Injection&#xf…

模拟建造游戏:城市:天际线Cities: Skylines for Mac/win中文原生版

《城市&#xff1a;天际线》&#xff08;Cities: Skylines&#xff09;是一款由Colossal Order开发&#xff0c;Paradox Interactive发行的城市建设模拟游戏。这款游戏于2015年首次发布&#xff0c;迅速赢得了玩家和评论家的好评&#xff0c;并成为了备受欢迎的城市建设游戏之一…