一种JVM运行参数的配置方法、装置、设备及介质与流程

文档序号:16608034发布日期:2019-01-14 21:17阅读:165来源:国知局
一种JVM运行参数的配置方法、装置、设备及介质与流程

本发明涉及java应用技术领域,特别是涉及一种jvm运行参数的配置方法、装置、设备及介质。



背景技术:

java应用程序(简称java应用)的使用越来越普及,当前部署java应用最常用的方式是通过容器的方式部署,通常情况下,容器为docker容器。容器化部署java应用具有轻量化、消耗资源低、部署速度快等许多优势。然而,容器作为一种新兴技术,现有的许多工具并没有针对在容器内运行的场景方面的优化,目前java应用运行所依赖的jvm(java虚拟机)就是如此。在jvm上运行java应用时,为获取应用运行的最佳性能,如果不显式为jvm指定运行参数,jvm会根据主机现有资源配置java应用的运行环境,例如“最大堆内存”会默认配置为主机内存的1/4。但是,由于jvm无法得知自身是否在容器中运行,因此并未考虑到容器的资源限制,也就是说容器的资源限制并没有对jvm的配置过程起作用,jvm依然根据实际运行主机的资源来配置java应用的运行环境,一旦java应用实际使用资源超过容器的资源配额时,容器就会强行停止java应用的运行。

由此可见,如何提供一种灵活的配置方法,使得在部署java应用时能够降低部署人员的工作量和出错可能性是本领域技术人员亟待解决的问题。



技术实现要素:

本发明的目的是提供一种java应用的jvm运行参数的配置方法、装置、设备及介质,用于改善配置的灵活性,使得在部署java应用时能够降低部署人员的工作量和出错可能性。

为解决上述技术问题,本发明提供一种java应用的jvm运行参数的配置方法,包括:

获取jvm所在容器的实际资源配额;

根据预设参数配置逻辑计算与所述实际资源配额相对应的jvm运行参数。

优选地,所述实际资源配额具体包括:

所述容器所在的主机节点的实际物理内存和所述容器自身内存配额;

所述根据预设参数配置逻辑计算与所述实际资源配额相对应的jvm运行参数具体包括:

根据所述实际物理内存的四分之一和所述容器自身内存配额的二分之一中的较小值计算所述jvm运行参数中的内存相关调优参数。

优选地,所述实际资源配额还包括:

所述容器所在的主机节点的cpu核数和所述容器自身cpu核数;

所述根据预设参数配置逻辑计算与所述实际资源配额相对应的jvm运行参数具体包括:

根据所述实际物理内存的四分之一和所述容器自身内存配额的二分之一中的较小值计算所述jvm运行参数中的内存相关调优参数;

根据所述cpu核数的四分之一和所述容器自身cpu核数中的较小值计算所述jvm运行参数中的jvm并发相关参数。

优选地,所述内存相关调优参数具体包括-xmx、-xms、-xmn、-xx:permsize、-xx:maxpermsize、-xx:newsize、-xx:maxnewsize、-xss、-xx:threadstacksize。

优选地,所述-xmx具体通过如下公式计算得到:

所述容器自身内存配额-(保留代码占用内存+线程栈大小*应用线程数+单个类内存*类数量)。

优选地,所述jvm并发相关参数具体包括-xx:parallelgcthreads、-xx:cicompilercount、-xx:concgcthreads。

优选地,所述配置方法还包括:

根据应用的使用场景,在基础镜像中配置默认的调优参数。

为解决上述技术问题,本发明还提供一种java应用的jvm运行参数的配置装置,包括:

获取单元,用于获取jvm所在容器的实际资源配额;

计算单元,用于根据预设参数配置逻辑计算与所述实际资源配额相对应的jvm运行参数。

优选地,所述实际资源配额包括:所述容器所在的主机节点的实际物理内存和所述容器自身内存配额;

所述计算单元包括:

