LVS-原理

一. 集群的概念

服务器集群简称集群是一种服务器系统,它通过一组松散集成的服务器软件和/或硬件连接起来高度紧密地协作完成计算工作。在某种意义上,他们可以被看作是一台服务器
集群系统中的单个服务器通常称为节点,通常通过局域网连接,但也有其它的可能连接方式。集群服务器通常用来改进单个服务器的计算速度和/或可靠性。一般情况下集群
服务器比单个服务器,比如工作站或超级服务器性能价格比要高得多。集群就是一组独立的服务器,通过网络连接组合成一个组合来共同完一个任务。

说的直白点,集群就是一组相互独立的服务器,通过高速的网络组成一个服务器系统,每个集群节点都是运行其自己进程的一个独立服务器。对网络用户来讲,网站后
端就是一个单一的系统,协同起来向用户提供系统资源,系统服务。

二. 为什么要使用集群

1) 集群的特点
高性能performance
一些需要很强的运算处理能力比如天气预报,核试验等。这就不是几台服务器能够搞定的。这需要上千台一起来完成这个工作的。

价格有效性
通常一套系统集群架构,只需要几台或数十台服务器主机即可,与动则上百万的专用超级服务器具有更高的性价比。

可伸缩性
当服务器负载压力增长的时候,系统能够扩展来满足需求,且不降低服务质量。

高可用性
尽管部分硬件和软件发生故障,整个系统的服务必须是7*24小时运行的。

2) 集群的优势
透明性
如果一部分服务器宕机了业务不受影响,一般耦合度没有那么高,依赖关系没有那么高。比如NFS服务器宕机了其他就挂载不了了,这样依赖性太强。

高性能
访问量增加,能够轻松扩展。

可管理性
整个系统可能在物理上很大,但很容易管理。

可编程性
在集群系统上,容易开发应用程序,门户网站会要求这个。

3) 集群分类及不同分类的特点
计算机集群架构按照功能和结构一般分成以下几类:
-  负载均衡集群(Loadbalancingclusters)简称LBC
-  高可用性集群(High-availabilityclusters)简称HAC
-  高性能计算集群(High-perfomanceclusters)简称HPC
-  网格计算(Gridcomputing)

就集群分类而言, 网络上面一般认为是有三个,负载均衡和高可用集群式我们互联网行业常用的集群架构。

1) 负载均衡集群
负载均衡集群为企业提供了更为实用,性价比更高的系统架构解决方案。负载均衡集群把很多客户集中访问的请求负载压力可能尽可能平均的分摊到计算机集群中处理。
客户请求负载通常包括应用程度处理负载和网络流量负载。这样的系统非常适合向使用同一组应用程序为大量用户提供服务。每个节点都可以承担一定的访问请求负载压力,
并且可以实现访问请求在各节点之间动态分配,以实现负载均衡。

负载均衡运行时,一般通过一个或多个前端负载均衡器将客户访问请求分发到后端一组服务器上,从而达到整个系统的高性能和高可用性。这样集群有时也被称为服务器群
一般高可用性集群和负载均衡集群会使用类似的技术,或同时具有高可用性与负载均衡的特点。

负载均衡集群的作用:
a)分担访问流量(负载均衡)
b)保持业务的连续性(高可用)

2) 高可用性集群
一般是指当集群中的任意一个节点失效的情况下,节点上的所有任务自动转移到其他正常的节点上,并且此过程不影响整个集群的运行,不影响业务的提供。类似是集群中运行着两个或两个以上的一样的节点,当某个主节点出现故障的时候,那么其他作为从 节点的节点就会接替主节点上面的任务。从节点可以接管主节点的资源(IP地址,架构身份等),此时用户不会发现提供服务的对象从主节点转移到从节点。
高可用性集群的作用:当一台机器宕机另一台进行接管。比较常用的高可用集群开源软件有:keepalive,heardbeat。

