2015年2月4日 星期三

Gradle & Nexus

Logdown -> http://villebez.logdown.com/posts/2015/01/27/gradle
最近為了改善程式庫相依、專案建置、佈署效率與正確的版本控管,所以研究了 Gradle 自動化工具。
另外,為了做部門的 Local Repository ,方便上傳、使用自行開發的 lib,所以建置了 Nexus 。
關於Nexus的安裝啟用,官網 nexus-book 已經有很詳細的參考說明了,
step by step就可以執行一個基本的Repository Server了。
推薦qrtt1在Codedata發表一系列關於Gradle的文章,【認識 Gradle】
從ant -> Maven -> Gradle,利用範例講解的很詳細。
如果要了解專案相依管理,可以直接跳到這篇 【認識 Gradle】(7)Java 專案相依管理
這篇並不是要介紹這兩個工具,
只是個紀錄,紀錄用了Gradle遇到的問題與解決方式,所以請先對Gradle有初步的了解。
這些問題可能也是大家剛開始使用常會遇到的,希望可以幫到你/妳。
Q1: apply plugin 是什麼?? 有哪些可以使用
A1.1: 類似於import, include,也就是 reuse logic
A1.2: 請參考這裡,更進階可以自行客製Plugin
Q2: 程式中文註解,造成編譯失敗
A2: 請服用~ compileJava.options.encoding = 'UTF-8'
Q3: 在MVNrepository找不到想要的libs
A3: 幾個方法,1. 上傳到自行建置的Repository Server,2. include local jar file
Q4: 什麼是providedCompile,跟compile有什麼差別
A4: providedCompile也是編譯時,專案會用到的jar,但跟compile最大的差異在,宣告為providedCompile的jar file不會打包到war file,所以當我的專案需要用到tomcat-catalina libs時,如果將它宣告為compile,則war檔在tomcat server執行時會造成library conflict錯誤。
Q5: 如何改變webapp dir
A5: project.webAppDirName = 'WebContent'

Java Thread Pool

Logdown -> http://villebez.logdown.com/posts/2014/10/16/238021
這篇主要還是延續前篇 JAVA POP3 Server 實作,改善效能問題。
其實我的問題就如同 Gossip@Openhome 的 Design Pattern: Thread Pool 模式 教學說明的第一段,如下:
「在 Thread-Per-Message 模式 中,每次請求來到,就建立一個新的執行緒,用完就不再使用,然後執行緒的建立需要系統資源,對於一個接受許多請求的情況,不斷的建立新執行緒,會導致系統 效能的降低。」
有興趣看 Thread Pool 的演進,可以看看以下這三個 Design Pattern
  1. Thread-Per-Message 模式
  2. Worker Thread 模式
  3. Thread Pool 模式
但是這裡我沒有要實作 Thread Pool 模式,我只是要了解原理跟用途就好,因為 JavaSE 5.0 以後,已經有 util 可以直接達到 Thread Pool的效果了,也就是 concurrent util
所以為了這個效能問題呢,將程式改寫,並加上 Monitor Thread 程式來監看 Thread Pool 使用情形。

不廢話,直接看程式,其他自己看 java api


...

    public void run() {
        // creating the ThreadPoolExecutor

        ThreadPoolExecutor executorPool = new ThreadPoolExecutor(50, 300, 10,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(30),
                Executors.defaultThreadFactory());
        // start the monitoring thread

        MonitorThread monitor = new MonitorThread(executorPool, 5);
        Thread monitorThread = new Thread(monitor);
        monitorThread.start();

        try {
            while (keeprunning) {
                Socket clientSocket = listenSocket.accept();
                clientSocket.setSoTimeout(10000);
                clientSocket.setTcpNoDelay(true);
                executorPool.execute(new manageconnection(clientSocket));
            }
        } catch (IOException excpt) {
            log.error("Sorry ,Failed I/O:" + excpt);
        }
    }

...


MonitorThread.java


public class MonitorThread implements Runnable {
    private static final Logger log = Logger.getLogger(MonitorThread.class);
    private ThreadPoolExecutor executor;

    private int seconds;

    private boolean run = true;
    
    public void shutdown() {
        this.run = false;
    }

    public MonitorThread(ThreadPoolExecutor executor, int delay) {
        this.executor = executor;
        this.seconds = delay;
    }

    @Override
    public void run() {
        while (run) {
            log.info(String
                    .format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",
                            this.executor.getPoolSize(),
                            this.executor.getCorePoolSize(),
                            this.executor.getActiveCount(),
                            this.executor.getCompletedTaskCount(),
                            this.executor.getTaskCount(),
                            this.executor.isShutdown(),
                            this.executor.isTerminated()));
            try {
                Thread.sleep(seconds * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}


output
[monitor] [50/50] Active: 1, Completed: 3, Task: 4, isShutdown: false, isTerminated: false