#
???
??? 今天項(xiàng)目終于順利驗(yàn)收了,從5月到現(xiàn)在,我辛苦了大半年,終于把項(xiàng)目完成了。
?????? 這是我做得最成功的一次項(xiàng)目,我的很多想法在這個(gè)項(xiàng)目中都得到實(shí)現(xiàn),并被證明是正確的。
?????? 之后,也許去蘭州,也許去重慶,我期待著更有挑戰(zhàn)的項(xiàng)目。
?????? 把a(bǔ)funms在公司的網(wǎng)絡(luò)環(huán)境測(cè)試,現(xiàn)在的公司網(wǎng)絡(luò)環(huán)境測(cè)試真是很適合測(cè)試網(wǎng)管軟件,因?yàn)樵O(shè)備數(shù)量適中,有4臺(tái)網(wǎng)絡(luò)設(shè)備和10臺(tái)服務(wù)器,而且服務(wù)器種類齊全,有Windows、Linux、Aix、Solaris和Hp-ux。
?????? 因?yàn)樾瞧谔斓闹貥?gòu)了初始化(裝載節(jié)點(diǎn))部分的代碼,本來想測(cè)試這部分的,但后來發(fā)現(xiàn)“網(wǎng)絡(luò)發(fā)現(xiàn)程序”也有好多問題,主要集中在三點(diǎn):
?????? 1.子網(wǎng)的網(wǎng)關(guān)是否在子網(wǎng)內(nèi)(換句話說就是網(wǎng)關(guān)的IP地址是不是一定要是子網(wǎng)內(nèi)的有效IP)
?????? 2.如何確定網(wǎng)絡(luò)設(shè)備
?????? 3.如何確定網(wǎng)絡(luò)設(shè)備的port
?????? 有些問題我一時(shí)也不清楚,只待日后慢慢研究。
?????? 之后,我測(cè)試loader程序,沒問題。
?????? 今天系統(tǒng)順利通過專門組評(píng)審。對(duì)他們所提出的問題,我都作了比較專業(yè)的回答。有點(diǎn)像當(dāng)年的論文答辯一樣。沒想到這么簡(jiǎn)單,哈哈。
????
?????? 離開齊魯?shù)娜兆诱娴闹溉湛纱耍嫦肟禳c(diǎn)離開這里,因?yàn)檫€有很多事情等著我做。
??????? 今天要做一個(gè)tomcat監(jiān)視,參考了ens和華中電力的相關(guān)代碼,發(fā)現(xiàn)他們的做法都是先取到html代碼,然后從這html代碼中提取自己想要的數(shù)據(jù),這太麻煩了,我在想有沒有更好的辦法。
??????? 研究了tomcat的源碼后,終于有了發(fā)現(xiàn)。我要的數(shù)據(jù)可以通過以下代碼得到:
???????--------server information------------------?
?????? 服務(wù)器信息:ServerInfo.getServerInfo()
??????? jvm版本:System.getProperty("java.runtime.version")
??????? jvm vendor:System.getProperty("java.vm.vendor")
??????? 操作系統(tǒng):System.getProperty("os.name")
??????? 操作系統(tǒng)版本:System.getProperty("os.version")
???????--------jvm information------------------
?????? free_memory:Runtime.getRuntime().freeMemory()
?????? total_memory:Runtime.getRuntime().totalMemory()
?????? max_memory:Runtime.getRuntime().maxMemory()
?????? ---------應(yīng)用列表-------------------
????? private Element createApplications()
?{
??Element applications = null;
??try
??{
???applications = new Element("applications");
???
???MBeanServer mBeanServer = Registry.getServer();
???????? ObjectName queryHosts = new ObjectName("*:j2eeType=WebModule,*");
???????? Set hostsON = mBeanServer.queryNames(queryHosts, null);
???Iterator iterator = hostsON.iterator();
???while(iterator.hasNext())
???{
????ObjectName contextON = (ObjectName)iterator.next();
????????? String webModuleName = contextON.getKeyProperty("name");???????? ????????????
????String hostName = null;
????????? String contextName = null;
????????? if(webModuleName.startsWith("http://"))
?????????????? webModuleName = webModuleName.substring(2);
?????????
????????? int slash = webModuleName.indexOf("/");
????????? if(slash != -1)
????????? {
????????????? hostName = webModuleName.substring(0, slash);
????????????? contextName = webModuleName.substring(slash);
????????? }
????else continue;
?
????????? if("/".equals(contextName)) continue;
?????????
????????? Element oneApp = new Element("application_information");
????????? try
????????? {???????
????????????? ObjectName queryManager = new ObjectName(contextON.getDomain() + ":type=Manager,path=" + contextName + ",host=" + hostName + ",*");
????????????? Set managersON = mBeanServer.queryNames(queryManager, null);
????????????? ObjectName managerON = null;
????????????? for(Iterator iterator2 = managersON.iterator(); iterator2.hasNext();)
???????????????? managerON = (ObjectName)iterator2.next();
?
????????????? Element wmn = new Element("web_module_name");
????????????? wmn.setText(contextName.substring(1));
?????????
????????????? Element as = new Element("active_sessions");
?????????? as.setText(mBeanServer.getAttribute(managerON, "activeSessions").toString());
?????????
?????????? Element sc = new Element("session_count");
?????????? sc.setText(mBeanServer.getAttribute(managerON, "sessionCounter").toString());
?????????
?????????? Element mas = new Element("max_active_sessions");
?????????? mas.setText(mBeanServer.getAttribute(managerON, "maxActive").toString());?
?????????? oneApp.addContent(wmn);
?????????? oneApp.addContent(as);
?????????? oneApp.addContent(sc);
?????????? oneApp.addContent(mas);
?????????? applications.addContent(oneApp);
????????? }
????????? catch(Exception e)
????????? {
????????? ?System.out.println("Error in TomcatMonitor.createApplications()-2");
????????? }//end_try
???}//end_while
??}
??????? catch(Exception e)
??????? {
??????? ?System.out.println("Error in TomcatMonitor.createApplications()-1");
??????? }//end_try
??????? return applications;
?}
1.修改界面
2.完成閥值設(shè)置的代碼
3.完成tomcat和oracle的監(jiān)控
如果還有時(shí)間,就把文檔寫完。
??????? 明日項(xiàng)目要驗(yàn)收了。再想起11月1日,仍然讓我激動(dòng)。那天我給用戶演示我們的系統(tǒng),得到用戶的高度評(píng)價(jià),黃部說“沒想到你們能做得這么好”。半年來,這個(gè)項(xiàng)目的所有不順心的事都一掃而光,我用自己的努力證明我的實(shí)力。
?????
??????? 公司都不支持我把產(chǎn)品推倒重做,尤其是劉潔,不相信我在兩個(gè)月內(nèi)可以完成所有的功能。可我還是堅(jiān)持自己的觀點(diǎn)。所以,有時(shí)自己認(rèn)為是對(duì)是就一定要堅(jiān)持。
??????? 未來還有很多事等著我去做,我會(huì)繼續(xù)努力。
到12月1日,這幾天的任務(wù)安排:
1.完成架構(gòu)的修改;
2.完成Tomcat的監(jiān)視,作為“應(yīng)用節(jié)點(diǎn)”的首個(gè)例子,來測(cè)試這個(gè)新的frame
把修改后的版本定為afunms V2.0
??????? 今天對(duì)afunms進(jìn)行比較大的改動(dòng),突然,有一個(gè)問題我覺得我必須思考,我為什么作出這種架構(gòu)?我的架構(gòu)是基于什么來考慮的?
???????? 現(xiàn)在很明確的只有兩點(diǎn):
??????? 1.業(yè)務(wù)視圖??? 2.被監(jiān)視對(duì)象的標(biāo)準(zhǔn)化。
?
??????? 這兩點(diǎn)肯定是太少了,至少還應(yīng)該多點(diǎn):網(wǎng)絡(luò)智能化管理。只是現(xiàn)在我還想不出來應(yīng)該怎么做,哈哈。
??
??????? 今天去找夏部,跟他談驗(yàn)收問題,可是他又提一些新想法,什么丟包率,錯(cuò)誤率。。。真是暈倒。用戶的需求總是不斷變化,面對(duì)不斷變化的需求我們總是很無奈。其實(shí)這些數(shù)據(jù),系統(tǒng)中都有,只是我們沒有展現(xiàn)出來。這兩天把這些做完,希望下周能驗(yàn)收。這樣我們就可以回北京了。
?????? 今天和mm在QQ上視頻聊天,以前不覺得她漂亮,可是今天覺得她好漂亮哦,也許是很久沒見的原因,哈哈。希望早日看到她。
???????
?????? 我對(duì)網(wǎng)管軟件有一個(gè)很完整的想法,齊魯項(xiàng)目是我實(shí)踐這個(gè)想法的第一步,由于時(shí)間和人力的原因,我僅實(shí)現(xiàn)了1/3。今天開始我要實(shí)現(xiàn)剩下的2/3,不論是在齊魯還是回北京,我都得把它完成。
?????? 剩下的2/3主是對(duì)應(yīng)用的監(jiān)控以及如何實(shí)現(xiàn)把應(yīng)用作為與設(shè)備一樣的被監(jiān)視對(duì)象。為什么要把應(yīng)用也看成與設(shè)備一樣呢?因?yàn)楹芏嘤脩舳加挟嫵鲎约骸皹I(yè)務(wù)視圖”的需求,而如果把應(yīng)用當(dāng)成單個(gè)個(gè)體(而不是象以前,把應(yīng)用當(dāng)成設(shè)備上被監(jiān)視對(duì)象)就可以很容易實(shí)現(xiàn)“業(yè)務(wù)視圖”。
我們要實(shí)現(xiàn)三個(gè)功能:在
jsp
頁面上生成報(bào)表(包括一個(gè)表和一個(gè)圖)、生成
pdf
報(bào)表和
excel
報(bào)表。
原來的代碼雖然已經(jīng)實(shí)現(xiàn)了這些功能,但每個(gè)類的功能不明確,而且存在大量重復(fù)代碼。于是想到用設(shè)計(jì)模式來解決這個(gè)問題。起初想用裝飾模式(
Decorator Pattern
),但經(jīng)過分析,發(fā)現(xiàn)裝飾模式適合于那種需要把多個(gè)功能動(dòng)態(tài)組合在一起的情況。但對(duì)于一個(gè)
report
,我們并不需要它同時(shí)能生成
pdf
和
excel
(即不是多個(gè)功能的組合)。
橋梁模式(
Bridge Pattern
)才是最適合的。橋梁模式的用意是
"
將抽象化(
Abstraction
)與實(shí)現(xiàn)化(
Implementation
)脫耦,使得二者可以獨(dú)立地變化
"
。(
According to GoF, the Bridge Pattern is intended to "Decouple an abstraction from its implementation so that the two can vary independently"
)
類圖如下:

