基于OVSDB协议在SDN控制器ONOS开发配置管理OVS API

2023-11-02

为了更好的分享体验,博客搬迁至极客驿站 ,欢迎查阅

基于OVSDB协议在SDN控制器ONOS开发配置管理OVS API

  1. 介绍
  2. 准备工作
  3. 开发步骤
  4. 问题排查

介绍
目前protocol 中ovsdb协议层面已经实现,但是基于ovsdb protocol的上层接口并不完善,ONOS只支持以下几种
网桥操作
boolean addBridge(BridgeDescription bridgeDescription);
void deleteBridge(BridgeName bridgeName);
Collection getBridges();
端口操作
void addPort(BridgeName bridgeName, String portName);
void deletePort(BridgeName bridgeName, String portName);
Collection getPorts();
Set getPortNumbers();
List getLocalPorts(Iterable ifaceIds);
Controller操作
List getControllers();
void setControllers(List controllers);
接口操作
boolean addPatchMode(String ifaceName, PatchDescription patchInterface);
boolean removePatchMode(String ifaceName);
boolean addTunnelMode(String intf, TunnelDescription tunnelDesc);
boolean removeTunnelMode(String intf);
这些配置远远不够
准备工作
增加api配置ovs,首先需要熟悉ovsdb rfc7047内容,其中规定了协议内容,如何操作ovsdb数据库,有哪些限制这一点非常重要,不然可能排查bug时很难找到其中原因,另外还需要熟悉ovsdb数据库各表的各个字段以及属性,这个可以从ovs-vswitchd.conf.db.5.pdf中查找或者在数据模板/usr/share/openvswitch/vswitch.ovsschema中查看,不需记忆;需要值得一提的对于写操作,下发的transcat string不能出现字段类型为immutable类型的column值,例如:可以vswitch.ovsschema查看到Interface Name字段是不可更改的,这个字段在通过ovsdb协议下发update或mutate操作,不能再value字段中携带,否则会导致更新失败。这个后面有举例说明。
这里写图片描述
开发步骤
Api框架图
这里写图片描述
基于ONOS整体框架良好的封装特性,在ONOS增加对底层接口配置特性,可分为以下四个步骤
1、 在onos-api模块中找到所属分类,增加接口,BridgeConfig,ControllerConfig,InterfaceConfig,PortAdmin,PortConfig,PowerConfig,QueueConfig这些配置类是我们需要关注的,在onos api这一层,并没有暴露很多细节,这里它只是定义一个接口参数和返回类型,至于底层如何实现,使用ovsdb还是netconf它并不关心,只要匹配对应的driver就可以了
2、 在driver层实现1步骤中的接口,比如现在BridgeConfig中的接口目前只有ovsdbBridgeConfig一种实现,而ControllerConfig中的接口有若干种实现;
这里写图片描述
以ovsdbBridgeConfig为例,它会获取一个当前设备的ovsdb协议连接,然后调用ovsdb协议封装的API进行具体实现,所有的driver接口实现都类似,另外需要注意,因为java接口implements关系,如果一个onos api在driver有多种实现,除了要实现特定协议的处理流程,其他类型协议需要打桩处理,否则编译出错;另外如果新增driver接口,比如新增ovsdbQueueConfig Driver,需要在onos/drivers/ovsdb/src/main/resources/ovsdb-driver.xml增加对应配置,否则behavior执行时会提示not support。
这里写图片描述
3、 第二步骤中提到的client中的接口实际上是ovsdb协议实现封装的一层对外API,这一步就需要在这里增加接口,这里增加的接口和第一步中的api类似的,只不过第一步中api是屏蔽底层细节的,底层可以是任何协议,而这一步的api是具体某种协议的api,ovsdb协议的api位置在onos\protocols\ovsdb\api,所有对外接口放在OvsdbClientService抽象接口中;另外其中的一些测试实现类也需要打桩处理。
4、 实现第三步骤中定义的接口,这里就是调用协议接口,来实现自己想要的功能,以创建tunnel隧道接口为例
这里写图片描述
这里面其实是对数据库的操作,最终会通过ovsdb协议下发到openvswitch,其中的操作适合ovsdb rfc定义是一致的
具体每个表的操作,可以到onos\protocols\ovsdb\rfc\src\main\java\org\onosproject\ovsdb\rfc\table中去参考,其中的表属性是和OpenvSwitch一一对应的
这里写图片描述
问题排查
按照上述流程开发,所有的ovs操作都是可以支持的,如果遇到问题,改如何排查?
大致可分为两种:1、查看onos log ,如果log中有导致该问题的异常,那么这个问题就比较容易解决,解决掉异常即可
2、如果onos log中没有异常,但是执行配置操作,转发平面ovs没有任何反应,没有看到想要的配置下发,例如onos执行qos的配置,但是转发面没有出现任何相关的配置,而onos也没有报任何错误。这个时候可能就是下发ovsdb协议可能违背了一些限制,导致更新失败,但是onos并不会报违背了哪些限制导致更新失败,如何知道具体什么原因导致的配置失败呢?答案是使用ovsdb-client –v transact命令模拟onos下发ovsdb协议配置操作,在ovs这个地方如果因为某种类型不匹配,它会打印出详细错误信息
但是ovsdb-client –v transact [SERVER] TRANSACTION这条命令的TRANSACTION本身很复杂,手工敲可能不太现实,这个TRANSACTION可以在onos 代码加log打印出来,如下图:
这里写图片描述
transactString就是最终要下发的操作,将这个打印出来,然后使用ovsdb-client命令验证下发操作失败的具体原因,需要强调的是transactString的内容是和rfc7047协议规定吻合的。
以下发ingress policing rate/burst为例,打印出来如下:
transact string{“id”:“e676f626-4e80-45cb-ae45-2f5500b016d6”,“method”:“transact”,“params”:[“Open_vSwitch”,{“op”:“update”,“row”:{“ingress_policing_rate”:[“set”,[100]],“ingress_policing_burst”:[“set”,[100]]},“where”:[[“_uuid”,“==”,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]],“table”:“Interface”}]}

