云内基于 SRv6 的 SFC 方案

news2025/1/18 4:50:35

1. 基于 SRv6 的 SFC 服务链

 

为满足用户的业务数据安全、稳定等需求,提供各种基础保障或增值优化服务,在传统网络中,经常使用业务功能节点(如负载均衡、防火墙等)实现服务供应。但这些业务功能节点往往与网络拓扑和硬件资源耦合紧密,各个业务功能节点均为专用的设备形态且部署繁杂。当开通新业务或业务流程发生变更时,需要更改网络拓扑,甚至改造和升级网络设备,对周边的支撑系统也会有影响。

随着云计算网络的普及、虚拟化技术的成熟和应用,网络功能动态加载,资源按需分配,业务灵活开通等特点明显加强,而服务供应也必不可少。如果还使用传统网络的服务供应部署方式,已无法满足云计算网络灵活多变的组网特点、客户多种多样的业务需求。因此,服务链 SFC 技术被提出,该技术从满足客户业务数据安全、稳定等需求角度出发,更契合新时代网络特点,使业务功能灵活性得到更大的发挥。

SFC ( Service Function Chain 服务链)是由一系列业务节点有序构成,各业务节点可对数据流量进行流量检查、处理等操作。通过将用户数据报文依照业务逻辑以此通过各业务功能节点,就能轻松实现 SFC 服务链功能。随着云服务市场规模的扩大,在云内实现 SFC 也有着庞大的市场需求。

SFC 大部分通过 NSH 标准化服务链技术实现,但这些方案仍存在一定程度的限制:配置时需要根据流量的转发路径,基于每条业务流,依次在各个业务节点上逐跳配置。当 SFC 服务链扩容时,其配置复杂度也随之几何上升。由此可见,现有方案操作复杂,可扩展性差,不利于 SFC 的落地推广。

近年来随着云计算、大数据、物联网、人工智能等信息技术的快速发展和传统产业的数字化转型,数据量呈现几何级增长,同时计算成本快速下降,数字经济正进入算力时代。在算力网络中使用 IPv6 作为新一代 IP 承载协议,由此衍生了许多 IP 新技术。其中, SRv6 ( Segment Routing IPv6 )技术通过 IPv6 扩展头的方式,基于现有 IPV6 转发技术,实现了网络可编程化。

若能利用 SRv6 的路由编排特性实现 SFC ,将大幅简化 SFC 逐跳配置的繁杂度,并且也适应新时代大规模网络的发展。因此本文将探索基于 SRv6 技术支持 SFC 的实现,并尝试在云环境中实现该方案。

2. 城域网 SRv6 SFC 应用场景

基于 SRv6 的 SFC 组网架构

以城域网中 SRv6 使用场景为例,基于 SRv6 的 SFC 方案主要由用于下发服务链路径信息的( SDN 控制器)、业务分类节点( SC )、服务转发节点( SFF )和服务链集群( SFC Domain )组网构成。

如上图,服务供应商可通过 SDN 控制器向 SFC 业务分类节点下发服务链配置信息。服务链配置信息组织了 SFC 服务域中服务器路径次序,如:( VBRAS, FW, CGN, Server ) 、 ( VBRAS,FW ) 、( CGN, Server ) 等。

SC 和 SFF 将以 SRv6 隧道的形式为业务数据提供服务链。其中, SC 负责将业务流量导入 SRv6 隧道中, SFF 负责将业务流量传递到具体的服务供应机器。详细运作过程如下图:

当用户发起访问,业务数据经过 SC 时, SC 将业务数据引入到 SRv6 隧道中进行转发。业务数据随后传递到 SFF , SFF 解读报文中的路径信息,并按信息次序传递数据包到具体的服务链机器( SF )中处理,之后数据包被返还到 SFF , SFF 按路径信息传递到下一个 SFF 或者隧道尾节点。

数据包经过各服务器成功处理后,到达尾节点时,报文中服务链信息部分将被剥去,并按原始业务数据路径被传递。

基于 SRv6 的 SFC 实现原理

SID 标记路径

