工作階段總結(jié)

程序整體框架概述

所接觸的是數(shù)據(jù)采集方面的任務(wù)况鸣,整個數(shù)據(jù)采集模塊主框架被封裝在一個a.jar包之中搔驼,程序入口common通過啟動命令指定,使用nohuo與&指令將服務(wù)運(yùn)行在后臺:

 nohup java -cp 'pwd'/a.jar main.common [args]>>nohup.out &

進(jìn)入common繼續(xù)往下看:
首先關(guān)注啟動命令中所指定的args參數(shù)签赃,此參數(shù)指定配置文件路徑痪欲,(程序啟動后咬腋,a.jar文件所在目錄即為根目錄绢馍,指定路徑以此為基礎(chǔ))向瓷。通過jar包sysconfig類中定義的靜態(tài)方法,讀取cfg配置文件內(nèi)容舰涌,依次賦值給sysconfig類中的靜態(tài)變量猖任,作后續(xù)使用。
之后利用jar包Server類中的ServerRun靜態(tài)方法瓷耙,通過讀取上述sysconfig類中的port靜態(tài)變量朱躺,使用mina框架提供的socket通信方法,監(jiān)聽本機(jī)端口搁痛。

public static void ServerRun(int PORT) throws Exception {

        SocketAcceptor acceptor = new NioSocketAcceptor();
        acceptor.setReuseAddress(true);

        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
        chain.addLast("threadPool", new ExecutorFilter(Executors.newFixedThreadPool(sysconfig.socket_poolsize)));

        acceptor.setHandler(new Server());
        acceptor.getSessionConfig().setUseReadOperation(true);
        acceptor.getSessionConfig().setReadBufferSize(30000);
        acceptor.bind(new InetSocketAddress(PORT));
        
        System.out.println("Listening on port " + PORT);
        for (;;) {
            Thread.sleep(1000);
        }
    }

如此一來长搀,通過telnet連接至指定端口,就可以做到與程序進(jìn)行交互鸡典。Server類繼承mina框架的IoHandAdapter類源请,便于管理連接,[mian Iohander事件觸發(fā)機(jī)制可以參考該博文]
(https://blog.csdn.net/boonya/article/details/51583823)
當(dāng)消息被接收到時彻况,messageReceived事件被觸發(fā)谁尸,這是應(yīng)用程序需要處理輸入信息的地方。這里將首次與外部js文件產(chǎn)生調(diào)用纽甘,(關(guān)于java與js的相互調(diào)用良蛮,大家可自行查閱相關(guān)資料)而后續(xù)大量的操作均需要通過外部js代碼進(jìn)行完成,如此重要的操作自然需要一個專門的類進(jìn)行封裝悍赢。js類概要功能如下:

import javax.script.*;
public class js {
    public ScriptEngine engine = null;
    public static ScriptEngineManager manager = new ScriptEngineManager();
    public js(String args) throws Exception {
        m_args = args;
        engine = manager.getEngineByName("JavaScript");
        engine.put("engine", engine);
        engine.put("core", this);
        engine.put("args", args);
        ...
        m_files.add(sysconfig.js_run_path + sysconfig.entry_js);
    }
    public Object runfile(String filename) throws Exception {
        java.io.FileReader reader = null;
        try { 
            reader = new java.io.FileReader(filename); 
            return engine.eval(reader);
        } finally {
            try{ reader.close(); } catch(Exception e){}
        }
    }
    public Object include(String filename) throws Exception{
        return this.runfile(sysconfig.js_run_path + filename);
    }
}

簡單地說决瞳,就是通過getEngineByName初始化一個ScriptEngine,然后通過put()對變量賦值左权,通過eval執(zhí)行js程序皮胡。
了解了js類的主要方法,回過頭繼續(xù)看messageReceived方法中所作的處理涮总。

public class Server extends IoHandlerAdapter {
    @Override
    public void messageReceived(IoSession session, Object message) throws UnsupportedEncodingException {
        String buf = new String(((IoBuffer) message).array(), sysconfig.socket_recv_encode);
        buf = buf.trim();
        if (buf.length() > 0) {
            try {
                    js jengine = new js(buf);
                    jengine.engine.put("client", new Requ(session));
                    jengine.include(sysconfig.entry_js);
                }
                jengine.engine.put("input_0_0_0", buf);
                jengine.engine.eval("main(input_0_0_0)");
            } catch (Exception ex) {
                ex.printStackTrace();
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
                session.closeOnFlush();
            }
        }
    }
}

