此场景描述了使用带有Linux网桥的ML2插件的OpenStack网络服务的供应商网络实现。

供应商网络通常以灵活性为代价提供简单性、性能和可靠性。与其他场景不同,只有管理员可以管理提供者网络,因为它们需要物理网络基础结构的配置。此外,供应商网络缺乏固定和浮动IP地址的概念,因为它们只处理实例的2层连接。

在许多情况下,已经熟悉虚拟网络体系结构的操作人员,他们依赖于物理网络基础设施,为layer - 2、layer - 3或其他服务提供无缝地部署OpenStack网络服务。特别是,这个场景吸引了希望从计算网络服务(nova - net)迁移到OpenStack网络服务的操作人员。随着时间的推移,操作人员可以在这个最小的部署上建立更多的云网络特性。

在OpenStack网络引入分布式虚拟路由器(DVR)之前,所有网络流量都通过一个或多个专用网络节点,这些节点的性能和可靠性都很有限。物理网络基础设施通常比在软件中处理各种网络操作的通用主机提供更好的性能和可靠性。

总的来说,OpenStack网络软件组件最能处理三层操作的影响性能和可靠性。为了提高性能和可靠性,供应商网络将layer - 3操作移动到物理网络基础设施。

在一个特定的用例中,OpenStack部署驻留在一个混合环境中,传统的虚拟化和裸机使用了相当大的物理网络基础设施。在OpenStack部署中运行的应用程序可能需要直接的layer - 2访问,通常是使用VLANs,在部署之外的应用程序。

与Open vSwitch(OVS)的提供者网络相比,这个场景完全依赖于本地的Linux网络服务,这使得它成为本指南中最简单的场景。

示例配置创建了一个VLAN提供者网络。然而,它也支持Flat(未标记的或本地的)提供者网络。

先决条件

这些先决条件定义了部署此场景所需的最小物理基础设施和立即的OpenStack服务依赖关系。

例如,网络服务直接依赖于身份服务,而计算服务直接依赖于网络服务。而像镜像服务没有依赖性的服务,是因为网络服务没有直接依赖它。

然而,计算服务依赖于镜像服务来启动一个实例。本场景中的示例配置假定了网络服务组件的基本配置知识。

为了便于说明,管理网络使用10.0.0 / 24,供应商网络使用192.0.2.0 / 24,198.51.100.24,和203.0.113.0 / 24。

基础设施

1.一个具有两个网络接口的控制节点:管理和provider。provider接口连接到物理网络基础设施交换机/路由到外部网络(通常是Internet)的通用网络。

2.至少两个计算节点有两个网络接口:管理和供应商。提供商接口连接到物理网络基础设施切换到外部网络(通常是因特网)的通用网络。

硬件要求

网络布局

服务布局

控制节点的OpenStack服务

在neutron.conf文件中具有数据库服务器的合适配置
在neutron.conf文件中具有消息队列服务的合适配置。
在neutron.conf文件中具有openstack keystone服务的合适配置
在nova.conf文件中具有openstack计算 控制/管理服务的合适配置去使用neutron
neutron服务器服务、ML2插件、Linux网桥代理、DHCP代理和任何依赖关系。

计算节点的Openstack服务

在neutron.conf文件中具有openstack keystone服务的合适配置
在nova.conf文件中具有openstack计算 控制/管理服务的合适配置去使用neutron
ML2插件,Linux网桥代理,以及任何依赖项。

架构

一般的供应商网络架构使用物理网络基础设施来处理网络流量的交换和路由。

一般的体系架构

控制器节点包含以下网络组件:

1.Linux bridge代理管理虚拟交换机之间的连接性,以及通过虚拟端口与其他网络组件(如名称空间和底层接口)进行交互。

2.管理qdhcp名称空间的DHCP代理。qdhcp名称空间为使用供应商网络的实例提供DHCP服务。

控制节点组件回顾

控制节点组件连接

注意:为了便于说明,该图包含两个不同的提供者网络。

计算节点包含以下网络组件:

1.Linux bridge代理管理虚拟交换机之间的连接,以及通过虚拟端口与其他网络组件(如名称空间、安全组和底层接口)的交互。