3) 高性能计算集群
高性能计算集群采用将计算任务分配到集群的不同计算节点儿提高计算能力,因而主要应用在科学计算领域。比较流行的HPC采用Linux操作系统和其它一些免费软件来完成并行运算。这一集群配置通常被称为Beowulf集群。这类集群通常运行特定的程序以发挥HPCcluster的并行能力。这类程序一般应用特定的运行库, 比如专为科学计算设计的MPI库。HPC集群特别适合于在计算中各计算节点之间发生大量数据通讯的计算作业,比如一个节点的中间结果或影响到其它节点计算结果的情况。

三. 负载均衡集群介绍

负载均衡集群是 Load Balance 集群, 是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端提供服务的一种方式。
负载均衡集群的作用:提供一种廉价、有效、透明的方法,来扩展网络设备和服务器的负载带宽、增加吞吐量,加强网络数据处理能力、提高网络的灵活性和可用性。简单来说,也就是:
1) 把单台计算机无法承受的大规模的并发访问或数据流量分担到多台节点设备上分别处理,减少用户等待响应的时间,提升用户体验。
2) 单个重负载的运算分担到多台节点设备上做并行处理,每个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力得到大幅度提高。
3) 7*24小时的服务保证,任意一个或多个设备节点设备宕机,不能影响到业务。在负载均衡集群中,所有计算机节点都应该提供相同的服务,集群负载均衡获取所有对该服务的如站请求。

常用的负载均衡分为:
1) 开源软件负载均衡:  Nginx, LVS, Haproxy  (Nginx和Haproxy通常做七层负载均衡LVS做四层负载均衡. 但是Nginx也可以通过stream模块做四层负载均衡, Haproxy也可以做四层负载均衡 ) ;
2) 商业的硬件负载均衡: 设备F5、Netscale ;

简单理解一下软件负载均衡:
1) 所谓分层的负载均衡,都是以网络的模型来说的。四层就是基于IP和端口的负载均衡,七层就是基于URL等应用信息的负载均衡。所以简单的说四层负载均衡就是通过IP和端口接收请求再分发至真实的服务器,七层是通过URL或主机名接收请求,然后分发至真实的服务器。
2) .而七层的实现也是在四层的基础上是实现的,没有四层就不可能有七层。在第七层上可以做许多事情,比如可以根据七层的浏览器类别区分是手机还是PC,将WEB服务器分为2组,手机登陆专门的移动端网站。
3) 对客户端来说,客户端好像是访问的同一台主机。其实为了有更好的用户体验,从智能DNS入手,根据客户端IP来源将域名解析到距离客户端最近的一台服务器或者访问最快速的一台服务器,但这些内容客户端都是感觉不到的,客户端感觉到的只能是访问网站很快。

linux virtual server简称LVS,Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲, CPU、I/O处理能力很快会成为瓶颈。由于单台服务器的性能总是有限的,简单的提高硬件性能并不能真正解决这个问题。为此,必须采用多服务器和负载均衡技术才能满足大量并发访问的需要。Linux 虚拟服务器(Linux Virtual Servers,LVS) 使用负载均衡技术将多台服务器组成一个虚拟服务器。它为适应快速增长的网络访问需求提供了一个负载能力易于扩展,而价格低廉的解决方案。lvs的负载能力特别强,优化空间特别大,lvs的变种DPVS据说是lvs性能的几倍,由爱奇艺开发,并广泛用于爱奇艺IDC。其他负载均衡服务器还有nginx,haproxy,F5,Netscale。
 

 

 

LVS负载均衡分为三层架构(也就是LVS负载均衡主要组成部分):