内存相关调优参数计算单元,用于根据所述实际物理内存的四分之一和所述容器自身内存配额的二分之一中的较小值计算所述jvm运行参数中的内存相关调优参数。

优选地,所述实际资源配额还包括:所述容器所在的主机节点的cpu核数和所述容器自身cpu核数;

所述计算单元还包括:

jvm并发相关参数计算单元,用于根据所述cpu核数的四分之一和所述容器自身cpu核数中的较小值计算所述jvm运行参数中的jvm并发相关参数。

优选地,所述内存相关调优参数包括-xmx、-xms、-xmn、-xx:permsize、-xx:maxpermsize、-xx:newsize、-xx:maxnewsize、-xss、-xx:threadstacksize。

优选地,所述-xmx通过如下公式计算得到:

所述容器自身内存配额-(保留代码占用内存+线程栈大小*应用线程数+单个类内存*类数量)。

优选地,所述jvm并发相关参数具体包括-xx:parallelgcthreads、-xx:cicompilercount、-xx:concgcthreads。

优选地,所述配置装置还包括:

默认配置单元,用于根据应用的使用场景,在基础镜像中配置默认的调优参数。

为解决上述技术问题,本发明还提供一种java应用的jvm运行参数的配置设备,包括存储器,用于存储计算机程序;

处理器,用于执行所述计算机程序时实现如上述所述的java应用的jvm运行参数的配置方法的步骤。

为解决上述技术问题,本发明还提供一种计算机可读存储介质,所述计算机可读存储介质上存储有计算机程序,所述计算机程序被处理器执行时实现如上述所述的java应用的jvm运行参数的配置方法的步骤。

本发明所提供的java应用的jvm运行参数的配置方法,首先是获取jvm所在容器的实际资源配额,然后根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。由于每次在容器启动时,都要执行上述步骤,因此,得到jvm运行参数都是根据当前容器的实际资源配额确定的,也就是说,jvm运行参数的选取是一个动态的选取过程,因此能够克服采用固定资源配置jvm运行参数所带来的资源过多分配或分配不足的问题;并且上述方法确定后,能够自动获取实际资源配额,以及根据预设参数配置逻辑进行计算,也就无需部署人员指定相应的环境变量,因此能够大大降低部署人员的工作量以及出错的可能性。

此外,本发明还提供与上述方法对应的java应用的jvm运行参数的配置装置、设备及计算机存储介质,效果如上所述。

附图说明

为了更清楚地说明本发明实施例,下面将对实施例中所需要使用的附图做简单的介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1为本发明实施例提供的一种java应用的jvm运行参数的配置方法的流程图;

图2为本发明实施例提供的一种java应用的jvm运行参数的配置装置的结构图;

图3为本发明实施例提供的一种java应用的jvm运行参数的配置设备的结构图。

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下,所获得的所有其他实施例,都属于本发明保护范围。

为了解决背景技术提到的问题,相关技术中有两种解决方式,一种方式是在制作java应用的基础镜像(主要包括标准的运行环境)时规定基础镜像运行所要求的资源配额,并在基础镜像中配置合适的jvm运行参数,在部署应用时,容器的资源必须满足基础镜像的资源要求。这种方式可以避免容器的资源限制对jvm造成的影响,但是由于采用了固定资源配置jvm,要么造成资源过多的分配,要么资源分配无法满足java应用的运行,不够灵活。另一种方式是将jvm的运行参数以环境变量方式传入容器,jvm启动时使用环境变量里的资源配置。这种方式虽然解决了第一种方式产生的问题,但是要求传入的环境变量必须与容器的资源配额一致,这就要求在每次部署应用时,部署人员都要根据容器的资源配额指定相应的环境变量,无疑增加了部署人员的工作量以及出错的可能性。

本发明的核心是提供一种java应用的jvm运行参数的配置方法、装置、设备及介质,用于改善配置的灵活性,使得在部署java应用时能够降低部署人员的工作量和出错可能性。