计算节点组件回顾

计算节点组件连接

注意:为了便于说明,该图包含两个不同的提供者网络。

Packet flow

南北网络流量在一个实例和外部网络之间传输,通常是互联网。东西网络流量在实例之间传播。

案例1:南北向流量

物理网络基础架构处理供应商和外部网络之间的路由和潜在的其他服务

在这种情况下,提供商和外部简单地区分可用于实例的网络和仅可经由路由器访问的网络,以说明物理网络基础设施处理路由

然而,供应商网络支持直接连接到外部网络,如因特网。

外部网络

网络203.0.113./

供应商网络(VLAN)

网络192.0.2./

带有MAC地址TG的网关192.0.2. 

计算节点1

具有MAC地址I1和192.0.2.11的实例1

实例1驻留在计算节点1上,并使用提供者网络。

实例向外部网络的主机发送一个包。

下面的步骤涉及计算节点1。

1.实例1的tap接口(1)将包转发给供应商网桥qbr。该包包含目标MAC地址TG,因为目的地驻留在另一个网络上。

2.安全组规则(2)在供应商网桥上qbr处理防火墙和跟踪数据包。

3.供应商网桥qbr将数据包转发到逻辑VLAN接口device.sid。该接口引用底层物理供应商接口和包含提供者网络分割ID的sid。

4.逻辑VLAN接口device.sid。该接口通过物理提供程序接口将包转发到物理网络。

以下步骤涉及物理网络基础设施:

1.交换机(3)处理供应商网络与路由器(4)之间的任何VLAN标记操作。

2.路由器(4)将数据包从提供者网络路由到外部网络。

3.交换机(3)处理路由器(4)和外部网络之间的任何VLAN标记操作。

4.交换机(3)将数据包转发到外部网络。

注意:返回的流量也遵循类似的步骤。

南北网络流量流向

案例2:在不同网络上的实例的东西向流量

物理网络基础设施处理提供者网络之间的路由。

供应商网络1

网络:192.0.2.0/24

带有MAC地址TG1的网关:192.0.2.1 

供应商网络2

网络:198.51.100.0/24

网关:带MAC地址TG2的198.51.100.1

计算节点1

带有192.0.2.11 和MAC地址为I1的实例1

计算节点2

带有MAC地址为I2和198.51.100.11 的实例2

实例1驻留在计算节点1上,并使用提供者网络1。

实例2驻留在计算节点2上,并使用提供者网络2。

实例1发送一个包到实例2。

以下步骤涉及计算节点1:

1.实例1的tap接口将包转发给供应商网桥qbr。该包包含目标MAC地址TG1,因为目的地驻留在另一个网络上。

2.安全组规则在供应商网桥qbr上处理防火墙和数据包的状态跟踪。

3.供应商网桥qbr将数据包转发到逻辑VLAN接口device.sid。该接口引用底层物理提供者接口和包含提供者网络分割ID的sid。

4.逻辑VLAN接口device.sid。该接口将包通过物理提供程序接口转发给物理网络基础设施。

以下步骤涉及物理网络基础设施:

1.交换机(3)处理供应商网络1与路由器(4)之间的任何VLAN标记操作。

2.路由器(4)将数据包从提供者网络1路由到提供者网络2。

3.交换机(3)处理路由器(4)和提供者网络2之间的任何VLAN标记操作。

4.交换机(3)将数据包转发到计算节点2。

以下步骤涉及计算节点2:

1.物理供应商接口将包转发到逻辑VLAN接口device.sid。该接口引用底层物理提供者接口和包含提供者网络分割ID的sid。

2.逻辑VLAN接口device.sid。该接口将包转发给供应商网桥qbr。

3.安全组规则(5)在供应商网桥qbr上处理数据包的防火墙和状态跟踪。

4.供应商网桥qbr将数据包转发到实例2上的tap接口(6)。

返回的流量也遵循类似的步骤。

在不同网络上的实例的东西向流量流向

案例3:在同一网络中实例的东西向流量

物理网络基础结构处理提供者网络中的交换。

供应商网络

网络:192.0.2.0/

计算节点1

带有MAC地址为I1和192.0.2.11 的实例1