服务链信息(即服务器地址序列)以 SID 的形式被封装在 IPv6 SRH 扩展头中,作为 SRv6 报文在上文所述的 SRv6 TE Policy 中流转。同时, SC 、 SFF 等地址也可以用 SID 来标记,引导报文路径。因此 SID 相当于网络中的位置标记,其值可使用 IPv6 地址。

不同的 SID 其对应的处理逻辑也不一样。比如 SFF 需要解析并保存 SRv6 报文信息,将数据包分发给不同的 SF ,如果 SF 不支持 SRv6 、 IPv6 等,在分发前 SFF 还需要解封 SRv6 外层报文等等。所以节点在收到 SDN 控制器下发的服务链配置信息后,也会在本地建立相应的 SID 表( Local SID Table ) 。

因此,依据 SID 对应的不同操作,可将其分类如下:

报文转发过程

在 SRv6 TE Policy 中 SC 节点、 SFF 节点、尾节点对 SRv6 报文的转发操作如下:

  1. SC 节点收到用户网络原始报文后,根据服务链信息进行SRv6 报文封装,此时 IPv6 报文的目的地址是 SFF 的 End.AS SID , SRH 头部包括服务链全路径信息( SID List )。
  2. SFF 收到报文以后,通过查找 Local SID 表发现目的地址为本地 End.AS SID ,保存当前 SL ( SID List 指针)值,并执行 End.AS SID 对应指令——解封报文,去除 IPv6 报文头部后将原始报文通过配置的出接口发送到 SF 进行处理。
  3. 当 SF 处理完报文并将报文发回给 SFF , SFF 会根据收报文的入接口查找配置信息,然后依据配置的 SID list 重新封装 SRv6 报文,封装后报文 SRH 中 SID list 与 SC 上 SRv6 TE Policy 路径一致, SRH 中的 SL 值为步骤2中保存的 SL 值减1。此时 SRv6 报文目的地址是本地 End.AS SID 之后的下一个 SID (即 Device C 的 End SID )。SFF 根据报文的目的 IPv6 地址,查找 IPv6 路由表转发报文。
  4. ( 在真实服务链路径中,不一定每个节点都需要把报文传递到 SF 中,有时可能只是路径需要经过了该节点,因此节点只需查找路由并转发报文到下一个节点即可。图中 Device C 就是模拟这样的节点。)当 Device C 接收到报文以后,通过查找 Local SID 表发现目的地址为本地 End SID ,按 Srv6 转发流程处理报文。目的地址替换为 D1 (即尾节点的 End SID ), SL-1 ,查找 IPv6 路由表转发报文。
  5. 尾节点接收到报文以后,通过查找 Local SID 表发现目的地址 D1 为本地 SID ,将目的地址替换为 D2 (即尾节点的 End.DT4 SID ), SL-1 变为0。尾节点执行 End.DT4 SID 对应指令——解封装 SRv6 报文,并将原始报文转发到对应 VPN 。

3. Linux 中的 SRv6 SFC 模型

上文通过城域网中基于 SRv6 的 SFC 应用场景,梳理了 SFC 的实现流程。而在通用服务器中实现服务链功能,则需要系统实现 srv6 技术。目前 linux 系统从 4.10 开始已有支持。

Linux SRv6 协议栈

模型图

在机器中部署 namesapce 模拟 SRv6 网络节点。host 1 请求 host 4 的流量将被引导到 SRv6 封装中,经过 host 2 和 host 3 节点处理后再发送到 host 4。host 4 收到 host1 的请求中不带有 SRv6 报文,对 SRv6 过程不感知。

其中 host1 通过 route 命令对原始报文执行 SRv6 封装操作;host2 作为中间转发节点,通过 route 命令对 SRv6 报文执行转发操作;host3 作为 SRv6 过程的尾节点,通过 route 命令配置剥除 SRv6 报文,并将原始报文发送到目标机器 host4 中。

测试方法

执行如下脚本:

      
#!/bin/bash

TMUX=4hs1sw

# Kill tmux previous session
tmux kill-session -t $TMUX 2>/dev/null

# Clean up the previous network namespaces
for ns in h1 h2 h3 h4 switch; do
	ip netns delete ${ns} 2>/dev/null
done

ip netns add h1
ip netns add h2
ip netns add h3
ip netns add h4
ip netns add switch

