【星海随笔】SDN neutron (二) Neutron-plugin(ML2)

在这里插入图片描述

Neutron架构之Neutron-plugin Core-plugin(ML2)篇

Neutron-server接收两种请求:

REST API请求:接收REST API请求,并将REST API分发到对应的Plugin(L3RouterPlugin)。
RPC请求:接收Plugin agent请求,分发到对应的Plugin(NeutronL3agent)。

Neutron-plugin分为Core-plugin和Service-plugin。

Core-plugin:ML2负责管理二层网络,ML2主要包括Network、Subnet、Port三类核心资源,对三类资源进行操作的REST API是原生支持的。
Service-plugin:实现L3-L7网络,包括Router、Firewall、VPN。
在这里插入图片描述

core-plugin

core-plugin(ML-2)
|- - - - - - - - - - - - - - - - - - - - - - - |
Type Manager(Vxlan) - - - - - - - Mechanism Manager(openvswitch )
每部分又分为Manager和Driver

在这里插入图片描述

执行流

_eventlet_wsgi_server():
service.serve_wsgi(service.NeutronApiService)
WsgiService.start
config.load_paste_app(app_name)
在这里插入图片描述

neutron.api.v2.router:APIRouter.factory

Neutron插件是Neutron的一个重要组成部分,它允许Neutron与不同的网络技术进行集成。
首先,我们需要安装Neutron插件。Neutron插件可以是Open vSwitch、Linux Bridge、Cisco Nexus、VMware NSX等。在安装Neutron插件之前,我们需要确保已经安装了Neutron服务。

以Open vSwitch为例,我们可以使用以下命令安装Open vSwitch插件:

sudo apt-get install neutron-plugin-openvswitch-agent 

安装Neutron插件后,我们需要配置它。配置文件通常位于/etc/neutron/plugins/目录下。以Open vSwitch为例,我们需要编辑/etc/neutron/plugins/ml2/ml2_conf.ini文件。

在该文件中,我们需要配置以下参数:

- type_drivers:指定支持的网络类型,例如vlan、vxlan等。
- tenant_network_types:指定租户网络类型,例如vlan、vxlan等。
- mechanism_drivers:指定网络机制驱动程序,例如Open vSwitch、Linux Bridge等。
- bridge_mappings:指定物理网络和虚拟网络之间的映射关系。

以下是一个示例配置文件:

[ml2] 
type_drivers = flat,vlan,vxlan 
tenant_network_types = vxlan
mechanism_drivers = openvswitch 

[ml2_type_flat] 
flat_networks = external 

[ml2_type_vxlan] 
vni_ranges = 1:1000 

[securitygroup] 
enable_security_group = True 
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver 

[ovs] 
bridge_mappings = external:br-ex 

在上面的示例中,我们指定了Open vSwitch插件支持的网络类型为flat、vlan和vxlan。我们还指定了租户网络类型为vxlan,并将机制驱动程序设置为Open vSwitch。我们还指定了物理网络和虚拟网络之间的映射关系,例如将外部网络映射到br-ex网桥。
完成Neutron插件的配置后,我们需要重启Neutron服务以使配置生效。我们可以使用以下命令重启Neutron服务:

sudo service neutron-server restart 
sudo service neutron-plugin-openvswitch-agent restart 

neutron-plugin 分为 core-plugin 和 service-plugin 两类

L2-L3称为core plugin,包含network、subnet、port
L4-L7称为service plugin,包含router、firewall、loadbalancer、VPN、metering等等

Openstack neutron加载plugin
RESOURCES = {'network': 'networks',
             'subnet': 'subnets',
             'subnetpool': 'subnetpools',
             'port': 'ports'}