计算节点2

带有MAC地址为I2和192.0.2.12的实例2

实例1驻留在compute节点1中。

实例2驻留在compute节点2中。

两个实例都使用相同的提供者网络。

实例1发送一个包到实例2。

以下步骤涉及计算节点1:

1.实例1的tap接口(1)将包转发给供应商网桥qbr。该包包含目标MAC地址I2,因为目的地位于同一网络。

2.安全组规则(2)在供应商网桥qbr上处理防火墙和数据包的状态跟踪。

3.供应商网桥qbr将数据包转发到逻辑VLAN接口device.sid。该接口引用底层物理提供者接口和包含提供者网络分割ID的sid。

4.逻辑VLAN接口device.sid。该接口将包通过物理提供程序接口转发给物理网络基础设施。

以下步骤涉及物理网络基础设施:

1.交换机(3)将数据包从计算节点1转发到计算节点2。

以下步骤涉及计算节点2:

1.物理提供程序接口将包转发到逻辑VLAN接口device.sid。该接口引用底层物理提供者接口和sid包含提供者网络分割ID的sid。

2.逻辑VLAN接口device.sid将包转发给供应商网桥qbr。

3.安全组规则(4)在供应商网桥qbr上处理数据包的防火墙和状态跟踪。

4.供应商网桥qbr将包转发给实例2的 tap接口(5)。

返回的流量也遵循类似的步骤。

在同一网络中实例的东西向流量流向

示例配置

使用下面的示例配置作为在您的环境中部署该场景的模板。

请注意:在此场景中缺少L3代理将阻止常规元数据代理的操作。您必须使用配置驱动来提供实例元数据。

控制器节点

1.配置内核以禁用反向路径过滤。编辑/etc/sysctl.配置文件:

net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=

2.加载新内核配置:

$ sysctl -p

3.配置常见的选项。编辑/etc/neutron/neutron.配置文件:

[DEFAULT]
verbose = True
core_plugin = ml2
service_plugins =

注意:service_plugins选项不包含任何值,因为网络服务不提供像路由这样3层服务。

4.配置ML2插件和Linux网桥代理。编辑/etc/neutron/plugins/ml2/ml2_conf.ini文件:

[ml2]
type_drivers = flat,vlan
tenant_network_types =
mechanism_drivers = linuxbridge [ml2_type_flat]
flat_networks = provider [ml2_type_vlan]
network_vlan_ranges = provider [linux_bridge]
physical_interface_mappings = provider:PROVIDER_INTERFACE [vxlan]
enable_vxlan = False [securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
enable_security_group = True
enable_ipset = True

将PROVIDER_INTERFACE替换为处理提供者网络的底层接口的名称。例如,eth1。

注意:

tenant_network_types选项不包含任何值,因为架构不支持项目(私有)网络。
network_vlan_range选项中的provider值缺乏VLAN ID范围,以支持使用任意VLAN ID。

5.配置DHCP代理。编辑/etc/neutron/dhcp_agent.ini文件:

[DEFAULT]
verbose = True
interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
dhcp_delete_namespaces = True

6.启动以下服务

    Server
Linux bridge agent
DHCP agent

计算节点

1.配置内核以禁用反向路径过滤。编辑/etc/sysctl.配置文件:

net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=0
 

2.加载新内核配置:

$ sysctl -p

3.配置常见的选项。编辑/etc/neutron/neutron.配置文件:

[DEFAULT]
verbose = True

4.配置Linux网桥代理。编辑/etc/neutron/plugins/ml2/ml2_conf.ini文件:

[linux_bridge]
physical_interface_mappings = provider:PROVIDER_INTERFACE [vxlan]
enable_vxlan = False [securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
enable_security_group = True
enable_ipset = True

将PROVIDER_INTERFACE替换为处理提供者网络的底层接口的名称。例如,eth1。

5.启动以下服务:

Linux bridge agent

验证服务操作

1.提供管理项目凭据。
2.验证代理的存在和操作:

$ neutron agent-list
+--------------------------------------+--------------------+------------+-------+----------------+---------------------------+
| id | agent_type | host | alive | admin_state_up | binary |
+--------------------------------------+--------------------+------------+-------+----------------+---------------------------+
| 09de6af6-c5f1--8b09-18801f068c57 | Linux bridge agent | compute2 | :-) | True | neutron-linuxbridge-agent |
| 188945d1-9e70--a276-df924e0788a4 | Linux bridge agent | compute1 | :-) | True | neutron-linuxbridge-agent |
| e76c440d-d5f6--a674-d689630b629e | DHCP agent | controller | :-) | True | neutron-dhcp-agent |
| e9901853--45b1-8a92-3712bdec0416 | Linux bridge agent | controller | :-) | True | neutron-linuxbridge-agent |
+--------------------------------------+--------------------+------------+-------+----------------+---------------------------+