为了使本技术领域的人员更好地理解本发明方案,下面结合附图和具体实施方式对本发明作进一步的详细说明。

图1为本发明实施例提供的一种java应用的jvm运行参数的配置方法的流程图。如图1所示,该方法包括:

s10:获取jvm所在容器的实际资源配额。

s11:根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。

需要说明的是,本发明所述的配置方法可以采用脚本的方式实现,具体是在制作java应用的基础镜像完毕后,在基础镜像中加入该配置方法,使得在运行基础镜像的容器启动时自动执行该脚本。

本实施例中对于步骤s10中容器的类型不作限定,但是通常情况下是docker容器,java应用的类型也不作限定,jvm的类型也不作限定。至于实际资源配额中的资源主要是影响jvm运行参数的资源,例如内存资源,cpu资源等,因此,本实施例中,对于实际资源配额也不作限定。可以理解的是,实际资源配额的选取影响最终jvm运行参数的选取,实际资源配额考虑的因素越多,则jvm运行参数的选取越准确合理,但是一定程度上会影响容器启动的速度。

本实施例中预设参数配置逻辑可以根据实际情况确定实际资源配额对应的结果,具体逻辑本实施例不再赘述。在具体实施中,预设参数配置逻辑可以是以函数的表达形式,这样将实际资源配额带入到函数中即可计算得到jvm运行参数,另一种方式是,将每种实际资源配对应的jvm运行参数制作为映射关系,那么预设参数配置逻辑其实是一种关于实际资源配和jvm运行参数的映射关系。预设参数配置逻辑是何种表现方式,不影响本发明的技术方案的实施。在具体实施中,预设参数配置逻辑可以是根据实际经验来确定,也可以是搜集大量的历史数据,通过对历史数据进行分析统计得到。

本发明实施例提供的java应用的jvm运行参数的配置方法,首先是获取jvm所在容器的实际资源配额,然后根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。由于每次在容器启动时,都要执行上述步骤,因此,得到jvm运行参数都是根据当前容器的实际资源配额确定的,也就是说,jvm运行参数的选取是一个动态的选取过程,因此能够克服采用固定资源配置jvm运行参数所带来的资源过多分配或分配不足的问题;并且上述方法确定后,能够自动获取实际资源配额,以及根据预设参数配置逻辑进行计算,也就无需部署人员指定相应的环境变量,因此能够大大降低部署人员的工作量以及出错的可能性。

在上述实施例的基础上,作为优选地实施方式,实际资源配额具体包括:

容器所在的主机节点的实际物理内存和容器自身内存配额;

对应的,s11具体包括:

根据实际物理内存的四分之一和容器自身内存配额的二分之一中的较小值计算jvm运行参数中的内存相关调优参数。

举例而言,实际物理内存可以通过/proc/meminfo文件获取,容器自身内存配额可以通过/sys/fs/cgroup/memory目录下的文件获取。

作为优选地实施方式,内存相关调优参数具体包括-xmx、-xms、-xmn、-xx:permsize、-xx:maxpermsize、-xx:newsize、-xx:maxnewsize、-xss、-xx:threadstacksize。需要说明的是,内存相关调优参数并不限于上述几种参数,还可以包括其它参数,例如,-xx:newratio、-xx:survivorratio、-xx:largepagesizeinbytes等。

-xss规定了每个线程堆栈的大小,一般情况下256k就可以满足要求,其主要影响进程中并发线程数大小。

-xms初始的heap的大小,默认(minheapfreeratio参数可以调整)空余堆内存小于40%时,jvm就会增大堆直到-xmx的最大限制。

-xmx堆内存大小。默认(maxheapfreeratio参数可以调整)空余堆内存大于70%时,jvm会减少堆直到-xms的最小限制。在很多情况下,-xms和-xmx设置成一样的。这么设置,是因为当heap不够用时,会发生内存抖动,影响程序运行稳定性。