ip -netns switch link add veth1 type veth peer name enp0s8 netns h1
ip -netns switch link add veth2 type veth peer name enp0s8 netns h2
ip -netns switch link add veth3 type veth peer name enp0s8 netns h3
ip -netns switch link add veth4 type veth peer name enp0s8 netns h4


###################
#### Node: h1 #####
###################
echo -e "\nNode: h1"
ip netns exec h1 sysctl -w net.ipv6.conf.all.forwarding=1

ip -netns h1 link set dev lo up

ip -netns h1 link set dev enp0s8 address 00:00:00:00:00:01
ip -netns h1 addr add fc00::1/64 dev enp0s8
ip -netns h1 link set dev enp0s8 up

ip -netns h1 -6 route add fcf0:12::100 via fc00::2

# 2 SIDs here!
# - fcf0:12::100 steers the packet to node h2 where the SRv6 End function is
#   applied (SL=1 on ingress -> SL=0 on egress)
# 
# - fcf0::23::6006 steers the packet to node h3 where the decap function is
#   applied (SL=0 on ingress)
ip -netns h1 -6 route add fc00::4 encap seg6 mode encap \
	segs fcf0:12::100,fcf0:23::6006 dev enp0s8


###################
#### Node: h2 #####
###################
echo -e "\nNode: h2"
ip netns exec h2 sysctl -w net.ipv6.conf.all.forwarding=1

ip -netns h2 link set dev lo up

ip -netns h2 addr add fc00::2/64 dev enp0s8
ip -netns h2 link set dev enp0s8 address 00:00:00:00:00:02
ip -netns h2 link set dev enp0s8 up

ip -netns h2 -6 route add fcf0:23::6006 via fc00::3

# apply the SRv6 End function for updating the active SID
ip -netns h2 -6 route add fcf0:12::100 encap seg6local action End dev enp0s8


###################
#### Node: h3 #####
###################
echo -e "\nNode: h3"
ip netns exec h3  sysctl -w net.ipv6.conf.all.forwarding=1

ip -netns h3 link set dev lo up

ip -netns h3 addr add fc00::3/64 dev enp0s8
ip -netns h3 link set dev enp0s8 address 00:00:00:00:00:03
ip -netns h3 link set dev enp0s8 up

# apply the SRv6 End.DT6 function to decap the packet and to deliver
# the inner packet to host h4.
ip -netns h3 -6 route add fcf0:23::6006 encap seg6local \
	action End.DT6 table 254 dev enp0s8

# all the hosts are in the same network...
#
#                  +-----+---------------------------------+-----+
#  - decap packet: | ... | IPv6 DA=fc00:1, SA=fc00::4, ... | ... |
#                  +-----+---------------------------------+-----+
# 
# host h3 tries to route the decap packet and it finds out that such
# packet can be sent directly from node h1 to node h4.
# As a result, the node h3 sends an icmpv6 redirect packet to host h1.
# We do not want to send this packet to the host h1, so we filter it.

ip netns exec h3 ip6tables -t mangle -A POSTROUTING  \
	-p icmpv6 --icmpv6-type redirect -j DROP


###################
#### Node: h4 #####
###################
echo -e "\nNode: h4"
ip netns exec h4  sysctl -w net.ipv6.conf.all.forwarding=1

ip -netns h4 link set dev lo up

ip -netns h4 addr add fc00::4/64 dev enp0s8
ip -netns h4 link set dev enp0s8 address 00:00:00:00:00:04
ip -netns h4 link set dev enp0s8 up


#######################
#### Node: switch #####
#######################
echo -e "\nNode: switch"
ip -netns switch link set dev lo up
ip -netns switch link set dev veth1 up
ip -netns switch link set dev veth2 up
ip -netns switch link set dev veth3 up
ip -netns switch link set dev veth4 up

ip -netns switch link add sw0 type bridge
ip -netns switch link set dev sw0 up

ip -netns switch link set dev veth1 master sw0
ip -netns switch link set dev veth2 master sw0
ip -netns switch link set dev veth3 master sw0
ip -netns switch link set dev veth4 master sw0

sleep 1

