Google Code Prettify

2015年6月22日 星期一

install GlassFish Server

上次介紹 JBoss Application Server,今天來看一下 GlassFish 4.1 怎麼安裝。

  • 解壓縮: unzip glassfish-4.1-web.zip,解壓縮可得到一個目錄 glassfish4,將這個目錄搬到你希望安裝的地方,例如: mv glassfish /usr/local/bin,這樣就等於安裝到這個目錄下。

  • 設定 Java 路徑
cd /usr/local/bin/glassfish4/glassfish/config
於 asenv.conf 中設定 AS_JAVA 變數,指向要使用的 Java 路徑,例如:
AS_JAVA=/usr/local/jdk1.8.0_71
這個設定如果不設定,會使用系統預設的 Java。
  • 啟動:
cd /usr/local/bin/glassfish4/bin
./asadmin start-domain

  • 設定管理者密碼: 預設的管理者帳號是 admin,密碼空白 (沒有密碼),glassfish 強迫要設定密碼後才可登入,所以現在為管理者設定密碼。
  •  ./asadmin change-admin-password
  • enable SSL:
asadmin --host [host] --port [port] enable-secure-admin
假設這台 server 的 hostname 為 gfserver,那麼下如下指令,開啟 SSL,4848 是預設的管理介面使用的 port。
./asadmin --host gfserver --port 4848 enable-secure-admin



  • 部署程式: 進入管理者介面後,在左邊選單可以看到「Applications」,點選後出現如下畫面,按畫面中的【Deploy】即可將 war file 上傳並部署上 glassfish server。


2015年6月6日 星期六

fork Function


在「Advanced.Programming.in.the.UNIX.Environment, 3rd.Edition」一書中的8.3節 (p. 230),有個小程式,如下,是用來說明 UNIX 環境中,使用 fork 產生子行程 (child process),要注意的一些事,先看一下程式:

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 
 4 int globvar = 6;
 5 char buf[] = "a write to stdout\n";
 6 
 7 int main(void) {
 8     int var;
 9     pid_t pid;
10 
11     var = 88;
12     if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
13         printf("write error");
14     printf("before fork\n");
15 
16     if ((pid = fork()) < 0) {
17         printf("fork error");
18     }
19     else if (pid == 0) {
20         globvar++;
21         var++;
22     }
23     else {
24         sleep(2);
25     }
26 
27     printf("pid = %ld, getpid = %ld, glob = %d, var = %d\n", (long) pid, (long) getpid(), globvar, var);
28     _exit(0);
29 }

上面的程式很簡單的利用 fork 產生一個子行程,等待 2 秒後,印出一段訊息,顯示 fork 傳回值、行程的 pid (process id)、全域變數及區域變數,執行結果如下: (我的程式命名為 forEx01.c)
[steven@CentOS7 Debug]$ ./forkEx01
a write to stdout
before fork
pid = 0, getpid = 9214, glob = 7, var = 89
pid = 9214, getpid = 9213, glob = 6, var = 88
[steven@CentOS7 Debug]$ 
根據上述的執行結果,說明如下:
  1. fork 函數會產生一個子行程,子行程會執行父行程 (parent process) fork 之後的指令。
  2. fork 函數在父行程會傳回子行程的 pid,在子行程則傳回 0,子行程如果要得到父行程的 pid,可以透過 getppid 函數得到值。
  3. 上面程式讓父行程睡 2 秒後再印出結果,所以第一個結果是子程式印出的,第二個結果是父行程印出的,通常確實是會得到如上的結果 (除了 pid、getpid 的值會不同之外),但是,實際上有時會是父行程先印出,因為那個行程先執行,由 OS 決定,這裡父行程睡 2 秒只是增加子行程先執行的機率。
  4. 上述程式的全域變數 (global variable) 和區域變數 (local variable) 於子行程中都被加 1,但是都沒有影響到父行程的值,這表示不管是全域變數或區域變數,父行程、子行程都不共用!
  5. 子行程的輸出接在父行程 fork 前已輸出的內容之後,父行程後面的輸出又接在子行程的輸出之後,完全不會互相覆蓋,因為父行程和子行程會共享在 fork 之前已開啟的所有檔案描述符 (file descriptions),也就是說兩個行程會共享這些檔案的檔案指標! 標準輸出是在父行程一開始執行時就被開啟的,所以會被兩個行程共享。
除了上述程式所展現的父行程、子行程關係外,另外針對行程的一些基本觀念整理如下:
  1. UNIX 系統在系統啟動後,會啟動許多 process 來處理一些系統面的事,其中一個 pid 為 1 的 process 稱為 init process,是負責啟動和關閉系統。
  2. 程式以 fork 啟動一個或數個子行程,當子行程結束後,父行程要負責將其佔用的資源都回收後,才可真正將其結束,在子行程已經執行完,但是父行程尚未將其資源回收前,這個子行程就稱為 zombie (僵屍)。
  3. 如果父行程比子行程更早結束,子行程並不會被迫結束,而是會交由 init process 管理,也就是說,子行程的 ppid 會被改為 1,之後子行程結束,其資源會由 init process 進行回收。