第一层:负载调度器(load balancer/ Director),它是整个集群的总代理,它在有两个网卡,一个网卡面对访问网站的客户端,一个面对整个集群的内部。负责将客户端的请求发送到一组服务器上执行,而客户也认为服务是来自这台主的。举个生动的例子,集群是个公司,负载调度器就是在外接揽生意,将接揽到的生意分发给后台的真正干活的真正的主机们。当然需要将活按照一定的算法分发下去,让大家都公平的干活。
第二层:服务器池(server pool/ Realserver),是一组真正执行客户请求的服务器,可以当做WEB服务器。就是上面例子中的小员工。  
第三层:共享存储(shared storage),它为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。一个公司得有一个后台账目吧,这才能协调。不然客户把钱付给了A,而换B接待客户,因为没有相同的账目。B说客户没付钱,那这样就不是客户体验度的问题了。

 IP负载均衡与负载调度算法
IP负载均衡技术
负载均衡技术有很多实现方案,有基于DNS域名轮流解析的方法、有基于客户端调度访问的方法、有基于应用层系统负载的调度方法,还有基于IP地址的调度方法,在这些负载调度算法中,执行效率最高的是IP负载均衡技术。

LVS的IP负载均衡技术是通过IPVS模块来实现的,IPVS是LVS集群系统的核心软件,它的主要作用是:安装在Director Server上,同时在Director Server上虚拟出一个IP地址,用户必须通过这个虚拟的IP地址访问服务。这个虚拟IP一般称为LVS的VIP,即Virtual IP。访问的请求首先经过VIP到达负载调度器,然后由负载调度器从Real Server列表中选取一个服务节点响应用户的请求。当用户的请求到达负载调度器后,调度器如何将请求发送到提供服务的Real Server节点,而Real Server节点如何返回数据给用户,是IPVS实现的重点技术,IPVS实现负载均衡机制有三种,分别是NATTUNDR(下面会详细介绍);

负载调度算法
负载调度器是根据各个服务器的负载情况,动态地选择一台Real Server响应用户请求,根据不同的网络服务需求和服务器配置,IPVS实现了如下八种负载调度算法:rr、wrr、Wlc、Dh、SH、Lc、Lblc

LVS负载均衡调度算法

VS的调度算法决定了如何在集群节点之间分布工作负荷。当director调度器收到来自客户端访问VIP的上的集群服务的入站请求时,director调度器必须决定哪个集群节点应该
处理请求。

Director调度器用的调度方法基本分为两类 (如下所列, LVS总共有10种调度算法, 常用的也就四种调度算法, 下面会说到):
静态调度算法:rr,wrr,dh,sh
动态调度算法:wlc,lc,lblc,lblcr, sed, nq

静态调度 (也就是固定调度算法)的4种算法:
rr(轮询)
轮询调度:这种是最简单的调度算法,就是将请求A一个,B一个,A一个,B一个 ...... 循环的发。就算A主机挂掉了,调度器还是会将请求发送到A。十分均衡。

wrr(权重, 即加权轮询)
加权轮询调度:这种算法是在rr基础上实现的,只不过加了权重,权重范围为1-100,假设A的服务器性能好,就给A的权重设置的高一点,设为2,而B主机是1。这样就实现A二个,B一个,A二个,B一个 ...... 循环的发。这样照顾到了服务器性能。

sh(源地址哈希)
源地址散列:主要是实现将此前的session(会话)绑定。将此前客户的源地址作为散列键,从静态的散列表中找出对应的服务器,只要目标服务器是没有超负荷的就将请求发送过去。
就是说某客户访问过A,现在这个客户又来了,所以客户请求会被发送到服务过他的A主机。 dh(目的地址哈希) 目的地址散列:以目的地址为关键字查找一个静态hash表来获得需要的RS。以目标地址为标准挑选。 功能是和sh近似的,但应用场景不同; 举个dh调度算法的例子:
假设1号客户访问了web集群的一个动态页面,调度器将请求转发个A服务器,A服务器的PHP将这个动态请求运行了一遍,生成了缓存并回应1号客户。这下2号客户也访问了这个动态页面,
调度器应该将请求发给A。毕竟A已经跑过这段程序了,有缓存,对吧。所以这既是dh算法)