?
類名 | 功能 | 角色 |
AbstractionReport | 所有功能報(bào)表的父類 | 抽象化(Abstraction) |
PdfReport | 生成pdf報(bào)表文件 | 修正抽象化 (Refined Abstraction) |
ExcelReport | 生成excel報(bào)表文件 | 修正抽象化 |
JspReport | 在jsp中調(diào)用,生成報(bào)表 | 修正抽象化 |
? | ? | ? |
ImplementorReport | 所有數(shù)據(jù)報(bào)表的父類 | 實(shí)現(xiàn)化(Implementor) |
NetworkPerformanceReport | 網(wǎng)絡(luò)設(shè)備性能報(bào)表 | 具體實(shí)現(xiàn)化 (Concrete Implementor) |
ServerPerformanceReport | 服務(wù)器性能報(bào)表 | 具體實(shí)現(xiàn)化 |
PortTrafficReport | 接口流量報(bào)表 | 具體實(shí)現(xiàn)化 |
AbstractionReport的功能是生成pdf或excel文件,而ImplementorReport的功能是收集數(shù)據(jù),為生成報(bào)表作準(zhǔn)備。
AbstractionReport的子類相對(duì)固定,因?yàn)槲覀儸F(xiàn)在只要實(shí)現(xiàn)三個(gè)功能,當(dāng)然,如果以后還想再實(shí)現(xiàn)其他功能,比如生成txt報(bào)表或html報(bào)表,我們還能再擴(kuò)展,增加兩個(gè)類TxtReport和HtmlReport即可實(shí)現(xiàn)。
ImplementorReport的子類就比較多了,列出的只是其中三個(gè)。
任意一個(gè)AbstractionReport與ImplementorReport的組合都能有不同的功能。有了以上的各個(gè)類,我們就能生成各種各樣的報(bào)表,比如我們要生成一個(gè)“網(wǎng)絡(luò)設(shè)備性能”的pdf報(bào)表文件,就這么寫:
?????? AbstractionReport report = new PdfReport(new NetworkPerformanceReport());???????
?????? report.createReport();
生成excel報(bào)表文件:
?????? AbstractionReport report = new ExcelReport(new NetworkPerformanceReport());???????
?????? report.createReport();
?
生成“服務(wù)器性能報(bào)表”pdf報(bào)表文件:
?????? AbstractionReport report = new PdfReport(new ServerPerformanceReport());???????
?????? report.createReport();
?
生成“服務(wù)器性能報(bào)表”excel報(bào)表文件:
??? ??? AbstractionReport report = new ExcelReport(new ServerPerformanceReport());???????
?????? report.createReport();
??????? 在以前的項(xiàng)目中,都是用popchart(一個(gè)applet)畫,因?yàn)閜opchart比較簡(jiǎn)單,生成一個(gè)圖要寫的代碼也不多。而且,我始終覺得popchart畫出來的圖要比jfreechart好看得多。但popchart有缺點(diǎn),因?yàn)槭莂pplet,所以在有些瀏覽器中不能用,而且要想生成pdf或excel報(bào)表都不可能。
??????? 為了生成pdf和excel的報(bào)表,我最終還是放棄了popchart選擇jfreechart。今天用橋梁模式重構(gòu)了report部份代碼,可以生成pdf和excel的報(bào)表,這個(gè)我以前一直很想要的功能今天實(shí)現(xiàn)了。當(dāng)然,要感謝老聶前期對(duì)jfreechart、iText和jxl的研究,三者的完美結(jié)合實(shí)現(xiàn)了功能強(qiáng)大的Report。
?????? 橋梁模式,這個(gè)曾被我多次使用過的pattern,今天再一次證明了它的實(shí)用性。
?????? 同時(shí),download了jfreechart的demo,里面包括了所有jfreechart可以生成的圖的代碼。jfreechart本身是免費(fèi)的,但這些demo的代碼卻是收費(fèi)的,呵呵,這倒是一種很好的贏利模式,jfreechart的開發(fā)者們真夠smart!
???????
???
?前段時(shí)間,系統(tǒng)連續(xù)跑幾天,tomcat jvm內(nèi)存總在不斷減少,最多只能跑三天,memory就不夠了。
把tomcat jvm 從64m增加到128m仍不能解決問題,估計(jì)是哪個(gè)程序有問題,于是下載了JProbe來測(cè)試,
找出了幾個(gè)占內(nèi)存大的class,修改程序。情況有所好轉(zhuǎn),可是不能根本解決。
?????? 前天突然想到會(huì)不會(huì)是DBManager.java中出了問題,于是刪除了其中一些可有可無的代碼。經(jīng)過三天的測(cè)試,哈哈,果然,jvm free memory再不會(huì)持續(xù)下降了,問題得到根本解決,好高興。以前寫程序不會(huì)太注意內(nèi)存的問題,但因?yàn)橛辛舜谓?jīng)歷,我開始重視如何把程序?qū)懙酶珶捫?/font>
?????? ENS曾出現(xiàn)非常大的問題,就是跑了幾天后tomcat就自己關(guān)掉了,真可笑!還好,我的系統(tǒng)不曾出現(xiàn)過這種嚴(yán)重的問題。我對(duì)我的系統(tǒng)afunms還是很有信心的,哈哈
。發(fā)現(xiàn)整個(gè)系統(tǒng)只占不到30m的內(nèi)存,其實(shí)原來的64m是完全夠用了!
今天遇到一種極恐怖的病毒 svhost32.exe,不但是把端星的服務(wù)停了,而且有多種變種。
重裝機(jī)器也沒用,最后還是手動(dòng)刪除相關(guān)的病毒文件,機(jī)器才正常。
一下午就折騰這事,原計(jì)劃把report程序?qū)懲暌矝]寫,不但浪費(fèi)我時(shí)間,最主要是搞得我
心情極度郁悶。