目前市面上最常见的负载均衡技术方案主要有三种:
基于DNS负载均衡,
DNS负载均衡主要适用于的场景是多地集群的方式,也就是可能北京有一个数据中心,在其中部署了一整套的集群提供服务,在上海有一个数据中心,也部署了同样的一套的集群来提供服务,用于预防地震,水灾,整个机房断电的故障,这种可以将请求发送给不同的数据中心,从而可以使用户更加快速的访问到服务
基于硬件负载均衡,例如那些贵的离谱的硬件设备,F5,A10,并发百万级别
硬件负载均衡,硬件厂商一般能提供强力的服务,稳定性较高,性能较好,能支持百万级别的并发量,缺点就是太贵了,在一个数据中心,一般买俩就够了,做成主备的形式,提供高可靠,高可用
基于软件负载均衡。
DNS一般由gslb本文也主要介绍利用软件进行负载均衡方案:Nginx、LVS、HAProxy 是目前使用最广泛的三种负载均衡软件,本人都在多个项目中实施过,通常会结合Keepalive做健康检查,实现故障转移的高可用功能。
- 4 层负载均衡转发
负载均衡设备在接收到第一个来自客户端的 SYN 请求时,即通过上述方式选择一个最佳的服务器, 并对报文中的目标 IP 地址进行修改(改为后端服务器 IP),直接转发给该服务器。 TCP 的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。 - 7 层负载均衡代理
负载均衡设备如果要根据真正的应用层内容再选择服务器,
只能先代理最终的服务器和客户端建立连接(TCP 三次握手)后,才可-能接收到客户端发送的真正应用层内容的报文, 然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立 TCP 连接。
所以从这个技术原理上来看,七层负载均衡明显地对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。
7层负载均衡相较于4层负载均衡在更耗费性能的同时,也获得了更加智能的优点,由于在应用层进行识别,所以7层负载均衡可以基于不同的协议(如http、radius、dns等)进行负载,也可以根据应用层协议中有意义的内容来进行负载,如:除了根据IP加端口进行负载外,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。
在四层(tcp)实现负载均衡的软件:
lvs——>重量级
nginx——>轻量级,带缓存功能,正则表达式较灵活
haproxy——>模拟四层转发,较灵活
在七层(http)实现反向代理的软件
haproxy——>天生技能,全面支持七层代理,会话保持,标记,路径转移;
nginx——>只在http协议和mail协议上功能比较好,性能与haproxy差不多;
apache——>功能较差
总的来说,一般是lvs做4层负载;nginx做7层负载;haproxy比较灵活,4层和7层负载均衡都能做一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术。具体的应用需求还得具体分析:
1)如果是中小型的 Web 应用,比如日PV小于1000 万,用 Nginx 就完全可以了;
2)如果机器不少,可以用DNS轮询, LVS所耗费的机器还是比较多的;大型网站或重要的服务,且服务器比较多时,可以考虑用LVS。
还有一种是通过硬件来进行进行,常见的硬件有比较昂贵的F5和Array等商用的负载均衡器,它的优点就是有专业的维护团队来对这些服务进行维护、缺点就是花销太大,所以对于规模较小
的网络服务来说暂时还没有需要使用;另外一种就是类似于 Nginx/LVS/HAProxy 的基于 Linux 的开源免费的负载均衡软件,这些都是通过软件级别来实现,所以费用非常低廉。目前关于网
站架构一般比较合理流行的架构方案: Web 前端采用Nginx/HAProxy+Keepalived 作负载均衡器;后端采用 MySQL 数据库一主多从和读写分离,采用 LVS+Keepalived 的架构。 当然要根据
项目具体需求制定方案。下面说说各自的特点和适用场合。
下面简单说下Nginx、LVS、HAProxy 负载均衡软件的优缺点:
1.LVS
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。
现在 LVS 已经是 Linux 标准内核的一部分,从 Linux2.4 内核以后,已经完全内置了 LVS 的各个功能模块,无需给内核打任何补丁,可以直接使用 LVS 提供的各种功能。
1.1LVS 负载均衡机制
1.LVS是四层负载均衡,也就是传输层上,传输层有TCP/UDP,LVS 支持 TCP/UDP 的负载均衡。因为 LVS 是四层负载均衡,因此它相对于其它高层负载均衡的解决办法,比如 DNS 域名轮流解析、应用层负载的调度、客户端的调度等,它的效率是非常高的。
2.所谓四层负载均衡 ,也就是主要通过报文中的目标地址和端口。七层负载均衡 ,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容。
3.LVS 的转发主要通过修改 IP 地址(NAT 模式,分为源地址修改 SNAT 和目标地址修改 DNAT)、修改目标 MAC(DR 模式)来实现。
1.2LVS负载模式
1.2.1NAT 模式:网络地址转换
1、NAT(Network Address Translation)是一种外网和内网地址映射的技术。NAT 模式下,网络数据报的进出都要经过 LVS 的处理。LVS 需要作为 RS(真实服务器)的网关。
2、当包到达 LVS 时,LVS 做目标地址转换(DNAT),将目标 IP 改为 RS 的 IP。RS 接收到包以后,仿佛是客户端直接发给它的一样。RS 处理完,返回响应时,源 IP 是 RS IP,目标 IP 是客户端的 IP。这时 RS 的包通过网关(LVS)中转,LVS 会做源地址转换(SNAT),将包的源地址改为 VIP,这样,这个包对客户端看起来就仿佛是 LVS 直接返回给它的。
1.2.2DR 模式:直接路由
1、DR 模式下需要 LVS 和 RS 集群绑定同一个 VIP(RS 通过将 VIP 绑定在 loopback 实现),但与 NAT 的不同点在于:请求由 LVS 接受,由真实提供服务的服务器(RealServer,RS)直接返回给用户,返回的时候不经过 LVS。
2、详细来看,一个请求过来时,LVS 只需要将网络帧的 MAC 地址修改为某一台 RS 的 MAC,该包就会被转发到相应的 RS 处理,注意此时的源 IP 和目标 IP 都没变,LVS 只是做了一下移花接木。RS 收到 LVS 转发来的包时,链路层发现 MAC 是自己的,到上面的网络层,发现 IP 也是自己的,于是这个包被合法地接受,RS 感知不到前面有 LVS 的存在。而当 RS 返回响应时,只要直接向源 IP(即用户的 IP)返回即可,不再经过 LVS。
3、DR 负载均衡模式数据分发过程中不修改 IP 地址,只修改 mac 地址,由于实际处理请求的真实物理 IP 地址和数据请求目的 IP 地址一致,所以不需要通过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。
- 典型组网:
- 将2台弹性云服务器绑定同一个虚拟IP。
-将绑定了虚拟IP的这2台弹性云服务器配置Keepalived+LVS(DR模式),组成LVS主备服务器。这2台服务器作为分发器将请求均衡地转发到不同的后端服务器上执行。 - 配置另外2台弹性云服务器作为后端RealServer服务器。
- 关闭2台后端RealServer弹性云服务器的源/目的检查。
- 检查LVS主备服务器的源/目的检查是否关闭,请参见关闭源/目的检查(适用于高可用负载均衡集群场景)。
若采用控制台方式将弹性云服务器与虚拟IP绑定,则源/目的检查自动关闭;若采用调用接口方式将弹性云服务器与虚拟IP绑定,则需要手动关闭源/目的检查。
Keepalived + LVS调度服务端安装配置以及后端RealServer服务器配置可以参考业内通用的配置方法,此处不做详细介绍
1.2.3IP隧道模式
隧道模式则类似于VPN的方式,使用网络分层的原理,在从客户端发来的数据包的基础上,封装一个新的IP头标记(不完整的IP头,只有目的IP部)发给RS,RS收到后,先把DR发过来的数据包的头给解开,还原其数据包原样,处理后,直接返回给客户端,而不需要再经过DR。
1.3LVS调度算法
1.3.1轮询调度(Round-RobinScheduling)
调度器通过”轮询”调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。
1.3.2加权轮询调度(WeightedRound-RobinScheduling)
调度器通过”加权轮询”调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。
1.3.3最小连接调度(Least-ConnectionScheduling)
调度器通过”最少连接”调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用”最小连接”调度算法可以较好地均衡负载。
1.3.4加权最小连接调度(WeightedLeast-ConnectionScheduling)
在集群系统中的服务器性能差异较大的情况下,调度器采用”加权最少链接”调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值
1.3.5基于局部性的最少链接(Locality-BasedLeastConnectionsScheduling)
基于局部性的最少链接”调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用”最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。
1.3.6带复制的基于局部性最少链接(Locality-BasedLeastConnectionswithReplicationScheduling)
1.3.7目标地址散列调度(DestinationHashingScheduling)
目标地址散列”调度算法根据请求的目标IP地址,作为散列键(HashKey)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空
1.3.8源地址散列调度(SourceHashingScheduling)
源地址散列”调度算法根据请求的源IP地址,作为散列键(HashKey)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
1.4LVS的优势和缺点
1.4.1 优点
1、抗负载能力强,因为lvs工作方式的逻辑是非常之简单,而且工作在网络4层仅做请求分发之用,没有流量,所以在效率上基本不需要太过考虑。在我手里的 lvs,仅仅出过一次问题:在并发最高的一小段时间内均衡器出现丢包现象,据分析为网络问题,即网卡或linux2.4内核的承载能力已到上限,内存和 cpu方面基本无消耗。
2、配置性低,这通常是一大劣势,但同时也是一大优势,因为没有太多可配置的选项,所以除了增减服务器,并不需要经常去触碰它,大大减少了人为出错的几率。
3、工作稳定,因为其本身抗负载能力很强,所以稳定性高也是顺理成章,另外各种lvs都有完整的双机热备方案,所以一点不用担心均衡器本身会出什么问题,节点出现故障的话,lvs会自动判别,所以系统整体是非常稳定的。
4、无流量,上面已经有所提及了。lvs仅仅分发请求,而流量并不从它本身出去,所以可以利用它这点来做一些线路分流之用。没有流量同时也保住了均衡器的IO性能不会受到大流量的影响。
5、基本上能支持所有应用,因为lvs工作在4层,所以它可以对几乎所有应用做负载均衡,包括http、数据库、聊天室等等
1.4.2 缺点
LVS 的缺点是:
1)软件本身不支持正则表达式处理,不能做动静分离;而现在许多网站在这方面都有较强的需求,这个是 Nginx/HAProxy+Keepalived 的优势所在。
2)如果是网站应用比较庞大的话, LVS/DR+Keepalived 实施起来就比较复杂了,特别后面有 Windows Server 的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,
Nginx/HAProxy+Keepalived 就简单多了。
2.Nginx
Nginx 是一个强大的 Web 服务器软件,用于处理高并发的 HTTP 请求和作为反向代理服务器做负载均衡。具有高性能、轻量级、内存消耗少,强大的负载均衡能力等优势。
2.1 Nignx 的架构设计
- 相对于传统基于进程或线程的模型(Apache就采用这种模型)在处理并发连接时会为每一个连接建立一个单独的进程或线程,且在网络或者输入/输出操作时阻塞。这将导致内存和 CPU 的大量消耗,因为新起一个单独的进程或线程需要准备新的运行时环境,包括堆和栈内存的分配,以及新的执行上下文,当然,这些也会导致多余的 CPU 开销。最终,会由于过多的上下文切换而导致服务器性能变差。
- Nginx 的架构设计是采用模块化的、基于事件驱动、异步、单线程且非阻塞。
- Nginx 大量使用多路复用和事件通知,Nginx 启动以后,会在系统中以 daemon 的方式在后台运行,其中包括一个 master 进程,n(n>=1) 个 worker 进程。所有的进程都是单线程(即只有一个主线程)的,且进程间通信主要使用共享内存的方式。
2.2Nginx 负载均衡
1、Nginx 负载均衡主要是对七层网络通信模型中的第七层应用层上的 http、https 进行支持。
2、Nginx 是以反向代理的方式进行负载均衡的。反向代理(Reverse Proxy)方式是指以代理服务器来接受 Internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 Internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
3、Nginx 实现负载均衡的分配策略有很多,Nginx 的 upstream 目前支持以下几种方式:
- 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
- weight:指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。
- ip_hash:每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
- fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
- url_hash(第三方):按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。
3.Haproxy
1、HAProxy 支持两种代理模式 TCP(四层)和HTTP(七层),也是支持虚拟主机的
2、HAProxy 的优点能够补充 Nginx 的一些缺点,比如支持 Session 的保持,Cookie 的引导;同时支持通过获取指定的 url 来检测后端服务器的状态。
3、HAProxy 跟 LVS 类似,本身就只是一款负载均衡软件;单纯从效率上来讲 HAProxy 会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。
4、HAProxy 支持 TCP 协议的负载均衡转发,可以对 MySQL 读进行负载均衡,对后端的 MySQL 节点进行检测和负载均衡,大家可以用 LVS+Keepalived 对 MySQL 主从做负载均衡。
5、HAProxy 负载均衡策略非常多:Round-robin(轮循)、Weight-round-robin(带权轮循)、source(原地址保持)、RI(请求URL)、rdp-cookie(根据cookie)。
4.Keepalived
1、keepalived是保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防止单点故障。
2、以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。
3、keepalived是可以工作在第三层、第四层、第五层的检测服务器状态的软件
4、如果有一台web服务器死机,或工作出现故障,keepalived将检测到,并将其从系统中剔除;当web服务器工作正常后keepalived自动将web服务器加入到服务器集群中
4.1Keepalived的工作原理
1、三层、四层、五层工作在TCP/IP协议栈的IP层、TCP层、应用层。原理如下:
- 三层:keepalived使用三层方式工作是,keepalived会定期向服务器集群中的服务器发送一个IMCP的数据包,也就是ping程序,如果发现某台服务器的IP地址没有激活,keepalived便报告这台服务器失效,并将它从集群中删除,这种情况的典型例子是某台服务器被非法关机。三层的方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。
- 四层:主要是以TCP端口的状态来决定服务器工作正常与否。如web服务器的端口一般是80,如果keepalived检测到80端口没有启动,则keepalived将这台服务器从集群中剔除。
- 五层:应用层,比三层和四层要复杂一点,keepalived将根据用户的设定检查服务器程序运行是否正常,如果与用户设定的不相符,则keepalived将把服务器从服务器集群中剔除。
2、基于VRRP虚拟路由冗余协议,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。
3、keepalived主要有三个模块,分别是core、check和vrrp。core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查,包括常见的各种检查方式。vrrp模块是来实现VRRP协议的。
4.2keepalived的作用
- 高可用-可持续的服务器质量
- 负载均衡-横向扩展
- 实现对失效服务器的隔离-通过健康监测,保证服务的可用性
- 实现:vrrp协议实现。(冗余网关路由协议)
5 Nginx和LVS对比的总结
1)Nginx 工作在网络的 7 层,所以它可以针对 http 应用本身来做分流策略,比如针对域名、目录结构等,相比之下 LVS 并不具备这样的功能,所以 Nginx 单凭这点可利用的场合就远多于LVS了;但 Nginx 有用的这些功能使其可调整度要高于 LVS,所以经常要去触碰触碰,触碰多了,人为出问题的 几率也就会大。
2)Nginx 对网络稳定性的依赖较小,理论上只要 ping 得通,网页访问正常, Nginx就能连得通,这是 Nginx 的一大优势! Nginx 同时还能区 分内外网,如果是同时拥有内外网的节点,就相当单机拥有了备份线路; LVS 就比较依赖于网络环境,目前来看服务器在同一网段内并且 LVS 使用 direct 方式分流,效果较能得到保证。另外注意, LVS 需要向托管商至少申请多一个 ip 来做Visual IP,貌似是不能用本身的 IP 来做 VIP 的。要做好 LVS 管理员,确实得跟进学习很多有关网络通信方面的知识,就不再是一个 HTTP 那么简单了。
3)Nginx 安装和配置比较简单,测试起来也很方便,因为它基本能把错误用日志打印出来。 LVS 的安装和配置、测试就要花比较长的时间了; LVS 对网络依赖比较大,很多时候不能配置成功都是因为网络问题而不是配置问题,出了问题要解决也相应的会麻烦得多。
4)Nginx 也同样能承受很高负载且稳定,但负载度和稳定度差 LVS 还有几个等级:Nginx 处理所有流量所以受限于机器 IO 和配置;本身的 bug 也还是难以避免的。
5)Nginx 可以检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点。目前 LVS 中ldirectd 也能支持针对服务器内部的情况来监控,但 LVS 的原理使其不能重发请求。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中 出现故障, Nginx 会把上传切到另一台服务器重新处理,而 LVS 就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而恼火。
6)Nginx 对请求的异步处理可以帮助节点服务器减轻负载,假如使用 apache 直接对外服务,那么出现很多的窄带链接时 apache 服务器将会占用大 量内存而不能释放,使用多一个 Nginx 做 apache代理的话,这些窄带链接会被 Nginx 挡住,apache 上就不会堆积过多的请求,这样就减少了相 当多的资源占用。这点使用squid 也有相同的作用,即使 squid 本身配置为不缓存,对 apache 还是有很大帮助的。
7)Nginx 能支持 http、 https 和 email( email 的功能比较少用), LVS 所支持的应用在这点上会比 Nginx 更多。在使用上,一般最 前端所采取的策略应是 LVS,也就是 DNS 的指向应为 LVS 均衡器,LVS 的优点令它非常适合做这个任务。重要的ip地址,最好交由 LVS 托管,比如数据 库的 ip、 webservice 服务器的 ip等等,这些 ip 地址随着时间推移,使用面会越来越大,如果更换 ip 则故障会接踵而至。所以将这些重要 ip 交给 LVS 托管是最为稳妥的,这样做的唯一缺点是需要的 VIP 数量会比较多。Nginx 可作为 LVS 节点机器使用,一是可以利用 Nginx的功能,二是可以利 用 Nginx 的性能。当然这一层面也可以直接使用 squid,squid 的功能方面就比 Nginx 弱不少了,性能上也有所逊色于 Nginx。Nginx 也可作为中层代理使用,这一层面 Nginx 基本上无对手,唯一可以撼动 Nginx 的就只有 lighttpd了,不过 lighttpd 目前还没有能做到 Nginx 完全的功能,配置也不那么清晰易读。另外,中层代理的 IP 也是重要的,所以中层代理也拥有一个VIP 和 LVS 是最完美的方案了。具体的应用还得 具体分析,如果是比较小的网站(日 PV 小于 1000 万),用 Nginx 就完全可以了,如果机器也不少,可以用DNS 轮询, LVS 所耗费的机器还是比较多 的;大型网站或者重要的服务,机器不发愁的时候,要多多考虑利用 LVS。
6 现在对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术
1)第一阶段:利用 Nginx 或 HAProxy 进行单点的负载均衡,这一阶段服务器规模刚脱离开单服务器、单数据库的模式,需要一定的负载均衡,但是仍 然规模较小没有专业的维护团队来进行维护,也没有需要进行大规模的网站部署。这样利用Nginx 或 HAproxy 就是第一选择,此时这些东西上手快, 配置容易,在七层之上利用 HTTP 协议就可以。这时是第一选择。
2)第二阶段:随着网络服务进一步扩大,这时单点的 Nginx (nginx也需要双高可用,或者增加节点,因为niginx的并发只有几万)已经不能满足,这时使用 LVS 或者商用 Array 就是首要选择, Nginx 此时就作为 LVS 或者 Array 的节点来使用,具体 LVS 或 Array 的是选择是根据公司规模和预算来选择,Array 的应用交付功能非常强大,本人在某项目中使用过,性价比也远高于 F5,商用首选!但是一般来说这阶段相关人才跟不上业务的提升,所以购买商业负载均衡已经成为了必经之路。
3)第三阶段:这时网络服务已经成为主流产品,此时随着公司知名度也进一步扩展,相关人才的能力以及数量也随之提升,这时无论从开发适合自身产品的定制,以及降低成本来讲开源的 LVS,已经成为首选,这时LVS 会成为主流。最终形成比较理想的基本架构为: Array/LVS — Nginx/Haproxy —Squid/Varnish — AppServer。
软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载实现。LVS就是基于Linux操作系统实现的一种软负载,HAProxy就是开源的并且基于第三应用实现的软负载。HAProxy相比LVS的使用要简单很多,功能方面也很丰富。当前,HAProxy支持两种主要的代理模式:”tcp”也即4层(大多用于邮件服务器、内部协议通信服务器等),和7层(HTTP)。在4层模式 下,HAProxy仅在客户端和服务器之间转发双向流量。7层模式下,HAProxy会分析协议,并且能通过允许、拒绝、交换、增加、修改或者删除请求 (request)或者回应(response)里指定内容来控制协议,这种操作要基于特定规则。
参考:
1、https://www.cnblogs.com/onesea/p/15069992.html
2、https://www.cnblogs.com/liping0826/p/13524397.html