动态调度算法,动态算法与静态算法最大的区别就是动态算法考虑了服务器的压力。 活动链接(active):客户与服务器建立连接并且有数据传送 非活动链接(inactive):只是建立连接,没有数据传送,没有断开连接 动态调度的6种算法 lc(最少链接) 最少连接调度:这种算法是看A,和B的主机谁的连接少,请求就发给谁。 简单算法:active
*256+inactive (谁小发给谁) wlc(加权最少链接)LVS的理想算法 加权最少链接:这种算法就是比lc多了一个加权。 简单算法:( active*256+inactive )/weight (谁小就发给谁) sed(最短期望延迟) 基于wlc算法,假设A,B的权重分别是1,2 。而A的链接数为1,B的链接数为2 。这样的话,用wlc算法得出的结果一样,而明显B的权重大,B的能力较强。用sed算法的话,就可以避免wlc出现的问题。 简单算法:(active+1)*256/weight (活动的连接数+1)*256/除以权重 谁小发给谁 A:(1+1)/1 B:(2+1)/2 (B小,交给B) nq(不用排队) 基于sed算法:在sed的基础上,若谁的链接数为0,直接将请求发送给它! LBLC(基于局部性的最少连接)类似于dh,目标地址hash 这个算法主要用于Cache集群系统,因为Cache集群的中客户请求报文的目标IP地址的变化,将相同的目标URL地址请求调度到同一台服务器,来提高服务器的访问的局部性和Cache命中率。从而调整整个集群的系统处理能力。
但是,如果realserver的负载处于一半负载,就用最少链接算法,将请求发送给活动链接少的主机。 LBLCR(带复制的基于局部性的最少链接) 该算法首先是基于最少链接的,当一个新请求收到后,一定会将请求发给最少连接的那台主机的。但这样又破坏了cache命中率。但这个算法中,集群服务是cache共享的,假设A的PHP跑了一遍,得到缓存。
但其他realserver可以去A那里拿缓存,这是种缓存复制机制。 负载调度器是根据各个服务器的负载情况,动态地选择一台Real Server响应用户请求,那么动态选择是如何实现呢,其实也就是这里要说的负载调度算法,根据不同的网络服务需求和服务器配置,
IPVS实现了如上的十种负载调度算法,下面详细讲述LVS最常用的四种调度算法
- 轮叫调度(Round Robin) "轮叫"调度也叫1:1调度,调度器通过"轮叫"调度算法将外部用户请求按顺序1:1的分配到集群中的每个Real Server上,这种算法平等地对待每一台Real Server,而不管服务器 上实际的负载状况和连接状态。 - 加权轮叫调度(Weighted Round Robin) "加权轮叫"调度算法是根据Real Server的不同处理能力来调度访问请求。可以对每台Real Server设置不同的调度权值,对于性能相对较好的Real Server可以设置较高的权值,而对于处理能力较弱的Real Server,可以设置较低的权值,这样保证了处理能力强的服务器处理更多的访问流量。充分合理的利用了服务器资源。同时,调度器还可以自动查询Real Server的负载情况,并动态地调整其权值。 - 最少链接调度(Least Connections) "最少连接"调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用"最小连接"调度算法可以较好地均衡负载。 - 加权最少链接调度(Weighted Least Connections) "加权最少链接调度""最少连接调度"的超集,每个服务节点可以用相应的权值表示其处理能力,而系统管理员可以动态的设置相应的权值,缺省权值为1,加权最小连接调度在分配新连接请求时尽可能使服务节点的已建立连接数和其权值成正比。 LVS调度算法的生产环境选型: 1)一般的网络服务,如http,nginx,mysql等常用的LVS调度算法为: a. 基本轮询调度rr b. 加权最小连接调度wlc c. 加权轮询调度wrc 2)基于局部性的最小连接lblc和带复制的给予局部性最小连接lblcr主要适用于web cache和DB cache; 3)源地址散列调度SH和目标地址散列调度DH可以结合使用在防火墙集群中,可以保证整个系统的出入口唯一; 其实对于LVS的理解,主要部分还是在于3种工作方式和8种调度算法,实际这些算法的适用范围很多,工作中最好参考内核中的连接调度算法的实现原理,然后根据具体的业务需求合理的选型。


 

 

 

 

 

 

 