這里首先生成一個js對象,之后通過put方法將一個Requ對象與client字符串綁定祷舀,Requ對象即為負(fù)責(zé)與telnet進(jìn)行通信的實(shí)現(xiàn)對象瀑梗,包括send和recv方法烹笔。(在后續(xù)程序中通過client.send(“msg”)即可往控制臺輸出內(nèi)容今魔,方便了解程序交互運(yùn)行的過程)榔幸。
緊接著調(diào)用include方法調(diào)用執(zhí)行一個外部js文件(sysconfig.entry_js在配置文件中的值為main.js夭坪,通過include方法拼湊出文件路徑拱层,進(jìn)一步調(diào)用runfile方法執(zhí)行main.js)钠署。而事實(shí)上核蘸,mian.js里面僅僅定義了一個main(args)函數(shù)鳍怨,因此在jengine.engine.put("input_0", buf);jengine.engine.eval("main(input_0)");這兩句代碼的作用僅僅是將接收到的buf數(shù)據(jù)傳輸給main(args)執(zhí)行选酗,其中由telnet傳輸?shù)腶rgs[0]此處一般為js文件名蒿柳,args[1]為后續(xù)參數(shù)饶套。通過main(args)函數(shù)繼續(xù)調(diào)用args[0]執(zhí)行各類操作。(這么做顯得main.js多此一舉垒探,完全可以在Server類中做同樣處理妓蛮,但我想既然存在,自然是有一定的道理圾叼,畢竟架構(gòu)師的經(jīng)驗(yàn)要豐富的多)蛤克。
到此處,基本的架構(gòu)邏輯捋順夷蚊,接下來就是在此基礎(chǔ)上各種具體應(yīng)用构挤,如果有人愿意看,下一篇就選取一個常用的數(shù)據(jù)庫指標(biāo)采集進(jìn)行詳細(xì)的陳述惕鼓。

所思所得

java與js文件的互相調(diào)用配合筋现,架構(gòu)師的作用

在java程序中通過js類封裝了ScriptEngine,并將core與當(dāng)前js對象綁定呜笑。之后在執(zhí)行的各js文件中夫否,通過core.include("*.js"),就可以繼續(xù)調(diào)用執(zhí)行其他js程序叫胁。js類中還有一個重要的方法newobject(String classname)凰慈,這個方法實(shí)現(xiàn)在js腳本程序中初始化jar包中封裝的類。

    public Object newobject(String classname) throws Exception {
        return Class.forName(classname).newInstance();
    }

這樣在js腳本程序中通過Object_classname= core.newobject(classname);就可以得到classname的實(shí)例對象驼鹅。
如此一來微谓,將主要功能模塊封裝在jar包中,具體使用時則通過js程序來調(diào)用输钩,這種設(shè)計(jì)使得程序的靈活性大大提高豺型,程序后期的擴(kuò)展性也得到了保障。(ps:在學(xué)校也曾讀過一兩本關(guān)于設(shè)計(jì)模式的書买乃,淺嘗輒止姻氨,只能在以后的工作中多花功夫了)

java與telnet之間的命令傳輸

在java程序中通過Server類啟動并監(jiān)聽PORT端口,當(dāng)有一個遠(yuǎn)程端口接入剪验,就生成一個Requ對象負(fù)責(zé)通信肴焊,而根據(jù)約定前联,遠(yuǎn)程端口發(fā)送的命令格式為js文件名+" "+參數(shù)列表,解析命令字符串娶眷,通過core.include與runfile方法就可以實(shí)現(xiàn)執(zhí)行js程序并傳參的功能預(yù)期似嗤。

js奇妙體驗(yàn)

以前對js沒怎么研究過,只是初步知道是解釋型語言届宠,原生支持json烁落,語法簡單了解過。在這一個月的"使用"過程中豌注,深深體會到它的便捷與易用性伤塌,最簡單的如編寫一個js文件,代碼僅僅是一個方法幌羞,甚至只是幾個變量的初始化寸谜,而當(dāng)被eval()執(zhí)行過后,該方法就被加載到了內(nèi)存中属桦,之后就可以在其它地方直接調(diào)用執(zhí)行熊痴,產(chǎn)生一種C#擴(kuò)展方法的錯覺。

所遇到的一個問題

問題描述

在添加對postgresql數(shù)據(jù)庫指標(biāo)的采集功能時聂宾,發(fā)現(xiàn)無法采集數(shù)據(jù)果善,經(jīng)排查發(fā)現(xiàn)原因在于無法連接至postgresql數(shù)據(jù)庫。

