Search Google

Thursday, July 30, 2015

淺談Context based Java batch自動測試與JMX

今天要跟大家分享目前自動測試Context based Java batch的做法與使用的工具.  這裡說的Context based Java batch指的是所有batch job都是從Spring context將MBean export後透過JMX呼叫執行.  說到JMX第一個想到的通常就是JConsole.


我們的案例中export出三個MBean, JmxJobListMBean是用來檢視job清單, JmxJobRunner是用來執行job.

透過JmxJobListMBean的listJob可以得到一份job名稱的清單.

知道要執行的job名稱後再呼叫JmxJobRunner的runJob來執行job名稱對應的service.

將job名稱與參數分別填入p1, p2欄位後執行runJob即可取得執行結果

到目前為止我們已經透過JConsole呼叫MBean export出來的功能成功地執行batch job, 但是使用JConsole代表著需要人工執行, 如果不想自己寫code但又想要透過script自動執行驗證時又該怎麼做呢?  這時候我們可以用Jmxterm來達成, 下面是透過Jmxterm執行上述batch job的做法

首先使用下列指令建立與JMX server的連線
java -jar jmxterm-1.0-alpha-4-uber.jar -n -u ${user} -p ${password} -l ${jmx_server_ip}:${jmx_server_port}

接著執行下列指令取得job名稱清單
 run -b bean:name=JmxJobListMBean -d bean listJob

最後執行下列指令將參入帶入job名稱對應的service並執行
 run -b bean:name=JmxJobRunner -d bean runJob ${job名稱} ${參數}

下圖中有上述指令與執行結果


OK, 現在我們可以不用人工的方式透過JMX執行batch job了, 接下來我們要再結合JMeter達成自動執行+驗正執行結果.  我們會用到JMeter的OS process sampler執行上述指令, 待OS process sampler執行結束後再搭配其他sampler (eg. JDBC)或是單純使用post process assertion檢查執行結果是否如預期.


搭配JMeter OS process sampler後比較特別的地方是在原本與JMX server建立連線的指令後面多加了"-i jmxterm.txt", 這個新加的參數表示會把jmxterm.txt檔案內容餵進與JMX server建立的連線中執行.  所以jmxterm.txt的內容就是執行runJob的指令, eg.
run -b bean:name=JmxJobRunner -d bean runJob ${job名稱} ${參數}



Saturday, July 18, 2015

Bluemix業配文+入門教學

身為I社的一份子, 當公司全力在推CAMSS的時候一定也要來盡點心力, 我想大家對於中規中舉的介紹早已麻木, 所以就讓擅長打野武士戰法的我來跟大家介紹如何開開心心地以非正規的方式使用Bluemix提供的免費功能~

今天要介紹的功能是大部分webapp所環繞著的三大要素
1. Runtime server
2. Git server
3. DB server

1. Runtime server目前涵蓋了以下幾種大家常見的環境:
雖然我個人偏好在local跑Runtime server, 畢竟要設定或debug時還是比較方便, 但是如果可以在Bluemix上面跟客戶做完最後一哩路測試等於可以省去系統轉移+後續測試所需的工, 因為測試完之後只需要將帳號轉移給業主管理就結束了, 光是這點我想對許多SOHO族是相當有利, 而業主每個月付的費用就是原本需要花費的web hosting service費用.


想知道更多關於如何開始使用Runtime server請點這

2. 為什麼要特別提到Git server呢? 不就是做版本控管嗎?
是的, 在開發的過程中大家多多少少會需要做source code的版本控管, 也因為近年來許多opensource project陸續放到GitHub上讓越來越多人使用Git做版本控管.
要使用Git做版本控管一定要有個Git server, 如果用免費版的GitHub就表示所有放上去的source code自動成為opensource, 如果不想讓自己的source code變成opensource通常有兩種方式: (a) 付錢成為GitHub的付費使用者就可以把repository/project轉成私人模式, (b) 自己架Git server.
對於不想付費又不想自己架Git server的使用者而言, Bluemix提供的DevOps服務就顯得格外有用. 透過Bluemix的DevOps服務可以建立private Git server做版本控管同時保有source code的ownership.
想知道如何從local git client使用Bluemix提供的Git server請點這