当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间。
PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链。
IPVS是工作在INPUT链上的,当用户请求到达INPUT时,IPVS会将用户请求和自己已定义好的集群服务进行比对,如果用户请求的就是定义的集群服务,
那么此时IPVS会强行修改数据包里的目标IP地址及端口,并将新的数据包发往POSTROUTING链。 POSTROUTING链接收数据包后发现目标IP地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器。
LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。

IPVS(ip virtual server):一段代码工作在内核空间,叫IPVS,是真正生效实现调度的代码。IPVS的总体结构主要由IP包处理、负载均衡算法、
                系统配置与管理三个模块及虚拟服务器与真实服务器链表组成。 ipvsadm:另外一段是工作在用户空间,叫ipvsadm,即IPVS管理器,负责为ipvs内核框架编写规则,定义谁是集群服务,而谁是后端真实的服务器(Real Server)。

 

DS:Director Server。指的是前端负载均衡器节点。
RS:Real Server。后端真实的工作服务器。
VIP:Virtual IP,向外部直接面向用户请求,作为用户请求的目标的IP地址。
DIP:Director Server IP,主要用于和内部主机通讯的IP地址。
RIP:Real Server IP,后端服务器的IP地址。
CIP:Client IP,访问客户端的IP地址。

 

 

 

LVS工作模式

NAT模式

 

 

1 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP。
2 PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链。
3 IPVS比对数据包请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器IP,然后将数据包发至POSTROUTING链。
 此时报文的源IP为CIP,目标IP为RIP。 4 POSTROUTING链通过选路,将数据包发送给Real Server 5 Real Server比对发现目标为自己的IP,开始构建响应报文发回给Director Server。 此时报文的源IP为RIP,目标IP为CIP。 6 Director Server在响应客户端前,此时会将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP。
NAT特性
RIP最好是内网IP
RS的网关必须指向DIP。
DIP和RIP必须在同一个网段内。
请求和回应的报文都必须经过director,director容易成为瓶颈。
nat支持端口转发。

DR模式

 

 

