參加工作的第一個月,我開始寫下第一篇博客

来源:https://www.cnblogs.com/LeeMouRen/archive/2018/05/06/8992509.html
-Advertisement-
Play Games

參加工作 關於從學生到職場的轉變與心態起伏,已然有許多文筆好的朋友感嘆過,我想自己作為一個平凡的人,相較他人也不會有更為特別的感受,自然也就不值當多說。只簡單聊聊自身的情況,1月份畢業於非電腦專業,3月底檔案上的職業欄從 變成了 手動滑稽,編程功底相比電腦專業的各位前輩有較大差距,但這就是我職業 ...


參加工作

關於從學生到職場的轉變與心態起伏,已然有許多文筆好的朋友感嘆過,我想自己作為一個平凡的人,相較他人也不會有更為特別的感受,自然也就不值當多說。只簡單聊聊自身的情況,1月份畢業於非電腦專業,3月底檔案上的職業欄從學生變成了軟體開發高級工程師手動滑稽,編程功底相比電腦專業的各位前輩有較大差距,但這就是我職業生涯的起點。
進入部門一個月,接觸的東西大多都是在學校聽過但沒有用過的,考慮到腦容量的問題,防止以後持續的東忘西,終於決定將一部分通用的技術或理念或心得記錄下來,就從現在開始。

程式整體框架概述

我所接觸的是數據採集方面的任務,整個數據採集模塊主框架被封裝在一個a.jar包之中,程式入口common通過啟動命令指定,使用nohuo與&指令將服務運行在後臺:

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