SUB_RESOURCES = {}
COLLECTION_ACTIONS = ['index', 'create']
MEMBER_ACTIONS = ['show', 'update', 'delete']
REQUIREMENTS = {'id': attributes.UUID_PATTERN, 'format': 'json'}
class APIRouter(wsgi.Router):

    @classmethod
    def factory(cls, global_config, **local_config):
        return cls(**local_config)

    def __init__(self, **local_config):
    	#创建mapper
        mapper = routes_mapper.Mapper()
        #获取NeutornManage的core_plugin,这个定义在/etc/neutron/neutron.conf,比如我的是core_plugin = ml2
        plugin = manager.NeutronManager.get_plugin()
        #扫描neutron/extensions下所有的extension
        ext_mgr = extensions.PluginAwareExtensionManager.get_instance()
        ext_mgr.extend_resources("2.0", attributes.RESOURCE_ATTRIBUTE_MAP)

        col_kwargs = dict(collection_actions=COLLECTION_ACTIONS,
                          member_actions=MEMBER_ACTIONS)
		#构建映射规则函数
        def _map_resource(collection, resource, params, parent=None):
            allow_bulk = cfg.CONF.allow_bulk
            allow_pagination = cfg.CONF.allow_pagination
            allow_sorting = cfg.CONF.allow_sorting
            #创建controller
            controller = base.create_resource(
                collection, resource, plugin, params, allow_bulk=allow_bulk,
                parent=parent, allow_pagination=allow_pagination,
                allow_sorting=allow_sorting)
            path_prefix = None
            if parent:
                path_prefix = "/%s/{%s_id}/%s" % (parent['collection_name'],
                                                  parent['member_name'],
                                                  collection)
            mapper_kwargs = dict(controller=controller,
                                 requirements=REQUIREMENTS,
                                 path_prefix=path_prefix,
                                 **col_kwargs)
            # mapper.collection这个就是构建映射规则
            #collection:一个字符串,就是资源的复数形式,比如networks
            #resource:一个字符串,就是资源的单数形式,比如network
            return mapper.collection(collection, resource,
                                     **mapper_kwargs)
	   #构建/的映射规则
        mapper.connect('index', '/', controller=Index(RESOURCES))
        
        for resource in RESOURCES:
        	#针对每一个核心资源(network、subnet等),调用_map_resource,构建映射规则
            _map_resource(RESOURCES[resource], resource,
                          attributes.RESOURCE_ATTRIBUTE_MAP.get(
                              RESOURCES[resource], dict()))
            resource_registry.register_resource_by_name(resource)
		#SUB_RESOURCES是空的,没啥用
        for resource in SUB_RESOURCES:
            _map_resource(SUB_RESOURCES[resource]['collection_name'], resource,
                          attributes.RESOURCE_ATTRIBUTE_MAP.get(
                              SUB_RESOURCES[resource]['collection_name'],
                              dict()),
                          SUB_RESOURCES[resource]['parent'])

        #清除当前配置在策略引擎中的所有规则。其在单元测试中和核心API router初始化的最后调用,确保在所有扩展加载之后加载规则
        policy.reset()
        #初始化wsgi.Router
        super(APIRouter, self).__init__(mapper)
四种组网模型

在这里插入图片描述

Type Manager

#neutron/plugins/ml2/managers.py
class TypeManager(stevedore.named.NamedExtensionManager):
    """Manage network segment types using drivers."""
    def __init__(self):
        # Mapping from type name to DriverManager
        self.drivers = {}
        LOG.info(_("Configured type driver names: %s"),
                 cfg.CONF.ml2.type_drivers)
        super(TypeManager, self).__init__('neutron.ml2.type_drivers',
                                          cfg.CONF.ml2.type_drivers,
                                          invoke_on_load=True)
        LOG.info(_("Loaded type driver names: %s"), self.names())
        self._register_types()
        self._check_tenant_network_types(cfg.CONF.ml2.tenant_network_types)

    def create_network_segments(self, context, network, tenant_id):
        """Call type drivers to create network segments."""
        segments = self._process_provider_create(network)
        session = context.session
        with session.begin(subtransactions=True):
            network_id = network['id']
            if segments:
                for segment in segments:
                    segment = self.reserve_provider_segment(
                        session, segment)
                    db.add_network_segment(session, network_id, segment)
            else:
                segment = self.allocate_tenant_segment(session)
                db.add_network_segment(session, network_id, segment)
