一種關(guān)于Storm使用的實時消息處理方法
【專利摘要】本發(fā)明公開了一種關(guān)于Storm使用的實時消息處理方法,屬于Storm技術(shù)領(lǐng)域,本發(fā)明要解決如何在消息處理的過程中不丟失數(shù)據(jù),而且可以使整個處理系統(tǒng)具有很好的擴展性的問題。技術(shù)方案為:所有Topology的提交在Storm的客戶端節(jié)點上進行,由Nimbus所在的控制節(jié)點分配給其他Supervisor所在的工作節(jié)點進行處理。Nimbus首先將提交的Topology進行分片,分成一個個的Task,并將Task和Supervisor相關(guān)的信息提交到 zookeeper集群上,Supervisor去zookeeper集群上認領(lǐng)自己的Task,通知自己的Worker進程進行Task的處理。
【專利說明】
一種關(guān)于Storm使用的實時消息處理方法
技術(shù)領(lǐng)域
[0001 ]本發(fā)明涉及一種Storm技術(shù)領(lǐng)域,具體地說是一種關(guān)于Storm使用的實時消息處理方法。
【背景技術(shù)】
[0002]隨著互聯(lián)網(wǎng)應(yīng)用的高速發(fā)展,企業(yè)積累的數(shù)據(jù)量越來越大,越來越多。隨著GoogleMapReduce、Hadoop等相關(guān)技術(shù)的出現(xiàn),處理大規(guī)模數(shù)據(jù)變得簡單起來,但是這些數(shù)據(jù)處理技術(shù)都不是實時的系統(tǒng),它們的設(shè)計目標也不是實時計算。畢竟實時的計算系統(tǒng)和基于批處理模型的系統(tǒng)(如Hadoop )有著本質(zhì)的區(qū)別。
[0003]但是隨著大數(shù)據(jù)業(yè)務(wù)的快速增長,針對大規(guī)模數(shù)據(jù)處理的實時計算變成了一種業(yè)務(wù)上的需求,缺少“實時的Hadoop系統(tǒng)”已經(jīng)成為整個大數(shù)據(jù)生態(tài)系統(tǒng)中的一個巨大缺失。Storm正是在這樣的需求背景下出現(xiàn)的,Storm很好地滿足了這一需求。Storm為集群組件,Storm的集群從形式上看和Hadoop的集群非常相似,也是采用主從架構(gòu)。但是在Hadoop上面運行的是MapReduce的Job,而在Storm上面運行的是Topology。它們有很大的不同。它們之間的關(guān)鍵區(qū)別是,一個MapReduceJob會有啟動、運行到最終會結(jié)束的過程,而一個Topology在啟動后,會永遠運行。在Storm的集群里面有兩種節(jié)點:控制節(jié)點和工作節(jié)點??刂乒?jié)點上面運行一個后臺進程Nimbus,它的作用類似于Hadoop里面的JobTrackeroNimbus負責在集群里面分發(fā)執(zhí)行代碼,分配工作給工作節(jié)點,并且監(jiān)控任務(wù)的執(zhí)行狀態(tài)。每一個工作節(jié)點上面運行一個叫作Supervisor的守護進程。Supervisor會監(jiān)聽分配給自己所在機器的工作,根據(jù)需要啟動/關(guān)閉工作進程。每一個工作進程執(zhí)行一個Topology的一個子集,一個運行的Topology由運行在很多機器上的很多工作進程組成。
[0004]在Storm出現(xiàn)之前,對于需要實現(xiàn)計算的任務(wù),開發(fā)者需要手動維護一個消息隊列和消息處理者所組成的實時處理網(wǎng)絡(luò),消息處理者從消息隊列中取出消息進行處理,然后更新數(shù)據(jù)庫,發(fā)送消息給其他隊列。所有這些操作都需要開發(fā)者自己實現(xiàn)。這種編程實現(xiàn)的模式存在以下缺陷:
1、單調(diào)乏味性:開發(fā)者需要花費大部分時間去配置消息如何發(fā)送,消息發(fā)送到哪里,如何部署消息的處理者,如何部署消息的中間處理節(jié)點等。如果使用Storm進行處理,那么開發(fā)者只需要很少的消息處理邏輯代碼,這樣開發(fā)者就可以專注于業(yè)務(wù)邏輯的開發(fā),從而大大提高了開發(fā)實時計算系統(tǒng)的效率;
2、脆弱性:程序不夠健壯,開發(fā)者需要自己編寫代碼以保證所有的消息處理者和消息隊列的正確運行;
3、可伸縮性差:當一個消息處理者能處理的消息達到自己能處理的峰值時,就需要對消息流進行分流,這時需要配置新的消息處理者,以讓它們處理分流消息。
[0005]對于需要處理大量消息流的實時系統(tǒng)來說,消息處理始終是實時計算的基礎(chǔ),消息處理的最后就是對消息隊列和消息處理者之間的組合。消息處理的核心是如何在消息處理的過程中不丟失數(shù)據(jù),而且可以使整個處理系統(tǒng)具有很好的擴展性,以便能夠處理更大的消息流。
【發(fā)明內(nèi)容】
[0006]本發(fā)明的技術(shù)任務(wù)是針對以上不足之處,提供一種關(guān)于Storm使用的實時消息處理方法,來解決如何在消息處理的過程中不丟失數(shù)據(jù),而且可以使整個處理系統(tǒng)具有很好的擴展性的問題。
[0007 ]本發(fā)明解決其技術(shù)問題所采用的技術(shù)方案是:
一種關(guān)于Storm使用的實時消息處理方法,在使用Storm的服務(wù)器集群中,使用Storm并依賴外部資源Zookeeper集群進行實時消息處理;Storm具有Nimbus和Supervisor,服務(wù)器集群的控制節(jié)點上部署Nimbus,服務(wù)器集群的每個工作節(jié)點上均部署Supervisor; Storm提交運行的程序為Topology ,Topology由Spout和Bolt構(gòu)成;包括如下步驟:
(1)、Topology的提交在控制節(jié)點上進行,把代碼首先存放到Nimbus所在的控制節(jié)點上,之后,把當前Storm運行的配置生成文件放到Nimbus所在的控制節(jié)點中,Nimbus所在的控制節(jié)點中同時還有序列化之后的Topo 1gy代碼文件;
(2)、Nimbus在設(shè)定Topology所關(guān)聯(lián)的Spouts和Bolts時,同時設(shè)置當前Spout和Bolt的worker進程的數(shù)目,即設(shè)置executor數(shù)目和task數(shù)目;根據(jù)worker進程的數(shù)目,盡量平均的將worker進程分配至各個工作節(jié)點運行;worker進程在哪個supervisor所在的工作節(jié)點上運行是由storm本身決定的;
(3 )、任務(wù)分配好之后,N i m b u s所在的控制節(jié)點將w ο r k e r進程的心跳信息提交到zookeeper 集群;
(4)、Supervisor所在的工作節(jié)點不斷的輪詢zookeeper集群,在zookeeper中保存了worker進程的心跳信息(所有Topology的任務(wù)分配信息、代碼存儲目錄和任務(wù)之間的關(guān)聯(lián)關(guān)系),Supervisor所在的工作節(jié)點通過輪詢zookeeper中的內(nèi)容,來領(lǐng)取自己的任務(wù),啟動worker進程運行;
(5)、一個Topology運行之后,不斷的通過Spouts來發(fā)送Stream流,通過Bolts不斷的處理接收到的Stream流,Stream流是無界的。
[0008]步驟(I)中,Topology的提交在控制節(jié)點上進行,把代碼首先存放到Nimbus所在的控制節(jié)點的inbox目錄下,之后,把當前Storm運行的配置生成文件stormconf.ser放到Nimbus所在的控制節(jié)點的stormdi st目錄中,在stormdist目錄中同時還有序列化之后的Topology代碼文件;
步驟(2)中,一個Topology的task數(shù)目的總和與executor數(shù)目的總和一致。
[0009]步驟(3)中,zookeeper集群中設(shè)置有workerbeats節(jié)點,workerbeats節(jié)點存儲了當前Topo I ogy的所有worker進程的心跳信息;
步驟(4)中,Supervisor所在的工作節(jié)點能夠不斷的輪詢zookeeper集群,在zookeeper的assignments節(jié)點中保存了所有Topology的任務(wù)分配信息、代碼存儲目錄和任務(wù)之間的關(guān)聯(lián)關(guān)系,Supervisor所在的工作節(jié)點通過輪詢zookeeper的assignments節(jié)點的內(nèi)容,來領(lǐng)取自己的任務(wù),啟動worker進程運行。
[0010]Zookeeper是一個為分布式應(yīng)用提供一致性服務(wù)的軟件,提供的功能包括:配置維護、域名服務(wù)、分布式同步、組服務(wù)。[ΟΟ?? ] Storm具有Nimbus和Supervisor,服務(wù)器集群的控制節(jié)點上部署Nimbus,服務(wù)器集群的每個工作節(jié)點上均部署Supervisor ;NimbuS負責在服務(wù)器集群里面發(fā)送代碼,分配Worker進程給工作節(jié)點,并且監(jiān)控工作節(jié)點狀態(tài);Supervisor監(jiān)聽所在工作節(jié)點的工作,根據(jù)需要啟動或關(guān)閉Worker進程;Nimbus和Supervi sor以及運行的Worker進程都把心跳信息保存在Zookeeper集群上;Nimbus根據(jù)Zookeerper集群上的心跳信息和任務(wù)運行狀況,進行調(diào)度和分配Worker進程。
[0012]Storm提交運行的程序為Topo I ogy ,Topology處理的最小的消息單位是一個Tuple,也就是一個任意對象的數(shù)組;Topo 1gy由Spout和Bo It構(gòu)成;Spout是發(fā)出Tuple的結(jié)點;Bolt能夠隨意訂閱某個Spout或者Bolt發(fā)出的Tuple; Spout和Bolt都統(tǒng)稱為component。
[0013]本發(fā)明的一種關(guān)于Storm使用的實時消息處理方法和現(xiàn)有技術(shù)相比,具有以下有益效果= Storm可以方便地在一個計算機集群中編寫與擴展復(fù)雜的實時計算,用于實時處理,保證每個消息都會得到處理;而且它很快,在一個小集群中,每秒可以處理數(shù)以百萬計的消息;并且可以使用任意編程語言來做開發(fā)。
【附圖說明】
[0014]下面結(jié)合附圖對本發(fā)明進一步說明。
[0015]附圖1為一種關(guān)于Storm使用的實時消息處理方法的Storm架構(gòu)圖。
【具體實施方式】
[0016]下面結(jié)合附圖及具體實施例對本發(fā)明作進一步說明。
[0017]本發(fā)明的一種關(guān)于Storm使用的實時消息處理方法,在使用Storm的服務(wù)器集群中,使用Storm并依賴外部資源Zookeeper集群進行實時消息處理;Storm具有Nimbus和Supervisor,服務(wù)器集群的控制節(jié)點上部署Nimbus,服務(wù)器集群的每個工作節(jié)點上均部署Supervisor ; Storm提交運行的程序為Topology,Topology由Spout和Bolt構(gòu)成;包括如下步驟:
(1)、Topology的提交在控制節(jié)點上進行,把代碼首先存放到Nimbus所在的控制節(jié)點的inbox目錄下,之后,把當前Storm運行的配置生成文件stormconf.ser放到Nimbus所在的控制節(jié)點的stormdi st目錄中,在stormdist目錄中同時還有序列化之后的Topo 1gy代碼文件;
(2)、Nimbus在設(shè)定Topology所關(guān)聯(lián)的Spouts和Bolts時,同時設(shè)置當前Spout和Bolt的worker進程的數(shù)目,即設(shè)置executor數(shù)目和task數(shù)目;根據(jù)worker進程的數(shù)目,盡量平均的將worker進程分配至各個工作節(jié)點運行;worker進程在哪個supervisor所在的工作節(jié)點上運行是由storm本身決定的;一個Topology的task數(shù)目的總和與executor數(shù)目的總和一致
(3 )、任務(wù)分配好之后,N i m b u s所在的控制節(jié)點將w ο r k e r進程的心跳信息提交到zookeeper集群;zookeeper集群中設(shè)置有workerbeats節(jié)點,workerbeats節(jié)點存儲了當前Topo I ogy的所有worker進程的心跳信息;
(4)、Supervi sor所在的工作節(jié)點能夠不斷的輪詢zookeeper集群,在zookeeper的assignments節(jié)點中保存了worker進程的心跳信息(所有Topology的任務(wù)分配信息、代碼存儲目錄和任務(wù)之間的關(guān)聯(lián)關(guān)系),Supervisor所在的工作節(jié)點通過輪詢zookeeper的assignments節(jié)點的內(nèi)容,來領(lǐng)取自己的任務(wù),啟動worker進程運行
(5)、一個Topology運行之后,不斷的通過Spouts來發(fā)送Stream流,通過Bolts不斷的處理接收到的Stream流,Stream流是無界的。
[0018]最后一步會不間斷的執(zhí)行,除非手動結(jié)束Topology。
[0019]所有Topology任務(wù)的提交必須在Storm客戶端節(jié)點上進行(需要配置storm.yaml文件),由Nimbus所在的控制節(jié)點分配給其他Supervisor所在的工作節(jié)點進行處理。Nimbus首先將提交的Topo 1gy進行分片,分成一個個的Task,并將Task和Supervi sor相關(guān)的信息提交到zookeeper集群上,Supervisor去zookeeper集群上認領(lǐng)自己的Task,通知自己的Worker進程進行Task的處理。
[0020]下面對Storm中的一些命令代碼進行說明:
一、Spout
Spout是Stream的消息產(chǎn)生源,Spout組件的實現(xiàn)可以通過繼承BaseRichSpout類或者其他Spout類來完成,也可以通過實現(xiàn)IRichSpout接口來實現(xiàn)。
[0021]public interface ISpout extends Serializable {
void open(Map conf, TopologyContext context, SpoutOutputCollectorcollector);
void close();void nextTuple();void ack(Object msgld);void fail(Object msgld);
} O
[0022]open()方法,是初始化方法。
[0023]closeO:在該spout將要關(guān)閉時調(diào)用。但是不保證其一定被調(diào)用,因為在集群中supervisor節(jié)點,可以使用kill _9來殺死worker進程。只有當Storm是在本地模式下運行,如果是發(fā)送停止命令,可以保證close的執(zhí)行。
[0024]ack(Object msgld):成功處理tuple時回調(diào)的方法,通常情況下,此方法的實現(xiàn)是將消息隊列中的消息移除,防止消息重放。
[0025]fail(Object msgld):處理tuple失敗時回調(diào)的方法,通常情況下,此方法的實現(xiàn)是將消息放回消息隊列中然后在稍后時間里重放。
[0026]nextTupleO:這是Spout類中最重要的一個方法。發(fā)射一個Tuple到Topology都是通過這個方法來實現(xiàn)的。調(diào)用此方法時,storm向spout發(fā)出請求,讓spout發(fā)出元組(tuple)到輸出器(ouput col lector)。這種方法應(yīng)該是非阻塞的,所以spout如果沒有元組發(fā)出,這個方法應(yīng)該返回。nextTuple、ack和fail都在spout任務(wù)的同一個線程中被循環(huán)調(diào)用。當沒有元組的發(fā)射時,應(yīng)該讓nextTuple睡眠一個很短的時間(如一毫秒),以免浪費太多的CPU。
[0027]繼承了BaseRichSpout后,不用實現(xiàn)close、activate、deactivate、ack、fail和getComponentConf igurat1n方法,只關(guān)心最基本核心的部分。
[0028]通常情況下(Shell和事務(wù)型的除外),實現(xiàn)一個Spout,可以直接實現(xiàn)接口IRichSpout,如果不想寫多余的代碼,可以直接繼承BaseRichSpout。
[0029]二、Bolt
Bolt類接收由Spout或者其他上游Bolt類發(fā)來的Tuple,對其進行處理。Bolt組件的實現(xiàn)可以通過繼承BasicRichBolt類或者IRichBolt接口等來完成。
[0030]prepare方法:此方法和Spout中的open方法類似,在集群中一個worker中的task初始化時調(diào)用。它提供了bolt執(zhí)行的環(huán)境。
[0031 ] declareOutputFields方法:用于聲明當前BoIt發(fā)送的TupIe中包含的字段(field),和Spout中類似。
[0032]cleanup方法:同ISpout的close方法,在關(guān)閉前調(diào)用。同樣不保證其一定執(zhí)行。
[0033]execute方法:這是Bolt中最關(guān)鍵的一個方法,對于Tuple的處理都可以放到此方法中進行。具體的發(fā)送是通過emit方法來完成的。execute接受一個tuple進行處理,并用prepare方法傳入的OutputCol lector的ack方法(表示成功)或fail (表示失敗)來反饋處理結(jié)果。
[0034]Storm提供了IBasicBolt接口,其目的就是實現(xiàn)該接口的Bolt不用在代碼中提供反饋結(jié)果了,Storm內(nèi)部會自動反饋成功。如果你確實要反饋失敗,可以拋出FailedExcept1n0
[0035]通常情況下,實現(xiàn)一個Bolt,可以實現(xiàn)IRichBolt接口或繼承BaseRichBolt,如果不想自己處理結(jié)果反饋,可以實現(xiàn)IBasicBolt接口或繼承BaseBasicBolt,它實際上相當于自動實現(xiàn)了collector, emit.ack(inputTuple) ο
[0036]三、Topology運行方式
在開始創(chuàng)建項目之前,了解Storm的操作模式(operat1n modes)是很重要的。Storm有兩種運行方式,本地運行的提交方式和分布式提交方式。
[0037]本地運行的提交方式,例:
LocalCluster cluster = new LocalClusterO;cluster.submitTopo1gy(TOPOLOGY—NAME,conf,builder.createTopology());
Thread.sleep(2000);cluster.shutdown();
分布式提交方式,例:
StormSubmitter.submitTopology(TOPOLOGY—NAME, conf, builder.createTopology0)。
[0038]需要注意的是,在Storm代碼編寫完成之后,需要打包成jar包放到Nimbus中運行,打包的時候,不需要把依賴的jar都打迚去,否則如果把依賴的storm, jar包打進去的話,運行時會出現(xiàn)重復(fù)的配置文件錯誤導(dǎo)致Topology無法運行。因為Topology運行之前,會加載本地的storm.yaml配置文件。
[0039]運行的命令如下:stormjar StormTopology.jar mainclass [args]。
[0040]storm守護進程的命令:
Nimbus: storm nimbus 啟動nimbus守護進程;
Supervisor: storm supervisor 啟動supervisor守護迪程;
UI: storm ui這將啟動stormUI的守護進程,為監(jiān)測storm集群提供一個基于web的用戶界面。
[0041 ] DRPC: storm drpc 啟動DRPC的守護進程。
[0042]storm管理命令:
JAR:storm jar topology_jar topology_class [arguments...]。
[0043]jar命令是用于提交一個集群拓撲.它運行指定參數(shù)的topology_class中的main()方法,上傳topology_jar到nimbus,由nimbus發(fā)布到集群中。一旦提交,storm將激活拓撲并開始處理topology_class中的main()方法,main()方法負責調(diào)用StormSubmitter.submitTopology O方法,并提供一個唯一的拓撲(集群)的名。如果一個擁有該名稱的拓撲已經(jīng)存在于集群中,jar命令將會失敗。常見的做法是在使用命令行參數(shù)來指定拓撲名稱,以便拓撲在提交的時候被命名。
[0044]KILL:storm kill topology_name [-w wait_time];
殺死一個拓撲,可以使用kill命令。它會以一種安全的方式銷毀一個拓撲,首先停用拓撲,在等待拓撲消息的時間段內(nèi)允許拓撲完成當前的數(shù)據(jù)流。執(zhí)行kill命令時可以通過-W[等待秒數(shù)]指定拓撲停用以后的等待時間。也可以在Storm UI界面上實現(xiàn)同樣的功能。
[0045]Deactivate:storm deactivate topology_name;
停用拓撲時,所有已分發(fā)的元組都會得到處理,spouts的nextTuple方法將不會被調(diào)用。也可以在Storm UI界面上實現(xiàn)同樣的功能。
[0046]Activate:storm activate topology_name;
啟動一個停用的拓撲。也可以在Storm UI界面上實現(xiàn)同樣的功能。
[0047]Rebalance:storm rebalance topology_name [_w wait_time] [_n worker_count] [_e component_name=executer_count]...;
rebalance使你重新分配集群任務(wù)。這是個很強大的命令。比如,你向一個運行中的集群增加了節(jié)點。rebalance命令將會停用拓撲,然后在相應(yīng)超時時間之后重分配worker,并重啟拓撲;
例:storm rebalance wordcount-topology -w 15 -η 5 -e sentence-spout=4 ~esplit_bolt=8 o
[0048]還有其他管理命令,如:Remoteconfvalue、REPL、Classpath等新建storm項目注意事項。
[0049]為了開發(fā)storm項目,classpath里面需要有storm的jar包。最推薦的方式是使用Maven,不使用maven的話可以手動把storm發(fā)行版里面的所有的jar包添加到classpath。
[0050]通過上面【具體實施方式】,所述技術(shù)領(lǐng)域的技術(shù)人員可容易的實現(xiàn)本發(fā)明。但是應(yīng)當理解,本發(fā)明并不限于上述的【具體實施方式】。在公開的實施方式的基礎(chǔ)上,所述技術(shù)領(lǐng)域的技術(shù)人員可任意組合不同的技術(shù)特征,從而實現(xiàn)不同的技術(shù)方案。
[0051]除說明書所述的技術(shù)特征外,均為本專業(yè)技術(shù)人員的已知技術(shù)。
【主權(quán)項】
1.一種關(guān)于storm使用的實時消息處理方法,其特征在于在使用Storm的服務(wù)器集群中,使用Storm并依賴外部資源Zookeeper集群進行實時消息處理;Storm具有Nimbus和Supervisor,服務(wù)器集群的控制節(jié)點上部署Nimbus,服務(wù)器集群的每個工作節(jié)點上均部署Supervisor ; Storm提交運行的程序為Topology,Topology由Spout和Bolt構(gòu)成;包括如下步驟: (1)、Topology的提交在控制節(jié)點上進行,把代碼首先存放到Nimbus所在的控制節(jié)點上,之后,把當前Storm運行的配置生成文件放到Nimbus所在的控制節(jié)點中,Nimbus所在的控制節(jié)點中同時還有序列化之后的Topo 1gy代碼文件; (2)、Nimbus在設(shè)定Topo1gy所關(guān)聯(lián)的Spouts和Bolts時,同時設(shè)置當前Spout和Bolt的worker進程的數(shù)目,即設(shè)置executor數(shù)目和task數(shù)目;根據(jù)worker進程的數(shù)目,將worker進程分配至各個工作節(jié)點運行; (3 )、任務(wù)分配好之后,N i m b u s所在的控制節(jié)點將w ο r k e r進程的心跳信息提交到zookeeper 集群; (4)、Supervisor所在的工作節(jié)點不斷的輪詢zookeeper集群,在zookeeper中保存了worker進程的心跳信息,Supervisor所在的工作節(jié)點通過輪詢zookeeper中的內(nèi)容,來領(lǐng)取自己的任務(wù),啟動worker進程運行; (5)、一個Topology運行之后,不斷的通過Spouts來發(fā)送Stream流,通過Bolts不斷的處理接收到的Stream流,Stream流是無界的。2.根據(jù)權(quán)利要求1所述的一種關(guān)于Storm使用的實時消息處理方法,其特征在于步驟(1)中,Topology的提交在控制節(jié)點上進行,把代碼首先存放到Nimbus所在的控制節(jié)點的inbox目錄下,之后,把當前Storm運行的配置生成文件stormconf.ser放到Nimbus所在的控制節(jié)點的stormdist目錄中,在stormdist目錄中同時還有序列化之后的Topo1gy代碼文件。3.根據(jù)權(quán)利要求1所述的一種關(guān)于Storm使用的實時消息處理方法,其特征在于步驟(2)中,一個Topology的task數(shù)目的總和與executor數(shù)目的總和一致。4.根據(jù)權(quán)利要求1所述的一種關(guān)于Storm使用的實時消息處理方法,其特征在于步驟(3)中,zookeeper集群中設(shè)置有workerbeats節(jié)點,workerbeats節(jié)點存儲了當前Topo1gy的所有worker進程的心跳信息; 步驟(4)中,Supervi sor所在的工作節(jié)點能夠不斷的輪詢zookeeper集群,在zookeeper的assignments節(jié)點中保存了所有Topology的任務(wù)分配信息、代碼存儲目錄和任務(wù)之間的關(guān)聯(lián)關(guān)系,Supervisor所在的工作節(jié)點通過輪詢zookeeper的assignments節(jié)點的內(nèi)容,來領(lǐng)取自己的任務(wù),啟動worker進程運行。
【文檔編號】G06F9/44GK105824618SQ201610135228
【公開日】2016年8月3日
【申請日】2016年3月10日
【發(fā)明人】張福勛, 楊培強
【申請人】浪潮軟件集團有限公司