## Create a new tmux session
tmux new-session -d -s $TMUX -n h1 ip netns exec h1 bash
tmux new-window -t $TMUX -n h2 ip netns exec h2 bash
tmux new-window -t $TMUX -n h3 ip netns exec h3 bash
tmux new-window -t $TMUX -n h4 ip netns exec h4 bash
tmux new-window -t $TMUX -n switch ip netns exec switch bash
tmux set-option -g mouse on
tmux select-window -t :0
tmux attach -t $TMUX

SREXT 实现 unaware SRv6 SFC 代理

linux 协议栈中已经实现了 srv6 封装、解封、转发的功能。但在目前 SFC 应用场景中, SF 不一定能支持 IPv6 ,需要有 unaware srv6 的代理实现来过渡支持。这方面可通过加载 srext 内核模块来实现。

模型图

部署三个虚机,分别模拟入口节点(ingress),出口节点(egress)和 unaware srv6 服务端代理节点(nfv)。

其中 nfv 节点上有三个 namespace ,模拟 unaware srv6 服务端。

当数据进入 nfv 节点中, srext 将剥除 srv6 部分报文并发送到 vnf namespace 中,待 vnf namespace 处理完后,又将 srv6 部分重新封装到报文中,继续向下一个 srv6 节点发送。

以 client ping server 的请求过程为例,报文处理过程如下图所示:

测试方法

https://netgroup.github.io/SRv6-net-prog/testbed-basic.html

4. 云内基于 SRv6 的 SFC 方案

在云环境中实现基于 SRv6 的 SFC 方案,需要在 OVS 中实现 SRv6 的操作,控制面可通过 SDN Controller 把 SFC 的编排路径下发到 OVS 流表中, OVS 依据流表配置,将业务链信息压入 SRv6 报文中并转发,由此实现 SFC 业务操作。

OVS 中实现 SRv6 转发

模型图

在云环境中, SFC 的部署可能与客户机器在同一个或者不同节点上,两者对 SRv6 数据包的操作大致一样。用户对 OVS 将流量引至 SFC 的过程无感知。

当用户和 SFC 在不同节点上时, OVS 对业务流量操作如下:

  1. 控制面可通过 SDN 控制器、 OVS 命令行等向 OVS 下发服务链信息配置流表,包括目标报文标记( eg. 五元组)和服务链信息( SID 列表),服务链信息流表在 OVS 中将转化为端口对数据包的具体操作(封装、解封、转发)。
  2. OVS 对接用户的端口(port 1)收到业务流量后,查找流表,如果命中了服务链信息配置流,则封装 SRv6 报文,将服务链路径信息依次全部压入 SRH 中 SID List 字段,初始化 SID List 指针,将 IPv6 目的地址指向 SID List 首节点。将报文转发到下一个处理端口(port 2)。
  3. 当中间端口(port 2、port 3)收到 SRv6 报文后,依据控制面的配置,这些端口将执行转发动作:将 SID List 指针值减一,替换 IPv6 目的地址,转发到下一个节点。
  4. 当对接 SF 的端口(port 4、port 5)收到 SRv6 报文后,依据控制面的配置,这些端口将先执行解包动作,保存报文中的 SID 指针等信息,然后发送原始业务报文给对应的 SF ;当 SF 返回原始业务报文后, OVS 再读取保存的信息执行封包动作,然后转发到下一个节点(port 6)。
  5. 当目标客户机所在端口(port 6)收到 SRv6 报文后,依据控制面的配置,这些端口将执行解包动作,删除包含服务链信息的 SRv6 部分,将原始业务报文转发给目标机器。至此完成基于 SRv6 的 SFC 流程,其过程用户无感知。

测试方法

为验证 OVS 对 SFC 业务的 SRv6 过程,在此简化模型如下:

在该模型中验证 OVS 对 SRv6 的封装、转发和解封。其中 namespace1 和 namespace4 模拟业务通信的客户机, namespace2 和 namespace3 模拟 SF ,但这里使用的 namespace 并不具备真正的 SF 功能,因此并未对数据包进行任何操作,只是转发给 OVS ,以此验证 OVS 功能。