Type Drivers
  1. Flat模型最为简单,所有的虚拟机共用一个私有IP网段,IP地址在虚拟机启动时完成注入,虚拟机间的通信直接通过HyperVisor中的网桥转发,公网流量在该网段的网关上进行NAT(Nova-network实现为开启nova-network主机内核的iptables,Neutron实现为网络节点上的l3-agent)。Flat DHCP模型与Flat区别在于网桥中开启了DHCP进程,虚拟机通过DHCP消息获得IP地址(Nova-network实现为nova-network主机中的dnsmaq,Neutron实现为网络节点上的dhcp-agent)。

Dnsmasq 的工作原理
Dnsmasq 在接受到用户的一个 DNS 请求时,首先会查找 /etc/hosts 这个文件,如果 /etc/hosts 文件没有请求的记录,然后查找 /etc/resolv.conf 中定义的外部 DNS(也叫上游 DNS 服务器,nameserver 配置),外部 DNS 通过递归查询查找到请求后响应给客户端,然后 dnsmasq 将请求结果缓存下来(缓存到内存)供后续的解析请求。
配置 Dnsmasq 为 DNS 缓存服务器,同时在 /etc/hosts 文件中加入本地内网解析,这样一来每当内网机器查询时就会优先查询 hosts 文件,这就等于将 /etc/hosts 共享给全内网机器使用,从而解决内网机器互相识别的问题。相比逐台机器编辑 hosts 文件或者添加 Bind DNS 记录,仅编辑一个 hosts 文件,这简直太容易了。

  1. VLAN模型引入了多租户机制,虚拟机可以使用不同的私有IP网段,一个租户可以拥有多个IP网段。虚拟机IP通过DHCP消息获取IP地址(Nova-network实现为nova-network主机中的dnsmaq,Neutron实现为网络节点上的dhcp-agent)。网段内部虚拟机间的通信直接通过HyperVisor中的网桥转发,同一租户跨网段通信通过网关路由,不同租户通过网关上的ACL进行隔离,公网流量在该网段的网关上进行NAT(Nova-network实现为开启nova-network主机内核的iptables,Neutron实现为网络节点上的l3-agent)。如果不同租户逻辑上共用一个网关,则无法实现租户间IP地址的复用。
  2. Overlay模型(主要包括GRE和VxlAN隧道技术),相比于VLAN模型有以下改进。1)租户数量从4K增加到16million;2)租户内部通信可以跨越任意IP网络,支持虚拟机任意迁移;3)一般来说每个租户逻辑上都有一个网关实例,IP地址可以在租户间进行复用;4)能够结合SDN技术对流量进行优化。
    在这里插入图片描述
    TYPE=0x8100,PRI是优先级字段,CFI不怎么常用,以太网中CFI=0。后面12位的VID就是VLAN的标签位,也就是说802.1q中一个局域网中最多有4096个VLAN,不过不同的交换机对VLAN的规划是不同的,用户实际在一台交换机上能用的VLAN数目要比4096少很多。很简单的一个字段吧,没有什么分域,更不能用来寻址,就只是一个标签,不过这对于传统局域网里的网络虚拟化来说就足够了。

在这里插入图片描述

vxlan与vlan区别:
vxlan支持更多的二层网络
vxlan使用12位bit表示vlan ID,因此最多支持2^12=4094个vlan
vxlan使用的ID使用24位bit,最多可以支持2^24个

已有的网络路径利用效率更高
vlan使用spanning tree protocol避免环路,会将一半的网络路径阻塞
vxlan的数据包封装成UDP通过网络层传输,可以使用所有的网络路径