解決問題過程中的所見所得

為什么無法連接postgresql數(shù)據(jù)庫系谐?明明代碼什么的都沒問題巾陕,自己編寫的數(shù)據(jù)庫連接測試的小程序也可以成功連接,不得不請教技術(shù)專家來解決纪他。問題描述清楚后鄙煤,老師鍵指如飛,我一個初出茅廬的小兵是眼花繚亂茶袒,再也插不上一句話梯刚。幾分鐘后老師排查出問題所在,原因很簡單薪寓,jar包沒有自動引用postgresql數(shù)據(jù)庫驅(qū)動包亡资。事后通過查看歷史命令,將大致排查過程簡單還原如下:

starce 命令跟蹤---查到數(shù)據(jù)庫連接不通
ps -ef | grep *.jar---得到程序pid
cd /proc/pid/fd ---進(jìn)入程序文件描述符文件夾
ll -h | grep *.jar---查看引用的所有jar包---發(fā)現(xiàn)沒有引用postgresql驅(qū)動jar包

解決方案

為了進(jìn)一步確認(rèn)驅(qū)動包是否可用向叉,在測試環(huán)境下進(jìn)行了一次破壞性試驗(yàn)锥腻。

cd /'home'/lib/
for name in `ls | grep *.jar$`;do `jar -xvf $name`;done
rm -rf *.jar
jar -cvf ojdbc14.jar *

由于ojdbc14.jar是一定會被引用,所以將所有的jar包解包后全部壓入ojdbc14.jar中母谎。重新運(yùn)行程序瘦黑,發(fā)現(xiàn)已經(jīng)可以正常連接至postgresql數(shù)據(jù)庫。技術(shù)與經(jīng)驗(yàn)的差距,僅僅不到10分鐘幸斥,不僅排查了問題存崖,還給出一個臨時的試驗(yàn)解決方案,當(dāng)然最終的解決是重新編譯打包程序睡毒。
事后嘗試直接改寫jar包中的META-INF/MANIFEST.MF文件,在其Class-Path后加上postgresql的包地址冗栗,但并不起作用(格式?jīng)]問題)演顾,所以請讀到此文的各位博友不吝賜教。

目前水平較低隅居,難免對各種各樣的問題理解不夠深徹钠至,還是希望各位博友多多留言交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胎源,一起剝皮案震驚了整個濱河市棉钧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涕蚤,老刑警劉巖宪卿,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異万栅,居然都是意外死亡佑钾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門烦粒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來休溶,“玉大人,你說我怎么就攤上這事扰她∈揸” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵徒役,是天一觀的道長孽尽。 經(jīng)常有香客問我,道長廉涕,這世上最難降的妖魔是什么泻云? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮狐蜕,結(jié)果婚禮上宠纯,老公的妹妹穿的比我還像新娘。我一直安慰自己层释,他們只是感情好婆瓜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般廉白。 火紅的嫁衣襯著肌膚如雪个初。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天猴蹂,我揣著相機(jī)與錄音院溺,去河邊找鬼。 笑死磅轻,一個胖子當(dāng)著我的面吹牛珍逸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播聋溜,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼谆膳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了撮躁?” 一聲冷哼從身側(cè)響起漱病,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎把曼,沒想到半個月后杨帽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗤军,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年睦尽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片型雳。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡当凡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纠俭,到底是詐尸還是另有隱情沿量,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布冤荆,位于F島的核電站朴则,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏钓简。R本人自食惡果不足惜乌妒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望外邓。 院中可真熱鬧撤蚊,春花似錦、人聲如沸损话。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至光涂,卻和暖如春庞萍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背忘闻。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工钝计, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人齐佳。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓葵蒂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親重虑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理秦士,服務(wù)發(fā)現(xiàn)缺厉,斷路器,智...
    卡卡羅2017閱讀 134,667評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,823評論 6 342
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 29,393評論 8 265
  • 月光下女子倉皇的奔跑 地上半截男人的尸體隧土,鮮血流淌 魔術(shù)師一把撲克飛揚(yáng) 跪在冰冷的地上祈禱的人 玻璃門旋轉(zhuǎn)提针,燈火輝...
    春衫袖閱讀 227評論 0 0
  • 看了朱子先生拍的這張圖,讀了他寫的深巷偶遇狗的文章曹傀,我便不由得想起曾經(jīng)我家養(yǎng)的那條狗辐脖。 我家養(yǎng)的是那種長不大的狗,...
    潤苼閱讀 316評論 0 2