https://pan.baidu.com/s/1u2cMprwoTE4-MePA9kEnBg?pwd=u67f

  1. 控制面下发 SFC 配置流表到 OVS , 指定从 port 2 接收到的报文需要依据 SID List 执行 SRv6 的封装;从 port 4 收到的报文执行 SRv6 转发动作;从 port 6 收到的报文执行解封操作。
  2. 当 port 2 收到报文时,检查是否命中 SFC 流表,如果命中则封装 SRv6 报文,并按照流表规则转发到 port3 。其中封装操作将服务链信息全部压入 SRH 中,由于 OVS port2 作为 SID List 的起点,所以初始化指针值为第二个 SID 即下一跳 SID ,并加上 IPv6 报文,且目的地址为下一跳 SID 。
  3. Namesapce 2 将 port3 发来的报文转发给 port 4 。OVS port 4 接收到报文后,如果命中 SFC 流表,则执行 SRv6 转发动作:SID List 指针值减一,更新 IPv6 目的地址。修改完 SRV6 报文后, OVS 按照流表规则转发到 port 5。
  4. Namespace 3 将 port5 发来的报文转发给 port 6。OVS port 6 接收到报文后,如果命中 SFC 流表,则执行 SRv6 解封动作:剥除 IPv6 和 SRH 部分报文,将原始报文发送到 port 7给目标机器。

云内基于 SRv6 的 SFC 方案

云环境中基于 OVS 实现 SFC 方案通过在 OVS 中配置服务链信息流表规则,简化逐跳策略路由配置的繁杂步骤,实现服务链业务的快速部署。该方案支持 IPv4/IPv6 双栈的业务流量,在 SFC 中通过使用 SREXT 支持 unaware SRv6 的 SF 接入,即也支持 IPv4/IPv6 双栈 SF 。

模型图

云环境中基于 OVS 实现 SFC 方案最小部署方案如下:

user-domain 和 server-domain 上可部署业务访问源和目标,分别接入 OVS 中两个不同的 port ;sfc-domain 作为服务链域机器,其上可部署具体的服务链应用,在此模型中使用三个不同的 vnf 模拟应用容器。考虑到目前许多环境未支持 SRv6 ,此处用 IPv4 来模拟, SF 中的应用都使用 IPv4 中即可。

OVS 中 user1-port 和 user2-port 作为 SFC SRv6 过程的起止端点,绑定了两个 SID (1:2::1, 2:3::2)作为服务链( SID List )中的起止 SID 。

在部署 sfc-domain 时,将具体的 SF 及其 ipv4 地址写入 Local SID Table 中,并使用两个接口(sfc-domain:ens3, sfc-domain:ens10)分别作为 SFC 域的出入接口对接 OVS 的 port (proxy0-port, proxy1-port)。这两个接口(ens3:[1:2::2], ens10:[2:3::1])分别与 OVS 起止 SID 在同一网段。

上图是以 tcp 消息请求过程为例的流量模型。其主要过程如下:

  1. 控制面配置服务链信息流表到 OVS 中,其中对接业务源的 user1-port 负责将业务报文封装到 SFC 的 SRv6 中,对接目标源的 user2-port 负责将 SFC 的 SRv6 剥除。
  2. 当业务源中客户端发起访问, OVS 中 user1-port 收到数据包后,查询流表内容,发现数据包命中 SFC 规则,于是将规则中的全量 SID (服务链[2::ad:f1,2::ad:f2,2::ad:f3]和 OVS 中起止 SID [1:2::1, 2:3::2] )依次压入 SRH 栈中,初始化 SID List 指针,封装 IPv6 报文,并将目的地址设置为下一跳 SID 即第一个 SF 地址( 2::ad:f1 )。
  3. 当 sfc-domain 接收到报文后,程序查找目的 IPv6 ,发现命中 LOCAL SID Table ,于是保存指针,剥除 SRv6 ,发送原始报文到 vnf1 中。当 vnf1 返还原始报文后, sfc-domain 将读取保存的指针信息,重新封装 SRv6 报文,递减指针值,更新下一跳 SID 到目的 IPv6 地址,查找 LOCAL SID Table 和路由表,如果命中就转发到下一跳 SID 所在接口。
  4. 当 sfc-domain 将报文转发到最后一个 SID (2:3::2)时,将报文通过 proxy1-port 发送到 OVS 中, OVS 查找流表,发现命中 SFC 解包规则,于是剥除 SRv6 部分,将原始报文从 user2-port 发送出去。至此, tcp 请求过程中的 SFC 处理完毕,业务目标收到报文仍是原始报文,对 SFC 处理无感知。