防止物理交换机Mac表耗尽
vlan需要在交换机的Mac表中记录Mac物理地址
vxlan采用隧道机制,Mac物理地址不需记录在交换机

依赖物理的二层来建立虚拟的大二层(vlan模式)

物理的二层指的是:物理网络是二层网络,基于以太网协议的广播方式进行通信
虚拟的二层指的是:neutron实现的虚拟的网络也是二层网络(openstack的vm机所用的网络必须是大二层),也是基于以太网协议的广播方式进行通信,但毫无疑问的是该虚拟网络依赖于物理的二层网络

依赖物理的三层来建立虚拟的大二层(gre模块与vxlan模式)

物理的三层指的是:物理网络是三层网络,基于ip路由的方式进行通信
虚拟的二层指的是:neutron实现的虚拟的网络仍然是二层网络(openstack的vm机所用的网络必须是大二层),仍然是基于以太网协议的广播方式进行通信,但毫无疑问的是该虚拟网络依赖于物理的三层网络,这有点类似于VPN的概念,根本原理就是将私网的包封装起来,最终打上隧道的ip地址传输。

用户(例如demo用户)可以在自己的project下创建网络(L2 network),该网络就是在大二层的基础上划分出来的,是一个隔离的二层网段。类似于物理网络世界中的虚拟 LAN (VLAN),每建立一个l2 network,都会被分配一个段ID,该段ID标识一个广播域,这个ID是被随机分配的,除非使用管理员身份在管理员菜单下,才可以手动指定该ID
子网是一组 IPv4 或 IPv6 地址以及与其有关联的配置。它是一个地址池,OpenStack 可从中向虚拟机 (VM) 分配 IP 地址。每个子网指定为一个无类别域间路由 (Classless Inter-Domain Routing) 范围,必须与一个网络相关联。除了子网之外,租户还可以指定一个网关、一个域名系统 (DNS) 名称服务器列表,以及一组主机路由。这个子网上的 VM 实例随后会自动继承该配置。
每个网络使用自己的 DHCP Agent,每个 DHCP Agent 在一个 Network namespace 内
不同网络内的IP地址可以重复(overlapping)
跨网络的子网之间的流量必须走 L3 Virtual Router

L2 network之Provider与Tenant的区别

Provider network 是由 Admin 用户创建的,而 Tenant network 是由 tenant 普通用户创建的。
Provider network 和物理网络的某段直接映射,比如对应某个 VLAN,因此需要预先在物理网络中做相应的配置。而 tenant network 是虚拟化的网络,Neutron 需要负责其路由等三层功能。
对 Flat 和 VLAN 类型的网络来说,只有 Provider network 才有意义。即使是这种类型的 tenant network,其本质上也是对应于一个实际的物理段。
对 GRE 和 VXLAN 类型的网络来说,只有 tenant network 才有意义,因为它本身不依赖于具体的物理网络,只是需要物理网络提供 IP 和 组播即可。
Provider network 根据 admin 用户输入的物理网络参数创建;而 tenant work 由 tenant 普通用户创建,Neutron 根据其网络配置来选择具体的配置,包括网络类型,物理网络和 segmentation_id。
创建 Provider network 时允许使用不在配置项范围内的 segmentation_id。

Mechanism Manager

ML2 plugin 通过 neutron.plugins.ml2.managers.MechanismManager 与配置了的 mechanism driver 交互。

MechanismManager管理MechanismDriver。
MechanismDriver在创建、更新、删除网络或端口的时候被调用,负责二层网络技术底层的具体实现,和不同的网
络设备进行交互。在每次事件中会调用到MechanismDriver的两个方法

Mechanism Driver

这部分是对各种 L2 技术的支持,例如 Open vSwitch,linux bridge 等等。