创建初始网络

这个例子创建了一个VLAN提供者网络。将VLAN ID和IP地址范围更改为适合您的环境的值。

1.提供管理项目凭据。

2.创建一个提供者网络:

$ neutron net-create provider- --shared \
--provider:physical_network provider --provider:network_type vlan \
--provider:segmentation_id
Created a new network:
+---------------------------+--------------------------------------+
| Field | Value |
+---------------------------+--------------------------------------+
| admin_state_up | True |
| id | 572a3fc9-ad1f-4e54-a63a-4bf5047c1a4a |
| name | provider- |
| provider:network_type | vlan |
| provider:physical_network | provider |
| provider:segmentation_id | |
| router:external | False |
| shared | True |
| status | ACTIVE |
| subnets | |
| tenant_id | e0bddbc9210d409795887175341b7098 |
+---------------------------+--------------------------------------+

注意:share选项允许任何项目使用此网络。

3.在供应商网络上创建子网:

$ neutron subnet-create provider- 203.0.113.0/ \
--name provider--subnet --gateway 203.0.113.1
Created a new subnet:
+-------------------+--------------------------------------------------+
| Field | Value |
+-------------------+--------------------------------------------------+
| allocation_pools | {"start": "203.0.113.2", "end": "203.0.113.254"} |
| cidr | 203.0.113.0/ |
| dns_nameservers | |
| enable_dhcp | True |
| gateway_ip | 203.0.113.1 |
| host_routes | |
| id | ff6c9a0b-0c81-4ce4-94e6-c6617a059bab |
| ip_version | |
| ipv6_address_mode | |
| ipv6_ra_mode | |
| name | provider--subnet |
| network_id | 572a3fc9-ad1f-4e54-a63a-4bf5047c1a4a |
| tenant_id | e0bddbc9210d409795887175341b7098 |
+-------------------+--------------------------------------------------+

验证网络操作

1.在控制节点上,验证qdhcp名称空间的创建:

$ ip netns
qdhcp-8b868082-e312-4110-8627-298109d4401c

注意:在启动实例之前,qdhcp名称空间可能不存在。

2.提供常规项目凭证。下面的步骤使用demo项目。

3.创建适当的安全组规则,允许ping和SSH访问实例。例如:

 
$ nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0
+-------------+-----------+---------+-----------+--------------+
| IP Protocol | From Port | To Port | IP Range | Source Group |
+-------------+-----------+---------+-----------+--------------+
| icmp | -1 | -1 | 0.0.0.0/0 | |
+-------------+-----------+---------+-----------+--------------+ $ nova secgroup-add-rule default tcp 22 22 0.0.0.0/0
+-------------+-----------+---------+-----------+--------------+
| IP Protocol | From Port | To Port | IP Range | Source Group |
+-------------+-----------+---------+-----------+--------------+
| tcp | 22 | 22 | 0.0.0.0/0 | |
+-------------+-----------+---------+-----------+--------------+
 

4.在供应商网络上启动一个具有接口的实例。