1 首先用户用CIP请求VIP。
2 根据上图可以看到,不管是Director Server还是Real Server上都需要配置相同的VIP,那么当用户请求到达我们的集群网络的前端路由器的时候,
请求数据包的源地址为CIP目标地址为VIP,此时路由器会发广播问谁是VIP,那么我们集群中所有的节点都配置有VIP,此时谁响应路由器那么路由器就会将用户请求发给谁,
这样一来我们的集群系统是不是没有意义了,那我们可以在网关路由器上配置静态路由指定VIP就是Director Server,或者使用一种机制不让Real Server
接收来自网络中的ARP地址解析请求,这样一来用户的请求数据包都会经过Director Servrer。 3 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP。 4 PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链。 5 IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。
此时的源IP和目的IP均未修改仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址 6 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。 7 RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP 8 响应报文最终送达至客户端。
第一种方式:
在路由器上明显说明vip对应的地址一定是Director上的MAC,只要绑定,以后再跟vip通信也不用再请求了,这个绑定是静态的,所以它也不会失效,也不会再次发起请求,
但是有个前提,我们的路由设备必须有操作权限能够绑定MAC地址,万一这个路由器是运行商操作的,我们没法操作怎么办?第一种方式固然很简便,但未必可行。 第二种方式: 在给别主机上(例如:红帽)它们引进的有一种程序arptables,它有点类似于iptables,它肯定是基于arp或基于MAC做访问控制的,很显然我们只需要在每一个real server上
定义arptables规则,如果用户arp广播请求的目标地址是本机的vip则不予相应,或者说相应的报文不让出去,很显然网关(gateway)是接受不到的,也就是director相应的
报文才能到达gateway,这个也行。第二种方式我们可以基于arptables。 第三种方式: 在相对较新的版本中新增了两个内核参数(kernelparameter),第一个是arp_ignore定义接受到ARP请求时的相应级别;第二个是arp_announce定义将自己地址向外通告时的通告级别。
【提示:很显然我们现在的系统一般在内核中都是支持这些参数的,我们用参数的方式进行调整更具有朴实性,它还不依赖于额外的条件,像arptables,也不依赖外在路由配置的设置,
反而通常我们使用的是第三种配置】 arp_ignore:定义接受到ARP请求时的相应级别
0: 只要本地配置的有相应地址,就给予响应。(默认) 1: 仅回应目标IP地址是本地的入网地址的arp请求。 2: 仅回应目标IP地址是本地的入网地址,而且源IP和目标IP在同一个子网的arp请 求。 3: 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应 4-7:保留未使用 8: 不回应所有的arp请求。 arp_announce:定义将自己地址向外通告是的通告级别; 0: 将本地任何接口上的任何地址向外通告 1: 试图仅向目标网络通告与其网络匹配的地址 2: 仅向与本地接口上地址匹配的网络进行通告
DR特性
特点1:保证前端路由将目标地址为VIP报文统统发给Director Server,而不是RS。
Director和RS的VIP为同一个VIP。
RS可以使用私有地址;也可以是公网地址,如果使用公网地址,此时可以通过互联网对RIP进行直接访问。
RS跟Director Server必须在同一个物理网络中。
所有的请求报文经由Director Server,但响应报文必须不能进过Director Server。
不支持地址转换,也不支持端口映射
RS可以是大多数常见的操作系统
RS的网关绝不允许指向DIP(因为我们不允许他经过director)
RS上的lo接口配置VIP的IP地址
DR模式是市面上用得最广的。
缺陷:RS和DS必须在同一机房中

补充:特点1的解决方法

  1. 在前端路由器做静态地址路由绑定,将对于VIP的地址仅路由到Director Server。存在问题:用户未必有路由操作权限,因为有可能是运营商提供的,所以这个方法未必实用。
  2. arptables:在arp的层次上实现在ARP解析时做防火墙规则,过滤RS响应ARP请求。这是由iptables提供的。
  3. 修改RS上内核参数(arp_ignore和arp_announce)将RS上的VIP配置在lo接口的别名上,并限制其不能响应对VIP地址解析请求。

Tunnel模式

 

 

1 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP 。
2 PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链。
3 IPVS比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层IP报文,封装源IP为为DIP目标IP为RIP。然后发至POSTROUTING链。
此时源IP为DIP,目标IP为RIP。 4 POSTROUTING链根据最新封装的IP报文,将数据包发至RS(因为在外层封装多了一层IP首部,所以可以理解为此时通过隧道传输)。 此时源IP为DIP,目标IP为RIP。 5 RS接收到报文后发现是自己的IP地址,就将报文接收下来,拆除掉最外层的IP后,会发现里面还有一层IP首部,而且目标是自己的lo接口VIP,那么此时RS开始处理此请求
处理完成之后,通过lo接口送给eth0网卡,然后向外传递。 此时的源IP地址为VIP,目标IP为CIP 6 响应报文最终送达至客户端

 

Tunnel模式特性
RIP、VIP、DIP全是公网地址。
RS的网关不会也不可能指向DIP
所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
不支持端口映射
RS的系统必须支持隧道

 

posted @ 2019-11-11 11:02  linux——quan  阅读(703)  评论(1编辑  收藏  举报