会按照配置顺序依次调用每一个Driver的对应函数来完成,比如对需要配置交换机的操作,可能Open vSwitch虚拟交换机和外部真实的物理交换机比如Cisco交换机都需要进行配置,这个时候需要Open vSwitch Mechanism Driver和Cisco Mechanisam Driver都被调用处理。

extension drivers,type drivers 和 mechanism drivers,如果其中任何一个不能接受新创建的 Network,都会导致创建 Network 失败,并且清除在 Network 在 DB 中的记录。

整个流程与创建 Network 类似。差别是少了调用 type drivers,因为 type drivers 针对的是 Network type 的支持,所以没有必要在 Port create 中调用。另一方面,创建 Port 会调用 rpc 通知 L2 agents,这是因为 Port 在 ML2 中还只是一个内存或者 DB 中的对象,真正在 SDN 中起作用的,是在各个 L2 agents 上的虚拟端口。ML2 通过 rpc 通知到 L2 agents,并创建相应的虚拟端口,这样,虚机,虚拟路由器,DHCP 服务等都能基于虚机端口提供网络服务。

Neutron 默认采用的 开源Open vSwitch 创建的虚机交换机

Mechanism Manager分发操作并具体传递操作到Mechanism Driver的方式与Type Manager相同,但是一个需要Mechanism Driver处理的操作是:会按照配置顺序依次调用每一个Driver的对应函数来完成,比如对需要配置交换机的操作,可能Open vSwitch虚拟交换机和外部真实的物理交换机比如Cisco交换机都需要进行配置,这个时候需要Open vSwitch Mechanism Driver和Cisco Mechanisam Driver都被调用处理。