测试方法

  1. 配置好 ovs 端口: https://pan.baidu.com/s/1uxIANuLHiJuJtdM37yEFZQ?pwd=k7xc 
  2. 配置 vm ,并测试: https://pan.baidu.com/s/1hQRDrpd-HrrFVuGWk9mYeQ?pwd=q5yn

综上,本文讨论了 SFC 服务链应用,及其在 linux 中的实现方案,以及在云环境中基于 SRv6 的实现方案,以探索算力网络时代下 SFC 在云环境中的快速部署。模型较为简单,开发仍在不断完善中。

Reference

  1. 《 SRv6 SFC 技术白皮书》
  2. https://github.com/netgroup/p4-srv6-usid/issues/4
  3. Ip route encap introduction https://www.man7.org/linux/man-pages/man8/ip-route.8.html

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

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

相关文章

Fortinet Accelerate 2023全球网安大会成功举办 加速推进网络安全行业融合与整合

近日,Fortinet全球网络安全大会——Fortinet Accelerate 2023 在美国奥兰多成功举办。在对企业数字化转型挑战及网络威胁趋势等行业热点进行深入探讨的同时,Fortinet全新发布了以融合与整合为核心设计理念的增强型产品和服务,帮助企业从容应对…

第2章 时间空间复杂度计算

1时间复杂度计算 时间复杂度是什么? 一个函数,用大O表示,例如:O(1), O(N), O(logN). 定性描述算法的运行时间。 时间复杂度常见图: 案例: O(1) let i 0 i 1 解释:每次执行这段代码&#…

【Paper Note】Video Swin Transformer

Video Swin Transformer 介绍架构3.2 3D Shifted Window based MSA Module3.2.1 在不重叠的三维窗口上的MSA3.2.2 3D Shifted Windows3.2.3. 3D Relative Position Bias 3.3 Architecture Variants3.4 Initialization from Pre-trained Model 总结 文章链接:https:/…

zabbix自动发现和自动注册部署

目录 zabbix自动发现 确保客户端上的zabbix-agent2服务状态正常 在web页面删除原有的客户端主机 在服务端和客户端上配置 hosts 解析 在 Web 页面配置自动发现 zabbix自动注册 环境准备 修改 zabbix-agent2 配置文件 在 Web 页面配置自动注册 zabbix自动发现 对于agen…

如何使用Git将本地代码上传GitHub仓库?

如何使用Git将本地代码上传GitHub仓库呢? 前提 要上传本地代码到GitHub仓库,那必然要先在GitHub上建立一个存储代码的仓库,这里我在仓库新建了一个名为5blog的仓库。 备注:本文章将以默认分支main为例来讲解上传步骤 接着我们打…

学习经验分享【26】论文写作画图方法(持续更新)

写作前面:论文投稿能否成功,图表作为比较直观的展现,起着关键的作用,图表丰富规范好看,一定程度上能够吸引编辑和审稿人的眼球,提升录用概率。就跟人的形象一样,形象好第一印象就会好&#xff0…

简单的重装系统教程

郁闷,最近电脑一直蓝屏重启,用 2 分钟就蓝屏一次,遂产生重装系统的想法。 准备 U盘(8G或以上) PE 工具: 微PE工具箱快速指引 | 微PE优盘使用说明书 (wepe.com.cn) 系统镜像: 官网 Windows 10 官网 Windows 11 M…

送给程序员的一份养生指南

本文是 Joe Kutner 的《程序员健康指南》的干货记录。时刻提醒自己要有一个健康的工作和生活方式。身体是革命的本钱,年轻的时候拿身体换钱,老了可能就要拿钱换身体。当你有被程序员职业困扰的健康问题时,希望这篇干货记录可以给予你一定的帮…

mybatis代码生成器模板配置