$ nova boot --flavor m1.tiny --image cirros-0.3.-x86_64-disk test_server
+--------------------------------------+-----------------------------------------------------------------+
| Property | Value |
+--------------------------------------+-----------------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-SRV-ATTR:host | - |
| OS-EXT-SRV-ATTR:hypervisor_hostname | - |
| OS-EXT-SRV-ATTR:instance_name | instance- |
| OS-EXT-STS:power_state | |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | - |
| OS-SRV-USG:terminated_at | - |
| accessIPv4 | |
| accessIPv6 | |
| adminPass | h7CkMdkRXuuh |
| config_drive | |
| created | --22T20::16Z |
| flavor | m1.tiny () |
| hostId | |
| id | dee2a9f4-e24c-444d-8c94-386f11f74af5 |
| image | cirros-0.3.-x86_64-disk (2b6bb38f-f69f-493c-a1c0-264dfd4188d8) |
| key_name | - |
| metadata | {} |
| name | test_server |
| os-extended-volumes:volumes_attached | [] |
| progress | |
| security_groups | default |
| status | BUILD |
| tenant_id | 5f2db133e98e4bc2999ac2850ce2acd1 |
| updated | --22T20::16Z |
| user_id | ea417ebfa86741af86f84a5dbcc97cd2 |
+--------------------------------------+-----------------------------------------------------------------+

5.确定实例的IP地址。下面的步骤使用203.0.113.3。

 
$ nova list
+--------------------------------------+-------------+--------+------------+-------------+--------------------------+
| ID | Name | Status | Task State | Power State | Networks |
+--------------------------------------+-------------+--------+------------+-------------+--------------------------+
| dee2a9f4-e24c-444d-8c94-386f11f74af5 | test_server | ACTIVE | - | Running | provider-101=203.0.113.3 |
+--------------------------------------+-------------+--------+------------+-------------+--------------------------+
 

6.在控制节点或任何访问提供者网络的主机上,ping IP地址:

 
$ ping -c 4 203.0.113.3
PING 203.0.113.3 (203.0.113.3) 56(84) bytes of data.
64 bytes from 203.0.113.3: icmp_req=1 ttl=63 time=3.18 ms
64 bytes from 203.0.113.3: icmp_req=2 ttl=63 time=0.981 ms
64 bytes from 203.0.113.3: icmp_req=3 ttl=63 time=1.06 ms
64 bytes from 203.0.113.3: icmp_req=4 ttl=63 time=0.929 ms --- 203.0.113.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.929/1.539/3.183/0.951 ms
 

7.获取对实例的访问。

8.测试连接到互联网:

 
$ ping -c 4 openstack.org
PING openstack.org (174.143.194.225) 56(84) bytes of data.
64 bytes from 174.143.194.225: icmp_req=1 ttl=53 time=17.4 ms
64 bytes from 174.143.194.225: icmp_req=2 ttl=53 time=17.5 ms
64 bytes from 174.143.194.225: icmp_req=3 ttl=53 time=17.7 ms
64 bytes from 174.143.194.225: icmp_req=4 ttl=53 time=17.5 ms --- openstack.org ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 17.431/17.575/17.734/0.143 ms
 

