virtualbox 虚拟机网络问题 VirtualBox虚拟机不同网络IP变动的最佳解决方案
2022-03-02 15:28 youxin 阅读(3526) 评论(0) 编辑 收藏 举报virtualbox 主机和虚拟机处于同一网段
首先说明使用有线网卡和使用wifi模式是不同的。
virtualbox默认的网络连接方式如下
这种连接方式虚拟机可以ping通宿主机和外网,但是宿主机无法ping通虚拟机,执行ip address命令可以看到虚拟机自动分配的ip地址是10.0.2.15(我这里显示的是这个ip,可能会有不同),跟宿主机根本不在一个网段。
VirtualBox的四种网络连接方式
可以看到桥接模式是最佳选项,它支持所有情况的访问 。
最简单的办法:使用桥接模式(虚拟机网卡的ip需要设置和主机在同一网段)
我的实际情况是在新建虚拟机的时候就设置好 bridge模式。 我是wifi网络,选择intel wifi. 然后建好虚拟机就行了,这种方法不需要额外设置,就可以有虚拟机和主机相互ping通的效果。可谓是开箱即用。
在虚拟机里选择要桥接的物理网卡,这里选择的是Intel wi-fi这个物理网卡:
因为启用了【网卡1】,虚拟机会给Ubuntu系统配置一块虚拟网卡【enp03】,这里我们设置Ubuntu虚拟网卡和桥接的Windows物理网卡在同一个网段,这样就可以实现互通了;
因为windows的wifi网卡地址是:10.4.23.200,所以设置虚拟机的enp0s3网卡地址为:10.4.23.218;这样两个系统现在都在真实的网络上,且可以正常上网。
出现的问题:有一次我发现主机可以ping通虚拟机,虚拟机ping不同主机。
解决办法:
控制面板->windows 防火墙->启用或关闭windows防火墙->关闭(建议重启计算机)。
Bridged(桥接模式)
桥接模式就是将主机的网卡,与虚拟机虚拟的网卡利用虚拟网桥进行通信。
- 类似于把物理主机虚拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样插在这个交换机当中,所以所有桥接下的网卡与网卡都是交换模式的,相互可以访问而不干扰。
- 虚拟机ip地址需要与主机在同一个网段,如果需要联网,则网关与DNS需要与主机网卡一致。
其网络结构如下图所示:
- 桥接模式:物理机和虚拟机在网络上是一样的,虚拟系统相当于在此网络下的一个独立系统,需要分配网络的一个独立IP。
- 连接时指定的桥接到哪个物理网卡,相当于要把虚拟系统接到那个网段的交换机上。
https://zhuanlan.zhihu.com/p/403513377
https://www.cnblogs.com/chenhaoqiang/p/9491902.html
https://zhuanlan.zhihu.com/p/403513377
桥接网络配置静态IP访问(最简单的方式,只需要配置一块网卡)
virtualbox设置桥接模式联网
注意:选择电脑正在使用的网卡!!!共享同一张网卡
- 在 CentOS 7 中,通过编辑网络配置文件来配置网络参数。找到
/etc/sysconfig/network-scripts/
目录下与网卡名对应的网络配置文件,如ifcfg-enp0s3
。 - 在该文件中,将
BOOTPROTO
的值设置为dhcp
,表示使用 DHCP 方式自动获取 IP 地址;或者将BOOTPROTO
的值设置为static
,表示手动配置 IP 地址。 - 如果使用静态 IP 地址,可以设置
IPADDR
、NETMASK
、GATEWAY
、DNS1
等参数,例如:
DEVICE=enp0s3
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.1.100 #与宿主机在同一个网络
NETMASK=255.255.255.0
GATEWAY=192.168.1.1 #要和宿主机相同
DNS1=8.8.8.8
DEFROUTE=yes
9.保存文件并退出编辑器,然后重新启动网络服务。systemctl restart network
这样,在虚拟机中设置桥接模式,并在 CentOS 7 中配置网络参数,就可以实现虚拟机与主机所在局域网的通信。
[参考文章:
Virtualbox桥接实现静态固定IP内外网访问
不同网络环境IP变动的最佳解决方案 (下面废弃,不可行)
网络连接种类
由下图可以看到,网络有很多种选择,但是我们常用的是这是三个 网络地址转换(NAT)、桥接网卡、仅主机(Host-Only)网络
为什么有这些网络选择呢,因为每种网络有着自己的特点,下面列举下主要特点
模式名称 | 特点 |
---|---|
网络地址转换(NAT) | 连接这个网络可以访问外部网络,但是外部网络不可访问虚拟机 |
桥接网卡 | 这个网络完全可以共享主机网络,主机网络发生变化时,也跟随变化,ip也随之变动 |
仅主机(Host-Only)网络 | 这个网络也可以用来主机访问虚拟机以及虚拟机上web服务,但是虚拟机不可访问外网 |
一、网络选择
从上面的介绍来看有多种网络可以选择
最简单的就是:选择桥接网卡,直接共享主机网络,主机、虚拟机之间访问都没有问题
但是我们家用或者公司使用,都不会固定ip的,主机随时变化,那么虚拟机的ip也随时变化,很不方便,我们希望虚拟机的ip是固定的,方便我们连接和访问服务使用
所以最终的选择是:网络地址转换(NAT) + 仅主机(Host-Only)网络 的组合
https://zhuanlan.zhihu.com/p/363202714
二、实施步骤
1.新增 仅主机(Host-Only)网络
操作步骤:管理 => 主机网路管理器 => 创建网络
然后就会在 控制面板 => 网络和 Internet => 网络连接
这里看到对应的网络,这样主机(Host-Only)网络的ip就配置好了
2.配置虚拟机网络
点击安装好的Centos7虚拟机 设置 => 网络 网卡1 启用 选择 仅主机(Host-Only) 这里的网卡顺序也是有意义的,对应内部的设置
网卡2 启用 选择 网络地址转换(NAT) 网络 ( 我选择的不是这个,是桥接网络)
(设置的时候需要关闭虚拟机,要不然不能选择网卡。)
3.虚拟机内部设置
启动Centos7
执行
ifconfig
得到如下结果
进入网络配置文件的路径
cd /etc/sysconfig/network-scripts/
可以看到 ifcfg-enp0s3 (仅主机(Host-Only) 对应的配置)
vi ifcfg-enp0s3
结果参考
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static #修改为static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp0s3
DEVICE=enp0s3
ONBOOT=yes # 改为yes
IPADDR=192.168.11.11 # 自定义该虚拟机的固定IP ,只要其 IP 在 192.168.11.0 / 24 这个网段就行
UUID=c7695ef6-167b-4589-8c04-4feedef3e203
修改完毕之后,需要重新启动网路
systemctl restart network
到这里就可以 执行 ifconfig 查看了,已经设置成固定ip了 同时 ping http://www.baidu.com 也是可以联网的
(
网络配置文件 /etc/sysconfig/network-scripts/ifcfg-enp0s3
/etc/sysconfig/network-scripts/ifcfg-enp0s3文件是最重要的网络配置文件,后面的enp0s3其实是网卡的名称,不同的Linux网卡的名称可能有所不同,但网络配置文件的路径位置基本不变,
YPE=Ethernet #类型Ethernet表示以太网
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp #引导协议,三个值:dhcp自动获取IP地址,static表示静态/固定IP,none表示引导时不使用协议
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes #以下几个是IPV6的相关信息
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp0s3 #网卡名称,有些网卡也会叫ens33
UUID=4899a9b4-3e56-46e4-9722-9267383c1b0d #UUID,这个应该是网卡的一个ID号吧
DEVICE=enp0s3 #网卡设备名称
ONBOOT=yes #网卡是否开机启动,yes表示开机启动
HWADDR=08:00:27:05:57:A2 #物理地址,即mac地址
4. 防火墙设置
上面这些操作之后发现,只能通过xshell 连接
如果xshell 不能连接 ,是没有安装sshd
yum list | grep ssh
yum install openssh-clients.x86_64
安装之后就可以了
当只能通过xshell 连接 ,比如启动一个tomcat服务8080端口,发现不能连接,这是就是防火墙问题了
CentOS 7的防火墙默认是firewall而不是之前的iptables, 所以需要确定防火墙是否已经关闭,如果没有安装iptables的话, 只需要通过
systemctl stop firewalld.service ## 关闭firewall防火墙
systemctl disable firewalld.service ## 禁止开机启动
然后通过
firewall-cmd --state
可以查看防火墙状态(关闭显示notrunning,开启显示running)。
可以使用关闭iptables防火墙
systemctl stop iptables.service
这样就能通过主机访问虚拟的服务了
总结
本文详细描述了VirtualBox设置静态ip和怎么让主机访问虚拟机内的服务,其中的一些网络配置都可以直接使用,linux指令也可以直接复制使用
https://zhuanlan.zhihu.com/p/363202714
【VirtualBox虚拟机】不同网络环境IP变动的最佳解决方案
在Linux系统中,网络接口的命名方式有所改变,以前的eth0、eth1等命名方式被改为了enp0s3、enp0s8等。这是因为现代计算机的网络接口越来越多,而且不同的网络接口可能会有不同的名称,这导致了以前的命名方式不够灵活,不能很好地适应现代计算机的需求。因此,Linux系统引入了一种新的命名方式,即enp0s3、enp0s8等。
然而,有些用户习惯了以前的命名方式,觉得新的命名方式不够直观,不好记忆。因此,他们希望将enp0s3改为eth0,以便更好地适应他们的使用习惯。
需求:
工作环境与家庭环境网络不同,无论接入什么网络,都需要保证虚拟机IP端口保持稳定不变,以便进行本地调试。
操作系统:CentOS 8
配置方法:
需要配置两个网卡,就可以解决该问题
打开虚拟机设置
进入网络
配置网卡1
网卡1:选择仅主机(Host-Only)网络,界面名称选择VirtualBox Host-Only Network(可能根据虚拟机安装配置不同,该网卡名称可能存在差异,总之是虚拟机的虚拟网卡);
高级中不需要配置,但也给出截图参考:
配置网卡2:
首先启用网卡2,连接方式选择:桥接网卡,其余全部默认,参考配置截图如下:
虚拟机的DHCP配置
虚拟机中查询IP
虚拟机重启后,直接会通过DHCP获取到IP,通过ifconfig查询即可。
IP及网络配置
固定IP配置
确定虚拟机内网网卡名称,不同系统或配置,文件名可能不一样,通过ifconfig命令ip地址确定是哪一个。
然后改内网网卡,使这台机器的IP固定,每台机器可能不一样,要修改自己机器的配置:
vim /etc/sysconfig/network-scripts/ifcfg-enp0s3
1
配置文件改为如下配置:
TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no # 这行要将dhcp改为static BOOTPROTO=static # 下面这行从yes改为no DEFROUTE=no IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=enp0s3 UUID=066b4926-b40c-4c28-a5b4-2310d2b96613 DEVICE=enp0s3 ONBOOT=yes # 追加以下几行 IPADDR=192.168.56.200 NETMASK=255.255.255.0 GATEWAY=192.168.56.1 DNS1=114.114.114.114 PREFIX=24
注意改DEFROUTE这行非常重要,别漏掉
网卡配置生效
nmcli c reload #重启网卡
nmcli c up enp0s3 #启动网卡3(内网)
或者用命令systemctl restart network
此时,如果你设置的固定IP和当前IP不同的话,SSH客户端会断开,如果在虚拟机中则不会。
连接互联网的桥接网卡不需要任何改动。
(
DEFROUTE意思:修改DEFROUTE配置项
DEFROUTE=yes #表示配置为默认路由
DEFROUTE=no #表示不配置为默认路由
)
hosts配置
我们将刚刚设置的所有虚拟机可以通过hosts进行配置,这样可以更加灵活和方便地调用,例如我的配置是:
192.168.56.200 demo
192.168.56.201 master
192.168.56.202 slave1
192.168.56.203 slave2
直接将这些追加在vim /etc/hosts文件最后,保存后我们就可以通过 ping hostname 的方式请求到对应的机器了。
比如我的配置,ping 192.168.56.200 就可以写为 ping demo 了。
最后以防万一,再试一下ping www.baidu.com,没问题的话,就可以愉快地做后面的事情了!
————————————————
实际发现问题:每次开启后,必须得手动运行一下命令:
systemctl restart network
才能ping www.baidu.com成功。
这个问题折腾了一天,没有找到解决方案。可选的方案为下面:
在/etc/systemd/system下创建auto_start.service文件,将执行脚本设置成系统服务器,就可以使用系统自带的设置开机启动服务。
[root@CentOS7-0001 /]# vi /etc/systemd/system/auto_start.service
[Unit] Description=The app auto run when reboot After=default.target [Service] ExecStart=/etc/rc.d/init.d/network restart [Install] WantedBy=default.target
//重启systemd服务、设置开机自启动,重启服务验证即可
[root@CentOS7-0001 /]# systemctl daemon-reload
[root@CentOS7-0001 /]# systemctl enable auto_start.service
[root@CentOS7-0001 /]# reboot
原文链接:https://blog.csdn.net/zhanhjxxx/article/details/122811638
在CentOS系统上,目前有NetworkManager和network两种网络管理工具。如果两种都配置会引起冲突,而且NetworkManager在网络断开的时候,会清理路由,如果一些自定义的路由,没有加入到NetworkManager的配置文件中,路由就被清理掉,网络连接后需要自定义添加上去。
https://blog.csdn.net/m0_52318340/article/details/133209095
在01.28好发现又不能ping通了。折腾了一天,发现是network和Networkmanager冲突了。
因为我发现手动去激活网卡 ,能短暂ping通一会儿,几秒钟会自动ping不通。重新restart network或者nmcli connection up 网卡名,又能ping通几秒钟,过会又不行。如此循环反复。
ifcfg-enp0s3
TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="static" DEFROUTE="no" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="enp0s3" UUID="6ef02a48-f732-4824-be14-70d767d8badb" DEVICE="enp0s3" ONBOOT="yes" IPADDR="192.168.31.101" NETMASK=255.255.255.0 GATEWAY=192.168.31.20 PREFIX=24 DNS1=114.114.114.114 #NM_CONTROLLED=no
/etc/sysconfig/network-scripts这个目录下没有ifcfg-enp0s8,我们不用管enp0s8,因为不用修改。
nmcli device status //查看网络接口详细
# nmcli connection down 网口名称
# nmcli connection up 网口名称
nmcli conn up 网卡名称,会启动进程dhclient
nmcli connection delete '有线连接 1'
成功删除连接 "有线连接 1" (5e8a09a5-a9c6-38a0-b223-2893e03dd848)。
然后再启动:
ifup enp0s8
https://www.cnblogs.com/jsjrj01/p/10297810.html
- 显示所有包括不活动连接
nmcli con show
- 显示所有活动连接
nmcli con show --active
- 显示网络连接配置
nmcli con show "System eth0“
- 显示设备状态
nmcli dev status
- 显示网络接口属性
nmcli dev show eno16777736
nmcli connection delete ens32 -> 删除已有的网卡连接名ens32,注:配置文件也被删,但原来的网络适配器(即网卡设备)还在
对于没有启用的网卡,使用命令ifup,开启网卡。注意网卡的名称
# ifup enp2s1 Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3)
linux系统重启网卡后网络不通(NetworkManager篇)
原文链接:https://blog.csdn.net/m0_51929611/article/details/109275309
CentOS7中,启动docker容器的时候提示警告WARNING: IPv4 forwarding is disabled. Networking will not work.
报错原因:
CentOS的内核中的ip_forward(IP转发)是默认关闭的,需要手动打开
解决方案:
修改配置文件:
vim /usr/lib/sysctl.d/00-system.conf
1
追加
net.ipv4.ip_forward=1
重启网络
systemctl restart network
如何将之前报警告的docker删掉,重新启动即可
在Docker网络配置中,有一项重要的参数是net.ipv4.ip_forward,它的作用是开启Linux内核的IP转发功能。通过开启该功能,Docker容器可以实现对外部网络的访问,使得容器可以与其他计算机进行通信。
最简单的,配置一个桥接网络即可实现静态ip内外网访问
Virtualbox桥接实现静态固定IP内外网访问
virtualbox安装Centos7虚拟机,配置网卡NAT网络后找不到网卡配置文件
解决办法:
方法一:
nmcli con add con-name enp0s8 type ethernet ifname enp0s8
采用命令生成配置文件(会生成新的uuid,此方法网络比较稳定,否则经常用着用着就挂掉了)
自动生成网卡配置文件
方法二:
拷贝一个网卡配置文件过来,改名为网卡名称(如ifcfg-enp0s8 ),修改name、device为网卡名称enp0s8
uuid改为从下面找到的对应的网卡,如cd60e522-1bdf-3035-bd27-e7b5b53b9c0c
nmcli con show
————————————————
版权声明:本文为CSDN博主「卡卡_罗特」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhang_jingrui/article/details/125638720
VirtualBox虚拟机配置双网卡同时链接内外网
1.什么是nmcli
以前我配置网卡的时候都要打vim /etc/sysconfig/network-scripts/ifcfg-eth0这么一长串命令,有很多配置名字还记不住就需要去看模板,好不容易配置完了,还得去重启网卡。直到今天我知道了这个nmcli命令,才发现原来配置网卡可以这么简单,妈妈再也不用担心我不会配置网卡了。
2.nmcli的用法
命令语法:
nmcli[ OPTIONS ] OBJECT { COMMAND | help }
值得一提的是OBJECT和COMMAND可以用全程也可以用简称,最少可以只用一个字母,但我们一般用头三个字母,这样不容易搞错。
我们使用nmcli命令去配置网卡时如果忘记了语法命令是可以用TAB键补齐命令的。
OBJECT里我们平时用的最多的就是connection和device,这里就跟大家简单区分一下connection和device
connection是连接,偏重于逻辑设置
device叫网络接口,是物理设备
多个connection可以应用到同一个device,但同一时间只能启用其中一个connection。
这样的好处是针对一个网络接口,我们可以设置多个网络连接,比如静态IP和动态IP,再根据需要up相应的connection。
下面是一些nmcli的常用命令介绍
nmcli device show 查看所有网卡设备信息
show 后跟网卡名是查看某个网卡的详细信息
nmcli connection show 查看所有连接
同理 show 后跟上连接名可以查看连接的详细信息
VirtualBox虚拟机设置双网卡:内网固定IP方便内部使用、外网DHCP方便上网
原文链接:https://blog.csdn.net/u012373717/article/details/132976664
NAT+ Host-Only模式实现静态IP
参考:https://zhuanlan.zhihu.com/p/403513377
总结:
桥接模式:实现虚拟机在真实的网络上;
NAT模式:实现虚拟机隐藏在物理机之后,能上网,但不能访问物理机;
Host-Only模式:实现虚拟机隐藏在物理机之后,不能上网,但可以访问物理机;
要配置宿主物理机可以访问虚拟机机,且虚拟机固定ip,可以配置2个虚拟机网卡,一种为 NAT模式(用于保证虚拟机可访问互联网),一种为Host-Only模式(用于保证物理机可以ssh到虚拟机),且Host-Only模式的网卡需配置网络为static
本文是使用VirtualBox安装的CentOS7 x86_64 Minimal版本的虚拟机
安装好 CentOS 系统的虚拟机。默认是网络的连接方式为 NAT,该模式可以访问外网。
如果需要将虚拟机在局域网内的 IP 设置为固定 IP,需要添加网卡 2 为 Host-only 模式
至此我们添加了两个网卡,一个是 Nat,第二个是 Host-Only。
CentOS7网卡的配置文件在这个目录下面:/etc/sysconfig/network-scripts/,网络配置文件的格式为: ifcfg-xxx,默认的网络配置文件是:ifcfg-enp0s3
编辑 ifcfg-enp0s3 这个文件,将其中的 ONBOOT=no 改为 ONBOOT=yes,如果在安装 CentOS 的时候就设置了网络,则可以忽略这一步。
最终ifcfg-enp0s3文件内容如下:
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="dhcp"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="enp0s3"
UUID="6020592b-9f11-4cb6-aeac-8bcc3dba3690"
DEVICE="enp0s3"
# ONBOOT设置为yes
ONBOOT="yes"
保存文件并重启网络服务,重启网络的命令是 service network restart
ping www.baidu.com 可以 ping 通,说明与外网已经连通
但是此时我们的 IP 任然是动态的 IP,我们需要在添加一个网卡,也就是网卡 2,在文章的一开始已经让大家添加了网卡 2
复制ifcfg-enp0s3命名为ifcfg-enp0s8 命令为cp ifcfg-enp0s3 ifcfg-enp0s8
我们需要编辑ifcfg-enp0s8,最后重启网络即可
ifcfg-enp0s8文件需要变动的地方如下:
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
# BOOTPROTO改为static,意为静态模式
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
# NAME改为enp0s8,和文件名称后缀ifcfg-xxx保持一致
NAME="enp0s8"
# UUID 也需要修改,UUID可以重新生成一个,直接在命令行输入 uuidgen,回车就会出现结果,把结果复制过来。
UUID="87a8c150-3d1a-4111-97aa-816692dcf504"
# NAME改为enp0s8,和文件名称后缀ifcfg-xxx保持一致
DEVICE="enp0s8"
ONBOOT="yes"
# IPADDR需要在指定的IP范围内,NETMASK也和指定的服务器网络掩码一致,可以在VirtualBox主机网络配置管理器DHCP服务器中查看
IPADDR=192.168.56.102
NETMASK=255.255.255.0
VirtualBox 主机网络配置管理器 DHCP 服务器配置如下:
如上步骤设置好后,我们就可以启动虚拟机后,使用局域网 IP 用 XShell 连接而且可以访问外网了。
[root@localhost ~]# nmcli con show
NAME UUID TYPE DEVICE
NAME UUID TYPE DEVICE
enp0s3 6ef02a48-f732-4824-be14-70d767d8badb ethernet enp0s3
enp0s8 19d24bd9-d7d4-3edf-887d-a4fd30785feb ethernet enp0s8
cat ifcfg-enp0s3
UUID="6ef02a48-f732-4824-be14-70d767d8badb"
cat ifcg-enp0s8
UUID="19d24bd9-d7d4-3edf-887d-a4fd30785feb"]
可以用nmcli device show 和nmcli conn show 查看uuid和ip.
原文链接:https://blog.csdn.net/y1534414425/article/details/122347295
https://blog.csdn.net/cospeed/article/details/107044220
https://www.jianshu.com/p/305f7384cfe9