-xx:permsize为设置持久代(permgen)初始值,通常情况下物理内存的1/64。

-xx:maxpermsize为设置持久代最大值。

-xx:newsize为设置年轻代大小

-xx:maxnewsize为年轻代最大值。

-xss为每个线程的堆栈大小。

-xx:threadstacksize为threadstacksize。

可以理解的是,当得到了实际物理内存的四分之一和容器自身内存配额的二分之一后,取二者的较小值,通过较小值计算jvm运行参数中的内存相关调优参数。由于计算jvm运行参数中的内存相关调优参数为本领域技术人员熟知,因此具体计算过程本实施例不再赘述。

优选地,-xmx可以通过如下公式计算得到:

堆内存大小=容器自身内存配额-(保留代码占用内存+线程栈大小*应用线程数+单个类内存*类数量)。

上述公式中,容器自身内存配额从/sys/fs/cgroup/memory目录下的文件中获取;保留代码占用内存具体根据应用代码规模的估计值,例如250mb;线程栈大小默认1mb;应用线程数可配置,通过环境变量传入;单个类内存根据类规模的估计值,例如6kb;类数量可配置,通过环境变量传入,或者统计jar包中class文件的数量得到。

在上述实施例的基础上,作为优选地实施方式,本实施例中,实际资源配额增加了cpu调优。实际资源配额还包括:

容器所在的主机节点的cpu核数和容器自身cpu核数;

s11具体包括:

根据实际物理内存的四分之一和容器自身内存配额的二分之一中的较小值计算jvm运行参数中的内存相关调优参数;

根据cpu核数的四分之一和容器自身cpu核数中的较小值计算jvm运行参数中的jvm并发相关参数。

在上一实施例中对于jvm运行参数中的内存相关调优参数进行了详细说明,本实施例不再赘述。本实施例中主要说明jvm运行参数中的jvm并发相关参数的计算。

优选地,jvm并发相关参数具体包括-xx:parallelgcthreads、-xx:cicompilercount、-xx:concgcthreads。

其中,parallelgcthreads表示jvm在进行gc的时候,用于gc的线程数,例如-xx:parallelgcthreads=43,表示配置gc线程数为43。

-xx:cicompilercount表示设置最大并行编译数。

-xx:concgcthreads表示定义并发cms过程运行时的线程数。比如value=4意味着cms周期的所有阶段都以4个线程来执行。

需要说明的是,jvm并发相关参数并不限于上述几种参数,还可以包括其它参数,本实施例不作限定。

在上述实施例的基础上,作为优选地实施方式,还包括:

根据应用的使用场景,在基础镜像中配置默认的调优参数。

具体实施中,除了内存相关调优参数和jvm并发相关参数的外,还可以配置默认的调优参数。需要说明的是,默认的调优参数需要根据应用的使用场景,例如,以下几种参数:

-xx:+useparallelgc、-xx:gctimeratio、-xx:adaptivesizepolicyweight、-xx:minheapfreeratio、-xx:maxheapfreeratio、时区配置、字符集配置。由于上述默认的调优参数对于多数jvm是适用的,因此,通过默认设置的方式可以减少部署容器时的配置工作量。

需要说明的是,上述所述的java应用的jvm运行参数的配置方法是灵活加入应用的基础镜像中的,如果用户有特殊的要求,需要单独配置jvm的内存相关调优参数和jvm并发相关参数,则可以跳过上述步骤。因此,面对这种情况,可以在进行java应用的jvm运行参数的配置之前,首先判断用户是否有自主配置的要求,如果有的话,则按照用户的配置要求执行,如果没有的话,则按照上述配置方法配置。在按照用户的配置要求执行之前,还需要检测用户配置的内存相关调优参数是否超过了容器自身内存配额,如果是,则输出提示信息以提示用户内存配置过大,并终止应用执行,以免发生oom错误。同样的,还需要检测用户配置的jvm并发相关参数是否超过了cpu核数的四分之一和容器自身cpu核数中的较小值,如果是,则输出提示信息。