3. webapp絕大部分應該都會需要用到DB, 以往我們難免需要自己在local電腦上架個DB server或付費租用線上DB才能開始開發測試. 今天Bluemix真正實現了"只要有心人人都可以有100MB的免費DB空間可用"!
這個部份比較tricky, 正規文件裡面並沒有特別說明(匆匆帶過倒是有), 所以在這裡特別說明如何從local端存取Bluemix提供的DB instance.
首先我們需要先有一個Runtime server instance (可以參照第1點結尾的連結), 這樣申請下來的DB server才有地方可掛 --> 才有地方可以看設定.
接著點擊上圖紅色框框申請DB server instance, 要注意的是下圖中的兩個紅色框框. 上面的紅色框框指定新申請的DB server instance要掛到哪一個Runtimer server instance, 下面的紅色框框指名要使用免費方案 --> 100MB空間 + 10 concurrent connections
到目前為止我們知道我們有了一個Runtime server + 一個DB server, 接下來我們要透過Runtime server的設定取得DB server的連線資訊. 從Bluemix的儀表板中看到一個Runtime server instance:

點進上圖下方紅色框框代表的Runtime server instance之後可以看到該instance的配置
到這裡我們就已經快要完成取經任務, 只要再點進上圖中左方panel中的"環境變數"就可以看到DB的設定參數!

有了上圖中右邊兩個紅色框框的資訊我們就可以從local直接透過Internet存取這100MB的free DB.

當然, 不把DB掛進Runtime server也可以透過DB service提供的web UI進行"簡單"的操作
如果想要透過這個web UI匯入格式稍微複雜一點的資料就會碰壁, web UI畢竟無法提供command line指令的細顆粒度微調, 所以我還是偏好直接透過Data Server Runtime Client直接建立remote connection操作的野武士戰法.

相信沒有直接按"End"鍵一路看到這裡的捧友們此時對於如何使用Bluemix提供的service已經有更深一層的了解, 雖然不是太正規的用法, 但是我相信對於中小企業的企業主與SOHO族們應該相當有幫助.

我們下回見~

Thursday, April 23, 2015

距離上次分享Linux container相關文章已經五年多了, 沒想到五年後居然有人用Linux container搞出了大名堂, 是的, 就是Docker!  最近越來越常聽到大家在討論Docker, 但是也很常聽到有人在問Docker跟VM到底哪裡不同.


舉個例子來說明:

在以前如果想要在同一台電腦上面同時虛擬化AP server + APP, DB, Mail server applications, 我們需要在Hosting OS上面跑三個VM instances (如下圖左邊的VMs), 每一個VM instance雖然只執行各自被指派的任務 (如下圖左邊填滿橘色, 綠色, 灰色的部分), 但是從OS層來說卻是在同一台實體機器上執行了四份OS, 相同的libraries被重覆載入四次 (如下圖左邊藍色的部分), 所以記憶體, CPU等資源等於浪費了.

有了Container (如下圖右邊的Containers)我們就不需要浪費資源在各application共用的部分, 下圖右邊的Containers所要表現的就是我們不再需要為了執行虛擬化的application而重複地在各個虛擬環境中執行OS, 各虛擬環境透過使用Hosting OS已經載入過的libraries替我們節省實體機器上的資源, 當然, 這只是眾多優點中的一個而已.


另外一個優點就是透過maintain Dockerfile (點我看sample)能幫助我們更清楚地知道每個application的環境是如何建立出來的, 包含需要安裝哪些套件, 需要先設定什麼樣的參數與執行什麼樣的指令.  
Dockerfile中可以reference既有的docker image讓我們動態且快速的調整出不同情況下所需的虛擬環境, 而且Dockerfile很小的文字檔, 需要的人很快就可以取得並在自己的環境把image build出來, 而不需要隨便就傳個幾GB的流量.

概念上的說明進行到這裡就好, 關於Docker的基本設定+使用google已經提供很多資訊了, 下面是我實際設定+使用過程中預到的問題以及小筆記:


// unable to run firefox from docker

// configure docker to use devicemapper rather than aufs (某些application需要在devicemapper模式下才能在docker中執行, eg. DB2)
https://gist.github.com/pcolazurdo/e61cfb84812a70b93e74
umount -l $(grep 'aufs' /proc/mounts | awk '{print $2}' | sort -r)
rm -rf /var/lib/docker
vi /etc/init.d/docker
touch /var/lib/boot2docker/profile
在profile中加入
#!/bin/sh
EXTRA_ARGS="--storage-opt dm.basesize=20G --storage-driver=devicemapper"

