一种识别磁盘异常的方法、装置及分布式存储系统与流程

文档序号:23094347发布日期:2020-11-27 12:52阅读:162来源:国知局
本发明属于分布式数据存储
技术领域
:,更具体地涉及一种识别磁盘异常的方法、装置及分布式存储系统。
背景技术
::磁盘作为分布式存储系统中数据最终存储的地方,磁盘的故障在存储系统中非常常见,集群中单个或少量磁盘出现故障后如何保证系统业务不受影响,是存储软件必须解决的问题。在分布式存储系统中,当磁盘出现异常情况时,会导致io请求处理失败,osd(objectstoragedevice,对象存储设备)会收到io请求失败的响应,该响应一般是针对部分错误码进行简单的重试,而对于大部分错误会触发osd异常退出。发明人在实现本发明实施例的过程中,发现相关技术至少存在以下技术问题:1)对于本可以进行容错修复的错误未修复,导致磁盘最终被踢出集群,错误的磁盘当坏盘处理,增加了系统运营成本;2)osd异常退出触发集群视图变更,会引起io性能波动;3)osd异常退出后触发数据重构,影响集群整体的io性能。技术实现要素:针对现有技术的以上缺陷或改进需求,本发明提供了一种识别磁盘异常的方法、装置及分布式存储系统,其目的在于准确识别出磁盘的异常情况,以解决系统运营成本高、进程异常退出引起的io性能波动的技术问题。为实现上述目的,按照本发明的一个方面,提供了一种识别磁盘异常的方法,所述方法应用于分布式存储系统,所述分布式存储系统包括至少一台应用主机,所述至少一台应用主机包括内核模块和虚拟块设备,所述方法包括:通过所述虚拟块设备向所述内核模块中部署osd与磁盘的映射关系;当所述osd读写磁盘时,将接收到的io请求提交给所述虚拟块设备,在所述虚拟块设备发送所述io请求后,所述内核模块截获所述io请求;所述内核模块根据所述映射关系将所述io请求经scsi层提交给所述osd对应的磁盘;当所述io请求在所述磁盘响应失败时,所述内核模块获取scsi错误码,并解析所述scsi错误码;根据所述scsi错误码的解析结果识别所述磁盘的异常。可选地,所述内核模块部署于linux系统内核的bio层,所述内核模块用于与所述scsi层进行交互。可选地,所述在所述虚拟块设备发送所述io请求后,所述内核模块截获所述io请求,具体包括:在所述虚拟块设备发送所述io请求至所述linux系统内核的vfs层时,所述内核模块从所述vfs层截获所述io请求。可选地,所述根据所述scsi错误码的解析结果识别所述磁盘的异常,包括:对所述scsi错误码的解析结果进行分类,并分别处理所述分类的结果;其中,所述分类包括需要重试的io、需要重置的io、坏扇区错误以及不可修复错误。可选地,所述方法还包括:获取io错误次数、io时延信息以及磁盘smart信息;根据所述scsi错误码的解析结果、所述io错误次数、所述io时延信息以及所述磁盘smart信息对所述磁盘进行故障预测;根据所述故障预测的结果对所述磁盘进行预防处理。按照本发明的另一方面,提供了一种识别磁盘异常的装置,所述装置应用于分布式存储系统,所述分布式存储系统包括至少一台应用主机,所述至少一台应用主机包括内核模块和虚拟块设备,所述装置包括:信息部署模块,用于通过所述虚拟块设备向所述内核模块中部署osd与磁盘的映射关系;数据处理模块,用于当所述osd读写磁盘时,将接收到的io请求提交给所述虚拟块设备,在所述虚拟块设备发送所述io请求后,所述内核模块截获所述io请求;数据提交模块,用于所述内核模块根据所述映射关系将所述io请求经scsi层提交给所述osd对应的磁盘;错误码解析模块,用于当所述io请求在所述磁盘响应失败时,所述内核模块获取scsi错误码,并解析所述scsi错误码;磁盘异常识别模块,用于根据所述scsi错误码的解析结果识别所述磁盘的异常。可选地,所述内核模块部署于linux系统内核的bio层,所述内核模块用于与所述scsi层进行交互。可选地,所述磁盘异常识别模块具体用于:对所述scsi错误码的解析结果进行分类,并分别处理所述分类的结果;其中,所述分类包括需要重试的io、需要重置的io、坏扇区错误以及不可修复错误。可选地,所述装置还包括:信息获取模块,用于获取io错误次数、io时延信息以及磁盘smart信息;故障预测模块,用于根据所述scsi错误码的解析结果、所述io错误次数、所述io时延信息以及所述磁盘smart信息对所述磁盘进行故障预测;预处理模块,用于根据所述故障预测的结果对所述磁盘进行预防处理。按照本发明的又一方面,提供了一种分布式存储系统,所述分布式存储系统包括:至少一台应用主机;所述至少一台应用主机包括:至少一个处理器;与所述至少一个处理器通信连接的存储器;以及内核模块和虚拟块设备;其中,所述存储器存储有可被所述至少一个处理器执行的指令,所述指令被所述至少一个处理器执行,以使所述至少一个处理器能够基于所述内核模块和所述虚拟块设备执行如上所述的识别磁盘异常的方法。总体而言,通过本发明所构思的以上技术方案与现有技术相比,具有如下有益效果:本发明实施例提供了一种识别磁盘异常的方法、装置及分布式存储系统,通过增加内核模块和虚拟块设备,获取磁盘的scsi错误码,根据所述scsi错误码的解析结果识别出磁盘的异常情况,由此,可以针对不同的错误码在软件层面进行详细处理,最大限度的确保了系统稳定运行;对于真正的硬件故障,也可以主动触发节点隔离,从而避免了进程异常退出引起的io性能波动、数据重构等问题。附图说明一个或多个实施例通过与之对应的附图进行示例性说明,这些示例性说明并不构成对实施例的限定,附图中具有相同参考数字标号的元件表示为类似的元件,除非有特别申明,附图中的图不构成比例限制。图1是本发明实施例提供的一种分布式存储系统的结构示意图;图2是本发明实施例提供的一种分布式存储系统中osd提交io请求给磁盘的流程示意图;图3是本发明实施例提供的一种识别磁盘异常的方法的流程图;图4是本发明另一实施例提供的一种识别磁盘异常的方法的流程图;图5是本发明实施例提供的一种识别磁盘异常的装置的结构示意图。具体实施方式为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。请参阅图1,图1是本发明实施例提供的一种分布式存储系统的结构示意图。所述分布式存储系统100包括至少一台应用主机10,所述应用主机10具体可以是服务器,所述分布式存储系统100可以将多台服务器组成一个超大服务器集群。在该服务器集群中,包括配置中心和存储节点。其中,可以是一台或多台应用主机10构成所述配置中心,所述存储节点包括一个或多个,每一个存储节点可以由一台或多台应用主机10构成。所述存储节点与所述配置中心通信连接,所述配置中心用于管理所述存储节点的资源分配、存储等。比如,所述配置中心将所述存储节点中的每一应用主机10的磁盘资源整合到一起,形成一个巨大的资源池,对外提供存储服务,按需分配给应用使用。其中,所述应用主机10的操作系统可以是linux操作系统,所述linux操作系统包括系统内核。在本实施例中,在所述系统内核中设置内核模块,比如将其命名为kernel_mod。所述内核模块用于在osd下发io请求时,通过所述内核模块截获所述io请求,由所述内核模块与scsi(smallcomputersysteminterface,小型计算机系统接口)层进行交互,从而可以避免bio(blockinputoutput,块设备的输入/输出)层对scsi错误码进行转化,导致osd无法感知磁盘上的真实错误。其中,所述scsi错误码是scsi设备在处理io请求时,当发生错误后针对不同错误原因定义的错误码。scsi错误码可以通过sensekey、sensecode、sensequalifier三部分组成,例如sensekey:3sensecode:11sensequalifier:0,表示的scsi错误码是:mediumerror–unrecoveredreaderror,即读到了坏扇区。具体地,请参阅图2,所述内核模块可以设于系统内核的bio层。可以理解的是,当磁盘完成io请求处理后会返回处理结果,所述处理结果经过所述bio层之后,由于linux系统对设备进行抽象封装,bio层会向上屏蔽不同类型块设备之间的差异,对于scsi层和磁盘自然也会屏蔽scsi协议中定义的各类错误码,所以当底层磁盘发生异常引起io错误后,scsi层返回的错误码在bio层会进行转换,转换为所述bio层的通用错误码,比如eio错误码等,所述eio是linux系统中定义的一个错误码,其具体定义比如:#defineeio5/*i/oerror*/,即表示io失败。bio层再将所述通用错误码通过vfs(virtualfilesystem,虚拟文件系统)层返回给osd,osd获得所述通用错误码后并不能感知底层磁盘真正的错误,从而无法进行细分处理。因此,在本实施例中,通过在bio层设置所述内核模块,通过所述内核模块与scsi层进行交互,避免通用bio层对scsi层错误码进行转化,导致osd无法感知磁盘上的真实错误。其中,所述内核模块可以按照linux标准的内核模块进行开发,可以在操作系统启动或业务需要时通过insmod(insertmodule,载入驱动模块)标准命令在操作系统中插入所述内核模块。所述insmod标准命令用于加载模块,通过模式的方式在需要时载入内核,可使内核精简,高效。此类载入的模块,通常为设备驱动程序。在所述内核模块插入bio层后,自动在操作系统中虚拟出一个块设备,即虚拟块设备,其名称可以自定义,比如/dev/block_dev等。其中,当osd启动时不再打开原始的磁盘,而是打开由新增内核模块虚拟出的所述虚拟块设备,并将osd与磁盘的映射关系添加至所述内核模块中,通过所述内核模块的内存维护所述osd与磁盘的映射关系。在分布式存储系统(比如ceph)中osd与磁盘通常是一一对应的,每个osd进程对应一块磁盘。可以预先设置好所述osd与所述磁盘的映射关系。其中,在osd运行过程中需要提交io请求至所述磁盘时,由于osd启动阶段打开的是所述虚拟块设备,所以下发的所述io请求经过所述vfs层处理后会被所述内核模块截获,所述内核模块按照内存中维护的所述osd与磁盘的映射关系,将所述io请求经所述scsi层提交给osd对应的磁盘。其中,io请求经过osd应用软件层处理后最终写入磁盘或从磁盘读取,osd对磁盘进行读写,并在磁盘上的io请求发生错误时,感知详细的错误原因。在所述io请求返回时,按照原路径返回,所述内核模块获取scsi错误码并解析所述scsi错误码,将解析的结果返回给osd,所述osd可以根据所述返回的结果对错误码进行分类处理。其中,所述内核模块可以根据scsi标准协议解析所述scsi错误码。在所述协议中包含详细的错误原因以及错误码定义,在协议数据包中携带有错误码,通过解析所述scsi标准协议即可获取所述scsi错误码。其中,所述osd根据返回的结果对错误码进行分类处理具体可以包括:a)对于需要重试的io请求进行重试处理;b)对于需要重置的io进行重置(reset,即重启)处理;c)对于坏扇区错误,可通过触发读修复从其他正常副本读取数据,重新写入本地进行修复;d)对于不可修复错误,则触发osd上报monitor集群,将故障节点踢出集群,避免故障重启影响系统稳定运行。在其他一些实施例中,所述内核模块还可以用于统计磁盘信息、io信息、scsi错误码信息等,根据这些信息进一步对磁盘故障进行预测,从而提升系统的可靠性。例如,所述内核模块还用于获取io错误次数、io时延信息以及磁盘smart(self-monitoringanalysisandreportingtechnology,自我监测、分析及报告技术)信息;根据所述scsi错误码的解析结果、所述io错误次数、所述io时延信息以及所述磁盘smart信息对所述磁盘进行故障预测;根据所述故障预测的结果对所述磁盘进行预防处理。需要说明的是,当所述应用主机10包括多个osd和多个磁盘时,只需在所述应用主机10的系统内核中增加一个所述内核模块和虚拟块设备,通过所述一个内核模块和虚拟块设备维护全部osd与磁盘的对应关系。在本实施例中,如图1所示,所述应用主机10还包括一个或多个处理器11,以及存储器12,图1中以一个处理器11为例。处理器11和存储器12可以通过总线或其他方式连接,图1中以通过总线连接为例。存储器12作为一种非易失性计算机可读存储介质,可用于存储非易失性软件程序、非易失性计算机可执行程序以及模块,如本发明实施例中的识别磁盘异常的方法对应的程序指令/模块(例如,图5中的各个模块)。处理器11基于上述内核模块和上述虚拟块设备,通过运行存储在存储器12中的非易失性软件程序、非易失性计算机可执行程序以及模块,从而执行所述应用主机10的各种功能应用以及数据处理,即实现下述方法实施例识别磁盘异常的方法。存储器12可以包括存储程序区和存储数据区,其中,存储程序区可存储包含所述内核模块和所述虚拟块设备的操作系统、至少一个功能所需要的应用程序;存储数据区可存储根据识别磁盘异常的装置的使用所创建的数据等。此外,存储器12可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他非易失性固态存储器件。在一些实施例中,存储器12可选包括相对于处理器11远程设置的存储器,这些远程设置的存储器可以通过网络连接至识别磁盘异常的装置。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。所述一个或多个模块存储在所述存储器12中,当被所述一个或多个处理器11执行时,执行下述方法实施例中的识别磁盘异常的方法,例如,图3和图4所示的方法。本发明实施例提供的分布式存储系统100可以执行本发明实施例所提供的识别磁盘异常的方法,具备执行方法相应的功能模块和有益效果。未在本实施例中详尽描述的技术细节,可参见本发明实施例提供的方法。请参阅图3,图3是本发明实施例提供的一种识别磁盘异常的方法的流程图。所述方法可以应用于上述分布式存储系统100,所述方法包括:s101、通过所述虚拟块设备向所述内核模块中部署osd与磁盘的映射关系;其中,所述osd与磁盘的映射关系包括每一osd对应的磁盘,具体可以是一一对应的关系。osd提交的io请求根据所述映射关系提交所述io请求至所述osd对应的磁盘。s102、当所述osd读写磁盘时,将接收到的io请求提交给所述虚拟块设备,在所述虚拟块设备发送所述io请求后,所述内核模块截获所述io请求;其中,所述虚拟块设备是内核系统中自定义的内核模块生成的。所述内核模块部署于linux系统内核的bio层,所述内核模块用于与linux系统内核的scsi层进行交互,比如,所述内核模块传递io请求至所述scsi层,或者从所述scsi层获取scsi错误码。所述虚拟块设备是所述内核模块插入后在操作系统中虚拟出来的一个块设备。当osd启动时,通过系统函数打开磁盘在操作系统中对应的块设备,比如所述虚拟块设备。所述虚拟块设备从osd获得io请求后,转发给linux系统内核的vfs层,经所述vfs层处理后,所述io请求会被所述内核模块截获。此时,所述io请求不是通过vfs层到达通用的bio层,由此,可以在io请求在磁盘得到响应后,避免该响应被bio层转化为通用的错误码。s103、所述内核模块根据所述映射关系将所述io请求经scsi层提交给所述osd对应的磁盘;s104、当所述io请求在所述磁盘响应失败时,所述内核模块获取scsi错误码,并解析所述scsi错误码;s105、根据所述scsi错误码的解析结果识别所述磁盘的异常。其中,io请求经过osd应用软件层处理后最终写入磁盘或从磁盘读取,osd对磁盘进行读写,并在磁盘上的io请求发生错误时,感知详细的错误原因。在所述io请求返回时,按照原路径返回,所述内核模块获取scsi错误码并解析所述scsi错误码,将解析的结果返回给osd,所述osd可以根据所述返回的结果对错误码进行分类处理。其中,所述内核模块可以根据scsi标准协议解析所述scsi错误码。在所述协议中包含详细的错误原因以及错误码定义,在协议数据包中携带有错误码,通过解析所述scsi标准协议即可获取所述scsi错误码。所述scsi错误码是scsi设备在处理io请求时,当发生错误后针对不同错误原因定义的错误码。scsi错误码可以通过sensekey、sensecode、sensequalifier三部分组成,例如sensekey:3sensecode:11sensequalifier:0,表示的scsi错误码是:mediumerror–unrecoveredreaderror,即读到了坏扇区。其中,所述根据所述scsi错误码的解析结果识别所述磁盘的异常,包括:对所述scsi错误码的解析结果进行分类,并分别处理所述分类的结果。其中,所述分类包括需要重试的io、需要重置的io、坏扇区错误以及不可修复错误。所述分别处理所述分类的结果包括:对于需要重试的io请求进行重试处理;对于需要重置的io进行重置(reset,即重启)处理;对于坏扇区错误,可通过触发读修复从其他正常副本读取数据,重新写入本地进行修复;对于不可修复错误,则触发osd上报monitor集群,将故障节点踢出集群,避免故障重启影响系统稳定运行。本发明实施例提供了一种识别磁盘异常的方法,该方法可以应用于上述实施例描述的分布式存储系统,该方法通过所述虚拟块设备向所述内核模块中部署osd与磁盘的映射关系;当所述osd读写磁盘时,将接收到的io请求提交给所述虚拟块设备,在所述虚拟块设备发送所述io请求后,所述内核模块截获所述io请求;所述内核模块根据所述映射关系将所述io请求经scsi层提交给所述osd对应的磁盘;当所述io请求在所述磁盘响应失败时,所述内核模块获取scsi错误码,并解析所述scsi错误码;根据所述scsi错误码的解析结果识别所述磁盘的异常。由此,本发明实施例提供的识别磁盘异常的方法能够感知磁盘的真实错误,并且针对不同的错误在应用软件层进行细分处理,从而最大限度的保证了系统稳定的运行。并且,对于真正的硬件故障,也可以主动触发节点隔离,从而避免了进程异常退出引起的io性能波动、数据重构等问题。需要说明的是,图3提供的识别磁盘异常的方法与上述系统实施例具有相同的发明构思,未在本发明实施例详尽描述的部分具体可以参考上述系统实施例。请参阅图4,图4是本发明另一实施例提供的一种识别磁盘异常的方法的流程图。图4与上述图3的主要区别在于,所述方法还包括:s106、获取io错误次数、io时延信息以及磁盘smart信息;s107、根据所述scsi错误码的解析结果、所述io错误次数、所述io时延信息以及所述磁盘smart信息对所述磁盘进行故障预测;s108、根据所述故障预测的结果对所述磁盘进行预防处理。其中,所述io错误次数和io时延信息都是所述io请求经osd提交给磁盘的过程中产生的,可以周期性的统计这些信息。所述磁盘smart信息指的是磁盘的硬件检测模块检测到的信息,该信息包括磁盘健康状况、不稳定扇区数、smart错误日志、smart自检日志等。所述scsi错误码的解析结果可以是上述实施例中在osd上结合io流程中返回的scsi错误码的分析结果。所述内核模块可以根据所述scsi错误码的解析结果、所述io错误次数、所述io时延信息以及所述磁盘smart信息对所述磁盘进行故障预测,从而根据所述故障预测的结果对所述磁盘进行预防处理。其中,对所述磁盘进行故障预测的基本思路可以是,按照磁盘io时延信息、各种错误原因,结合磁盘的smart信息中的部分指标进行故障预测,例如,一般会重点关注下述几个指标::smart5–reallocated_sector_count.smart187–reported_uncorrectable_errors.smart188–command_timeout.smart197–current_pending_sector_count.smart198–offline_uncorrectable.当检测到磁盘的这些指标接近或超过阈值时,则认为该磁盘可能在短时间内会出现故障。此时可以开始数据重构等,并将该磁盘踢出集群,从而避免了故障出现后再进行事后处理所带来的风险,比如等出现故障后再处理时,有可能在处理过程中又出现其他磁盘故障,从而造成出现多点故障引起数据丢失等问题。本发明实施例提供的识别磁盘异常的方法,通过增加内核模块,获取磁盘的scsi错误码,针对不同的错误码在软件层面进行详细处理,最大限度的确保系统的稳定运行,对于真正的硬件故障,也能主动触发节点隔离,避免进程异常退出引起的io性能波动等问题。另外,通过内核模块对磁盘的smart信息、io性能等进行统计,从而对磁盘进行故障预测,由此,进一步提升了系统的可靠性。请参阅图5,图5是本发明实施例提供的一种识别磁盘异常的装置的结构示意图。所述装置20可以应用于上述实施例中的分布式存储系统,所述装置20包括信息部署模块21、数据处理模块22、数据提交模块23、错误码解析模块24以及磁盘异常识别模块25。其中,所述信息部署模块21用于通过所述虚拟块设备向所述内核模块中部署osd与磁盘的映射关系;所述数据处理模块22用于当所述osd读写磁盘时,将接收到的io请求提交给所述虚拟块设备,在所述虚拟块设备发送所述io请求后,所述内核模块截获所述io请求;所述数据提交模块23用于所述内核模块根据所述映射关系将所述io请求经scsi层提交给所述osd对应的磁盘;所述错误码解析模块24用于当所述io请求在所述磁盘响应失败时,所述内核模块获取scsi错误码,并解析所述scsi错误码;所述磁盘异常识别模块25用于根据所述scsi错误码的解析结果识别所述磁盘的异常。其中,所述内核模块部署于linux系统内核的bio层,所述内核模块用于与所述scsi层进行交互。其中,所述磁盘异常识别模块25具体用于:对所述scsi错误码的解析结果进行分类,并分别处理所述分类的结果;其中,所述分类包括需要重试的io、需要重置的io、坏扇区错误以及不可修复错误。在一些实施例中,同样如图5所示,所述装置20还包括信息获取模块26、故障预测模块27和预处理模块28。所述信息获取模块26用于获取io错误次数、io时延信息以及磁盘smart信息;所述故障预测模块27用于根据所述scsi错误码的解析结果、所述io错误次数、所述io时延信息以及所述磁盘smart信息对所述磁盘进行故障预测;所述预处理模块28用于根据所述故障预测的结果对所述磁盘进行预防处理。需要说明的是,上述识别磁盘异常的装置可执行本发明实施例所提供的识别磁盘异常的方法,具备执行方法相应的功能模块和有益效果。未在识别磁盘异常的装置实施例中详尽描述的技术细节,可参见本发明实施例所提供的识别磁盘异常的方法。本发明实施例还提供了一种非易失性计算机存储介质,所述非易失性计算机存储介质存储有计算机可执行指令,该计算机可执行指令被一个或多个处理器执行,例如图1中的一个处理器31,可使得上述一个或多个处理器可执行上述任意方法实施例中的识别磁盘异常的方法。本发明实施例还提供了一种计算机程序产品,所述计算机程序产品包括存储在非易失性计算机可读存储介质上的计算机程序,所述计算机程序包括程序指令,当所述程序指令被所述应用主机执行时,使所述应用主机执行上述方法实施例所述的识别磁盘异常的方法。以上所描述的装置或设备实施例仅仅是示意性的,其中所述作为分离部件说明的单元模块可以是或者也可以不是物理上分开的,作为模块单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络模块单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施例方案的目的。通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到各实施方式可借助软件加通用硬件平台的方式来实现,当然也可以通过硬件。基于这样的理解,上述技术方案本质上或者说对相关技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品可以存储在计算机可读存储介质中,如rom/ram、磁碟、光盘等,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行各个实施例或者实施例的某些部分所述的方法。最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;在本发明的思路下,以上实施例或者不同实施例中的技术特征之间也可以进行组合,步骤可以以任意顺序实现,并存在如上所述的本发明的不同方面的许多其它变化,为了简明,它们没有在细节中提供;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的范围。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1