1.mybatis代码生成器的介绍 代码生成器的目标就是简化单表的增删改查操作,这些标准化的流程工作,交给机器来实现,不需要程序员自己去完成。一般对一张表的操作有,根据主键查询,根据map集合查询,单条数据插…

追踪行人和车辆,并使用deep-person-reid训练自定义追踪模型(行人和车辆两类)

deep-person-reid训练自定义模型 1. 准备代码2. market1501格式3 转换格式代码4. 训练5 追踪测试 仅供参考,目前实现的格式转化还是存在一定的问题,导致训练后的模型精度很高,分配上还是没有完全符合market1501的格式。依照这样训练的模型&am…

UG NX二次开发(C#)-建模-求解两条样条曲线的最大距离

文章目录 1、前言2、最大距离示例3、NXOpen代码实现1、前言 在UG NX中计算两条样条曲线的最小距离是我们常用的,但是计算最大距离却很少用,但是UG NX二次开发为我们提供了这个计算方法,我们只需要调用即可。本小节是用于计算两条样条曲线的最大距离的二次开发讲解。 2、最…

封装通用el-form表单(2种方式)

1、序言 项目地址:git clone form-demo: 封装通用el-form 一个后台管理系统最常见的是表单,表单最常见的是输入框、下拉选择、日期选择、单选、复选框等等, 系统添加若干模块,就复制粘贴若干个el-form、el-form-item,有…

Ubuntu下好用的截图工具flameshot

在Linux环境下截图也是十分重要的东西,flameshot则是一款十分好用的工具 sudo apt-get install flameshot 即可安装 安装完成后打开设置(settings) -> 设备(Devices) -> 键盘快捷键(keyboard Shortcuts),滑到最底下,找到一个加号 点击加号填入以…

300块买什么蓝牙耳机好?无线蓝牙耳机300左右推荐

不管你的手机是否被保留3.5mm的音频接口,蓝牙耳机必定是可以入手的,无束缚的听歌方式对我们中的大多数人都有着很强的吸引力。大多数都定价在几十几百几千不等,但是在300左右的价位更受大众欢迎,说明了中端市场是该类产品竞争最激…

如何把Ai绘画工具放到我们的App中

Scribble Diffusion 是一个简单的在线服务,它使用 AI 将粗略的草图转换为精致的图像,每一张图像都是不同的(而且没有版权困扰)。简单来说,我们只需要「用画笔描绘一张草图,在输入描述后稍等片刻」&#xff…

【Linux】1、操作系统、计算机硬件和软件、Linux 介绍

目录 一、计算机的硬件和软件(1) 硬件(2) 软件 二、操作系统(1) OS 作用(2) OS 举例 三、Linux 内核(1) 介绍(2) Linux 发行版 四、虚拟机 一、计算机的硬件和软件 (1) 硬件 🖥️ 计算机由硬件和软件组成 🖥️ 硬件:计算机中由电子、机械和…

pandas汇总和描述性统计

本文介绍pandas中汇总和描述性统计中的基本内容,仅供参考。 目录 1描述和汇总统计 1.1sum方法 1.2idxmin和idxmax方法 1.3describe方法 1.4描述和汇总统计的常用方法 2相关系数和协方差 3唯一值、值计数以及成员资格 3.1唯一值 3.2值计数 3.3成员资格 1…

【区块链】走进web3的世界-获取Token价格

1、通过预言机获取Token价格(需要部署合约) 在以太坊区块链上,由于智能合约本身无法获取外部数据,因此需要使用预言机 (Oracle) 来获取外部数据。 以下是一个获取代币价格的示例: 选择预言机:首先需要选…

ThreadLocal小记

1、ThreadLocal介绍 1.1、官方介绍 /*** This class provides thread-local variables. These variables differ from* their normal counterparts in that each thread that accesses one (via its* {code get} or {code set} method) has its own, independently initiali…

PPOCR - 命令行训练模型基本流程和常用命令+visualdl可视化

前言 本文记录实践中用paddleocr训练自己的模型的基本步骤和常用命令,以detection为例 更详细内容请参考官方文档https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.6/doc/doc_ch 〇、环境准备 0.1 paddlepaddle环境安装 paddle环境安装链接 根据自己的…