为了让本领域技术人员进一步理解本发明所提出的技术方案,下文中还提供一种与上述方法对应的应用场景的实施例,以docker容器为例说明。

在制作java应用运行的基础镜像时分为两种情况,一种情况是在基础镜像中直接配置默认的调优参数,使得每次在部署docker容器时,都按照默认的调优参数进行配置,从而减轻了配置的工作量。另一种情况是调优参数需要依据当前docker容器的实际资源配额进行配置。具体是基础镜像中添加一个脚本,该脚本所执行的功能就是获取jvm所在容器的实际资源配额,再根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。当docker容器启动前,首先会调用上述提到的脚本,从而完成该脚本所能实现的动作。在执行完该脚本所对应的动作后,再根据基础镜像制作具体java应用镜像,即应用的程序包,最后再对docker容器运行时所用的资源配额进行配置,并以java应用镜像启动docker容器。

上述实例对于java应用的jvm运行参数的配置方法的实施例进行了详细描述,本发明实施例还提供java应用的jvm运行参数的配置装置及设备的实施例。其中,装置部分的实施例主要从软件功能的角度描述,设备部分的实施例主要从硬件角度描述。

图2为本发明实施例提供的一种java应用的jvm运行参数的配置装置的结构图。如图2所示,该装置包括:

获取单元10,用于获取jvm所在容器的实际资源配额;

计算单元11,用于根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。

本实施例中对于容器的类型不作限定,但是通常情况下是docker容器,java应用的类型也不作限定,jvm的类型也不作限定。至于实际资源配额中的资源主要是影响jvm运行参数的资源,例如内存资源,cpu资源等,因此,本实施例中,对于实际资源配额也不作限定。可以理解的是,实际资源配额的选取影响最终jvm运行参数的选取,实际资源配额考虑的因素越多,则jvm运行参数的选取越准确合理,但是一定程度上会影响容器启动的速度。

本实施例中预设参数配置逻辑可以根据实际情况确定实际资源配额对应的结果,具体逻辑本实施例不再赘述。在具体实施中,预设参数配置逻辑可以是以函数的表达形式,这样将实际资源配额带入到函数中即可计算得到jvm运行参数,另一种方式是,将每种实际资源配对应的jvm运行参数制作为映射关系,那么预设参数配置逻辑其实是一种关于实际资源配和jvm运行参数的映射关系。预设参数配置逻辑是何种表现方式,不影响本发明的技术方案的实施。在具体实施中,预设参数配置逻辑可以是根据实际经验来确定,也可以是搜集大量的历史数据,通过对历史数据进行分析统计得到。

本发明实施例提供的java应用的jvm运行参数的配置装置,首先是获取jvm所在容器的实际资源配额,然后根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。由于每次在容器启动时,都要执行上述步骤,因此,得到jvm运行参数都是根据当前容器的实际资源配额确定的,也就是说,jvm运行参数的选取是一个动态的选取过程,因此能够克服采用固定资源配置jvm运行参数所带来的资源过多分配或分配不足的问题;并且上述方法确定后,能够自动获取实际资源配额,以及根据预设参数配置逻辑进行计算,也就无需部署人员指定相应的环境变量,因此能够大大降低部署人员的工作量以及出错的可能性。

作为一种优选地实施方式,实际资源配额包括:容器所在的主机节点的实际物理内存和容器自身内存配额;

计算单元包括:

内存相关调优参数计算单元,用于根据实际物理内存的四分之一和容器自身内存配额的二分之一中的较小值计算jvm运行参数中的内存相关调优参数。

作为一种优选地实施方式,实际资源配额还包括:容器所在的主机节点的cpu核数和容器自身cpu核数;

计算单元还包括:

jvm并发相关参数计算单元,用于根据cpu核数的四分之一和容器自身cpu核数中的较小值计算jvm运行参数中的jvm并发相关参数。