進入common繼續往下看:
首先關註啟動命令中所指定的args參數,此參數指定配置文件路徑,(程式啟動後,a.jar文件所在目錄即為根目錄,指定路徑以此為基礎)。通過jar包sysconfig類中定義的靜態方法,讀取cfg配置文件內容,依次賦值給sysconfig類中的靜態變數,作後續使用。
之後利用jar包Server類中的ServerRun靜態方法,通過讀取上述sysconfig類中的port靜態變數,使用mina框架提供的socket通信方法,監聽本機埠。

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連接至指定埠,就可以做到與程式進行交互。Server類繼承mina框架的IoHandAdapter類,便於管理連接,[mian Iohander事件觸發機制可以參考該博文]
(https://blog.csdn.net/boonya/article/details/51583823)
當消息被接收到時,messageReceived事件被觸發,這是應用程式需要處理輸入信息的地方。這裡將首次與外部js文件產生調用,(關於java與js的相互調用,大家可自行查閱相關資料)而後續大量的操作均需要通過外部js代碼進行完成,如此重要的操作自然需要一個專門的類進行封裝。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執行js程式。
瞭解了js類的主要方法,回過頭繼續看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對象即為負責與telnet進行通信的實現對象,包括send和recv方法。(在後續程式中通過client.send(“msg”)即可往控制台輸出內容,方便瞭解程式交互運行的過程)。
緊接著調用include方法調用執行一個外部js文件(sysconfig.entry_js在配置文件中的值為main.js,通過include方法拼湊出文件路徑,進一步調用runfile方法執行main.js)。而事實上,mian.js裡面僅僅定義了一個main(args)函數,因此在jengine.engine.put("input_0", buf);jengine.engine.eval("main(input_0)");這兩句代碼的作用僅僅是將接收到的buf數據傳輸給main(args)執行,其中由telnet傳輸的args[0]此處一般為js文件名,args[1]為後續參數。通過main(args)函數繼續調用args[0]執行各類操作。(這麼做顯得main.js多此一舉,完全可以在Server類中做同樣處理,但我想既然存在,自然是有一定的道理,畢竟架構師的經驗要豐富的多)。
到此處,基本的架構邏輯捋順,接下來就是在此基礎上各種具體應用,如果有人願意看,下一篇就選取一個常用的資料庫指標採集進行詳細的陳述。

所思所得

java與js文件的互相調用配合,架構師的作用

在java程式中通過js類封裝了ScriptEngine,並將core與當前js對象綁定。之後在執行的各js文件中,通過core.include("*.js"),就可以繼續調用執行其他js程式。js類中還有一個重要的方法newobject(String classname),這個方法實現在js腳本程式中初始化jar包中封裝的類。

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

這樣在js腳本程式中通過Object_classname= core.newobject(classname);就可以得到classname的實例對象。
如此一來,將主要功能模塊封裝在jar包中,具體使用時則通過js程式來調用,這種設計使得程式的靈活性大大提高,程式後期的擴展性也得到了保障。(ps:在學校也曾讀過一兩本關於設計模式的書,淺嘗輒止,只能在以後的工作中多花功夫了)

java與telnet之間的命令傳輸

在java程式中通過Server類啟動並監聽PORT埠,當有一個遠程埠接入,就生成一個Requ對象負責通信,而根據約定,遠程埠發送的命令格式為js文件名+" "+參數列表,解析命令字元串,通過core.include與runfile方法就可以實現執行js程式並傳參的功能預期。

js奇妙體驗

以前對js沒怎麼研究過,只是初步知道是解釋型語言,原生支持json,語法簡單瞭解過。在這一個月的"使用"過程中,深深體會到它的便捷與易用性,最簡單的如編寫一個js文件,代碼僅僅是一個方法,甚至只是幾個變數的初始化,而當被eval()執行過後,該方法就被載入到了記憶體中,之後就可以在其它地方直接調用執行,產生一種C#擴展方法的錯覺。

所遇到的一個問題

問題描述

在添加對postgresql資料庫指標的採集功能時,發現無法採集數據,經排查發現原因在於無法連接至postgresql資料庫。

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

為什麼無法連接postgresql資料庫?明明代碼什麼的都沒問題,自己編寫的資料庫連接測試的小程式也可以成功連接,不得不請教技術專家來解決。問題描述清楚後,老師鍵指如飛,我一個初出茅廬的小兵是眼花繚亂,再也插不上一句話。幾分鐘後老師排查出問題所在,原因很簡單,jar包沒有自動引用postgresql資料庫驅動包。事後通過查看歷史命令,將大致排查過程簡單還原如下:

starce 命令跟蹤---查到資料庫連接不通
ps -ef | grep *.jar---得到程式pid
cd /proc/pid/fd ---進入程式文件描述符文件夾
ll -h | grep *.jar---查看引用的所有jar包---發現沒有引用postgresql驅動jar包

解決方案

為了進一步確認驅動包是否可用,在測試環境下進行了一次破壞性試驗。

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中。重新運行程式,發現已經可以正常連接至postgresql資料庫。技術與經驗的差距,僅僅不到10分鐘,不僅排查了問題,還給出一個臨時的試驗解決方案,當然最終的解決是重新編譯打包程式。
事後嘗試直接改寫jar包中的META-INF/MANIFEST.MF文件,在其Class-Path後加上postgresql的包地址,但並不起作用(格式沒問題),所以請讀到此文的各位博友不吝賜教。

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 項目開發中,大家都會使用日誌框架(LogBack, log4j , java.util.logging 等)。下麵來簡單的瞭解一下日誌框架的大體設計思路。 類圖: ...
  • Spring介紹 Spring的核心是一個輕量級(Lightweight)的容器(Container),它是實現IoC(Inversion of Control)容器和非入侵性(No intrusive)的框架,並提供AOP(Aspect-oriented programming)概念的實現方式;提 ...
  • 技巧提示:mysql讀寫分離搭建好之後,配合nginx的負載均衡,可以高效的mysql的集群性能,同時免去麻煩的query分流。比如,sever1收到的請求就專門鏈接slave1從mysql讀取數據,配合nginx的反向代理實現的分流,就可以優雅的把mysql的query請求分壓到不同的mysql- ...
  • 1.服務註冊與發現基礎架構 註冊中心: 接受服務提供者的註冊、存儲服務提供者的服務信息 ,比如ip 埠號 服務名這些信息; 並且與微服務保持心跳,如果心跳不能保持則註銷該實例。 所以註冊中心主要提供服務提供者信息的存儲,另外與服務提供者保持心跳以監控服務提供者的存活。 服務提供者: 向註冊中心提供 ...
  • 1.微服務技術選型圖如下圖所示: 2.如何進行微服務架構設計: 深入業務功能, 滿足功能性需求 非功能性需求關註擴展性,穩定性。可維護性,伸縮性,高可用,高性能 堅持kiss原則,防止簡單問題複雜化 註: 可伸縮性是指系統通過增加或減少硬體水平從而提升或降低系統性能的難易程度。可伸縮性分為scale ...
  • 責任鏈模式 一.什麼是責任鏈模式? 責任鏈模式為請求創建一個接受者對象的鏈,這種模式給予請求的類型,對請求的發送者和接收者進行解耦.(將接受者對象連成一條鏈,並且在該鏈上傳遞請求,直到有一個接受者對象處理它,通過讓更多對象有機會處理請求,避免了發送者和接受者之間的耦合度)這種類型的設計模式屬於行為型 ...
  • 單例模式 一.什麼是單例模式? 單例模式是java中最簡單的設計模式之一,屬於創建型設計模式,這種模式涉及到一個的單一的類,該類負責創建自己的對象,這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。(1.單例類只能有一個實例,2.單例類必須自己創建自己唯一實例,2.單例類 ...
  • 模板模式和鉤子函數 一.什麼是模板模式? 定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變一個演算法的結構就能重新定義該演算法的某些特定步驟,模板模式屬於設計模式中的行為模式。 二.如何實現模板模式? 三.模板模式的實現要素? 準備一個抽象基類,將部分邏輯以具體方法的形式 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...