// create local docker registry (for local push/pull, 如果想讓開發測試團隊在內網就能夠分享docker images, 自己建個docker registry是個不錯的選擇)
http://cloudcounselor.com/2014/01/07/docker-private-registry-on-centos-rhel-6-5/

// private docker-registry
yum install -y docker-registry
default port: 5000
default repository location: /var/lib/docker-registry
編輯/var/lib/boot2docker/profile:
EXTRA_ARGS="--storage-opt dm.basesize=40G --storage-driver=devicemapper --insecure-registry localdocker:5000"
編輯/etc/hosts:
{intranet IP} localdocker
編輯/etc/hosts後要重啓docker:
/etc/init.d/docker stop
/etc/init.d/docker start
push to private docker-registry: docker push localdocker:5000/{repository}:{tag}
pull from private docker-registry: docker pull localdocker:5000/{repository}:{tag}

// docker-registry rest api (用來管理local docker registry裡的docker images+版本)
https://docs.docker.com/reference/api/registry_api/#delete-a-repository-tag
eg. get tags of mydb2:
GET http://localdocker:5000/v1/repositories/library/mydb2/tags
eg. remove ssosdpbase tag from db2-trinity:
DELETE http://localdocker:5000/v1/repositories/library/mydb2/tags/base
remove repository:
DELETE http://localdocker:5000/v1/repositories/mydb2

Wednesday, December 15, 2010

修改CodeIgniter (aka. CI)使其能正確執行oci_bind_by_name所需步驟

修改CodeIgniter (aka. CI)使其能正確執行oci_bind_by_name所需步驟:
Step 1.
/system/database/DB_driver.php -->
line 293:
--
if (FALSE === ($this->result_id = $this->simple_query($sql)))
++
if (FALSE === ($this->result_id = $this->simple_query($sql, $binds)))
line 440:
--
function simple_query($sql)
++
function simple_query($sql, $binds=FALSE)
line 447:
--
return $this->_execute($sql);
++
return $this->_execute($sql, $binds);

Step 2.
/system/database/drivers/oci8/oci8_driver.php -->
line 165:
--
function _execute($sql)
++
function _execute($sql, $binds=FALSE)
line 172-172:
--
++
if($binds != FALSE) {
foreach($binds as $k => $bind) {
oci_bind_by_name($this->stmt_id, $bind['name'], $bind['value']);
}
}

使用範例:
$sql = "insert
into related_firm
(
TYPE,
NAME,
CONTACT_ADDR,
CONTACT_NUMBER,
CONTACT_FAX,
SN
)
values
(
:TYPE,
:NAME,
:CONTACT_ADDR,
:CONTACT_NUMBER,
:CONTACT_FAX,
:SN
)";
$params[] = array('name'=>':TYPE', 'value'=>$this->type);
$params[] = array('name'=>':NAME', 'value'=>$this->name);
$params[] = array('name'=>':CONTACT_ADDR', 'value'=>$this->contactAddress);
$params[] = array('name'=>':CONTACT_NUMBER', 'value'=>$this->contactNumber);
$params[] = array('name'=>':CONTACT_FAX', 'value'=>$this->contactFax);
$params[] = array('name'=>':SN', 'value'=>$this->serialNumber);
$db = $this->load->database('TESTDB', TRUE);
$db->query($sql, $values, TRUE);

Thursday, December 09, 2010

Generate setter/getter for PHP in Eclipse

很久沒發文了,慶祝今天找到個快速產生setter/getter的套件,特別上來分享一下!

話說使用Eclipse開發Java class時在變數上點右鍵後選source即可看到自動產生setter/getter的選項,但開發PHP class時卻沒有這項貼心的功能~
詢問Google老師之後看到了很多做法,其中不乏自行編輯Eclipse的template for auto code completion,但是最讚的莫過於PHP source plugin這個套件,裝完之後Eclipse的toolbar上會出現"PHP Source",點下去即可選擇要產生特定變數的Getter/Setter :-)