作为一种优选地实施方式,内存相关调优参数包括-xmx、-xms、-xmn、-xx:permsize、-xx:maxpermsize、-xx:newsize、-xx:maxnewsize、-xss、-xx:threadstacksize。

作为一种优选地实施方式,-xmx通过如下公式计算得到:

容器自身内存配额-(保留代码占用内存+线程栈大小*应用线程数+单个类内存*类数量)。

作为一种优选地实施方式,jvm并发相关参数具体包括-xx:parallelgcthreads、-xx:cicompilercount、-xx:concgcthreads。

作为一种优选地实施方式,配置装置还包括:

默认配置单元,用于根据应用的使用场景,在基础镜像中配置默认的调优参数。

由于装置部分的实施例与方法部分的实施例相互对应,因此装置部分的实施例请参见方法部分的实施例的描述,这里暂不赘述。

图3为本发明实施例提供的一种java应用的jvm运行参数的配置设备的结构图。如图3所示,该设备包括存储器20,用于存储计算机程序;

处理器21,用于执行计算机程序时实现如上述实施例所述的java应用的jvm运行参数的配置方法的步骤。

由于设备部分的实施例与方法部分的实施例相互对应,因此设备部分的实施例请参见方法部分的实施例的描述,这里暂不赘述。在本发明的一些实施例中,处理器21和存储器20可通过总线或其它方式连接。

本发明实施例提供的java应用的jvm运行参数的配置设备,包括存储器和处理器,处理器在执行存储器中的程序时,首先是获取jvm所在容器的实际资源配额,然后根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。由于每次在容器启动时,都要执行上述步骤,因此,得到jvm运行参数都是根据当前容器的实际资源配额确定的,也就是说,jvm运行参数的选取是一个动态的选取过程,因此能够克服采用固定资源配置jvm运行参数所带来的资源过多分配或分配不足的问题;并且上述方法确定后,能够自动获取实际资源配额,以及根据预设参数配置逻辑进行计算,也就无需部署人员指定相应的环境变量,因此能够大大降低部署人员的工作量以及出错的可能性。

最后,本发明还提供一种计算机可读存储介质,计算机可读存储介质上存储有计算机程序,计算机程序被处理器执行时实现如上述实施例所述的java应用的jvm运行参数的配置方法的步骤。

可以理解的是,所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台移动终端(可以是手机,平板电脑,或者手持设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:u盘、移动硬盘、只读存储器(read-onlymemory,rom)、随机存取存储器(randomaccessmemory,ram)、磁碟或者光盘等各种可以存储程序代码的介质。

由于本部分的实施例与方法部分的实施例相互对应,因此本部分的实施例请参见方法部分的实施例的描述,这里暂不赘述。

本发明实施例提供的计算机可读存储介质,存储有计算机程序,使得处理器在执行该程序时,首先是获取jvm所在容器的实际资源配额,然后根据预设参数配置逻辑计算与实际资源配额相对应的jvm运行参数。由于每次在容器启动时,都要执行上述步骤,因此,得到jvm运行参数都是根据当前容器的实际资源配额确定的,也就是说,jvm运行参数的选取是一个动态的选取过程,因此能够克服采用固定资源配置jvm运行参数所带来的资源过多分配或分配不足的问题;并且上述方法确定后,能够自动获取实际资源配额,以及根据预设参数配置逻辑进行计算,也就无需部署人员指定相应的环境变量,因此能够大大降低部署人员的工作量以及出错的可能性。

以上对本发明所提供的java应用的jvm运行参数的配置方法、装置、设备及介质进行了详细介绍。说明书中各个实施例采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似部分互相参见即可。对于实施例公开的装置而言,由于其与实施例公开的方法相对应,所以描述的比较简单,相关之处参见方法部分说明即可。应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以对本发明进行若干改进和修饰,这些改进和修饰也落入本发明权利要求的保护范围内。

还需要说明的是,在本说明书中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1