yum install openstack-neutron-openvswitch -y
vi /etc/neutron/plugins/ml2/openvswitch_agent.ini 
[ovs]
tunnel_bridge = br-tun
local_ip = 192.168.100.20   #隧道IP地址 管理网卡IP地址
integration_bridge = br-int
tenant_network_type = vxlan
tunnel_type = vxlan
tunnel_id_ranges = 1:1000
enable_tunneling = true
[agent]
tunnel_types = vxlan
l2_population = true
[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
enable_security_group = true
systemctl start neutron-openvswitch-agent.service
systemctl enable neutron-openvswitch-agent.service
ifconfig 
brctl show
ovs-vsctl show 
Neutron-VLAN-OVS

在这里插入图片描述

与Linux bridge不同,openvswitch 不是通过eth1.1 eth1.2这样的vlan接口来隔离不同的vlan,而是通过openvswitch的流表规则来指定如何对进出br-int的数据进行转发,实现不同vlan的隔离。

图中计算节点的所有虚拟机都连接在int网桥上,虚拟机分为两个网络。Int网桥会对到来的数据包根据network的不同打上vlan id号,然后转发到eth网桥,eth网桥直连物理网络。这时候流量就从计算节点到了网络节点。
网络节点的ehx int网桥的功能相似,多了一个ex网桥,这个网桥是管理提前创建好的,和物理网卡相连,ex网桥和int网桥之间通过一对patch-port相连,虚拟机的流量到达int网桥后经过路由到ex网桥。

OpenvSwitch的组成

1.ovs的主要组成模块如下:

ovs-vswitchd:OVS守护进程是,OVS的核心部件,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换(flow-based switching)。它和上层 controller 通信遵从 OPENFLOW 协议,它与 ovsdb-server 通信使用 OVSDB 协议,它和内核模块通过netlink通信,它支持多个独立的 datapath(网桥),它通过更改flow table 实现了绑定和VLAN等功能。
ovsdb-server:轻量级的数据库服务,主要保存了整个OVS 的配置信息,包括接口啊,交换内容,VLAN啊等等。ovs-vswitchd 会根据数据库中的配置信息工作。它于 manager 和 ovs-vswitchd 交换信息使用了OVSDB(JSON-RPC)的方式。
ovs-dpctl:一个工具,用来配置交换机内核模块,可以控制转发规则。  
ovs-vsctl:主要是获取或者更改ovs-vswitchd 的配置信息,此工具操作的时候会更新ovsdb-server 中的数据库。  
ovs-appctl:主要是向OVS 守护进程发送命令的,一般用不上。
ovsdbmonitor:GUI 工具来显示ovsdb-server 中数据信息。  
ovs-controller:一个简单的OpenFlow 控制器  
ovs-ofctl:用来控制OVS 作为OpenFlow 交换机工作时候的流表内容。
在这里插入图片描述

2.OpenvSwitch的工作流程

通过ovs实现虚拟机和外部通信的过程,通信流程如下:

1.VM实例 instance 产生一个数据包并发送至实例内的虚拟网络接口 VNIC,图中就是 instance 中的 eth0.
2.这个数据包会传送到物理机上的VNIC接口,如图就是vnet接口.
3.数据包从 vnet NIC 出来,到达桥(虚拟交换机) br100 上.
4.数据包经过交换机的处理,从物理节点上的物理接口发出,如图中物理机上的 eth0 .
5.数据包从 eth0 出去的时候,是按照物理节点上的路由以及默认网关操作的,这个时候该数 据包其实已经不受你的控制了.

注:一般 L2 switch 连接 eth0 的这个口是一个 trunk 口, 因为虚拟机对应的 VNET 往往会设置 VLAN TAG, 可以通过对虚拟机对应的 vnet 打 VALN TAG 来控制虚拟机的网络广播域. 如果跑多个虚拟机的话, 多个虚拟机对应的 vnet 可以设置不同的 vlan tag, 那么这些虚拟机的数据包从 eth0(4)出去的时候, 会带上TAG标记. 这样也就必须是 trunk 口才行。

# 添加网桥:
ovs-vsctl add-br br0  
  
# 列出所有网桥:
ovs-vsctl list-br
  
# 判断网桥是否存在:
ovs-vsctl br-exists br0
  
# 将物理网卡挂载到网桥上:
ovs-vsctl add-port br0 eth0
  
# 列出网桥中的所有端口:
ovs-vsctl list-ports br0
  
# 列出所有挂载到网卡的网桥:
ovs-vsctl port-to-br eth0
  
# 查看ovs的网络状态:
ovs-vsctl show
  
# 删除网桥上已经挂载的网口:
ovs-vsctl del-port br0 eth0
  
# 删除网桥:
ovs-vsctl del-br br0
  
# 设置控制器:
ovs-vsctl set-controller br0 tcp:ip:6633
  
# 删除控制器:
ovs-vsctl del-controller br0
  
# 设置支持OpenFlow Version 1.3:
ovs-vsctl set bridge br0 protocols=OpenFlow13  
  
# 删除OpenFlow支持设置:
ovs-vsctl clear bridge br0 protocols 
  
# 设置vlan标签:
ovs-vsctl add-port br0 vlan3 tag=3 -- set interface vlan3 type=internal
  
# 删除vlan标签:
ovs-vsctl del-port br0 vlan3 
  
# 查询 VLAN:
ovs-vsctl show 
ifconfig vlan3 
  
# 查看网桥上所有交换机端口的状态:
ovs-ofctl dump-ports br0
  
# 查看网桥上所有的流规则:
ovs-ofctl dump-flows br0
  
# 查看ovs的版本:
ovs-ofctl -V# 给端口配置tagovs-vsctl set port br-ex tag=101

OpenFlow协议定义了交换机在报文匹配失败时向控制器申请流表的方法,当交换机收到一个不能被当前流表各条流匹配的数据包时,通过将失配报文的相关信息封装在Packet-In消息中发送给控制器,让控制器知晓报文失配情况,由控制器通过Flow-Mod等消息向交换机安装新流表。

extension

在neutron/plugins/ml2/manager.py文件中,除了Type Manager与Mechanism之外还定义有Extension Manger

extension应该放在neutron/extensions文件夹下,或者在配置文件中设置api_extensions_path
extension的class名应该和文件同名,当然首字母应该大写
应该实现neutron.api.extensions.py中ExtensionDescriptor定义的接口
在对应的plugin的supported_extension_aliases 中增加我们extension的别名。

create_network

create_network_in_db
extension_manager.process_create_network
type_manager.create_network_segments
mechanism_manager.create_network_precommit
db commit
mechanism_manager.create_network_postcommit

create_subnet

create_subnet_in_db
extension_manager.process_create_subnet
mechanism_manager.create_subnet_precommit
db commit
mechanism_manager.create_subnet_postcommit

create_port

create_port_in_db
extension_manager.process_create_port
port biding
mechanism_manager.create_port_precommit
db commit
mechanism_manager.create_port_postcommit

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

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

相关文章

操作系统(一)基础知识及操作系统启动

文章目录 前言前置基础知识计算机组成CPU磁盘内核中断、异常、系统调用局部性原理 启动操作系统计算机加电是如何正常执行服务的?开机自检BIOS(Basic Input/Output System)BootLoader 小结 前言 本文主要涉及操作系统的简介、硬件结构、内存…

Proteus仿真--基于数码管设计的可调式电子钟

本文主要介绍基于51单片机的数码管设计的可调式电子钟实验(完整仿真源文件及代码见文末链接) 仿真图如下 其中数码管主要显示电子钟时间信息,按键用于调节时间 仿真运行视频 Proteus仿真--数码管设计的可调式电子钟(仿真文件程…

WMS配送中心主要业务流程

业务流程图 入库 波次出库 按门店和门店所属送货路线确定出库波次 入库 出库 移库、封仓 门店欠货能要点 1. 日常补货:分拣仓位商品小于当前商品在该位置的补货下限的时候;生成对此进行补货任务;补货完成后确认任务,系统变更库存…

YOLOv8-Seg改进:分割注意力系列篇 | 高效多尺度注意力 EMA | ICASSP2023

🚀🚀🚀本文改进:EMA跨空间学习高效多尺度注意力引入到YOLOv8中进行二次创新,改进方法1)head层输出层结合;2)加入backbone; 🚀🚀🚀EMAAttention 亲测在多个数据集能够实现涨点,同样适用于小目标分割 🚀🚀🚀YOLOv8-seg创新专栏:http://t.csdnimg.cn/…

