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

news2024/12/23 5:39:58

目录

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];
};

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

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

相关文章

C++的第一道门坎:类与对象(三)

目录 一.再谈构造函数 1.1构造函数体赋值 1.2初始化列表 1.3explicit关键字 二.static成员 2.1概念 ​编辑 2.2特性 三.友元 3.1友元函数 3.2友元类 4.内部类 一.再谈构造函数 1.1构造函数体赋值 class Date { public:Date(int year,int month,int day){_year ye…

使用KEPServer连接欧姆龙PLC获取对应标签数据(标签值类型改为字符串型)

1.创建通道(通道),(选择对应的驱动,跟当前型号PLC型号对应)。 2.创建设备,(填入IP地址以及欧姆龙的默认端口号:44818) 3.创建对应的标签。这里关键讲诉下字…

【VSCode实战】转换大小写快捷键

今天在VSCode Insiders上编码,突然想将某常量转换为大写。按照virtual studio的习惯,我Ctrl Shift U没有效果,Ctrl U也没效果。网上搜了搜,原来VSCode Insiders没有这个默认功能。 而VSCode Insiders这么强大怎么可能没有大小…

Keras深度学习框架实战(1):图像分类识别

1、绪论 1.1 图像分类的定义 图像分类是计算机视觉领域中的一项基本任务,其定义是将输入图像分配给预定义类别中的一个或多个。具体来说,图像分类系统接受一个图像作为输入,并输出一个或多个类别标签,这些标签描述了图像中的内容…

pytorch 指定GPU的几种方法

在使用PyTorch时,你可以通过多种方式指定和使用GPU。以下是一些常见的方法: 1. 使用torch.device torch.device是PyTorch中用于指定设备(CPU或GPU)的对象。你可以通过将张量移动到指定设备来使用GPU。 import torch# 检查是否有可用的GPU device = torch.device("…

光子芯片:突破算力瓶颈的新希望

引言 在现代计算机科学中,计算能力的提升是推动技术进步的核心动力。然而,随着摩尔定律的逐渐失效,传统电子芯片的算力提升面临瓶颈。光子芯片作为一种新兴技术,因其高频率、低损耗和高信噪比的优点,正成为突破算力瓶…

抖音太可怕了,我卸载了

这两天刷短视频,上瘾了,太可怕了。 自己最近一直在研究短视频制作,所以下载了抖音,说实话,我之前手机上并没有抖音,一直在用B站。 用了两天抖音,我发现,这玩意比刷B站还容易上瘾啊…

打工人福音⚡:公牛充电交互协议,建议收藏!

分享《一套免费开源充电桩物联网系统,是可以立马拿去商用的!》 协议原文件下载地址: 链接: https://pan.baidu.com/s/1kW15Nfe9cjPDFLGPYJ-zUg?pwdagq2 提取码: agq2 1 总则 1.1 协议概述 本协议适用于公司所有充电产品包括交直流充电桩、…

SDK开发

为什么需要Starter? 理想情况:开发者只需关心调用哪些接口,传递哪些参数就跟调用自己写的代码一样简单。 开发starter的好处:开发者引入之后,可以直接在application.yml中写配置,自动创建客户端。 starter开发流程 …

bhyve:FreeBSD下的原生虚拟机管理器

hbyve简介 自 FreeBSD 10.0-RELEASE 起,BSD 许可的 bhyve 虚拟机管理器已成为底层系统不可或缺的一部分。bhyve 强大而灵活,支持多种客户机操作系统,涵盖 FreeBSD、OpenBSD 以及多个 Linux 发行版。在默认配置下,bhyve 提供对串行…

中建环能 | “农村生活污水治理稳质增效与智能运维技术研究及成套装备应用” 科技成果评价

中华环保联合会组织召开了中建环能科技股份有限公司申请的“农村生活污水治理稳质增效与智能运维技术研究及成套装备应用”技术成果评价会。会议由中华环保联合会水环境治理专业委员会秘书长刘愿军主持。 评审会委员 本次评价会邀请了7位相关专业领域的专家组成专家评价委员会。…

Meterpreter工具使用

Meterpreter属于stage payload,在Metasploit Framework中,Meterpreter是一种后渗透工具,它 属于一种在运行过程中可通过网络进行功能扩展的动态可扩展型Payload。这种工具是基于“内存DLL注 入”理念实现的,它能够通过创建一个新进…

RocketMq broker源码解析

broker 集群工作流程 NameSrv启动成功后,等待broker、Consumer和producer启动后也与NameSrv保持长连接, NameSrv相当于是路由控制中心。启动broker, broker与所有的NameSrv建立长连接, broker,通过定时线程定时向NameSrv发送心跳,broker信息…

mysql中子查询的语法和执行过程

大家好。我们在日常开发过程中,肯定都经常用到了子查询。今天我们就来聊一下mysql中子查询的一些语法以及子查询的执行过程。 一、子查询的语法 首先在开讲之前,我们先创建t1、t2两张表,并分别在表中插入三条数据,方便我们下面内…

JDK环境配置、安装

DK环境配置(备注:分32位与64位JDK,32位电脑只能按照32位JDK,64位电脑兼容32、64位JDK) 一、检查自己电脑是否安装过JDK 1.在电脑屏幕左下角,输入命令提示符CMD,打开命令提示符应用 2.在打开界…

AI视频下载:ChatGPT数据科学与机器学习课程

ChatGPT是一个基于OpenAI开发的GPT-3.5架构的AI对话代理。作为一种语言模型,ChatGPT能够理解并对各种主题生成类似人类的响应,使其成为聊天机器人开发、客户服务和内容创作的多用途工具。 此外,ChatGPT被设计为高度可扩展和可定制的,允许开发人员对其响应进行微调并将其集成到…

[stm32]——定时器与PWM的LED控制

目录 一、stm32定时器 1、定时器简介 2、定时器分类 3、通用定时器介绍 二、PWM相关介绍 1、工作原理 2、PWM的一般步骤 三、定时器控制LED亮灭 1、工程创建 2、代码编写 3、实现效果 四、采用PWM模式,实现呼吸灯效果 1、工程创建 2、代码编写 3、实现效果 一、stm3…

跨境电商多店铺:怎么管理?风险如何规避?

跨境电商的市场辽阔,有非常多的商业机会。你可能已经在Amazon、eBay、Etsy等在线平台向潜在客户销售产品了。为了赚更多的钱,你可能还在经营多个店铺和品牌。 但是,像Amazon、eBay、Etsy等知名平台会有自己的规则,他们开发了很多…

风电功率预测 | 基于TCN-GRU时间卷积门控循环单元的风电功率预测(附matlab完整源码)

完整代码 clc; clear close allX = xlsread(风电场预测.xlsx); X = X(5665:8640,:); %选取3月份数据 num_samples =

linux系统——性能检测工具glances

在linux系统中,由python开发的glances工具是一个功能强大的性能检测工具 可以通过yum进行安装 安装glances后,进入命令界面 glance支持网站模式,将监控到的数据以网站形式显示出来 这里需要用python包管理命令 使用glances -w开放…