下面的URL是該套件的官方網站:
http://pdt.plugins.e-surf.pl/features.php
裡面有screenshot供人瞻仰。。。

Saturday, May 22, 2010

紅酒"蒸"牛肉~

醞釀許久的煮飯魂終於在今天得到實現了~
參考前人的食譜(http://www.wretch.cc/blog/QLynnQ/7273158)之後,昨天下班後直奔sogo復興館B2的生鮮超市買了以下食材:





經過一整個晚上的浸泡,牛肉散發出迷人的香氣,放到鍋子裡稍微煎過之後更是香氣四溢!



牛肉起鍋後不用洗鍋子,直接把洋蔥放下去拌炒,接著再把紅蘿蔔與洋菇放下去一起炒,接著把蕃茄切塊丟進去煮成天然番茄醬,理論上現在應該就要把浸牛肉的紅酒倒進去悶煮,但有鑒於紅酒存量不足,於是拿水代替~









然後加入鹽,黑胡椒,香料攪拌調味









將煮好的醬汁與起鍋的牛肉混合後把之前保存下來的紅酒肉汁一併加到鍋內









再加點鹽、黑胡椒、香料就可以放進電鍋裡蒸了(為了確保蒸得夠久,我在電鍋的外鍋放了三碗水)!





最後就是清理環境,打完收工,等著吃飯囉~


Friday, March 19, 2010

等一下就下車

搭捷運的時候很常聽到"等一下就下車",今天早上不免俗的又聽到了~
很奇怪,看到行動不便的人讓座是很正常的一件事,為什麼要用"等一下就下車"當做理由呢?
還是說"等一下沒有要下車"就不打算讓坐,如果是這樣,幹麻還假惺惺的讓座呢?
反正等一下你下車自然會空出一個座位啊!
真是莫名奇妙~

Saturday, March 13, 2010

指定Eclipse使用JDK執行

Symdrome:

The Maven Integration requires that Eclipse be running in a JDK, beacuase a number of Maven core plugins are using jars from the JDK.

Please make sure the -vm options in eclipse.ini is pointing to a JDK and verify that Installed JREs are also using JDK installs.

Solution:
在eclipse.ini的最開頭(一定要在最開頭,而且-vm之後要換行!)加上jdk裡面javaw.exe的完整路徑,如下:
-vm
C:\Program Files\Java\jdk1.6.0_16\bin\javaw.exe

Sunday, March 07, 2010

Servicemix 3.3.1最常見的build error & solution

先給sulution:
http://cwiki.apache.org/SM/discussion-forums.html#nabble-tt25602583|a25603368

再給syndrome:

error: error reading
[Home_Dir]\.m2\repository\org\springframework\spring-dao\2.0.6\spring-dao-2.0.6.jar;
error in opening zip file
重點是error in opening zip file
根據官方說法,是被3rd party的東西影響到的,所以我們只需要將solution提供的repository加入pom.xml的repositories裡,再將zip file的目錄刪除,以上面的syndrome為例 --> [Home_Dir]\.m2\repository\org\springframework\spring-dao
然後重新執行mvn install皆可。

據說在3.3.2版本中會解決這個問題,至於他什麼時候要release,誰知道呢?
所以先將就一下temp solution,頂著先~

Thursday, March 04, 2010

不喜歡照著manual還做不出來的感覺!

Open source的東西這就是這樣。。。照著manual做還不一定能得到相同的結果!
http://servicemix.apache.org/building.html
已經是從SVN checkout src出來,還是在build的過程中得到這樣的錯誤訊息:

[INFO] Error building POM (may not be this project's POM).
Project ID: null:servicemix-utils:bundle:1.1.0
Reason: Cannot find parent: org.apache.servicemix:servicemix-pom for project: null:servicemix-utils:bundle:1.1.0 for project null:servicemix-utils:bundle:1.1.0

Google也不一定神準,花了點時間把垃圾過濾掉後終於找到解答
http://mail-archives.apache.org/mod_mbox/servicemix-users/201002.mbox/%3CA57F3D97-AB5E-4E7E-A84D-46B8771B9E5C@gmail.com%3E
原來是檔案根本就有問題!
刪掉讓maven在build的過程中自動再下載一次就解了,之後在build xerces也出現相同的錯誤,解法同樣是將對應的.pom檔移除。