场景7:带有Linux网桥的提供商网络的更多相关文章

  1. 场景6:具有OpenvSwitch的提供商网络

    此场景描述了使用带有Open vSwitch(OVS)的ML2插件的OpenStack网络服务的提供者网络实现. 在OpenStack网络引入分布式虚拟路由器之前,所有网络通信都通过一个或多个专门的网 ...

  2. linux 网桥的配置与实现

    ==================================================================================from: http://www.i ...

  3. linux网桥浅析

    linux网桥浅析 原文链接:http://hi.baidu.com/_kouu/item/25787d38efec56637c034bd0 什么是桥接?简单来说,桥接就是把一台机器上的若干个网络接口 ...

  4. Cloud Native Weekly | 华为云抢先发布Redis5.0,红帽宣布收购混合云提供商 NooBaa

    1——华为云抢先发布Redis5.0 2——DigitalOcean K8s服务正式上线 3——红帽宣布收购混合云提供商 NooBaa 4——微软发布多项 Azure Kubernetes 服务更新 ...

  5. 7.场景5:使用Linux桥的VRRP(L3HA)的高可用性

    此场景描述了使用ML2插件和Linux网桥的OpenStack网络服务的高可用性实现. 他的高可用性实施例增强了这样的场景:具有Linux网桥架构的传统使用了keepalived的虚拟路由器冗余协议( ...

  6. Linux网桥

    linux网桥的功能 转发数据包 网桥的功能在延长网络跨度上类似于中继器,然而它能提供智能化连接服务,即根据帧的终点地址处于哪一网段来进行转发和滤除.网桥对站点所处网段的了解是靠"自学习&q ...

  7. Linux网桥介绍

    网桥的功能类似于二层交换机,作用都是划分冲突域,它们之前且一些细微的差别,此处不展开. Linux网桥作为一个特殊的网桥的实现,有一些自己的特点,因为没有看代码,只能从功能上简单分析一下.个人认为,L ...

  8. Linux网桥模式配置

    Linux网关模式下将有线LAN和无线LAN共享网段实现局域网内互联: 思路其实很简单:就是将虚拟出一个bridge口,将对应的有线LAN和无线LAN都绑定在这个虚拟bridge口上,并给这个brid ...

  9. Spring Security构建Rest服务-1201-Spring Security OAuth开发APP认证框架之实现服务提供商

    实现服务提供商,就是要实现认证服务器.资源服务器. 现在做的都是app的东西,所以在app项目写代码  认证服务器: 新建 ImoocAuthenticationServerConfig 类,@Ena ...

随机推荐

  1. 清晰架构(Clean Architecture)的Go微服务: 日志管理

    良好的日志记录可以提供丰富的日志数据,便于在调试时发现问题,从而大大提高编码效率. 记录器提供的自动化信息越多越好,日志信息也需要以简洁的方式呈现,便于找到重要的数据. 日志需求: 无需修改业务代码即 ...

  2. $CF24D\ Broken Robot\ DP+$高斯消元

    Luogu Description 你收到的礼物是一个非常聪明的机器人,行走在一块长方形的木板上.不幸的是,你知道它是坏的,表现得相当奇怪(随机).该板由n行和m列的单元格组成.机器人最初是在i行和j ...

  3. [开源] SEPP——研发协作一站式管理平台

    演示地址 http://www.seqcer.com/ 仅对chrome浏览器做了完全适配,其他chromium核心浏览器或者firefox.safari也能使用,但是不推荐 仓库地址: 前端:htt ...

  4. 单用户登陆demo-后者挤到前者,类似QQ

    单用户登陆demo ,采用的是Tp5. 流程是,当用户首次登陆是验证用户帐号密码,成功的,用当前时间戳加上用户id和ip 拼接成一个标识,暂且sign ,然后存入cookie ,时间戳存入缓存redi ...

  5. js字符数组转化为数字数组

    先谈一谈需求,我有一个字符串数组,数组内容是字符类型的数字,需要把字符类型的数字转换为数字类型,找了找资料,发现牛人真是多,把前辈的经验总结一下. 例子 ['1','2','3'] => [1, ...

  6. 2019 ICCV、CVPR、ICLR之视频预测读书笔记

    2019 ICCV.CVPR.ICLR之视频预测读书笔记 作者 | 文永亮 学校 | 哈尔滨工业大学(深圳) 研究方向 | 视频预测.时空序列预测 ICCV 2019 CVP github地址:htt ...

  7. 构造分组背包(CF)

    Ivan is a student at Berland State University (BSU). There are n days in Berland week, and each of t ...

  8. windows环境下使用python3.x自带的CGI服务器测试cgi脚本(转)

    1.在桌面上新建一个文件夹作为服务器目录文件夹(文件夹名称自定义,文件夹位置自定义),在www文件下再建一个文件夹,文件夹名为“cgi-bin”,须是这个文件名,其他试过不行(原因暂时未知)

  9. AVR单片机教程——串口接收

    本文隶属于AVR单片机教程系列.   上一讲中,我们实现了单片机开发板向电脑传输数据.在这一讲中,我们将通过电脑向单片机发送指令,让单片机根据指令控制LED.这一次,两端的TX与RX需要交叉连接,单片 ...

  10. 使用 LinkedBlockingQueue 实现简易版线程池

    前一阵子在做联系人的导入功能,使用POI组件解析Excel文件后获取到联系人列表,校验之后批量导入.单从技术层面来说,导入操作通常情况下是一个比较耗时的操作,而且如果联系人达到几万.几十万级别,必须拆 ...