探索内存函数的奥秘【memcpy、memmove、memset、memcmp】

目录 一,memcpy函数 1,memcpy函数简介 2,memcpy函数的原理 3,memcpy函数的用法 4,注意事项 5,memcpy函数模拟实现 二,memmove函数 1,memmove函数简介 2,memmove函…

实验室(检验科)信息系统源码,医学检验LIS系统源码,云LIS源码

实验室(检验科)信息系统源码,LIS源码,基于云计算技术的LIS系统源码,云LIS源码 LIS系统(LaboratoryInformationSystem) 即 实验室(检验科)信息系统,它是医院信息管理的重要组成部分之…

Vue3 源码解读系列(三)——组件渲染

组件渲染 vnode 本质是用来描述 DOM 的 JavaScript 对象,它在 Vue 中可以描述不同类型的节点,比如:普通元素节点、组件节点等。 vnode 的优点: 抽象:引入 vnode,可以把渲染过程抽象化,从而使得组…

用 winget 在 Windows 上安装 kubectl

目录 kubectl 是什么? 安装 kubectl 以管理员身份打开 PowerShell 使用 winget 安装 kubectl 测试一下,确保安装的是最新版本 导航到你的 home 目录: 验证 kubectl 配置 kubectl 是什么? kubectl 是 Kubernetes 的命令行工…

38 路由的过滤器配置

