模块化事件驱动处理的制作方法

文档序号:6656632阅读:124来源:国知局
专利名称:模块化事件驱动处理的制作方法
相关申请的交叉引用本申请要求于2004年8月17日提交的名为“TECHNIQUES FORDELIVERING PERS ONALIZED CONTENT WITH A REAL-TIME ROUTINGNETWORK,MODULAR EVENT-DRIVEN ARCHITECTURE,MODULAREVENT-DRIVEN PROCESSING AND VIEWER FAILOVER TESTING A SYSTEMMEMORY WHILE AN OPERATING SYSTEM IS ACTIVE”的共同待批的美国临时专利申请第60/602,539号的优先权,该申请对所有目的而言通过引用包含在此,如同全文在本文献中描述一般。
背景本公开的实施例一般涉及高性能计算以及以模块化、事件驱动的方式提供计算服务。
计算设备可能具有在其中处理请求的有限数目的资源。为了有效处理请求,设备可能需要管理资源如何可被分配给哪些请求。当资源被分配给一请求时,该请求可被处理。设备可看到由于某些原因请求大量增长。例如,为网站向众多用户供应网页的服务器可从用户接收对网页的大量请求。如果资源未以有效的方式分配给请求,则用户可看到延迟。
附图简述

图1是示出根据一个实施例的系统的高层概观的框图。
图2是示出根据一个实施例能够加密并发送传出消息的四个任务的示例的框图。
图3是示出根据一个实施例用于处理任务以及它们之间的关系的高层描述的步骤的流程图。
图4是示出根据一个实施例的管理模块的高层概观的框图。
附图仅为说明起见而描述了一些实施例。本领域中的技术人员将容易地从以下讨论中认识到,可采用此处所示的结构和方法的替换实施例。
可通过参考说明书的其余部分以及附图来实现对此处所公开的公开的本质和优点的进一步理解。
详细描述在一个实施例中,模块化驱动处理提供多个线程边界,每一线程边界包括将由单个线程为给定事件执行的功能。多个队列可被通信耦合至线程边界,使得线程边界可由可经由其路由事件的队列连接。将计算功能划分成线程边界允许对因为其相应的队列可填充而可能对负载敏感的那些部分进行标识。诸如线程等计算资源然后可基于队列深度被动态分配给线程边界。
多个任务可处于定义的关系中以提供服务,其中每一任务可与一线程边界相关联且包括用于执行特定功能的代码单元。还可提供多个服务实用程序,其中每一服务实用程序包括可能可由多个任务访问的实用程序。
在某些实施例中,任务以及它们之间所定义的关系可在系统本身外部的高层描述,且能够与该高层描述相一致。在某些实施例中,这种高层描述可使用声明性语言,诸如可扩展标记语言(XML)。该高层外部描述允许对任务及其之间的关系进行动态配置,以及对其进行认证。
图1示出了根据一个实施例的系统101的高层概观。系统101可被设置在处理信息的任何计算设备中。例如,系统101可以被包括在服务器或路由器中。
系统101提供一些功能(例如,服务)。功能可分划分成多个线程边界103,其中每一线程边界103可为所需功能封装应用程序逻辑的一部分。线程边界可由线程边界队列105连接。事件107(例如,对服务的请求、消息)可经由线程边界队列105输入至线程边界103或从中输出。
事件可以是可能需要的任何处理。事件107的一个示例是远程客户机对服务的请求。例如,客户机可请求登录,在这种情况下,系统101(例如服务器)将需要检查客户机的凭证并然后采取适当的行动。根据某些实施例,系统101可通过将其封装为事件107并经由一连串线程边界103传递它,最终输出对登录的验证或拒绝来处理该请求,其中每一线程边界能够执行小片段服务。本领域的普通技术人员考虑到本说明书可以清楚事件的各种其它示例,例如,事件可包括处理对来自数据库的记录的请求、处理传入的电子邮件消息、处理传出的经编码的数据、发送传出的出错消息、处理对网页的请求等。
诸如服务器等计算系统可能需要同时处理大量事件。从而,线程边界103之间的事件107可驻留在线程边界队列105中。在线程边界103内,单个线程可处理事件107。然而,一旦第一线程边界103完成其对事件107的处理并将事件107置于队列105中之后,另一线程可选出事件107并将其移动通过下一线程边界103。
图1示出了两个线程边界103,但可提供任何数量的线程边界。众多计算系统提供复杂的功能,它们可按需被划分成众多线程边界103。功能到线程边界103的划分以及要使用的线程边界103的数目可以不同。本领域的普通人员考虑到本说明书时可以清楚众多变型。
功能到线程边界103的划分允许标识由于其相应的线程边界队列105可填充而可能对负载敏感的那些部分。在某些实施例中,资源分配模块109监视线程边界队列105,并基于队列深度将计算资源分配给相应的的线程边界103。例如,可确定第一队列105和第二队列105中所保存的事件的数目。资源可基于第一队列105和第二队列105中分别保存的事件的数目来分配。例如,如果第一队列105长于第二队列105,则更多资源可被分配给第一线程边界103。从而,线程边界103的负载可用于确定如何动态分配资源。尽管描述了队列长度,但可以理解,可使用用于确定负载的其它技术,诸如使用正由线程边界103处理的事件的数量。在图1中所示的实施例中,资源分配模块109可被集中化,从而与由线程边界103和队列105封装的应用程序逻辑分开。
在某些实施例中,资源分配模块109根据线程边界入站(inbound)队列105的长度或根据所需的其它度量将来自线程池111的线程分配给线程边界103。如相关领域的普通技术人员可以理解的,每一事件107可由线程边界103内的单个线程(或多个线程)处理。多个事件107可经由同一边界103并行处理,且这样的并行事件107处理可如需由多个线程(在一个实施例中,仅仅每个事件107一个线程)执行。
因此,系统101中可能成为瓶颈的部分可接收更多资源,从而平滑了应用程序流并改进了性能。由于分配可以是动态的,因此资源分配模块109可响应于变化的条件。如果例如系统101接收大量的某一类型的请求,正常不会是瓶颈的部分可能变得过载。在这样的情况下,资源分配模块109可通过动态更改计算资源分配来相应地作出反应。
这提供了优点,因为处理到线程边界的划分可以不涉及将单个请求分配给然后为该请求执行所有的处理的一个线程。按照每一请求可能需要的资源,每一请求可以不被相同地对待。系统101可将其自身调节到在事件可排成队列的线程边界处建立的负载。因此,系统101的内部性能可被监视,并可响应于负载来调节。
而且,系统101可使用线程边界的队列的队列长度来确定将资源分配到哪里。这允许系统101在没有引入关于如何对事件区分优先级的复杂功能的情况下确定将资源分配到哪里。
可以理解,尽管资源分配模块109可被示为单个实体,但作为此处所使用的术语,资源分配模块109指的是可被实现为软件、硬件、固件或这三者的任何组合的功能的集合。当资源分配模块109可被实现为软件时,它可被实现为单机程序,但也可按照其它方式实现,例如作为较大程序的一部分、作为多个单独程序、或者作为一个或多个静态或动态链接库。
如图1中所示,由每一线程边界103封装的功能可由一个或多个任务113执行。作为此处可使用的术语,任务113可包括用于执行特定功能的任何代码块。多个任务113可被包含在链中以提供所需的计算服务。
图2示出了能够加密以及发送消息的四个任务113的简单示例。要被加密和发送的输入消息201可由任务1接收,任务1检查目的地地址的有效性。如果目的地地址有效,则任务3加密输入消息201,而任务4将所加密的消息203作为输出发送给该目的地地址。另一方面,如果目的地地址无效,则任务2创建任务4作为输出消息203发送给起始地址的适当的出错消息。由这四个任务提供的功能如有所需可以是大得多的计算系统的一部分。
回到图1,任务113可以位于比线程边界103粒度更精细的层次上。多个任务113可以在单个线程边界103内封装,尽管线程边界103也有可能仅包含单个任务113。特定的任务113可被分配给特定的线程边界103。例如,图1示出任务1和2被封装在线程边界1内,任务3-5被封装在线程边界2内。在其它实施例中,任务1-5可在两个以上线程边界103之间划分,或者如有所需所有五个任务可被封装在单个线程边界内。根据各个实施例,存在将任务113分配到线程边界的多种可能性。相关领域的普通技术人员在考虑到本说明书时可以清楚,任务113与线程边界103之间的关系可如所需地由配置改变来设置和修改。
如图1中所示,不是所有所需的功能都可由任务113执行。例如,某些功能可由服务实用程序115执行,服务实用程序115可以是可由多个任务113使用的实用程序。除通过集中化标准实用程序来创造效率以外,服务实用程序115添加另一层灵活性。在其中任务113经由接口访问服务实用程序115的实施例中,有可能在不更改依赖于服务115的任何任务113的情况下交换服务115的实现。例如,如果需要众多任务113来写入日志文件,则可提供记入日志服务。任务113可经由服务实用程序115访问记入日志服务。服务115可存储状态,因此可由多个任务113为事件使用。
服务实用程序115可用作事件107的发起源。例如,当客户机发出请求时,网络协议服务115可负责将请求打包成事件107,并将其插入到适当的线程边界队列105内,以便使请求进入任务流。而事件107可由服务实用程序115创建,并传递给任务113以便处理,任务一般修改现有的事件107并将它们转发给其它任务113。
在某些实施例中,服务实用程序115可存储状态,而任务113可以是无状态(stateless)的。例如当前注册的用户的列表一般可由服务115控制。任务113可通过调用服务115上的方法来访问该列表。尽管任务113被描述为无状态的,但在某些实施例中,任务113可存储状态。
在一个实施例中,任务113可以不创建线程或了解哪些线程可以正在控制内部任务113过程。另一方面,服务实用程序115可以是线程安全的,因为它们可由运行在不同线程边界103中的多个任务113访问。因此,服务实用程序115可由多个线程访问。
何时利用任务113以及何时使用服务115可以不同。在某些实施例中,任务可以尽可能多地被使用。在这些实施例中,服务115可供穿过(cut across)众多任务113的实用程序、发起事件107的组件或管理状态的组件使用。在其它实施例中,任务113和/或服务实用程序115可按所需为更多或更少目的而使用。相关领域的普通技术人员在考虑到本说明书时可以清楚,术语“任务”和“服务”可仅在此处用于描述各种功能。对这些功能的这种特定命名可能不是强制性或重要的,实现各种实施例的机制和/或其特征可具有不同的名字、划分和/或格式。
如上所述,多个任务113可处于定义的关系中以便为服务提供所需功能。任务113之间所定义的关系可取决于要提供的功能。例如,取决于所需功能,任务113可被不同地安排。如上所述,任务113可接收事件107作为输入,在其上执行操作,并将(可能经变换的)事件传递给其它任务113以便进一步处理。任务113可基于事件107的内容或其它因素作出关于如何处理事件107和/或将其传到哪里的决定。
特定任务113可能能够接收特定输入,执行特定处理以及发送特定输出。任务113可使用0个或多个输入(换言之,即任务从中接收事件107形式的数据的源)以及0个或多个输出来处理代码,经由这些输出,任务113在处理之后发送事件107。与任务113相关联的输入、处理和输出可被认为是为任务113定义契约。源契约指定经由任务113的输入接收的事件107上的约束。宿契约描述任务113对通过其的事件107作出的改变。术语“输入”、“输出”、“源契约”以及“宿契约”是语言学上的术语,此处用来描述底层功能。可构想用于描述这样的方面和功能的其它名字。
为了示出源契约和宿契约的示例,客户机可通过将事件107(即,认证请求)发送给系统101(例如,服务器)来请求对用户的认证。为示例起见,假定事件107包含名为“用户名”的串、名为“口令”的串。该事件107可被传递给确认器任务113,该任务的源契约指定它接收名为“口令”的串以及名为“用户名”的串。任务113可使用这些串来认证用户。认证结果可被传递给下游的各个任务113,而确认器任务113的宿契约指定名为“有效”的布尔逻辑被添加到事件107。在其它情况中,任务113的宿契约可从事件107中移除项。
在某些实施例中,任务113及其之间所定义的关系可在系统本身外部的高层描述,并根据该高层描述配置。在某些实施例中,该高层描述可使用声明性语言,诸如可扩展标记语言(XML)。该高层外部描述可被存储在例如XML配置文件中。
该高层外部描述允许对任务113及其之间关系进行动态配置,以及对其极性认证。如相关领域的普通技术人员在考虑到本说明书时容易清楚的,任务113及其之间所定义的关系的高层描述可包括任务113的功能、输入和输出、源契约和宿契约、以及多个任务113可关联在一起来提供所需功能的方式、和任务113到线程边界103的分配的方式的描述。在某些实施例中,可在高层描述中包括更多或更少信息。
图3示出了根据一个实施例用于处理任务113及其之间关系的高层描述的步骤。在步骤301中,系统101读取高层描述(例如,从XML配置文件)。在步骤303中,系统101相应地动态配置多个任务。
对任务113和/或任务113之间的关系的动态修改可通过对高层描述进行相应修改来进行。在步骤305中,系统101可响应于对高层描述的相应修改来动态修改任务113。此外,在步骤307和309中,系统101可响应于对高层描述的相应修改来动态修改多个任务113之间关系、或任务113到线程边界103的分配。
在步骤311中,也可使用高层描述来自动确定任务113之间所定义的关系是否在逻辑上是一致的。这样的判定例如可包括对源和宿契约的验证。
图4示出了根据一个实施例的管理模块401的高层概观。如图4中所示,在某些实施例中,任务113、服务实用程序115和或线程边界103可被实现为使得这些组件可经由管理模块401来监视和控制。在这样的实施例中,任务113和/或其它组件可被通信地耦合至管理模块401,且这些任务或其它组件的属性(例如,活动连接的数目)可例如经由图形用户界面405或命令行407或在适当时经由配置文件由管理模块401监视或动态修改。
在这样的一个实施例中,组件与管理模块401之间的上述通信可经由Java管理扩展(JMX)的MBean接口来执行。在这样的实施例中,任务113、服务实用程序115和/或线程边界103可以是MBean的实现,因此自动包括向在这样的实施例中被建立在JMX顶部的管理模块401展示的MBean接口。
JMX将组件的主管、管理和监视与组件本身分开。这允许对应用程序的管理前端是可交换的。作为示例,诸如服务器等计算系统可包括以基于web的图形用户界面405以及用于监视和控制组件的命令行界面407两者打包的管理模块401。这些界面405、407可使用由JMX定义的规则和接口按照本领域的普通技术人员在考虑本说明书时清楚的方式独立开发。这些界面405、407可随后用于以本领域的普通技术人员在考虑本说明书时同样清楚的方式来监视和动态配置任务113、服务实用程序115和/或线程边界403。当然,如有所需,可在除JMX以外的开发环境中实现其它实施例。
如本领域的技术人员可以理解的,本公开可具体化成其它具体形式,而不背离其精神或基本特征。同样,对模块、特征、属性、方法和其它方面的具体命名和划分可能不是强制性或重要的,且实现各实施例或其特征的机制可具有不同的名字、划分和/或格式。而且,如本领域的普通技术人员所清楚的,本公开的模块、特征、属性、方法和其它方面可被实现为软件、硬件、固件或这三者的组合。只要组件可被实现为软件,该组件就可被实现为单机程序、较大程序的一部分、多个单独程序、静态或动态链接库、内核可加载模块、设备驱动程序和/或按照现在或将来计算机编程领域中的技术人员所已知的每一个和任何其它方式。此外,各实施例在任何方面都决不限于任何特定编程语言或限用于任何特定操作系统或环境。从而,本公开旨在对在所附权利要求书中所述的本公开的范围是说明性而非限制性的。
在一个实施例中,术语“和/或”可指示可使用由“和/或”连接的元素的任何组合。例如,使用“和/或”的短语中的两个单词或表示可意味着其中一个或另一个或这两者。在一个实施例中,术语“基本上”可意味着可被指定的大多数但不是全部,或者是可被指定的全部。在一个实施例中,术语“能够”可意味着被配置、适于、可以等。例如,术语“能够执行一动作”可意味着一元素可能可以执行动作、可被配置成执行该动作和/或可适于执行该动作。
各实施例可按照软件或硬件或两者组合中的控制逻辑的形式来实现。控制逻辑可作为适于指导信息处理设备执行一个实施例中所公开的一组步骤的多条指令被存储在信息存储介质中。基于本公开以及此处所提供的教导,本领域中的普通技术人员可以理解实现各实施例的其它方式和/或方法。
以上描述是说明性而非限定性的。当本领域的技术人员仔细阅读本公开之后,可以清楚本公开的众多变化。本公开的范围从而不应参考以上描述来确定,而是应参考待批的权利要求书以及其全部范围或等效技术方案来确定。
权利要求
1.一种用于处理事件的方法,所述方法包括确定多个线程边界中的第一线程边界处的负载,其中所述多个线程边界能够为一个或多个事件执行服务,其中所述多个线程边界中的每一线程边界包括至少一个任务,所述至少一个任务与所述至少一个任务能够执行的所述服务的至少一部分相关联;以及基于所确定的负载将一个或多个资源动态分配给所述第一线程边界,其中所述一个或多个资源允许所述第一线程边界的所述至少一个任务执行所述服务的与所述至少一个任务相关联的所述至少一部分。
2.如权利要求1所述的方法,其特征在于,所述负载是基于所述第一线程边界需要处理的事件的数目。
3.如权利要求2所述的方法,其特征在于,还包括提供多个线程边界队列,其中所述第一线程边界包括能够保存所述多个事件的第一线程边界队列。
4.如权利要求3所述的方法,其特征在于,所述负载是基于正保存在所述线程边界队列中的事件的数目来确定的。
5.如权利要求2所述的方法,其特征在于,所述第一线程边界能够在所述多个事件上执行所述服务的至少一部分。
6.如权利要求2所述的方法,其特征在于,还包括为所述多个线程边界中的第二线程边界确定第二负载;以及基于所确定的第二负载将第二组一个或多个资源动态分配给所述第二线程边界,其中所述第二组一个或多个资源允许所述第二线程边界的至少一个任务执行所述服务的至少第二部分。
7.如权利要求6所述的方法,其特征在于,所述第二负载是基于所述第二线程边界需要处理的第二事件的数目。
8.如权利要求6所述的方法,其特征在于,所述第一线程边界的负载以及所述第二线程边界的第二负载用于确定多少资源被分配给所述第一线程边界和所述第二线程边界。
9.如权利要求1所述的方法,其特征在于,所述将一个或多个资源动态分配给所述第一线程边界还包括基于所述负载将线程分配给所述第一线程边界,每一分配的线程执行所述服务的与其所分配的线程边界相关联的所述至少一部分。
10.如权利要求1所述的方法,其特征在于,所述多个线程边界中的每一个的至少一个任务具有已定义的关系以便为所述一个或多个事件执行所述服务。
11.如权利要求1所述的方法,其特征在于,所述一个或多个事件中的一个事件由所述多个线程边界处理以便为所述事件执行所述服务。
12.如权利要求1所述的方法,其特征在于,所述一个或多个事件中的第一事件和第二事件在所述第一线程边界中被并行处理。
13.一种用于处理事件的计算机系统,所述计算机系统包括多个线程边界,其中所述多个线程边界能够执行服务,其中所述多个线程边界中的第一线程边界包括能够执行所述服务的至少一部分的至少一个任务;耦合至所述线程边界的多个线程边界队列,其中所述第一线程边界包括能够保存一个或多个事件以便路由到所述第一线程边界的第一线程边界队列;以及能够基于所述第一线程边界队列的第一线程边界队列深度将一个或多个资源分配给所述第一线程边界的资源分配模块,其中所述第一线程边界队列深度是基于正保存在所述第一线程边界队列中的事件的数目。
14.如权利要求13所述的系统,其特征在于,所分配的一个或多个资源允许所述第一线程边界的至少一个任务为正保存在所述第一线程边界队列中的多个事件执行所述服务的所述至少一部分。
15.如权利要求13所述的系统,其特征在于,所述多个线程边界中的第二线程边界包括保存第二多个事件的第二线程边界队列,其中所述资源分配模块能够基于所述第一线程边界队列深度和所述第二线程边界队列深度将第一组资源分配给所述第一线程边界并将第二组资源分配给第二线程边界,其中所述第一线程边界队列深度是基于正保存在所述第一线程边界队列中的事件的数目,所述第二线程边界队列深度是基于正保存在所述第二线程边界队列中的第二事件的数目。
16.如权利要求13所述的系统,其特征在于,所述一个或多个资源包括一个或多个线程,其中所述一个或多个线程基于所述第一线程边界队列深度被分配给所述第一线程边界。
17.如权利要求16所述的系统,其特征在于,所分配的每一线程为所述多个事件执行所述第一线程边界内的至少一个任务。
18.如权利要求16所述的系统,其特征在于,还包括线程池,包括要基于线程边界队列深度而被分配给线程边界的所述一个或多个线程,所述线程池被耦合至所述资源分配模块。
19.如权利要求13所述的系统,其特征在于,所述多个任务中的每一个都是无状态的。
20.如权利要求13所述的系统,其特征在于,还包括能够提供实用程序的一个或多个服务实用程序,其中所述多个线程边界中的每一个中的至少一个任务可使用所述一个或多个服务实用程序中的一个服务实用程序来执行所述服务的其部分。
21.如权利要求20所述的系统,其特征在于,所述一个或多个服务实用程序的至少其中之一是有状态的。
22.如权利要求13所述的系统,其特征在于,所述多个线程边界的所述至少一个任务具有已定义的关系以便于为所述一个或多个事件执行所述服务。
23.如权利要求13所述的服务,其特征在于,所述多个事件中的一个事件由所述多个线程边界处理以便为所述事件执行所述服务。
24.如权利要求23所述的系统,其特征在于,所述事件从所述第一线程边界传递给所述第二线程边界的第二线程边界队列,使得所述第二线程边界可接下来处理所述事件。
25.如权利要求13所述的系统,其特征在于,所述一个或多个事件中的第一事件和第二事件在所述第一线程边界中被并行处理。
26.一种用于处理的计算机系统,所述计算机系统包括包括至少一个任务的第一线程边界,其中所述第一线程边界中的第一任务包括执行第一功能的处理功能;包括至少一个任务的第二线程边界,其中所述第二线程边界中的第二任务包括执行第二功能的处理功能;耦合至所述第一线程边界的第一线程边界队列;耦合至所述第二线程边界的第二线程边界队列,其中所述第二线程边界队列连接所述第一线程边界与所述第二线程边界,使得所述一个或多个事件经由所述第二线程边界队列从所述第一线程边界路由到所述第二线程边界;以及能够将一个或多个资源分配给所述第一和第二线程边界的资源分配模块,其中一个或多个资源允许第一和第二任务执行其第一和第二功能,其中所述一个或多个资源基于所述第一线程边界队列的第一线程边界队列深度以及所述第二线程边界队列的第二线程边界队列深度被分配给所述第一和第二线程边界,所述第一线程边界接收所述一个或多个资源中的第一组资源,所述第二线程边界接收所述一个或多个资源中的第二组资源。
27.如权利要求26所述的系统,其特征在于,所述一个或多个资源包括能够处理所述第一任务的第一功能或所述第二任务的第二功能的线程。
28.如权利要求27所述的系统,其特征在于,还包括线程池,包括要基于所述第一和第二线程边界队列深度而被分配给所述第一和第二线程边界的所述一个或多个线程。
29.如权利要求26所述的系统,其特征在于,所述第一和第二任务是无状态的。
30.如权利要求26所述的系统,其特征在于,还包括一个或多个服务实用程序,其中服务实用程序包括可由所述第一任务或第二任务在执行所述第一功能或所述第二功能时访问的实用程序。
31.如权利要求30所述的系统,其特征在于,所述一个或多个服务实用程序的至少其中之一是有状态的。
32.如权利要求26所述的系统,其特征在于,所述第一线程边界中的至少一个第一任务和所述第二线程边界中的至少一个任务具有已定义的关系以便为所述事件执行基于所述第一功能和第二功能的总体功能。
33.如权利要求26所述的系统,其特征在于,所述事件由所述多个线程边界处理以便为所述事件执行由所述第一和第二功能定义的总体功能。
34.如权利要求26所述的系统,其特征在于,所述一个或多个事件中的第一任务和第二任务被并行处理。
全文摘要
多个线程边界中的每一个包括要由单个线程为给定事件执行的功能。经由其可路由事件的多个队列可被耦合至线程边界。多个任务可按照定义的关系配置,每一任务与一线程边界相关联,且包括用于执行特定功能的代码单元。资源可基于队列深度被分配给线程边界。
文档编号G06F9/46GK101040261SQ200580027383
公开日2007年9月19日 申请日期2005年8月15日 优先权日2004年8月17日
发明者K·E·鲁默哈特, T·塔特尔, J·S·利克, J·J·贝內韦德, C·E·卡诺, A·黄 申请人:肖分析有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1