这个时候就可以使用ovsdb-client验证其正确性,
o[root@localhost ~]# ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“update”,“row”:{“ingress_policing_rate”:[“set”,[200]],“ingress_policing_burst”:[“set”,[200]]},“where”:[[”_uuid",““,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]],“table”:“Interface”}]”
下面是执行上面命令打印的信息
[root@localhost ~]# ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“update”,“row”:{“ingress_policing_rate”:[“set”,[200]],“ingress_policing_burst”:[“set”,[200]]},“where”:[[”_uuid","
”,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]],“table”:“Interface”}]"
2016-09-08T06:29:50Z|00001|jsonrpc|DBG|unix:/var/run/openvswitch/db.sock: send request, method=“transact”, params=[“Open_vSwitch”,{“where”:[[“_uuid”,““,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]],“table”:“Interface”,“op”:“update”,“row”:{“ingress_policing_burst”:[“set”,[200]],“ingress_policing_rate”:[“set”,[200]]}}], id=0
2016-09-08T06:29:50Z|00002|poll_loop|DBG|wakeup due to 0-ms timeout
2016-09-08T06:29:50Z|00003|poll_loop|DBG|wakeup due to [POLLIN] on fd 3 (<->/var/run/openvswitch/db.sock) at lib/stream-fd.c:155
2016-09-08T06:29:50Z|00004|jsonrpc|DBG|unix:/var/run/openvswitch/db.sock: received reply, result=[{“count”:1}], id=0
[{“count”:1}]
证明有一个row更新了,这个说明transaction是正确的,如果是不正确的呢,比如在上面的transaction中row中增加一个name字段,它就会提示name字段不可更改
[root@localhost ~]# ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“update”,“row”:{“name”:“vnet0”,“ingress_policing_rate”:[“set”,[200]],“ingress_policing_burst”:[“set”,[200]]},“where”:[[”_uuid”,"
”,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]],“table”:“Interface”}]"
2016-09-08T06:34:52Z|00001|jsonrpc|DBG|unix:/var/run/openvswitch/db.sock: send request, method=“transact”, params=[“Open_vSwitch”,{“where”:[[“_uuid”,““,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]],“table”:“Interface”,“op”:“update”,“row”:{“name”:“vnet0”,“ingress_policing_burst”:[“set”,[200]],“ingress_policing_rate”:[“set”,[200]]}}], id=0
2016-09-08T06:34:52Z|00002|poll_loop|DBG|wakeup due to 0-ms timeout
2016-09-08T06:34:52Z|00003|poll_loop|DBG|wakeup due to [POLLIN] on fd 3 (<->/var/run/openvswitch/db.sock) at lib/stream-fd.c:155
2016-09-08T06:34:52Z|00004|jsonrpc|DBG|unix:/var/run/openvswitch/db.sock: received reply, result=[{“syntax”:”{“op”:“update”,“row”:{“ingress_policing_burst”:[“set”,[200]],“ingress_policing_rate”:[“set”,[200]],“name”:“vnet0”},“table”:“Interface”,“where”:[[“_uuid”,"
”,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]]}“,“details”:“Cannot update immutable column name in table Interface.”,“error”:“constraint violation”}], id=0
[{“details”:“Cannot update immutable column name in table Interface.”,“error”:“constraint violation”,“syntax”:”{“op”:“update”,“row”:{“ingress_policing_burst”:[“set”,[200]],“ingress_policing_rate”:[“set”,[200]],“name”:“vnet0”},“table”:“Interface”,“where”:[[“_uuid”,““,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]]}”}]
另外删除Ovsdb Table时需要考虑到各表之间的依赖关系,对于有strong reference关系的表,在删除子表时需要先将父表的引用删除;对于调用deleteConfig接口时,这个接口会根据传入的参数查找父表的引用进行删除,这里特别要注意附表引用的数据类型,以Port、QoS与Queue关系为例。
这里写图片描述
“Port”: {
“columns”: {
“name”: {
“type”: “string”,
“mutable”: false},

“qos”: {
“type”: {“key”: {“type”: “uuid”,
“refTable”: “QoS”},
“min”: 0, “max”: 1}},
“QoS”: {
“columns”: {
“type”: {
“type”: “string”},
“queues”: {
“type”: {“key”: {“type”: “integer”,
“minInteger”: 0,
“maxInteger”: 4294967295},
“value”: {“type”: “uuid”,
“refTable”: “Queue”},
“min”: 0, “max”: “unlimited”}},

这里Port引用Qos的时候,单数据接口type为uuid,Qos引用Queue时的数据类型为map类型,既存在key又有value;关于表元素的数据类型,可以在vswitch.ovsschema的定义中找到
错误的删除Queue元素的操作
ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“mutate”,“where”:[[“queues”,“includes”,[“uuid”,“dd2de53c-e4e7-4252-a191-72968a0f7859”]]],“mutations”:[[“queues”,“delete”,[“uuid”,“dd2de53c-e4e7-4252-a191-72968a0f7859”]]],“table”:“QoS”},{“op”:“delete”,“where”:[[”_uuid","
”,[“uuid”,“dd2de53c-e4e7-4252-a191-72968a0f7859”]]],“table”:“Queue”}]"
正确
ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“mutate”,“where”:[[“queues”,“includes”,[“map”,[[0,[“uuid”,“dd2de53c-e4e7-4252-a191-72968a0f7859”]]]]]],“mutations”:[[“queues”,“delete”,[“map”,[[0,[“uuid”,“dd2de53c-e4e7-4252-a191-72968a0f7859”]]]]]],“table”:“QoS”},{“op”:“delete”,“where”:[[”_uuid",“==”,[“uuid”,“dd2de53c-e4e7-4252-a191-72968a0f7859”]]],“table”:“Queue”}]"

OpenvSwitch transact命令 example
设置interface rate, mutate采用insert操作失败,采用+=可以
ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“mutate”,“where”:[[”_uuid",“==”,[“uuid”,“4aa0e983-29fd-4661-a05f-623e60fdf8e2”]]],“mutations”:[[“ingress_policing_rate”,“+=”,200]],“table”:“Interface”}]"

设置interface rate, update操作,去掉interface name不可更新的column
ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“update”,“row”:{“mac_in_use”:[“set”,[“fe:54:00:78:6d:17”]],“duplex”:[“set”,[“full”]],“admin_state”:[“set”,[“up”]],“error”:[“set”,[]],“type”:”“,“ingress_policing_burst”:[“set”,[100]],“cfm_mpid”:[“set”,[]],“mac”:[“set”,[]],“cfm_fault”:[“set”,[]],“cfm_flap_count”:[“set”,[]],“options”:[“map”,[]],“cfm_health”:[“set”,[]],“ingress_policing_rate”:[“set”,[100]],“bfd”:[“map”,[]],“ifindex”:[“set”,[36]],“ofport”:[“set”,[6]],“other_config”:[“map”,[]],“bfd_status”:[“map”,[]],“cfm_remote_mpids”:[“set”,[]],“cfm_fault_status”:[“set”,[]],“link_speed”:[“set”,[10000000]],“external_ids”:[“map”,[[“vm-id”,“e570935c-693a-458c-8a59-ca687e0473a3”],[“attached-mac”,“52:54:00:78:6d:17”],[“iface-status”,“active”],[“iface-id”,“2cf8fa66-3b07-4db1-8e0b-ec635af99237”]]],“mtu”:[“set”,[1500]],“lacp_current”:[“set”,[]],“link_resets”:[“set”,[1]],“cfm_remote_opstate”:[“set”,[]],“link_state”:[“set”,[“up”]],“ofport_request”:[“set”,[]],“lldp”:[“map”,[]],“statistics”:[“map”,[[“tx_packets”,1732],[“tx_errors”,0],[“collisions”,0],[“tx_dropped”,0],[“rx_dropped”,0],[“rx_crc_err”,0],[“rx_bytes”,0],[“rx_frame_err”,0],[“rx_over_err”,0],[“tx_bytes”,140292],[“rx_errors”,0],[“rx_packets”,0]]],“status”:[“map”,[[“driver_name”,“tun”],[“driver_version”,“1.6”],[“firmware_version”,”“]]]},“where”:[[”_uuid",“==”,[“uuid”,“4aa0e983-29fd-4661-a05f-623e60fdf8e2”]]],“table”:“Interface”}]"

ovsdb-client -v transact “[“Open_vSwitch”,{“op”:“update”,“row”:{“ingress_policing_rate”:[“set”,[200]],“ingress_policing_burst”:[“set”,[200]]},“where”:[[”_uuid",“==”,[“uuid”,“58dfdd10-43b9-45c7-aca6-e6fe6b5b6a7b”]]],“table”:“Interface”}]"

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于OVSDB协议在SDN控制器ONOS开发配置管理OVS API 的相关文章

  • 2019年SDN软件定义网络部分

    SDN 题目 二 配置IP添加网卡以及karaf程序启动 三 创建拓扑 四 打开网页查看拓扑 五 通过OVS手动添加网卡 设置网关 1 添加网卡 2 设置网关地址 开启路由转发 3 给H1 H2 H3 H4设置网关 六 OVS手工下发流表
  • [SDN]使用mininet搭建单臂路由的VLAN网络

    作者 xff1a 清水寺丞 简介 xff1a 正在学习unity xff0c 数据库 xff0c 计算机通信网络和python 喜欢部署各种奇奇怪怪的小项目 喜欢就点个关注一起学习吧 前言 xff1a 本文实践了使用mininet来搭建一个
  • SDN和SD-WAN的概念别再搞混了—Vecloud微云

    最近 xff0c SD WAN在融资领域是一个比较热的话题 国外几家SD WAN的头部企业不断地获得融资 xff0c 也包括被思科 VMware等巨头收购和兼并 xff0c 国内创业公司推出了各种SD WAN产品和解决方案 不得不说 xff
  • 万台规模下的SDN控制器集群部署实践

    目前在网络世界里 xff0c 云计算 虚拟化 SDN NFV这些话题都非常热 今天借这个机会我跟大家一起来一场SDN的深度之旅 xff0c 从概念一直到实践一直到一些具体的技术 本次分享分为三个主要部分 xff1a SDN amp NFV的
  • SDN控制器究竟在干啥?

    一提到SDN xff0c 大家就会想到南北向接口 xff0c 南向接口负责和交换机的交互 xff0c 北向接口负责和各种应用的交互 xff0c SDN控制器稳坐中间 xff0c 运筹帷幄 xff0c 决胜千里 在博主看来 xff0c 这只是
  • ONOS之开放分布式SDN操作系统

    为什么80 的码农都做不了架构师 xff1f gt gt gt 关于构建ONOS xff08 开放式网络操作系统 xff09 的项目专题 xff0c 是通过性能激发创建的实验性分布式 SDN 控制平台 xff0c 满足大型运营商网络的可扩展
  • openflow交换机流表删除_sdn交换机与普通交换机区别—Vecloud

    SDN xff0c 即Software Defined Network 软件定义网络 xff0c 传统的网络设备 交换机 路由器 的固由设备制造商锁定和控制 xff0c 所以SDN希望将网络控制与物理网络拓扑分离 xff0c 从而摆脱硬件对
  • SDN控制平台开源代码

    开源代码是指源代码在开放的许可下公开发布 xff0c 任何人都可以从源代码免费获得 复制 修改和分发 在SDN控制平台领域 xff0c 有许多开源代码可供选择 xff0c 如 xff1a OpenDaylight ONOS Ryu等 这些项
  • SDN框架漏洞

    1 数据平面 数据平面交换机 数据平面由启用了OpenFlow的交换机组成 xff0c 使其容易受到流表修改 拓扑欺骗和DDoS攻击等几种安全威胁 在流表修改攻击中 xff0c 恶意节点插入或修改流表规则 xff0c 以嗅探网络中正在发生的
  • SDN 中 DDoS 攻击问题(论文方法总结)

    SDN 中 DDoS 攻击类型 1 数据平面DDoS攻击 数据平面由多个启用OpenFlow的转发设备组成 这些设备被称为OpenFlow交换机 每个交换机都有一个有限的流表大小来存储规则和有限的处理能力来处理不匹配的数据包 xff0c 因
  • SDN, SD-WAN, NFV, VNF: What Is All This?

    本文转载至 xff1a http www velocloud com sd wan blog sdn sd wan nfv vnf Inscrutable alphabet soup Even the fully expanded term
  • Openstack Neutron 集成 SDN控制器

    Neutron 集成SDN控制器 一 xff0e Neutron的组成元素 Neutron server 可以理解为一个专门用来接收Neutron REST API 调用的服务器 xff0c 然后负责将不同的REST API分发到不同的ne
  • Centos搭建配置SDN

    文章目录 赛题 1 关闭Selinux和防火墙 2 安装相关服务并上传解压安装包 安装服务 安装ODL 启动OVS 启动karaf程序 3 安装组件 测试 4 创建拓扑 5 下发流表 6 启动HTTP Server功能 7 更多内容 赛题
  • Ubuntu下如何关闭指定端口的进程

    1 查看该端口的占用情况 lsof i 端口号 2 关闭进程 kill PID 可能不止一个进程
  • OpenvSwitch实现简单VLAN

    需求 现有拓扑结构如下的网络结构 s1 s4为交换机 h1 h9为主机 现欲让单数主机 h1 h3 h5 h7 h9 之间互相能ping通 双数主机之间互相能够ping通 但单数和双数主机之间不能访问 拓扑结构 s1
  • Ubuntu/Centos多方法安装mininet

    Ubuntu安装 方法一 apt 安装 sudo apt get install mininet 方法二 源码安装 下载源码 git clone git github com mininet mininet 查看并选择版本 cd minin
  • 基于OVSDB协议在SDN控制器ONOS开发配置管理OVS API

    为了更好的分享体验 博客搬迁至极客驿站 欢迎查阅 基于OVSDB协议在SDN控制器ONOS开发配置管理OVS API 介绍 准备工作 开发步骤 问题排查 介绍 目前protocol 中ovsdb协议层面已经实现 但是基于ovsdb prot
  • OpenFlow流表_时间因素

    目标 现有拓扑结构如下的网络结构 s1 s4为交换机 h1 h9为主机 现欲让h1和h2白天ping不通 晚上ping的通 拓扑结构 s1
  • [SDN]Mininet中的miniedit问题汇总

    作者 清水寺丞 简介 正在学习unity 数据库 计算机通信网络和python 喜欢部署各种奇奇怪怪的小项目 喜欢就点个关注一起学习吧 目录 前言 怎么打开MiniEdit 保存mn与py文件出现问题 为什么我run了拓扑之后终端没有出现m
  • SDN前沿技术【SMaRT-5G项目】

    目录 引言 节能方法 快速了解投资回报率 ROI ONF SMaRT 5G Initiative RAN 能量优化 方法 电池开 关方法 MIMO 睡眠和 RF 通道打开 关闭 高级睡眠模式 ASM RAN节能解决方案的

随机推荐

  • python中if__name__=='__main__'_python中的if __name__=='__main__': main()解析

    python中我们会看到一段代码是这样的 1 if name main 2 main 这段代码的什么意思 我们可以知道代码的意思是如果 name main 为Ture 则调用main 函数 有句话经典的概括了这段代码的意义 Make a s
  • OSCS开源安全周报第 55 期:JeecgBoot 远程代码执行漏洞

    本周安全态势综述 OSCS 社区共收录安全漏洞 11 个 公开漏洞值得关注的是 JeecgBoot 远程代码执行漏洞 企业微信私有化后台API未授权访问漏洞 WPS Office 存在代码执行漏洞 MPS 3pcb l4mv Microso
  • 前端常用的跨域方案

    目录 前言 跨域 解决跨域方案 一 修改本地HOST 二 JSONP 三 CORS 四 proxy 前言 发送请求XMLHttpRequest ajax ajax axois fetch http 192 168 0 103 8080 fi
  • Google Colab启动TensorFlow出现No dashboards are active for the current data set.

    我在Colab上面跟着federated learning for image classification教程做相关的东西 在用到tensorbord的时候 使用如下代码 test skip true load ext tensorboa
  • Android 大图显示优化方案-加载Gif 自定义解码器

    基于Glide做了图片显示的优化 尤其是加载Gif图的优化 原生Glide加载Gif图性能较低 在原生基础上做了自定义解码器的优化 提升Glide性能 Glide加载大图和Gif 尤其是列表存在gif时 会有明显卡顿 cpu和内存占用较高
  • JS中版本号的比较(AI)

    在 JavaScript 中 您可以使用字符串比较算法比较版本号 版本号通常采用 x y z 格式 其中 x y 和 z 均为数字 表示主版本号 次版本号和修订版本号 以下是比较版本号的一些示例代码 示例1 简单比较 AI 您可以使用比较运
  • 线性调频脉冲压缩

    线性调频脉冲压缩 LFM信号的数学表达式为 式中为f c载波频率 rect t T 为矩形信号 K B T是调频斜率 信号的顺势频率为f c Kt T 2 t T 2 典型线性调频信号如下图 在MATLAB中实验结果如下 在远场设置了一个目
  • 3. 自建DNS(bind9)

    3 自建DNS bind9 扩展关键词 web dns NamedManager 是一个基于Web的DNS管理系统 注意 下文操作是在172 10 10 11机器上处理的 关键配置注意对应 各主机ip 及其hostname的设置 一 bin
  • C++中class关键字

    在C 语言中class是定义类的关键字 C 中也可以使用struct定义类 两者区别是 用class定义的类 如果数据成员或成员函数没有说明则默认为private 私有 的 而用struct定义的 默认为public 公共 的 示例 inc
  • Vue-Vue列表渲染v-for

    v for 指令需要以 site in sites 形式的特殊语法 一 v for 循环数组 HTML代码 div ul li item li ul div JS代码 new Vue el app data list red green b
  • 数据结构中常见的树

    哈夫曼树 Huffman Tree 哈夫曼树 又被称为最优二叉树 属于带权值二叉树的一种 它的真实节点全部分布在叶子节点中 是各种可能的组合中 WPL 值最小的形式 组合形式可能不唯一 但 WPL 值一定为最小 介绍一下 WPL Weigh
  • c语言repeat语句的用法,关于Lua中的repeat...until循环语句的使用教程

    关于Lua中的repeat until循环语句的使用教程 这篇文章主要介绍了Lua中的repeat until循环语句使用教程 是Lua入门学习中的基础教程 需要的朋友可以参考下与for和while循环不同 在循环的顶部测试循环条件 Lua
  • 【JavaWeb】PowerDesigner的使用

    PowerDesigner 数据库设计的工具 01 PowerDesigner概述 02 数据模型 2 1 概念数据模型 2 1 1 PowerDesigner使用之概念数据模型 2 1 2 根据概念模型生成物理模型 2 2 物理数据模型
  • C# 参数中this 表示扩展扩展方法

    怎么使用 public static SlicedHull Slice this GameObject obj Vector3 position Vector3 direction Material crossSectionMaterial
  • IOTCS+Ekuiper搭建物联网边缘计算平台

    背景介绍 IOTCS 是专为物联网平台而设计的工业智能网关 自从 2020 年 10 月以来 我们从需求调研 设计 定型 研发 测试经过漫长的沉淀与孵化 最终顺利实现工业智能网关最初的设想 我们凭借创新设计理念 快捷的安装以及部署 易用的扩
  • pycharm+pyqt5:CreateProcess error=5,拒绝访问

    问题背景 使用pyqt5来做python的图形界面程序开发实验 提前安装并配置了相关环境 弄了一下午 终于弄好了 总体的安装教程就不多说了 说说我遇到的错误叭 问题分析 通过命令行下载好相关工具后 需要使用pycharm的external
  • ant利用正则表达式获取文件夹名

  • wait(),waitpid()函数

    首先我们来了解一下所谓的僵尸进程 僵尸进程就是两个进程 一个父进程 一个子进程 其子进程终止后 0 3G的用户内存被回收 而3 4G的部分内存被回收 但是3 4G内存中的PCB等待父进程回收 若PCB未被父进程回收 我们称这个进程为僵尸进程
  • css/wxss 用伪类实现竖线效果(图片+源码)before、after巧用

    源代码见本文末尾 本文的代码片段用HTML语言书写 适用于网页 微信原生小程序 框架uniapp等 小程序原生开发需要实现这样一个效果 用伪类啊 这个我熟 先讲讲思路 因为用before和after的效果是一样的 所以我们任选一个 选择be
  • 基于OVSDB协议在SDN控制器ONOS开发配置管理OVS API

    为了更好的分享体验 博客搬迁至极客驿站 欢迎查阅 基于OVSDB协议在SDN控制器ONOS开发配置管理OVS API 介绍 准备工作 开发步骤 问题排查 介绍 目前protocol 中ovsdb协议层面已经实现 但是基于ovsdb prot