3.3.断言工厂 我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件 例如Path/user/**是按照路径匹配,这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoute…

计算机毕业设计:水果识别检测系统 python 深度学习 YOLOv5

[毕业设计]2023-2024年最新最全计算机专业毕设选题推荐汇总 感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人 。 1、项目介绍 本文介绍了一种基于深度学习的水果检测与识别系统…

移动端模型部署框架

移动端模型部署框架 1. MNN整体特点轻量性通用性高性能易用性架构设计主体工具致谢移动端模型部署框架 1. MNN https://www.yuque.com/mnn/cn/about MNN是全平台轻量级高性能深度学习引擎,广泛支持了阿里巴巴在计算机视觉、语音识别技术、自然语言处理等领域的70多个AI应用…

【Java 进阶篇】Java中的 JSP(JavaServer Pages)

JavaServer Pages(JSP)是一种用于开发动态Web页面的Java技术。它是在静态Web页面中嵌入Java代码的一种方式,使得开发者可以借助Java的强大功能来创建动态、交互性强的Web应用程序。在本文中,我们将深入探讨JSP的概念、原理和基本用…

MYSQL内容补充:

一)联合索引: 1)定义:是给一张表上面的多个列增加索引,也就是说给表上面的多个列增加索引,供快速查询使用,当两个列的组合是唯一值时,联合索引是个不错的选择 联合索引和单个索引对比来讲,联合索引的所有索引项都会出现…

重温数据结构与算法之前缀和

文章目录 前言一、基础1.1 定义1.2 时间复杂度 二、扩展2.1 二维前缀和2.2 差分数组2.3 前缀积 三、LeetCode 实战3.1 长度最小的子数组3.2 二维区域和检索 - 矩阵不可变 参考 前言 前缀和(Prefix Sum),也被称为累计和,是一种在计…

SQL必知会(二)-SQL查询篇(5)-用通配符进行过滤

第6课、用通配符进行过滤 LIKE:匹配文本 LIKE:针对未知值进行过滤。通配符搜索只能用于文本字段。 1)百分号%通配符 %表示任何字符出现任意次数。 需求:找出所有以词 Fish 起头的产品 SELECT prod_id, prod_name FROM Product…

浅谈高并发以及三大利器:缓存、限流和降级

引言 高并发背景 互联网行业迅速发展,用户量剧增,系统面临巨大的并发请求压力。 软件系统有三个追求:高性能、高并发、高可用,俗称三高。三者既有区别也有联系,门门道道很多,全面讨论需要三天三夜&#…

Aria2 任意文件写入漏洞复现

漏洞描述 Aria2 是一款轻量级、多协议、多源下载工具(支持 HTTP/HTTPS、FTP、BitTorrent、Metalink),内置 XML-RPC 和 JSON-RPC 接口。 我们可以使用 RPC 接口来操作 aria2 并将文件下载到任意目录,从而造成任意文件写入漏洞。 …

Nginx常用配置与命令,nginx代理转发配置

Nginx特点 高并发、高性能; 模块化架构使得它的扩展性非常好; 异步非阻塞的事件驱动模型这点和 Node.js 相似; 相对于其它服务器来说它可以连续几个月甚至更长而不需要重启服务器使得它具有高可靠性; 热部署、平滑升级; 完全开源,生态繁荣; Nginx作用 Nginx 的最重要的…

【Excel】补全单元格值变成固定长度

我们知道股票代码都为6位数字,但深圳中小板代码前面以0开头,数字格式时前面的0会自动省略,现在需要在Excel表格补全它。如下图: 这时我们需要用到特殊的函数:TEXT或者RIGHT TEXT函数是Excel中一个非常有用的函数。TEX…

SpringBoot项目调用openCV报错:nested exception is java.lang.UnsatisfiedLinkError

今天在通过web项目调用openCV的时候提示如下错误: nested exception is java.lang.UnsatisfiedLinkError:org.opencv.imgcodecs.Imgcodecs.imread_0(Ljava/la如下图所示: 但是通过直接启动java main函数确正常,初步诊断和SpringBoot热加载…