tag:blogger.com,1999:blog-9097277910612402272019-01-05T17:31:43.076+08:00Ada Hsu 的胡思亂想Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.comBlogger943125tag:blogger.com,1999:blog-909727791061240227.post-60256047511548799112018-05-10T16:29:00.002+08:002018-05-10T16:29:26.608+08:00SHELL 下輸出貼齊的訊息<pre><code class="language-bash">
function getPosition {
echo -ne "\033[6n" # ask the terminal for the position
read -s -d\[ garbage # discard the first part of the response
read -s -d R pos # store the position in bash variable 'foo'
Y=$(echo "$pos" | cut -d\; -f 1)
X=$(echo "$pos" | cut -d\; -f 2)
}
## 以指定顏色在 TERMINAL 右側顯示指定內容
function showStatus {
WIDTH=$(tput cols)
COLOR=$1
MSG=$2
LENGTH=$(echo ${MSG} | wc -c)
# 取得目前座標 X: col, Y: row
getPosition
NEW_POS=$(expr ${WIDTH} - ${LENGTH})
REPEATE=$(expr ${NEW_POS} - ${X})
printf '.%.0s' $(seq 1 ${REPEATE})
echo -e "${COLOR}${MSG}${COLOR_RESET}"
}
COLOR_HIGHWHITE='\033[1;37m'
echo
echo -n "This is a Book"
showStatus "${COLOR_HIGHWHITE}" "[YES]"
</code></pre>
<br />
以下是執行範例:
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-UpYgqV36P5I/WvQCuajdVXI/AAAAAAAA7SA/gculIVAoZOQ3cI6D8UO9-BOgjUIwvPQagCLcBGAs/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7%2B2018-05-10%2B%25E4%25B8%258B%25E5%258D%25884.27.40.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="78" data-original-width="891" height="56" src="https://3.bp.blogspot.com/-UpYgqV36P5I/WvQCuajdVXI/AAAAAAAA7SA/gculIVAoZOQ3cI6D8UO9-BOgjUIwvPQagCLcBGAs/s640/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7%2B2018-05-10%2B%25E4%25B8%258B%25E5%258D%25884.27.40.png" width="640" /></a></div>
<br />Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-55770885050769454732017-11-10T14:50:00.001+08:002018-10-25T11:14:53.995+08:00在 macOS 上設定炫酷的 終端機 操作環境 - 使用 oh-my-zsh w/ Powerlevel9k<h5>2018/10/25 補充:更多的客製化:<a href="https://medium.com/the-code-review/powerlevel9k-personalise-your-prompt-for-any-programming-language-68974c127c63">Powerlevel9k: personalise your terminal prompt for any programming language</a></h5>
<h5>2018/08/15 補充:如果喜歡 <a href="https://pjchender.blogspot.com/2016/10/code-fira-code.html">Fira Code</a> 字體的話,可以套用 <a href="https://github.com/ryanoasis/nerd-fonts">font-firacode-nerd-font</a> </h5>
這兩天把個人在使用的終端機環境改造了一番,很能自嗨,所以留個記錄... XD<br />
<ol>
<li>先裝 <a href="https://brew.sh/index_zh-tw.html" target="_blank">Homebrew</a></li>
<li>再安裝 <a href="https://caskroom.github.io/" target="_blank">caskroom</a><br />
<pre><code class="language-bash">
brew update
brew install cask
</code></pre>
</li>
<li>參考<a href="http://icarus4.logdown.com/posts/177661-from-bash-to-zsh-setup-tips" target="_blank">這裡</a>完成 zsh / oh-my-zsh 的安裝</li>
<li>安裝 <a href="https://github.com/bhilburn/powerlevel9k/wiki/Install-Instructions#option-2-install-for-oh-my-zsh" target="_blank">Powerlevel9k</a></li>
<li>安裝相關字型
<ul>
<li>基本上就是 Powerline / Awesome / Nerd 三類字型選一個,個人建議 Nerd 類字型即可,因為它的 icon 最完整</li>
<li>以下指令可以啟用 caskroom 的字型庫管理<br />
<pre><code class="language-bash">
brew tab caskroom/fonts
brew update
</code></pre>
</li>
<li>nerd 相關的字型很多,可以挑一個自己喜歡的來裝,這裡安裝 Source Code Pro 版本<br />
<pre><code class="language-bash">
brew search nerd
</code></pre>
</li>
</ul>
</li>
<li>編輯 ~/.zshrc ,設定 Powerlevel9k 運作模式
<pre><code class="language-bash">
# 找到 ZSH_THEME 字串位置,改成如下:
POWERLEVEL9K_MODE=nerdfont-complete
ZSH_THEME="powerlevel9k/powerlevel9k"
</code></pre>
</li>
<li>參考<a href="https://github.com/bhilburn/powerlevel9k/wiki/Stylizing-Your-Prompt" target="_blank">作者的說明</a>及<a href="https://github.com/bhilburn/powerlevel9k/wiki/Show-Off-Your-Config" target="_blank">別人的設定</a>,組合出自己最酷炫的終端機界面,重點可先放在以下幾項測試:
<ul>
<li>POWERLEVEL9K_LEFT_PROMPT_ELEMENTS</li>
<li>POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS</li>
<li>POWERLEVEL9K_PROMPT_ADD_NEWLINE</li>
<li>POWERLEVEL9K_PROMPT_ON_NEWLINE</li>
</ul>
</li>
<li>個人的設定如下,加在 ~/.zshrc 檔案末端:
<pre><code class="language-bash">
POWERLEVEL9K_SHORTEN_DIR_LENGTH=2
POWERLEVEL9K_TIME_BACKGROUND="white"
POWERLEVEL9K_TIME_FOREGROUND="black"
# POWERLEVEL9K_TIME_FORMAT="%D{%H:%M:%S}"
POWERLEVEL9K_VCS_GIT_ICON='\uf1d3'
POWERLEVEL9K_VCS_GIT_GITHUB_ICON='\uf09b'
# POWERLEVEL9K_VCS_CLEAN_FOREGROUND='blue'
# POWERLEVEL9K_VCS_CLEAN_BACKGROUND='black'
# POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND='red'
# POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND='black'
# POWERLEVEL9K_VCS_MODIFIED_FOREGROUND='black'
# POWERLEVEL9K_VCS_MODIFIED_BACKGROUND='black'
POWERLEVEL9K_STATUS_VERBOSE=true
POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE=false
POWERLEVEL9K_VPN_ICON='\uf023'
POWERLEVEL9K_PROMPT_ON_NEWLINE=true
POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
POWERLEVEL9K_FOLDER_ICON='\uf114'
# Bateria
POWERLEVEL9K_BATTERY_CHARGING='yellow'
POWERLEVEL9K_BATTERY_CHARGED='blue'
POWERLEVEL9K_BATTERY_LOW_THRESHOLD='20'
POWERLEVEL9K_BATTERY_LOW_COLOR='red'
POWERLEVEL9K_BATTERY_CHARGED_BACKGROUND='46'
POWERLEVEL9K_BATTERY_CHARGED_FOREGROUND='235'
POWERLEVEL9K_BATTERY_CHARGING_BACKGROUND='178'
POWERLEVEL9K_BATTERY_CHARGING_FOREGROUND='235'
POWERLEVEL9K_BATTERY_LOW_BACKGROUND='88'
POWERLEVEL9K_BATTERY_LOW_FOREGROUND='235'
POWERLEVEL9K_BATTERY_CHARGED_ICON='\UF240'
POWERLEVEL9K_BATTERY_LOW_ICON='\UF240'
POWERLEVEL9K_BATTERY_CHARGING_ICON='\UF1E6'
POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND='white'
POWERLEVEL9K_BATTERY_DISCONNECTED_BACKGROUND='red'
POWERLEVEL9K_BATTERY_ICON='\UF1E6'
# Anaconda
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(anaconda battery)
POWERLEVEL9K_ANACONDA_RIGHT_DELIMITER='>'
POWERLEVEL9K_ANACONDA_LEFT_DELIMITER='<'
POWERLEVEL9K_ANACONDA_BACKGROUND='24'
POWERLEVEL9K_ANACONDA_FOREGROUND='111'
# POWERLEVEL9K_ANACONDA_ICON=''
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(os_icon context dir dir_writable vcs )
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status root_indicator background_jobs command_execution_time time battery anaconda)
</code></pre>
</li>
<li>記得在終端機中選定使用的字型為剛剛安裝的 Nerd 字型,不然只會看到亂碼 1/2 ... (這哏好冷) </li>
<li>效果如下,謝謝收看!<br /><a href="http://4.bp.blogspot.com/-_ClJ6F_KUyk/WgVL8MO0JZI/AAAAAAAA0U8/KH6EARh4Mq458d2kG57vuJOPAi82ZPRJQCK4BGAYYCw/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7%2B2017-11-10%2B%25E4%25B8%258B%25E5%258D%25882.47.39.png" imageanchor="1"><img border="0" height="52" src="https://4.bp.blogspot.com/-_ClJ6F_KUyk/WgVL8MO0JZI/AAAAAAAA0U8/KH6EARh4Mq458d2kG57vuJOPAi82ZPRJQCK4BGAYYCw/s640/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7%2B2017-11-10%2B%25E4%25B8%258B%25E5%258D%25882.47.39.png" width="640" /></a></li>
</ol>
<br />
<div>
<br /></div>
Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-56308958430782482222017-07-28T08:42:00.000+08:002017-08-04T15:34:14.740+08:00從 Google Container Engine 連線到 Google SQL for MySQL / 以 Java 為例看了一下發文記錄,這應該是此格在停業六年後重新生出來的文章,就... 留個記錄吧!<br />
<br />
這篇內容是以個人已理解的資訊為基礎所撰寫,特色是<b>知其然而不知其所以然</b>,所以<b>不保證理解上的正確性,請參考官方文件進行相互確認</b>,謝謝。<br />
<h3>
源起</h3>
<div>
我是在 2016 年時開始接觸容器應用的,不過實務上一直沒啥機會應用。後來在前公司的 2017 年計劃中原本有一項重點是預訂將營業相關的應用系統自單機移轉到雲端上(因為服務是面向全球),但公司停業了(所以我失業了),這項計劃也就不了了之。</div>
<div>
<br />
不過工作好像不是那麼好找,於是趁著找工作時的空檔,試著把這個計劃驗證一遍。<br />
<br /></div>
<div>
營業系統的核心架構是 APIs + MySQL,原本是在 Google 上開設兩台 VM 各司其職,實務上它並不具有 Non Stopping 的服務等級要求,也就是說若 API Server 或 MySQL 資料庫崩潰了,在管理人員進行修正前服務都是停擺的。</div>
<div>
<br /></div>
<div>
這次選擇的是雲端平台是 Google Cloud Platform,理由只是因為它直接提供了 Cloud SQL for MySQL,在資料量不多的情況下相信可以直接透過 mysqldump 無痛轉移資料庫內容。<br />
<h3>
示範平台</h3>
</div>
<div>
本案範例是在 macOS Sierra 上進行驗證,系統上包含了 Docker for Mac 17.06.0-ce、Java SDK 1.8.0_102、以及 MySQL Client for 5.7.17。Java 打包工具則為 Apache Maven 3.5.0,但應該 3.x 以上版本都能適用。</div>
<div>
<br /></div>
<div>
範例中使用的操作指令大致上都可以在各平台下操作,必要時會針對 Windows 平台部份進行<b>猜測</b>說明。</div>
<h3>
試用 Google Cloud Platform </h3>
Google 針對 Google Cloud Platform (以下稱 GCP)提供了 12 個月 300 美金的試用額度,這對於懶人測試員有很大的誘因,如果你不想在 2 ~ 3 星期內完成一大堆的測試,那麼 GCP 可以讓你安心的將測試項目安排在 52 星期內慢慢進行... XD<br />
<br />
啟用的方式很簡單:<br />
<ol>
<li>準備好一個 Google Account</li>
<li>準備好一張信用卡,Google 聲稱未取得使用者同意前不會扣款(有加入 Android Pay 的話應該會直接使用相關的設定)</li>
<li>登入 <a href="https://console.cloud.google.com/" rel="nofollow" target="_blank">Google Cloud Platform Console</a> 後,按下 <b>TRY IT FREE</b> 或<b>申請免費試用</b>按鈕<br /><a href="http://4.bp.blogspot.com/-tGU_ID-mUwg/WWh-vcuYMKI/AAAAAAAAxrI/8yHyzO7yN6Y-6g2utHMe0lsgGbwm63zvgCK4BGAYYCw/s1600/1.%2BGCP%2B%25E8%25A9%25A6%25E7%2594%25A8%25E9%2580%259A%25E7%259F%25A5.png" imageanchor="1"><img border="0" height="29" src="https://4.bp.blogspot.com/-tGU_ID-mUwg/WWh-vcuYMKI/AAAAAAAAxrI/8yHyzO7yN6Y-6g2utHMe0lsgGbwm63zvgCK4BGAYYCw/s640/1.%2BGCP%2B%25E8%25A9%25A6%25E7%2594%25A8%25E9%2580%259A%25E7%259F%25A5.png" width="640" /></a></li>
<li>依頁面指示填寫資料,這部份我忘了要填什麼了... XD</li>
<li>然後就正式啟用了<br /><a href="http://4.bp.blogspot.com/-o46RGTd35k0/WWs4SNZuq7I/AAAAAAAAxzA/2_Jj8E8TryMOXEq1PuqzML23SKzth9L9wCK4BGAYYCw/s1600/%25E9%2596%258B%25E5%25A7%258B%25E4%25BD%25BF%25E7%2594%25A8%2BGCP%2B%25E6%258B%25B7%25E8%25B2%259D.png" imageanchor="1"><img border="0" height="410" src="https://4.bp.blogspot.com/-o46RGTd35k0/WWs4SNZuq7I/AAAAAAAAxzA/2_Jj8E8TryMOXEq1PuqzML23SKzth9L9wCK4BGAYYCw/s640/%25E9%2596%258B%25E5%25A7%258B%25E4%25BD%25BF%25E7%2594%25A8%2BGCP%2B%25E6%258B%25B7%25E8%25B2%259D.png" width="640" /></a></li>
</ol>
<h3>
建立 GCP 專案</h3>
GCP 透過專案的概念協助管理人員於單一介面內管理與專案有關的各種 Google 服務,所以第一個就是建立 GCP 專案,上圖中紅框部份都能進入建立 GCP 專案的流程。<br />
<br />
建立專案所需要填寫的基本資料不多,就是給定一個<b>專案名稱</b>而以,然後 Cloud Console <b>會在專案名稱不衝突的情形下</b>會將這個專案名稱設定為<b>專案 ID</b>,這個專案 ID 在之後會常用到。<br />
<a href="http://2.bp.blogspot.com/-c5f_W9cQsqw/WXbsFfIQqlI/AAAAAAAAyNI/QUn0rXsQ2pwATeOM0UAoHzUWe9SFheAmACK4BGAYYCw/s1600/create-project.png" imageanchor="1"><img border="0" height="240" src="https://2.bp.blogspot.com/-c5f_W9cQsqw/WXbsFfIQqlI/AAAAAAAAyNI/QUn0rXsQ2pwATeOM0UAoHzUWe9SFheAmACK4BGAYYCw/s400/create-project.png" width="400" /></a><br />
<br />
決定好專案名稱及專案 ID 後即可建立一個新的 GCP 專案,Console 需要一點時間進行資源配置,當配置完成後即可在專案的<b>資訊主頁</b>上方確認當前的操作所影響的專案名稱,而<b>專案資訊</b>這張卡片也會顯示目前使用中的專案名稱及專案 ID。<br />
<a href="http://1.bp.blogspot.com/-RGVoccJRwFY/WXbtRmoKc1I/AAAAAAAAyNc/P_W61OPDH0Qam0GETqTR4iI88sBMqKgOwCK4BGAYYCw/s1600/create-project-2.png" imageanchor="1"><img border="0" height="318" src="https://1.bp.blogspot.com/-RGVoccJRwFY/WXbtRmoKc1I/AAAAAAAAyNc/P_W61OPDH0Qam0GETqTR4iI88sBMqKgOwCK4BGAYYCw/s640/create-project-2.png" width="640" /></a><br />
<br />
<br />
建立專案後會看到一個<b>入門指南</b>的卡片,可以花點時間看看。<br />
<h3>
建立 Cloud SQL 資料庫</h3>
回到前面所提到過的『營業系統的核心架構是 APIs + MySQL』這件事,大部份開發人員所想到的第一個問題應該就是如何建立一個雲端資料庫了!<br />
<br />
在 Cloud SQL 上建立一個 MySQL 資料庫很簡單,除了透過 Google Cloud SDK 以指令方式建立外,還可以透過 Cloud Console UI 建立。<br />
<br />
首先在 Cloud Console 資訊主頁中拉出左側的<b>產品與服務</b>選單、點選 <b>SQL</b> 服務然後進入 Cloud SQL 管理界面。<br />
<a href="http://2.bp.blogspot.com/-y7r2KWCFuJE/WWtFmzhZkFI/AAAAAAAAxzc/5li2wd1a38QVQL8o_z5Zm6k_zCaSnRYoACK4BGAYYCw/s1600/%25E9%25BB%259E%25E9%2581%25B8%2B%2BSQL.png" imageanchor="1"><img border="0" height="400" src="https://2.bp.blogspot.com/-y7r2KWCFuJE/WWtFmzhZkFI/AAAAAAAAxzc/5li2wd1a38QVQL8o_z5Zm6k_zCaSnRYoACK4BGAYYCw/s400/%25E9%25BB%259E%25E9%2581%25B8%2B%2BSQL.png" width="260" /></a><br />
<h4>
建立 MySQL 執行個體</h4>
目前並無任何執行中的 SQL 執行個體,所以必須點選<b>建立執行個體</b>鈕進行資料庫的建置動作,這邊可以選擇使用 MySQL 或 PostgreSQL(但是 Beta 中)資料庫,本案將使用 MySQL。<br />
<a href="http://3.bp.blogspot.com/-na7jxwT47ok/WWtGfpvLMAI/AAAAAAAAxzk/p4YYZG20OCQIhNHbq-kS_IYF6HHMeEkbQCK4BGAYYCw/s1600/%25E5%25BB%25BA%25E7%25AB%258B%25E5%259F%25B7%25E8%25A1%258C%25E5%2580%258B%25E9%25AB%2594.png" imageanchor="1"><img border="0" height="210" src="https://3.bp.blogspot.com/-na7jxwT47ok/WWtGfpvLMAI/AAAAAAAAxzk/p4YYZG20OCQIhNHbq-kS_IYF6HHMeEkbQCK4BGAYYCw/s400/%25E5%25BB%25BA%25E7%25AB%258B%25E5%259F%25B7%25E8%25A1%258C%25E5%2580%258B%25E9%25AB%2594.png" width="400" /></a><br />
<br />
選擇使用的資料庫種類,此處選 <b>MySQL</b><br />
<a href="http://3.bp.blogspot.com/-HW4U40zFMwU/WXbwZ7ZjDYI/AAAAAAAAyNs/n2ANzYrSoCARlYSheqTK1Ru5v1mF232GACK4BGAYYCw/s1600/create-mysql-0.png" imageanchor="1"><img border="0" height="235" src="https://3.bp.blogspot.com/-HW4U40zFMwU/WXbwZ7ZjDYI/AAAAAAAAyNs/n2ANzYrSoCARlYSheqTK1Ru5v1mF232GACK4BGAYYCw/s400/create-mysql-0.png" width="400" /></a><br />
<br />
<div>
依照建議選擇 <b>MySQL 第二代</b>的執行個體類型<br />
<a href="http://3.bp.blogspot.com/-AGeFtsAk__I/WXbwIIXOmMI/AAAAAAAAyNk/ghBPVT8-fb04wvvsI-8tgK9jvp-VzEwxACK4BGAYYCw/s1600/create-mysql-1.png" imageanchor="1"><img border="0" height="400" src="https://3.bp.blogspot.com/-AGeFtsAk__I/WXbwIIXOmMI/AAAAAAAAyNk/ghBPVT8-fb04wvvsI-8tgK9jvp-VzEwxACK4BGAYYCw/s400/create-mysql-1.png" width="367" /></a></div>
<div>
<h4>
填寫 MySQL 基本參數</h4>
<a href="http://2.bp.blogspot.com/-MOFUdzeKS2A/WXbw7tXzIOI/AAAAAAAAyN0/Oyc-pH_PUaYlhmK-OTsVjV8UbEw_eX97QCK4BGAYYCw/s1600/create-mysql-2.png" imageanchor="1"><img border="0" height="400" src="https://2.bp.blogspot.com/-MOFUdzeKS2A/WXbw7tXzIOI/AAAAAAAAyN0/Oyc-pH_PUaYlhmK-OTsVjV8UbEw_eX97QCK4BGAYYCw/s400/create-mysql-2.png" width="395" /></a><br />
<ol>
<li>執行個體 ID:日後要用什麼名字來識別這個資料庫</li>
<li>根密碼:即 MySQL root 使用者的密碼</li>
<li>位置:資料庫要放在哪個區域,其中 asia-east1 指的是台灣,此處建議連分區也一併指定,後續建立其他環境時可以集中在同一機房內<br />※詳細的區域資訊可以參考 <a href="https://cloud.google.com/about/locations/" target="_blank">Cloud Locations</a></li>
<ul>
</ul>
</ol>
<h4>
調整進階參數</h4>
</div>
<div>
點選<b>顯示進階選項</b>後有一些額外設定,設定後請記得按下<b>關閉</b>鈕以確保相關的變更被記錄下來。</div>
<div>
<a href="http://4.bp.blogspot.com/-8x0AE0TQICQ/WXb0NJnT9tI/AAAAAAAAyOE/Conk1XbDOaMbIiDyyNCT1n9Nr-0JmD3DQCK4BGAYYCw/s1600/create-mysql-3.png" imageanchor="1"><img border="0" height="400" src="https://4.bp.blogspot.com/-8x0AE0TQICQ/WXb0NJnT9tI/AAAAAAAAyOE/Conk1XbDOaMbIiDyyNCT1n9Nr-0JmD3DQCK4BGAYYCw/s400/create-mysql-3.png" width="372" /></a><br />
<ol>
<li>選擇資料庫版本:指定 MySQL 資料庫的版本,預設是 5.7</li>
<li>設定機器類型和儲存空間:指定 MySQL 運作環境的資源,請依用途妥善選擇對應的資源環境<br /><a href="http://2.bp.blogspot.com/-rSx_o_bVipo/WXb1qRIYsBI/AAAAAAAAyOQ/CrgRkdB_x1IKo_ZQHjpXBAB0yRCCUQIqACK4BGAYYCw/s1600/create-mysql-4.png" imageanchor="1"><img border="0" height="220" src="https://2.bp.blogspot.com/-rSx_o_bVipo/WXb1qRIYsBI/AAAAAAAAyOQ/CrgRkdB_x1IKo_ZQHjpXBAB0yRCCUQIqACK4BGAYYCw/s400/create-mysql-4.png" width="400" /></a></li>
<li>啟用自動備份與高可用性:決定是否進行自動備份,此處全部勾選以作為日後驗證備份機制之參考;<b>建立容錯移轉備用資源</b>指的是會在另一個機房建立一個資料庫備份,所有對資料庫的操作都會複製一份到備用資源這個執行個體來<br /><a href="http://3.bp.blogspot.com/-RdcDYGdjTTk/WXb2uliAs0I/AAAAAAAAyOY/QAGpCRRgW48qGJWXAk0il_GkehXOSpwlQCK4BGAYYCw/s1600/create-mysql-5.png" imageanchor="1"><img border="0" height="316" src="https://3.bp.blogspot.com/-RdcDYGdjTTk/WXb2uliAs0I/AAAAAAAAyOY/QAGpCRRgW48qGJWXAk0il_GkehXOSpwlQCK4BGAYYCw/s400/create-mysql-5.png" width="400" /></a></li>
<li>授權網路:開放哪些 IP 可透過 MySQL Client 連接資料庫<br /><a href="http://3.bp.blogspot.com/-xAqlWFKZSTI/WXb46OKyo2I/AAAAAAAAyOg/PM3YYOVkqgkK-p3kGm0daahbKbNQOIRCQCK4BGAYYCw/s1600/create-mysql-6.png" imageanchor="1"><img border="0" height="225" src="https://3.bp.blogspot.com/-xAqlWFKZSTI/WXb46OKyo2I/AAAAAAAAyOg/PM3YYOVkqgkK-p3kGm0daahbKbNQOIRCQCK4BGAYYCw/s400/create-mysql-6.png" width="400" /></a></li>
<li>新增 Cloud SQL 標記:等同於 my.cnf 中的設定,對於效能的最佳化參數都在此調整;lower_case_table_names 這是為了讓表格名稱可以不分大小寫(事實上就是強制小寫)之用<br /><a href="http://3.bp.blogspot.com/-Gj7apoD-W78/WXb5_zyHalI/AAAAAAAAyOs/NJO3wPWl2UAR06KwgYc0DQWdPm6rPRUsACK4BGAYYCw/s1600/create-mysql-7.png" imageanchor="1"><img border="0" height="251" src="https://3.bp.blogspot.com/-Gj7apoD-W78/WXb5_zyHalI/AAAAAAAAyOs/NJO3wPWl2UAR06KwgYc0DQWdPm6rPRUsACK4BGAYYCw/s400/create-mysql-7.png" width="400" /></a></li>
<li>設定維護時間:用途不明,不予解釋</li>
</ol>
<div>
本案最後的參數設定如下,確認沒有問題後按下<b>建立</b>鈕開始建置 MySQL 資料庫。</div>
<div>
<a href="http://1.bp.blogspot.com/-mvvn3pd2KZo/WXb64wV53UI/AAAAAAAAyO4/Y0j3Z4zkTy069Gk8pgPW0qQVdDXzr2hkgCK4BGAYYCw/s1600/create-mysql-8.png" imageanchor="1"><img border="0" height="400" src="https://1.bp.blogspot.com/-mvvn3pd2KZo/WXb64wV53UI/AAAAAAAAyO4/Y0j3Z4zkTy069Gk8pgPW0qQVdDXzr2hkgCK4BGAYYCw/s400/create-mysql-8.png" width="371" /></a></div>
<div>
<br /></div>
<div>
建置 MySQL 資料庫中的畫面,它需要一點時間,可以先泡個咖啡再回來。</div>
<div>
<a href="http://3.bp.blogspot.com/-1m3Yj1cUs18/WXb8HC2OvEI/AAAAAAAAyPE/efY73atFD1QLGD5oDQ8EVq9V0CvHgxOBgCK4BGAYYCw/s1600/create-mysql-9.png" imageanchor="1"><img border="0" height="196" src="https://3.bp.blogspot.com/-1m3Yj1cUs18/WXb8HC2OvEI/AAAAAAAAyPE/efY73atFD1QLGD5oDQ8EVq9V0CvHgxOBgCK4BGAYYCw/s640/create-mysql-9.png" width="640" /></a></div>
<div>
<br /></div>
<div>
完成後的資訊主頁會像這樣,其中可以注意會有兩個對外 IP 且分佈於不同機房。</div>
<div>
<a href="http://2.bp.blogspot.com/-GyROP95K6wk/WXb9cwaWZAI/AAAAAAAAyPQ/m2ZIDqL0aGw-UT64mSqTbb6j_jNPY9PAgCK4BGAYYCw/s1600/create-mysql-10.png" imageanchor="1"><img border="0" height="196" src="https://2.bp.blogspot.com/-GyROP95K6wk/WXb9cwaWZAI/AAAAAAAAyPQ/m2ZIDqL0aGw-UT64mSqTbb6j_jNPY9PAgCK4BGAYYCw/s640/create-mysql-10.png" width="640" /></a><br />
<br /></div>
<div>
點選各 Instance ID 後即可管理該執行個體,除了檢視運作狀態外還包含修改配置、匯入、匯出、開關服務、複製、甚至刪除資料庫等操作。</div>
<div>
<a href="http://2.bp.blogspot.com/-EhcYpNMzsPo/WXb-mxu2GxI/AAAAAAAAyPc/NXxoSZYcNB8cYqI7o8SMgGx9TGaBUQfBgCK4BGAYYCw/s1600/create-mysql-11.png" imageanchor="1"><img border="0" height="364" src="https://2.bp.blogspot.com/-EhcYpNMzsPo/WXb-mxu2GxI/AAAAAAAAyPc/NXxoSZYcNB8cYqI7o8SMgGx9TGaBUQfBgCK4BGAYYCw/s640/create-mysql-11.png" width="640" /></a></div>
<ol><ul>
</ul>
</ol>
<div>
<br /></div>
測試是否可以透過 MySQL Client 分別連上這兩個執行個體。</div>
<div>
<ol>
<li>主資料庫<br /><a href="http://2.bp.blogspot.com/-BvGkJwDay2c/WXb_WpwHawI/AAAAAAAAyPo/IgKbHn2qgtUq2kSnNh-nfQlCnFYED96rQCK4BGAYYCw/s1600/create-mysql-12.png" imageanchor="1"><img border="0" height="321" src="https://2.bp.blogspot.com/-BvGkJwDay2c/WXb_WpwHawI/AAAAAAAAyPo/IgKbHn2qgtUq2kSnNh-nfQlCnFYED96rQCK4BGAYYCw/s640/create-mysql-12.png" width="640" /></a></li>
<li>容錯資料庫<br /><a href="http://3.bp.blogspot.com/-AsTmWNYBwPs/WXb_mxwjetI/AAAAAAAAyPw/9jHYOghJezc3RvM8hpbsGAKuSsNc6uVNgCK4BGAYYCw/s1600/create-mysql-13.png" imageanchor="1"><img border="0" height="312" src="https://3.bp.blogspot.com/-AsTmWNYBwPs/WXb_mxwjetI/AAAAAAAAyPw/9jHYOghJezc3RvM8hpbsGAKuSsNc6uVNgCK4BGAYYCw/s640/create-mysql-13.png" width="640" /></a></li>
</ol>
<h4>
建立空白資料庫</h4>
<div>
為了後續測試所需,此時先在主資料庫 demo 上建立一個空白資料庫,名稱為 springbootdemo,這個資料庫會自動複製到容錯資料庫 demo-failover 去。</div>
<pre><code class="language-sql">CREATE DATABASE springbootdemo
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;</code></pre>
<div>
<a href="http://3.bp.blogspot.com/-CMjAZJoFGhw/WXcDz2NGfGI/AAAAAAAAyP4/jNWh3N5DE306HaMT01HXX0lEVXYU4Ku3gCK4BGAYYCw/s1600/create-mysql-14.png" imageanchor="1"><img border="0" height="308" src="https://3.bp.blogspot.com/-CMjAZJoFGhw/WXcDz2NGfGI/AAAAAAAAyP4/jNWh3N5DE306HaMT01HXX0lEVXYU4Ku3gCK4BGAYYCw/s400/create-mysql-14.png" width="400" /></a><br />
<h4>
IP 參照設定</h4>
</div>
<div>
為了便於操作,可將 Cloud SQL for MySQL 的兩個 IP 寫入 /etc/hosts (Widnows 平台請參考 <a href="https://blog.gtwang.org/windows/windows-linux-hosts-file-configuration/">手動設定網址與 IP 對應的 hosts 檔教學,適用 Windows、Mac OS X 與 Linux 系統</a> 一文說明)內,此處設定 mysql.gcp 對應到<b>主資料庫</b>,failover.gcp 對應到<b>容錯資料庫</b>。<br />
<a href="http://2.bp.blogspot.com/-hibJAXQkYjM/WXdeE7txSeI/AAAAAAAAyS0/pmAKj7MBFU82NrvyKNnS9I3wagCp7hAfQCK4BGAYYCw/s1600/create-mysql-15.png" imageanchor="1"><img border="0" height="328" src="https://2.bp.blogspot.com/-hibJAXQkYjM/WXdeE7txSeI/AAAAAAAAyS0/pmAKj7MBFU82NrvyKNnS9I3wagCp7hAfQCK4BGAYYCw/s640/create-mysql-15.png" width="640" /></a></div>
<div>
</div>
<h3>
Spring Boot 示範程式</h3>
再來是開發一個可以存取 Cloud SQL for MySQL 的應用程序,這裡選擇使用 <a href="https://projects.spring.io/spring-boot/" target="_blank">Spring Boot</a> 開發框架。<br />
<br />
選擇 Spring Boot 的理由主要是因為它可以整合 Tomcat 這類型的 Application Server,當我們需要將服務置入 Docker Container 中執行時就可以不必額外處理 Tomcat 在各種不同 Linux 散佈套件的差異。<br />
<h4>
複製範例程式</h4>
這個範例程式的功能是模擬兩個 API,分別是<b>顯示被呼叫的主機名稱</b>及<b>中止應用程序</b>(模擬程序崩潰)。請自 Github 上複製 <a href="https://github.com/AdaHsu/SpringBootDemo" target="_blank">SpringBootDemo</a> 這個專案,關於 Spring Boot 的設定細節請自行參考網路文章,此處不特別說明:<br />
<br />
以下命令列指令可以將 SpringBootDemo 專案複製到本地工作:<br />
<pre><code class="language-bash">git clone https://github.com/AdaHsu/SpringBootDemo.git</code></pre>
整個示範程式的目錄結構如下圖,需要自行調整的參數設定都在 Maven 的設定檔 pom.xml 中:<br />
<a href="http://2.bp.blogspot.com/-u4i52VS9oO4/WXcILgmmpbI/AAAAAAAAyQQ/4BvS1pNcrHgfbPbJRfyb_c43X5It00JzgCK4BGAYYCw/s1600/springboot-1.png" imageanchor="1"><img border="0" height="560" src="https://2.bp.blogspot.com/-u4i52VS9oO4/WXcILgmmpbI/AAAAAAAAyQQ/4BvS1pNcrHgfbPbJRfyb_c43X5It00JzgCK4BGAYYCw/s640/springboot-1.png" width="640" /></a><br />
<h4>
修改 Maven 設定檔</h4>
在 pom.xml 中要修改的地方有 3 個,主要和資料庫存取有關:<br />
<ol>
<li>local profile 下的 JDBC 連線資訊:確認已設定好 mysql.gcp 的 IP 參照,或直接將 mysql.gcp 替換為 Cloud SQL for MySQL 提供的對外 IP<br /><a href="http://1.bp.blogspot.com/-Kjm8Uv53aEw/WXdfbmYZk1I/AAAAAAAAyTA/ld1RnREC8b8kUFhe5psQxpCHgQk2NImeQCK4BGAYYCw/s1600/springboot-2.png" imageanchor="1"><img border="0" height="90" src="https://1.bp.blogspot.com/-Kjm8Uv53aEw/WXdfbmYZk1I/AAAAAAAAyTA/ld1RnREC8b8kUFhe5psQxpCHgQk2NImeQCK4BGAYYCw/s640/springboot-2.png" width="640" /></a><br /><a href="http://2.bp.blogspot.com/-TfGYThqKylQ/WXdfj0iduwI/AAAAAAAAyTI/MP-z-Qrtxkc_wB8Rs2WbMZeT4usKCIn8gCK4BGAYYCw/s1600/springboot-2.5.png" imageanchor="1"><img border="0" height="156" src="https://2.bp.blogspot.com/-TfGYThqKylQ/WXdfj0iduwI/AAAAAAAAyTI/MP-z-Qrtxkc_wB8Rs2WbMZeT4usKCIn8gCK4BGAYYCw/s640/springboot-2.5.png" width="640" /></a></li>
<li>JDBC 的使用者帳密設定:一般環境下應該要建立應用程式專屬帳號<br /><a href="http://1.bp.blogspot.com/--EZhAD8DNFc/WXcIzFxnJcI/AAAAAAAAyQo/gLa0VYOVSzQMLR3O0cQ-QPx8T9knt_3yQCK4BGAYYCw/s1600/springboot-3.png" imageanchor="1"><img border="0" height="146" src="https://1.bp.blogspot.com/--EZhAD8DNFc/WXcIzFxnJcI/AAAAAAAAyQo/gLa0VYOVSzQMLR3O0cQ-QPx8T9knt_3yQCK4BGAYYCw/s640/springboot-3.png" width="640" /></a></li>
</ol>
<h4>
測試程式運作狀態</h4>
完成修改後即可進行功能測試,測試前請先確認 Cloud SQL for MySQL 執行個體已啟用,然後下達以下指令打包程式,-P local 是指定產生本地測試用的版本,若為 -P gcp 則會產生 GCP 上適用的版本,可以從打包出來的檔名確認對應的執行環境。<br />
<pre><code class="language-bash">mvn -P local clean package</code></pre>
完成打包後會產生 target 目錄,此處已設定打包後的 jar 檔檔名會依指定的 Profile 不同而變化。<br />
<a href="http://3.bp.blogspot.com/-8D06CAIqkYU/WXcJ78aWACI/AAAAAAAAyQ4/2cDL99A1WPAk9JBfpSJ0oNQPTc3Cv_saQCK4BGAYYCw/s1600/springboot-4.png" imageanchor="1"><img border="0" height="138" src="https://3.bp.blogspot.com/-8D06CAIqkYU/WXcJ78aWACI/AAAAAAAAyQ4/2cDL99A1WPAk9JBfpSJ0oNQPTc3Cv_saQCK4BGAYYCw/s640/springboot-4.png" width="640" /></a><br />
<br />
為確保程式運作正常,建議先檢查資料庫連線參數是否正確設定,此參數應與 Maven 設定檔中設定的內容一致。<br />
<pre><code class="language-bash">head target/classes/application.properties</code></pre>
<a href="http://2.bp.blogspot.com/-62EU4crVx-Y/WXdhBAxsqaI/AAAAAAAAyTU/4Yef_CcWtJ09nKwqdvtxgNTLDMsTpsOXQCK4BGAYYCw/s1600/springboot-5.png" imageanchor="1"><img border="0" height="232" src="https://2.bp.blogspot.com/-62EU4crVx-Y/WXdhBAxsqaI/AAAAAAAAyTU/4Yef_CcWtJ09nKwqdvtxgNTLDMsTpsOXQCK4BGAYYCw/s640/springboot-5.png" width="640" /></a><br />
<br />
如果是 Windows 平台,那麼指令應該要改成如下:
<br />
<pre><code class="language-batch">type target/classes/application.properties</code></pre>
<br />
預先以 MySQL Client 連上資料庫,確認資料庫內未建立任何表格。<br />
<a href="http://4.bp.blogspot.com/-uGaQtBydqgE/WXcM3JFa_FI/AAAAAAAAyRU/kVahZHR-aHw2Q-a-Vh6JAlR7Fj5n1luaACK4BGAYYCw/s1600/springboot-6.png" imageanchor="1"><img border="0" height="368" src="https://4.bp.blogspot.com/-uGaQtBydqgE/WXcM3JFa_FI/AAAAAAAAyRU/kVahZHR-aHw2Q-a-Vh6JAlR7Fj5n1luaACK4BGAYYCw/s640/springboot-6.png" width="640" /></a><br />
<br />
啟動 Spring Boot 應用程式,若 JPA 能連接資料庫的話就不會有錯誤訊息,否則就會崩潰結束。<br />
<pre><code class="language-bash">java -jar target/SpringBootDemo-local.jar</code></pre>
<a href="http://4.bp.blogspot.com/-318Yrey239E/WXcNwI1KTgI/AAAAAAAAyRg/XlibRwfyyf4WFdX8LbolhcR0T_ty5zWMACK4BGAYYCw/s1600/springboot-7.png" imageanchor="1"><img border="0" height="130" src="https://4.bp.blogspot.com/-318Yrey239E/WXcNwI1KTgI/AAAAAAAAyRg/XlibRwfyyf4WFdX8LbolhcR0T_ty5zWMACK4BGAYYCw/s640/springboot-7.png" width="640" /></a><br />
<br />
檢視資料庫,確認 access_logs 表格已被建立出來。<br />
<a href="http://3.bp.blogspot.com/-FTk_hf3HChY/WXcOF6y-vhI/AAAAAAAAyRo/MlIW2BG3yYQxOgma0uGiVjycn3spPRa5wCK4BGAYYCw/s1600/springboot-8.png" imageanchor="1"><img border="0" height="244" src="https://3.bp.blogspot.com/-FTk_hf3HChY/WXcOF6y-vhI/AAAAAAAAyRo/MlIW2BG3yYQxOgma0uGiVjycn3spPRa5wCK4BGAYYCw/s320/springboot-8.png" width="320" /></a><br />
<h4>
驗證 API</h4>
第一個 API 的用途是將呼叫記錄寫入資料庫內,並且傳回提供服務的主機名稱,在部署到 Google Container Engine 時將用於識別是哪一個容器 / Pod 提供服務的。<br />
<pre><code class="language-bash">curl http://localhost:8080</code></pre>
<a href="http://3.bp.blogspot.com/-Aet3h3m2H7I/WXcPcLRZsqI/AAAAAAAAyR0/fp1sN3H40sAzipnwamPJjUuMLMli-y9fwCK4BGAYYCw/s1600/springboot-9.png" imageanchor="1"><img border="0" height="85" src="https://3.bp.blogspot.com/-Aet3h3m2H7I/WXcPcLRZsqI/AAAAAAAAyR0/fp1sN3H40sAzipnwamPJjUuMLMli-y9fwCK4BGAYYCw/s400/springboot-9.png" width="400" /></a><br />
<br />
第二個 API 的用途是中斷 Spring Boot 應用系統的執行,目的是模擬系統異常導致服務終止的情形。<br />
<pre><code class="language-bash">curl http://localhost:8080/crash</code></pre>
<a href="http://4.bp.blogspot.com/-6zoIrqYTgpo/WXcQaPEiYpI/AAAAAAAAyR8/doypYBymvuQ-oh40zy4QWFxojk8zJFEjwCK4BGAYYCw/s1600/springboot-10.png" imageanchor="1"><img border="0" height="80" src="https://4.bp.blogspot.com/-6zoIrqYTgpo/WXcQaPEiYpI/AAAAAAAAyR8/doypYBymvuQ-oh40zy4QWFxojk8zJFEjwCK4BGAYYCw/s400/springboot-10.png" width="400" /></a><br />
<br />
呼叫結束後可以確認到 Spring Boot 應用程式被終止。<br />
<a href="http://4.bp.blogspot.com/-vk1qXnlYjVk/WXcRAZzlfRI/AAAAAAAAySM/C7svTjaar5YY6-UXoVq0iQTRZ9HXkezNACK4BGAYYCw/s1600/springboot-11.png" imageanchor="1"><img border="0" height="204" src="https://4.bp.blogspot.com/-vk1qXnlYjVk/WXcRAZzlfRI/AAAAAAAAySM/C7svTjaar5YY6-UXoVq0iQTRZ9HXkezNACK4BGAYYCw/s640/springboot-11.png" width="640" /></a>
<br />
<br />
<div>
檢視資料庫,確認兩次呼叫記錄已被保存。</div>
<div>
<a href="http://3.bp.blogspot.com/-Vc1EfB_dFBU/WXcRUhP7AUI/AAAAAAAAySU/Uo6mVQM2-y4VJXGKZNlh3mNHugnCaK5zQCK4BGAYYCw/s1600/springboot-12.png" imageanchor="1"><img border="0" height="166" src="https://3.bp.blogspot.com/-Vc1EfB_dFBU/WXcRUhP7AUI/AAAAAAAAySU/Uo6mVQM2-y4VJXGKZNlh3mNHugnCaK5zQCK4BGAYYCw/s640/springboot-12.png" width="640" /></a><br />
<br /></div>
<div>
確認容錯資料庫內容也已同步更新。<br />
<pre><code class="language-bash">echo "select * from access_logs;" | mysql -u root -h failover.gcp -p springbootdemo</code></pre>
<a href="http://1.bp.blogspot.com/-atIDeRDrhxw/WXdiaCcDRTI/AAAAAAAAyTc/oQ7qfmPLIhMFdBd6IXRW6-JzERQY_bF7wCK4BGAYYCw/s1600/springboot-13.png" imageanchor="1"><img border="0" height="112" src="https://1.bp.blogspot.com/-atIDeRDrhxw/WXdiaCcDRTI/AAAAAAAAyTc/oQ7qfmPLIhMFdBd6IXRW6-JzERQY_bF7wCK4BGAYYCw/s640/springboot-13.png" width="640" /></a></div>
<h3>
打包 Docker 映像檔</h3>
從 Github 上下 clone 下來的檔案庫中包含兩個協助打包的 Dockerfile ,分別對應到打包成 local 及 gcp 兩個環境。<br />
<a href="http://4.bp.blogspot.com/-WBi5s-p_19o/WXdiyJ2ukkI/AAAAAAAAyTk/MgRqYEYw52wJkO9D8HjvssXjUtkE2UXBQCK4BGAYYCw/s1600/docker-1.png" imageanchor="1"><img border="0" height="74" src="https://4.bp.blogspot.com/-WBi5s-p_19o/WXdiyJ2ukkI/AAAAAAAAyTk/MgRqYEYw52wJkO9D8HjvssXjUtkE2UXBQCK4BGAYYCw/s640/docker-1.png" width="640" /></a><br />
<h4>
打包本地測試用映像檔</h4>
以下指令可以打包一個本地進行測試用的 docker image,MYSQL_IP 是記錄 /etc/hosts 中 demo.gcp 所指向 Cloud SQL for MySQL 的 Public IP,Windows 平台使用者請直接將 ${MYSQL_IP} 替換成 IP 位址即可:<br />
<pre><code class="language-bash">MYSQL_IP=$(grep mysql.gcp /etc/hosts | cut -d\ -f 1)
docker build -t spring-boot-demo:1 \
--add-host=mysql.gcp:${MYSQL_IP} \
-f Dockerfile.local .
</code></pre>
<a href="http://1.bp.blogspot.com/-vNSiTJpMVSc/WXdjOEYTuGI/AAAAAAAAyTs/e-Hm-98B0xU5M0fPevN3NN6XGEZKuAfdwCK4BGAYYCw/s1600/docker-2.png" imageanchor="1"><img border="0" height="418" src="https://1.bp.blogspot.com/-vNSiTJpMVSc/WXdjOEYTuGI/AAAAAAAAyTs/e-Hm-98B0xU5M0fPevN3NN6XGEZKuAfdwCK4BGAYYCw/s640/docker-2.png" width="640" /></a><br />
<br />
若是已將 pom.xml 中的 JDBC 連線字串替換成 IP 位址的話,那麼打包指令中的 --add-host 這段參數可以拿掉。<br />
<br />
若是 Windows 平台可以直接給定 mysql.gcp 所對應的 IP,以下指令請記得替換 <mysql public ip> 為實際 IP:
<br />
<pre><code class="language-bash">docker build -t spring-boot-demo:1 --add-host=mysql.gcp:<mysql public ip> -f Dockerfile.local .</code></pre>
<h4>
驗證映像檔 </h4>
打包完畢後可以啟動這個 Container 映像檔確認是否正常運作。
<br />
<pre><code class="language-bash">docker run --rm -p 8080:8080 spring-boot-demo:1</code></pre>
檢視 API 是否可被呼叫?<br />
<a href="http://3.bp.blogspot.com/-HxTv7vbxSsI/WXdlL64amdI/AAAAAAAAyT0/j4etUouaRf0HfoF_qO53LzA4aTeAbXlsgCK4BGAYYCw/s1600/docker-3.png" imageanchor="1"><img border="0" height="167" src="https://3.bp.blogspot.com/-HxTv7vbxSsI/WXdlL64amdI/AAAAAAAAyT0/j4etUouaRf0HfoF_qO53LzA4aTeAbXlsgCK4BGAYYCw/s400/docker-3.png" width="400" /></a><br />
<h4>
打包 GCP 線上版本</h4>
GCP 下載 Docker Images 的來源有二:第一種是上傳到 Docker Hub,另一種方式則是上傳到專案所在的 Cloud Storage 中。上傳到 Cloud Storage 時需指定 Docker 映像檔的 Tag,格式為 <b>gcr.io/<專案 ID>/<映像檔名>:<標籤></b>,其中 <專案 ID> 請參考專案資訊主頁中的<b>專案資訊</b>卡片。<br />
<a href="http://2.bp.blogspot.com/-7oZTXPR3hwk/WXdq17G5RGI/AAAAAAAAyUE/0MFgj8vmD2w72ZZMjRQ20VqGTVaEdEgagCK4BGAYYCw/s1600/docker-4.png" imageanchor="1"><img border="0" height="400" src="https://2.bp.blogspot.com/-7oZTXPR3hwk/WXdq17G5RGI/AAAAAAAAyUE/0MFgj8vmD2w72ZZMjRQ20VqGTVaEdEgagCK4BGAYYCw/s400/docker-4.png" width="350" /></a><br />
<br />
以下指令可以打包一個在 GCP 上運行的 Docker 映像檔,為了避免包裝映像檔失敗,此處會重新打包 Spring Boot 範例程式:
<br />
<pre><code class="language-bash">mvn -P gcp clean package
docker build -t gcr.io/springboot-demo/spring-boot-demo:1 -f Dockerfile.gcp .</code></pre>
<a href="http://2.bp.blogspot.com/-MhmHvtKto0w/WXdrvxc9brI/AAAAAAAAyUM/UQr2rqT8AW4Er0HQIXVo_hwuiRMtyGDDwCK4BGAYYCw/s1600/docker-5.png" imageanchor="1"><img border="0" height="324" src="https://2.bp.blogspot.com/-MhmHvtKto0w/WXdrvxc9brI/AAAAAAAAyUM/UQr2rqT8AW4Er0HQIXVo_hwuiRMtyGDDwCK4BGAYYCw/s640/docker-5.png" width="640" /></a><br />
<br />
稍候會將這個映像檔上傳到 Google Cloud Storage 中供 Container Engine 叫用。<br />
<h3>
建立 Google 容器叢集</h3>
<div>
Google Container Engine (GCE,有時會看到 GKE 指的是同一個服務) 是 Google 提供的容器服務,在使用容器服務之前需要建立一個用於部署容器的<b>容器叢集</b>。</div>
<div>
<br /></div>
<div>
拉出左側<b>產品與服務</b>選單,點選 <b>Container Engine</b> 功能項後即可進入 Container Engine 資訊主頁,第一次進入這個主頁時可能需要一點時間啟用 Container Engine 服務。<br />
<a href="http://3.bp.blogspot.com/-5n4-QECyj7I/WXf1s8GmHbI/AAAAAAAAyUc/XmCct-POwI8ALnSQ8ns4CMkzvZxB--YmACK4BGAYYCw/s1600/container-1.png" imageanchor="1"><img border="0" height="400" src="https://3.bp.blogspot.com/-5n4-QECyj7I/WXf1s8GmHbI/AAAAAAAAyUc/XmCct-POwI8ALnSQ8ns4CMkzvZxB--YmACK4BGAYYCw/s400/container-1.png" width="370" /></a><br />
<br />
有時候可能會發生沒有 Compute Engine API 權限而無法啟用 Container Engine 服務的問題,通常只要重新進入 Container Engine 資訊主頁即可改善。</div>
<div>
</div>
<h4>
建立容器叢集</h4>
<div>
在 Container Engine 資訊主頁中可以透過<b>建立容器叢集</b>按鈕建立新的叢集。</div>
<div>
<a href="http://2.bp.blogspot.com/-FMxGFnUfsTk/WXf4Hx-FUQI/AAAAAAAAyUw/LA64meX7AhsnC5UaAqX5ozclMomhdwGcQCK4BGAYYCw/s1600/container-2.png" imageanchor="1"><img border="0" height="272" src="https://2.bp.blogspot.com/-FMxGFnUfsTk/WXf4Hx-FUQI/AAAAAAAAyUw/LA64meX7AhsnC5UaAqX5ozclMomhdwGcQCK4BGAYYCw/s640/container-2.png" width="640" /></a></div>
<div>
<br /></div>
<div>
容器叢集基本上是透過 Compute Engine 裡頭的 VM 組建而成,它需要決定這個叢集的運作能量(財力決定能力?)。</div>
<div>
<ol>
<li>設定叢集參數(一)<br /><a href="http://3.bp.blogspot.com/-CmxbE8EY60c/WXf5sccsG_I/AAAAAAAAyU8/NvM_MLHGAowxURNo7UJj6-Zv58KsHOaxQCK4BGAYYCw/s1600/container-3.png" imageanchor="1"><img border="0" height="391" src="https://3.bp.blogspot.com/-CmxbE8EY60c/WXf5sccsG_I/AAAAAAAAyU8/NvM_MLHGAowxURNo7UJj6-Zv58KsHOaxQCK4BGAYYCw/s400/container-3.png" width="400" /></a></li>
<ul>
<li>名稱:本叢集的名稱</li>
<li>說明:若有多個叢集共存的情形下,可以在此填寫一些說明內容</li>
<li>區域:要將叢集放在哪個機房,此處放在先前建立的 Cloud SQL for MySQL 相同的機房內</li>
<li>叢集版本:這個應該不用動</li>
<li>機器類型:視需要自行調整,老話一句:財力決定規格、規格決定能力</li>
</ul>
<li>設定叢集參數(二)<br /><a href="http://4.bp.blogspot.com/-vCioow7MBwM/WXf7H96joeI/AAAAAAAAyVI/oy0p7oPadN0LM6r6rD1xdFgikG6_7GiTACK4BGAYYCw/s1600/container-4.png" imageanchor="1"><img border="0" height="365" src="https://4.bp.blogspot.com/-vCioow7MBwM/WXf7H96joeI/AAAAAAAAyVI/oy0p7oPadN0LM6r6rD1xdFgikG6_7GiTACK4BGAYYCw/s400/container-4.png" width="400" /></a></li>
<ul>
<li>節點映像檔:此案單純將 VM 當成容器載體,所以都選擇 Container-Optimized OS 這種映像檔</li>
<li>大小:指的是叢集大小,也就是多少個叢集節點(主機數),此處選 3 是為了後續驗證負載平衡及應用程序崩潰時是否會影響服務之用</li>
<li>其他參數暫時不需理會,直接按<b>建立</b>鈕即可開始建立容器叢集</li>
</ul>
<ul>
</ul>
<li>花一點時間(聽說 Google 優化過了,現在來不及去泡咖啡了)讓容器叢集成功建立後就可在 Container Engine 資訊主頁中看到叢集的相關資訊<br /><a href="http://3.bp.blogspot.com/-T3E8K-q4h1s/WXf-HTwQtQI/AAAAAAAAyVU/XI0k4WIeBcwYiXZE4GMiLa_E9uhKmBXIwCK4BGAYYCw/s1600/container-5.png" imageanchor="1"><img border="0" height="208" src="https://3.bp.blogspot.com/-T3E8K-q4h1s/WXf-HTwQtQI/AAAAAAAAyVU/XI0k4WIeBcwYiXZE4GMiLa_E9uhKmBXIwCK4BGAYYCw/s640/container-5.png" width="640" /></a></li>
<li>切換到 Compute Engine 資訊主頁中可以看到 3 個 VM 執行個體<br /><a href="http://1.bp.blogspot.com/-dNODHcBYE7w/WXf-o4bAS6I/AAAAAAAAyVc/iakTwwXJIWM2z1ZJrwaBhqvO93Hey2h6QCK4BGAYYCw/s1600/container-6.png" imageanchor="1"><img border="0" height="186" src="https://1.bp.blogspot.com/-dNODHcBYE7w/WXf-o4bAS6I/AAAAAAAAyVc/iakTwwXJIWM2z1ZJrwaBhqvO93Hey2h6QCK4BGAYYCw/s640/container-6.png" width="640" /></a></li>
<li>可以直接在瀏覽器中連接 VM 進行操作,有瀏覽器就能進行管理(但好不好用要看平台,用手機相信是很難用就是了)<br /><a href="http://4.bp.blogspot.com/-1o4-NQtfFM4/WXf_SgSUEOI/AAAAAAAAyVk/d7thygu1PO8YsHpGlVRXETEIPC1gSdcywCK4BGAYYCw/s1600/container-7.png" imageanchor="1"><img border="0" height="232" src="https://4.bp.blogspot.com/-1o4-NQtfFM4/WXf_SgSUEOI/AAAAAAAAyVk/d7thygu1PO8YsHpGlVRXETEIPC1gSdcywCK4BGAYYCw/s640/container-7.png" width="640" /></a></li>
<li>這是個 Kubernetes 專屬 VM,必然會看到一堆 Kubernetes 相關的容器在運作<br /><a href="http://2.bp.blogspot.com/-JzUzaiJPtZg/WXgAem8N1CI/AAAAAAAAyVw/B3Wg9ABXIYwUPWSOX7Fl0AqvnBo241UGQCK4BGAYYCw/s1600/container-8.png" imageanchor="1"><img border="0" height="476" src="https://2.bp.blogspot.com/-JzUzaiJPtZg/WXgAem8N1CI/AAAAAAAAyVw/B3Wg9ABXIYwUPWSOX7Fl0AqvnBo241UGQCK4BGAYYCw/s640/container-8.png" width="640" /></a></li>
<li>有些網路工具像是 ping、traceroute 等等預設是未安裝的,可以透過執行 toolbox 指令另外弄一個容器來提供這些功能<br /><a href="http://3.bp.blogspot.com/-_Z_o1FyiuLA/WXgB7GR8pGI/AAAAAAAAyV4/rw_GvjEehIAVnpkGiejKZsdRdxWEhXAYQCK4BGAYYCw/s1600/container-9.png" imageanchor="1"><img border="0" height="360" src="https://3.bp.blogspot.com/-_Z_o1FyiuLA/WXgB7GR8pGI/AAAAAAAAyV4/rw_GvjEehIAVnpkGiejKZsdRdxWEhXAYQCK4BGAYYCw/s640/container-9.png" width="640" /></a></li>
</ol>
</div>
<h3>
安裝 Google Cloud SDK</h3>
<div>
Google Cloud Platform 雖然是以專案方式管理某項服務所需的各種資源,例如本案中的 Cloud SQL for MySQL、Container Engine 等等,但 Cloud SQL 和 Container Engine 之間並無互通,要讓 Container 能連接上 Cloud SQL 必須透過 Cloud SQL Proxy 進行轉接。目前這些設定步驟尚無法完全透過 Web UI 加以操作,取而代之必須使用 Google Cloud SDK 進行設定。<br />
<br />
回到專案的資訊主頁,在<b>入門指南</b>這個資訊卡片下有一個『安裝 Cloud SDK』的連結,點擊它後即可取得各平台的安裝檔案(macOS 可以透過 <a href="https://caskroom.github.io/" target="_blank">Homebrew-Cask</a> 安裝),請依指示完成 Cloud SDK 安裝。<br />
<a href="http://2.bp.blogspot.com/-3W5agU2dbMw/WXgDgXhSecI/AAAAAAAAyWE/Az-SIjY4spUYg0xpOT42ClnKip7qcS_xgCK4BGAYYCw/s1600/sdk-1.png" imageanchor="1"><img border="0" height="400" src="https://2.bp.blogspot.com/-3W5agU2dbMw/WXgDgXhSecI/AAAAAAAAyWE/Az-SIjY4spUYg0xpOT42ClnKip7qcS_xgCK4BGAYYCw/s400/sdk-1.png" width="293" /></a><br />
<h4>
初始化 Cloud SDK</h4>
</div>
<div>
安裝完 Cloud SDK 後需要進行初始化操作以授權存取 Google Cloud Platform,指令如下:</div>
<pre><code class="language-bash">gcloud init</code></pre>
<ol>
<li>初始化過程中會透過瀏覽器進行線上認證<br /><a href="http://1.bp.blogspot.com/-XjUxxF3OJdQ/WXgFISjN4ZI/AAAAAAAAyWQ/WCS5K1-O_vUxsyeQx2RvkSlIELaMqdB_wCK4BGAYYCw/s1600/sdk-2.png" imageanchor="1"><img border="0" height="322" src="https://1.bp.blogspot.com/-XjUxxF3OJdQ/WXgFISjN4ZI/AAAAAAAAyWQ/WCS5K1-O_vUxsyeQx2RvkSlIELaMqdB_wCK4BGAYYCw/s640/sdk-2.png" width="640" /></a></li>
<li>需同意 Google Cloud SDK 這些權限<br /><a href="http://3.bp.blogspot.com/-vtLg-i3bPyk/WXgFk-zJvYI/AAAAAAAAyWY/1XonfJC2cG4MLzRBGbVEw4g_95U_KEGNwCK4BGAYYCw/s1600/sdk-3.png" imageanchor="1"><img border="0" height="400" src="https://3.bp.blogspot.com/-vtLg-i3bPyk/WXgFk-zJvYI/AAAAAAAAyWY/1XonfJC2cG4MLzRBGbVEw4g_95U_KEGNwCK4BGAYYCw/s400/sdk-3.png" width="280" /></a> </li>
<li>指定預設的專案<br /><a href="http://2.bp.blogspot.com/-QlWQXEm1BCA/WXgF7LKjhRI/AAAAAAAAyWg/BFkkz-RNeGYEz7Lq0OVAoCt5W1mUJ2zRACK4BGAYYCw/s1600/sdk-4.png" imageanchor="1"><img border="0" height="158" src="https://2.bp.blogspot.com/-QlWQXEm1BCA/WXgF7LKjhRI/AAAAAAAAyWg/BFkkz-RNeGYEz7Lq0OVAoCt5W1mUJ2zRACK4BGAYYCw/s640/sdk-4.png" width="640" /></a></li>
<li>設定 Compute Engine 預設的機房:應該是指若是透過 Cloud SDK 指令方式建立的 VM 都會以這個設定為準,這裡選 asia-east1-a<br /><a href="http://2.bp.blogspot.com/-RRtQaqQPjR4/WXgGUDAXqNI/AAAAAAAAyWo/hxMZlyM-u6smHO1V93k4m0zUrdCeG1PMwCK4BGAYYCw/s1600/sdk-5.png" imageanchor="1"><img border="0" height="294" src="https://2.bp.blogspot.com/-RRtQaqQPjR4/WXgGUDAXqNI/AAAAAAAAyWo/hxMZlyM-u6smHO1V93k4m0zUrdCeG1PMwCK4BGAYYCw/s640/sdk-5.png" width="640" /></a></li>
<li>初始化完成後會提示目前登入的帳號、預設專案、以及預設機房<br /><a href="http://3.bp.blogspot.com/-EX7iKUrbnkI/WXgGu3xdZFI/AAAAAAAAyWw/GOacYUtrM2AV8vlu32lxfoNLcEo60xlHQCK4BGAYYCw/s1600/sdk-6.png" imageanchor="1"><img border="0" height="80" src="https://3.bp.blogspot.com/-EX7iKUrbnkI/WXgGu3xdZFI/AAAAAAAAyWw/GOacYUtrM2AV8vlu32lxfoNLcEo60xlHQCK4BGAYYCw/s640/sdk-6.png" width="640" /></a></li>
<li>日後隨時可以檢視這些設定,也可以修改<br />
<pre><code class="language-bash">gcloud config list</code></pre>
<a href="http://2.bp.blogspot.com/-EjhqX4MZz5Y/WXgIDhgRNEI/AAAAAAAAyW8/SBf6_e6JjBsmLfXUy52-bhQIraJ0segugCK4BGAYYCw/s1600/sdk-7.png" imageanchor="1"><img border="0" height="247" src="https://2.bp.blogspot.com/-EjhqX4MZz5Y/WXgIDhgRNEI/AAAAAAAAyW8/SBf6_e6JjBsmLfXUy52-bhQIraJ0segugCK4BGAYYCw/s400/sdk-7.png" width="400" /></a></li>
</ol>
<h4>
管理 Cloud SDK 設定檔</h4>
<div>
若有多個 GCP 專案,則重覆執行 init 指令即可建立相應的設定檔。<br />
<a href="http://3.bp.blogspot.com/-W68AuzfEu14/WXgNb6wdS1I/AAAAAAAAyXI/pULV5YBYurMau1Z2LjzjiPDcM3mFCE5fgCK4BGAYYCw/s1600/sdk-8.png" imageanchor="1"><img border="0" height="346" src="https://3.bp.blogspot.com/-W68AuzfEu14/WXgNb6wdS1I/AAAAAAAAyXI/pULV5YBYurMau1Z2LjzjiPDcM3mFCE5fgCK4BGAYYCw/s640/sdk-8.png" width="640" /></a>
</div>
<div>
<br />
檢視目前已建立的專案 / 設定檔,新建立的設定檔會自動啟用。<br />
<pre><code class="language-bash">gcloud config configurations list</code></pre>
<a href="http://2.bp.blogspot.com/-fSVzYJqxYUs/WXgOA71sJwI/AAAAAAAAyXQ/JHbsjzn_wVcAzINX4movgZWi0jiu_L1LQCK4BGAYYCw/s1600/sdk-9.png" imageanchor="1"><img border="0" height="80" src="https://2.bp.blogspot.com/-fSVzYJqxYUs/WXgOA71sJwI/AAAAAAAAyXQ/JHbsjzn_wVcAzINX4movgZWi0jiu_L1LQCK4BGAYYCw/s640/sdk-9.png" width="640" /></a></div>
<div>
</div>
<div>
<br />
在多個設定檔同時存在的情形下,可以依需要啟用所需設定檔:
<br />
<pre><code class="language-bash">gcloud config configurations activate <proejct id></code></pre>
<a href="http://2.bp.blogspot.com/-cNloBuCGCOg/WXgPPnbZkOI/AAAAAAAAyXc/yG78XXbcFtkhvX3QEuFNMXr8I_h8HwstQCK4BGAYYCw/s1600/sdk-10.png" imageanchor="1"><img border="0" height="73" src="https://2.bp.blogspot.com/-cNloBuCGCOg/WXgPPnbZkOI/AAAAAAAAyXc/yG78XXbcFtkhvX3QEuFNMXr8I_h8HwstQCK4BGAYYCw/s400/sdk-10.png" width="400" /></a></div>
<br />
不需要的設定設定檔可以刪除,但不能刪除啟用中的設定檔。
<br />
<pre><code class="language-bash">gcloud config configurations delete <proejct id></code></pre>
<a href="http://4.bp.blogspot.com/-Ay3ejNXa0hY/WXgQSA6FeAI/AAAAAAAAyXk/rMjAr7DNr1ImdIEXXAHtyFc3tDAThy9ZQCK4BGAYYCw/s1600/sdk-11.png" imageanchor="1"><img border="0" height="126" src="https://4.bp.blogspot.com/-Ay3ejNXa0hY/WXgQSA6FeAI/AAAAAAAAyXk/rMjAr7DNr1ImdIEXXAHtyFc3tDAThy9ZQCK4BGAYYCw/s400/sdk-11.png" width="400" /></a><br />
<h4>
使用 Cloud SDK 進行管理 Cloud SQL</h4>
<div>
前面使用 Google Cloud Console 資訊主頁的各項操作都可以透過 Cloud SDK 完成相關設定,但是 Cloud SDK 之所以重要是因為它能讓管理人員在任何地方皆能連接 Cloud SQL for MySQL,此特性讓維運人員即使是在 4G 環境下仍然可以隨時檢視 Cloud SQL for MySQL 的資料庫狀況。</div>
<div>
<br /></div>
<div>
檢查專案中資料庫列表:
<br />
<pre><code class="language-bash">gcloud sql instances list</code></pre>
<a href="http://2.bp.blogspot.com/-scsTs9tXrZ0/WXgTrVh-PjI/AAAAAAAAyXw/ZE5TSBsWQCkpsNOHpZ6TW2Ixjv_1eBblQCK4BGAYYCw/s1600/sdk-12.png" imageanchor="1"><img border="0" height="96" src="https://2.bp.blogspot.com/-scsTs9tXrZ0/WXgTrVh-PjI/AAAAAAAAyXw/ZE5TSBsWQCkpsNOHpZ6TW2Ixjv_1eBblQCK4BGAYYCw/s640/sdk-12.png" width="640" /></a></div>
<br />
連線資料庫進行管理,為了讓管理人員隨時連線,Cloud SDK 需要一點時間調整防火牆設定:<br />
<pre><code class="language-bash">gcloud sql connect <db instance name> -u <user name></code></pre>
<a href="http://1.bp.blogspot.com/-CU7aTR3u_oo/WXgUc96jV_I/AAAAAAAAyX8/SHePp1CxClg2OisZtfOYhnB6EjQRO0f3ACK4BGAYYCw/s1600/sdk-13.png" imageanchor="1"><img border="0" height="492" src="https://1.bp.blogspot.com/-CU7aTR3u_oo/WXgUc96jV_I/AAAAAAAAyX8/SHePp1CxClg2OisZtfOYhnB6EjQRO0f3ACK4BGAYYCw/s640/sdk-13.png" width="640" /></a>
<br />
<h3>
設定 Cloud SQL Proxy</h3>
<div>
雖然覺得很蠢,但目前想要從 Google Container Engine 連接 Cloud SQL 服務的話,必須另外設定 Proxy,帶來的好處是應用程式開發時使用的 JDBC 資料庫連線都是指向本機 localhost 的,和一般開發過程中直接連線本地 MySQL 狀況相似。以下說明皆依據 <a href="https://cloud.google.com/sql/docs/mysql/connect-container-engine" target="_blank">官方說明文件</a> 進行整理,並加入個人驗證經驗。</div>
<div>
<h4>
安裝 kubernetes 管理元件</h4>
<div>
透過以下指令可以協助安裝管理 kubernetes 所需的管理元件。
<br />
<pre><code class="language-bash">gcloud components install kubectl</code></pre>
<a href="http://4.bp.blogspot.com/-eEUaIzcH7yY/WXgVdAhRIeI/AAAAAAAAyYI/F2HuHoNSVQUcoBIWswtj6enKwOLdUbBpgCK4BGAYYCw/s1600/proxy-1.png" imageanchor="1"><img border="0" height="95" src="https://4.bp.blogspot.com/-eEUaIzcH7yY/WXgVdAhRIeI/AAAAAAAAyYI/F2HuHoNSVQUcoBIWswtj6enKwOLdUbBpgCK4BGAYYCw/s400/proxy-1.png" width="400" /></a></div>
<br />
將 Cloud SDK 使用中的憑證授權給 kubectl 使用。
<br />
<pre><code class="language-bash">gcloud container clusters get-credentials <叢集名稱></code></pre>
<a href="http://3.bp.blogspot.com/-Vf88DksjWWg/WXjD2h-2vCI/AAAAAAAAyao/ns6xIrZlsxs1iBkRdv_yhchF9y0knjbHwCK4BGAYYCw/s1600/proxy-1.5.png" imageanchor="1"><img border="0" height="107" src="https://3.bp.blogspot.com/-Vf88DksjWWg/WXjD2h-2vCI/AAAAAAAAyao/ns6xIrZlsxs1iBkRdv_yhchF9y0knjbHwCK4BGAYYCw/s640/proxy-1.5.png" width="640" /></a><br />
<br />
以下指令可以檢視 Cloud SDK 目前支援的、已安裝的元件列表。<br />
<pre><code class="language-bash">gcloud componets list</code></pre>
<h4>
啟用 Cloud SQL API</h4>
</div>
<div>
請透過 <a href="https://console.cloud.google.com/flows/enableapi?apiid=sqladmin&redirect=https:%2F%2Fconsole.cloud.google.com">這個連結</a> 啟用 Cloud SQL 管理 API,也可以從 <b>產品與服務</b> --> <b>API 管理員</b> 的資訊主頁中選擇啟用 Cloud SQL API。<br />
<a href="http://2.bp.blogspot.com/-uvdAoQwr8OA/WXgXUz_ITnI/AAAAAAAAyYY/E0ueSYEhECAo3oeU4RW2t3_PiwGaI5afACK4BGAYYCw/s1600/proxy-2.png" imageanchor="1"><img border="0" height="283" src="https://2.bp.blogspot.com/-uvdAoQwr8OA/WXgXUz_ITnI/AAAAAAAAyYY/E0ueSYEhECAo3oeU4RW2t3_PiwGaI5afACK4BGAYYCw/s400/proxy-2.png" width="400" /></a>
<br />
<h4>
建立服務帳號</h4>
<div>
Cloud SQL Proxy 需要一個服務帳號串接 Container 及 Compute 平台,請從 Console 的 <b>產品與服務</b> --> <b>IAM 與管理</b> --> <b>服務帳戶</b> 功能選項中進入,或者直接點選 <a href="https://console.cloud.google.com/iam-admin/serviceaccounts/">這個連結</a> 進入前述資訊主頁(需再指定專案 ID)。預設會有一個用於連接 Compute Engine 的服務帳號。<br />
<a href="http://2.bp.blogspot.com/-8esMaDCFooI/WXgYnnMFheI/AAAAAAAAyYk/UEAIbz4GJ2AFGY8-Nlm_34YTpuqo9JvDgCK4BGAYYCw/s1600/proxy-3.png" imageanchor="1"><img border="0" height="220" src="https://2.bp.blogspot.com/-8esMaDCFooI/WXgYnnMFheI/AAAAAAAAyYk/UEAIbz4GJ2AFGY8-Nlm_34YTpuqo9JvDgCK4BGAYYCw/s640/proxy-3.png" width="640" /></a></div>
</div>
<br />
點選資訊主賈上方的<b>建立服務帳戶</b>連結,填入相關資訊後按建<b>建立</b>鈕。<br />
<a href="http://3.bp.blogspot.com/-5nQTC_SwAzQ/WXi0X0oR9RI/AAAAAAAAyZw/IFiLlI_FvfQSHM0cHhBhmtp08N3UVVqJACK4BGAYYCw/s1600/proxy-4.png" imageanchor="1"><img border="0" height="370" src="https://3.bp.blogspot.com/-5nQTC_SwAzQ/WXi0X0oR9RI/AAAAAAAAyZw/IFiLlI_FvfQSHM0cHhBhmtp08N3UVVqJACK4BGAYYCw/s400/proxy-4.png" width="400" /></a><br />
<ol>
<li>服務帳戶名稱:用來識別帳戶用途的名稱,隨便取</li>
<li>角色:請選擇 Cloud SQL --> Cloud SQL 用戶端</li>
<li>服務帳號 ID:若有需要可以自行修改</li>
<li>提供一組新的私密金鑰:請勾選,並且設定金鑰類型為 JSON,在帳號建立後會下載一個金鑰檔,請妥善保存;可以使用 SERVICE_KEY_FILE 這樣的變數去記錄保存位置,之後在匯入金鑰時會參照到<br /><a href="http://1.bp.blogspot.com/-RYCCFFHhqRA/WXi1c7LHMcI/AAAAAAAAyZ8/sI1DZrtEO8Qic8gKHno-dVVImKKol1pTwCK4BGAYYCw/s1600/proxy-5.png" imageanchor="1"><img border="0" height="104" src="https://1.bp.blogspot.com/-RYCCFFHhqRA/WXi1c7LHMcI/AAAAAAAAyZ8/sI1DZrtEO8Qic8gKHno-dVVImKKol1pTwCK4BGAYYCw/s640/proxy-5.png" width="640" /></a></li>
</ol>
<div>
<h4>
取得 Cloud SQL 執行個體連線字串</h4>
透過以下指令可以取得指定 Cloud SQL 執行個體的細節資訊,此處擷取的是它的連線字串,格式是:<b><專案 ID>:<區域>:<執行個體名稱></b>,此連線字串請標記為 CONNECTION_NAME 供後續使用。<br />
<pre><code class="language-bash">gcloud sql instances describe <MySQL Instance Name> | grep connectionName</code></pre>
<a href="http://4.bp.blogspot.com/-8n2baKUlzpo/WXjIGj5XxrI/AAAAAAAAybM/WJBQU2quy04dj32X5xJgJg7f-Frf_QypACK4BGAYYCw/s1600/proxy-6.png" imageanchor="1"><img border="0" height="202" src="https://4.bp.blogspot.com/-8n2baKUlzpo/WXjIGj5XxrI/AAAAAAAAybM/WJBQU2quy04dj32X5xJgJg7f-Frf_QypACK4BGAYYCw/s640/proxy-6.png" width="640" /></a><br />
<br />
若是 Windows 平台那就去掉 | 及之後 grep 指令,直接用眼睛找一下 connectionName 這個關鍵字。</div>
<h4>
建立識別資訊</h4>
<div>
為了讓 Container Engine 可以連接到 Cloud SQL,必須將剛剛建立的 MySQL 用戶端服務帳號匯入 Kubernets 中讓 Cloud Proxy 可以參照到:
<br />
<pre><code class="language-bash">kubectl create secret generic cloudsql-instance-credentials \
--from-file=credentials.json=${SERVICE_KEY_FILE}</code></pre>
<a href="http://3.bp.blogspot.com/-HFgDjaP-EJs/WXjEf5Llu3I/AAAAAAAAya0/xJ8Xwu5kTKgvWpH56YuBq80y3tJNEOGVACK4BGAYYCw/s1600/proxy-7.png" imageanchor="1"><img border="0" height="100" src="https://3.bp.blogspot.com/-HFgDjaP-EJs/WXjEf5Llu3I/AAAAAAAAya0/xJ8Xwu5kTKgvWpH56YuBq80y3tJNEOGVACK4BGAYYCw/s640/proxy-7.png" width="640" /></a><br />
<h4>
編輯 K8S 部署設定檔</h4>
</div>
<div>
在專案目錄下有一個 k8s-deploy-config.yaml 的 kubernetes 部署 (Deployment) 設定檔,可以協助在 Container Engine 中建立一個應用系統部署單位。</div>
<div>
<br /></div>
<div>
請修改部署設定檔中的以下設定:<br />
<a href="http://3.bp.blogspot.com/-WjweND5AXL4/WXjHs5Q9mkI/AAAAAAAAya8/eWlGrVd_XXEFKYUC3xsGILIwk6GXYUXSACK4BGAYYCw/s1600/proxy-8.png" imageanchor="1"><img border="0" height="342" src="https://3.bp.blogspot.com/-WjweND5AXL4/WXjHs5Q9mkI/AAAAAAAAya8/eWlGrVd_XXEFKYUC3xsGILIwk6GXYUXSACK4BGAYYCw/s640/proxy-8.png" width="640" /></a></div>
<div>
<ol>
<li>第 14 行的 Docker 映像檔標籤:請確認已打包成 GCP 線上版本所需設定,格式為:<b>gcr.io/<專案 ID>/<映像檔檔名>:<標籤></b></li>
<li>第 20 行的 Cloud SQL 執行個體連線字串</li>
</ol>
</div>
<div>
</div>
<h3>
在 Container Engine 上啟動 Spring Boot 應用程式</h3>
<div>
完成前述設定後會得到兩個檔案:一個給 GCP 啟動用的 Docker 映像檔及一個給 Kubernetes 啟動部署作業所需的設定檔。第一件事就是將 Docker 映像檔上傳到 Google Cloud Storage 中。</div>
<h4>
上傳 Dcoker 映像檔 到 Cloud Storage</h4>
<div>
以下指令可將先前打包過的 Spring Boot 應用程式映像檔上傳到 Cloud Storage 中,其中 <映像檔標籤名稱> 也就是編輯部署設定檔時指定的 Spring Boot 時的映像檔標籤。
<br />
<pre><code class="language-bash">gcloud docker -- push <映像檔標籤名稱></code></pre>
<a href="http://3.bp.blogspot.com/-swQ_IripTGo/WXjLIYeTwiI/AAAAAAAAybY/jTNH-Q1sADo1de5GC9OPEYSQjTpS4xqogCK4BGAYYCw/s1600/startup-1.png" imageanchor="1"><img border="0" height="170" src="https://3.bp.blogspot.com/-swQ_IripTGo/WXjLIYeTwiI/AAAAAAAAybY/jTNH-Q1sADo1de5GC9OPEYSQjTpS4xqogCK4BGAYYCw/s640/startup-1.png" width="640" /></a><br />
<br />
要確認是否上傳成功有兩個方式:<br />
<ol>
<li>透過瀏覽器瀏覽 https://gcr.io/<專案 ID>/<映像檔名稱> (不含標籤)進行確認。<br /><a href="http://3.bp.blogspot.com/-wzyBtruH9so/WXjLh2MxIwI/AAAAAAAAybg/qXWmp3LJLpg2_-XwTxXOkBe9rgYB3FanwCK4BGAYYCw/s1600/startup-2.png" imageanchor="1"><img border="0" height="194" src="https://3.bp.blogspot.com/-wzyBtruH9so/WXjLh2MxIwI/AAAAAAAAybg/qXWmp3LJLpg2_-XwTxXOkBe9rgYB3FanwCK4BGAYYCw/s640/startup-2.png" width="640" /></a></li>
<li>嘗試下載映像檔:若映像檔未正確上傳則會出現 not found 訊息
<pre><code class="language-bash">gcloud docker -- pull <映像檔標籤名稱></code></pre>
<a href="http://4.bp.blogspot.com/-IZKLKeWXy3A/WXjMO5Lq18I/AAAAAAAAybo/CoKeHfFWCKw-cGJR1gElTHqmjj4T4IvLwCK4BGAYYCw/s1600/startup-3.png" imageanchor="1"><img border="0" height="192" src="https://4.bp.blogspot.com/-IZKLKeWXy3A/WXjMO5Lq18I/AAAAAAAAybo/CoKeHfFWCKw-cGJR1gElTHqmjj4T4IvLwCK4BGAYYCw/s640/startup-3.png" width="640" /></a>
</li>
</ol>
<h4>
透過設定檔啟動 Kubernetes Pod</h4>
<div>
透過指定設定檔方式啟動 Pod。</div>
<pre><code class="language-bash">kubectl create -f k8s-deploy-config.yaml</code></pre>
<a href="http://2.bp.blogspot.com/-fxUbbEWDwLU/WXoAZakUXrI/AAAAAAAAyb8/Kn0o2tgGuhQtPPJZCUx27-n8-0ZusaligCK4BGAYYCw/s1600/startup-4.png" imageanchor="1"><img border="0" height="67" src="https://2.bp.blogspot.com/-fxUbbEWDwLU/WXoAZakUXrI/AAAAAAAAyb8/Kn0o2tgGuhQtPPJZCUx27-n8-0ZusaligCK4BGAYYCw/s400/startup-4.png" width="400" /></a><br />
<h4>
檢查 Pods 有沒有異常</h4>
Kubernetes 在啟動服務時可以透過以下指令,經檢視 RESTARTS 次數確認 Pods 啟動有無異常?
<br />
<pre><code class="language-bash">kubectl get pods</code></pre>
<a href="http://1.bp.blogspot.com/-6VDmGzyDHCU/WXoBXh8y1GI/AAAAAAAAycE/80KF33h2T-4gM1x1umvTl-6Wexh8ZslwACK4BGAYYCw/s1600/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7%2B2017-07-27%2B23.05.29.png" imageanchor="1"><img border="0" height="66" src="https://1.bp.blogspot.com/-6VDmGzyDHCU/WXoBXh8y1GI/AAAAAAAAycE/80KF33h2T-4gM1x1umvTl-6Wexh8ZslwACK4BGAYYCw/s400/%25E8%259E%25A2%25E5%25B9%2595%25E5%25BF%25AB%25E7%2585%25A7%2B2017-07-27%2B23.05.29.png" width="400" /></a><br />
<h4>
開放 Spring Boot 應用程式供外界使用</h4>
<div>
確認 Pod 沒有一直重啟後即表示相關設定沒有問題,可以正式發佈供外界存取。Kubernets 開放服務的指令是 expose,如下例:
<br />
<pre><code class="language-bash">kubectl expose deploy <deploy name> --port=<對外開放的埠號> --target-port=<Container 實際開放的埠號> --type=LoadBalancer</code></pre>
</div>
<div>
<a href="http://1.bp.blogspot.com/-YbipLDC7dy0/WXoGEHfgfTI/AAAAAAAAyck/FfCR8TomwIQlA0k4J7M_z9hqIFFx8-KaACK4BGAYYCw/s1600/startup-8.png" imageanchor="1"><img border="0" height="62" src="https://1.bp.blogspot.com/-YbipLDC7dy0/WXoGEHfgfTI/AAAAAAAAyck/FfCR8TomwIQlA0k4J7M_z9hqIFFx8-KaACK4BGAYYCw/s640/startup-8.png" width="640" /></a><br />
<ol>
<li><deploy name>:請參考啟動 Pod 時的輸出或是部署設定檔內的設定</li>
<li><對外開放的埠號>:這個服務實際要開放給外界連接的埠號</li>
<li><Container 實際開放的埠號>:在 Docker 映像檔中實際接受服務的埠號</li>
</ol>
<div>
當 service 被 expose 後,可以檢視該 service 的狀態 ,其中 EXTERNAL-IP 即為外界可以存取此服務的入口:
<br />
<pre><code class="language-bash">kubectl get services</code></pre>
</div>
<div>
<a href="http://4.bp.blogspot.com/-3MjUgIUS4Rk/WXoHjBoTEHI/AAAAAAAAyc8/DGVme0W2yUgA7rPfbxtMvYOHi3hWeD63QCK4BGAYYCw/s1600/startup-9.png" imageanchor="1"><img border="0" height="106" src="https://4.bp.blogspot.com/-3MjUgIUS4Rk/WXoHjBoTEHI/AAAAAAAAyc8/DGVme0W2yUgA7rPfbxtMvYOHi3hWeD63QCK4BGAYYCw/s640/startup-9.png" width="640" /></a><br />
<br />
實際連線可以看到 API 回覆了 Pod 的名稱:<br />
<a href="http://1.bp.blogspot.com/-lXUObJH2SyU/WXoIJiFqR-I/AAAAAAAAydE/h8ItznekyJkgGK1usuxbPYbR2Lcway3hACK4BGAYYCw/s1600/startup-10.png" imageanchor="1"><img border="0" height="93" src="https://1.bp.blogspot.com/-lXUObJH2SyU/WXoIJiFqR-I/AAAAAAAAydE/h8ItznekyJkgGK1usuxbPYbR2Lcway3hACK4BGAYYCw/s400/startup-10.png" width="400" /></a><br />
<br />
若需要提供多個 Pods 以確保外界<b>有機會</b>繼續使用服務的話,可以擴充多個 deployment 。
<br />
<pre><code class="language-bash">kubectl scale deploy <deploy name> --replicas=<Pod 數量></code></pre>
<a href="http://3.bp.blogspot.com/-_qBJQ_2wtaA/WXoJgypLMLI/AAAAAAAAydg/ZIfPJKqTa-UhtFDBZOLqBR3kAfiraQOvgCK4BGAYYCw/s1600/startup-11.png" imageanchor="1"><img border="0" height="70" src="https://3.bp.blogspot.com/-_qBJQ_2wtaA/WXoJgypLMLI/AAAAAAAAydg/ZIfPJKqTa-UhtFDBZOLqBR3kAfiraQOvgCK4BGAYYCw/s400/startup-11.png" width="400" /></a><br />
<br />
此時檢查 Pod 狀態會看到產生指定個數的 Pods:<br />
<a href="http://4.bp.blogspot.com/-BuoWIOHQ0wQ/WXoJy6RAcnI/AAAAAAAAydo/O1ZLdz-lhywcJrRY4mQWRXyfO74uWbTZACK4BGAYYCw/s1600/startup-12.png" imageanchor="1"><img border="0" height="153" src="https://4.bp.blogspot.com/-BuoWIOHQ0wQ/WXoJy6RAcnI/AAAAAAAAydo/O1ZLdz-lhywcJrRY4mQWRXyfO74uWbTZACK4BGAYYCw/s640/startup-12.png" width="640" /></a><br />
<br />
經多次存取後,可以發現 Kubernets 確實將流量分散到不同 Pod 去,雖然分流的規則不明,而且還有很高機率會導向正在重啟的 Pod 去。<br />
<a href="http://1.bp.blogspot.com/-eb42cbDDuN8/WXoKrzCJ2tI/AAAAAAAAyd4/JDEMLH18UugM7BtXUqGnnFzv4JokLxKdwCK4BGAYYCw/s1600/startup-13.png" imageanchor="1"><img border="0" height="400" src="https://1.bp.blogspot.com/-eb42cbDDuN8/WXoKrzCJ2tI/AAAAAAAAyd4/JDEMLH18UugM7BtXUqGnnFzv4JokLxKdwCK4BGAYYCw/s400/startup-13.png" width="378" /></a><br />
<br />
在此可以呼叫第二個 API 將 Container 弄壞,然後看看 Kubernetes 會不會自動重啟新的 Container 出來。<br />
<a href="http://4.bp.blogspot.com/-WV_0vU4GBiI/WXoMlpS1dfI/AAAAAAAAyeM/15BIq9Qdii4f8rVUCh4DQ0lN9DVICRhbQCK4BGAYYCw/s1600/startup-14.png" imageanchor="1"><img border="0" height="312" src="https://4.bp.blogspot.com/-WV_0vU4GBiI/WXoMlpS1dfI/AAAAAAAAyeM/15BIq9Qdii4f8rVUCh4DQ0lN9DVICRhbQCK4BGAYYCw/s640/startup-14.png" width="640" /></a></div>
</div>
<h3>
Kubernetes 日誌追查與異常排除</h3>
<h4>
檢視 Pod 日誌記錄</h4>
<pre><code class="language-bash">kubectl logs -f <Pod Name> -c <Container Name></code></pre>
<div>
<ol>
<li><Pod Name> 即 kubectl get pods 時取得的 Name 欄位</li>
<li><Container Name> 即部署設定檔中設定的 containers 設定中的 name 欄立</li>
</ol>
<div>
範例一:檢視 springboot 的執行日誌</div>
<div>
<a href="http://4.bp.blogspot.com/-Dc-18k9mSvY/WXoDZ0mUVFI/AAAAAAAAycQ/iheNsWjKIJMOlsTrsZgG3t4GurGpTsJ8gCK4BGAYYCw/s1600/startup-6.png" imageanchor="1"><img border="0" height="224" src="https://4.bp.blogspot.com/-Dc-18k9mSvY/WXoDZ0mUVFI/AAAAAAAAycQ/iheNsWjKIJMOlsTrsZgG3t4GurGpTsJ8gCK4BGAYYCw/s640/startup-6.png" width="640" /></a></div>
<div>
<br /></div>
<div>
範例二:檢視 Cloud SQL Proxy 的執行日誌</div>
<div>
<a href="http://1.bp.blogspot.com/-EEhcemyoZJ0/WXoD5lISgTI/AAAAAAAAycY/1rkOIjwUZMcmn60Y1Gx-P1bk5HKYljX5gCK4BGAYYCw/s1600/startup-7.png" imageanchor="1"><img border="0" height="176" src="https://1.bp.blogspot.com/-EEhcemyoZJ0/WXoD5lISgTI/AAAAAAAAycY/1rkOIjwUZMcmn60Y1Gx-P1bk5HKYljX5gCK4BGAYYCw/s640/startup-7.png" width="640" /></a></div>
<h4>
Spring Boot 無法連線 Cloud SQL</h4>
<div>
如果 Spring Boot 無法連線到 Cloud SQL 時必然會導致 Container 崩潰,此時的問題通常是因為先前的<b>服務帳號</b>沒有完整。請到 <b>產品與服務</b> --> <b>IAM 與管理</b> --> <b>IAM</b> 資訊主頁中確認先前建立的服務帳號是否被正確建立(包含該服務帳號的角色)。<br />
<a href="http://2.bp.blogspot.com/-CBsvd0omYy0/WXoL7OdBH2I/AAAAAAAAyeE/JOQkvjGO3dMs9lO6Sw7YVM56RkFyeIMowCK4BGAYYCw/s1600/trouble-1.png" imageanchor="1"><img border="0" height="364" src="https://2.bp.blogspot.com/-CBsvd0omYy0/WXoL7OdBH2I/AAAAAAAAyeE/JOQkvjGO3dMs9lO6Sw7YVM56RkFyeIMowCK4BGAYYCw/s640/trouble-1.png" width="640" /></a><br />
<br />
若服務帳號沒有正確顯示在 IAM 資訊主頁中,請複製<b>服務帳號</b>內完整的 EMAIL 設定到 IAM 資訊主頁內自行新增即可,角色一樣請指定為 <b>Cloud SQL 用戶端</b>。</div>
<h3>
與官方作法不同處說明</h3>
</div>
<div>
<ol>
<li>在 Cloud SQL Proxy 時並沒有建立 cloudsql-db-credentials 這個識別 (secret),這是因為這邊是由 Spring Boot 應用程式提供資料庫連線的帳密</li>
<li>若想將資料庫帳密放到 <b>識別檔</b> (secret) 內的話,可以參考 <a href="https://github.com/GoogleCloudPlatform/container-engine-samples/blob/master/cloudsql/cloudsql_deployment.yaml">cloudsql_deployment.yaml</a> 這個範例設定部署檔</li>
</ol>
</div>
<h3>
參考文件</h3>
<div>
<ol>
<li><a href="https://jhipster.github.io/tips/018_tip_kubernetes_and_google_cloud_sql.html" target="_blank">Kubernetes and Google Cloud SQL</a></li>
<li><a href="https://cloud.google.com/sql/docs/mysql/connect-container-engine" target="_blank">Connecting from Google Container Engine</a></li>
<li><a href="https://github.com/GoogleCloudPlatform/cloudsql-proxy/issues/37#issuecomment-297265064">Client fails on createEphemeral</a></li>
</ol>
</div>
<h3>
後續的驗證與調整</h3>
</div>
<div>
有空的話會來驗證一下這些操作... </div>
<div>
<ol>
<li>如何更新應用程式版本:目前不知道是不是只要上傳新的映像檔即可?</li>
<li>如何真正達到服務不中斷:Kubernetes 預設的分流規則會把流量導向隨便一個 Pod,即使該 Pod 正在重建立,此時就會出現系統無回應的錯誤訊息</li>
<li>打開 <a href="https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/">Dashboard</a>:據說檢視 Kubernetes 運作狀態好方便... ?</li>
</ol>
<h3>
關於 Load Balancer</h3>
</div>
</div>
<div>
<ol>
<li>標準型(就上面那個例子)的 Load Balancer 是沒有做 Healthy Check 的,所以導致前面說到的經常性的把流量導到掛掉的那個 Pod ... XD</li>
<li>Ingress 的 Load Balancer 似乎有相關的 Healthy Check ,還支援跨區域的分流 XD</li>
</ol>
</div>
Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-77576481544955711992011-08-12T17:55:00.037+08:002017-07-17T10:42:19.912+08:00Chrome 擴充功能 - Plus Plurk 介紹<div class="paragraph">
<span style="font-size: large;">※本 Chrome Extension 已廢止,感謝大家支持,造成不便懇請見諒!</span><br />
<br />
基本上這是一個協助格揆我將發佈在 <a href="https://plus.google.com/111339507987885509119/posts" target="googleplus">Google Plus</a> 上的訊息同步到 <a href="http://www.plurk.com/adahsu" target="plurk">Plurk</a> 的 <a href="http://www.google.com.tw/chrome" target="chrome">Google 瀏覽器</a> 擴充套件 / 功能。原本只是格揆個人單純在同步文字訊息使用,但是經過一陣加油添醋式的亂改後覺得也許可以開放給 Google Plus 及 Plurk 的重度使用者試看看,於是就把它上到 <a href="https://chrome.google.com/webstore?hl=zh-TW" target="webstore">Chrome 線上應用程式商店</a> 了。 </div>
<h4>
開發源由歷程</h4>
<div class="paragraph">
當不小心偷渡進 Google Plus 後,格揆一度因為專心在 Google Plus 上打混而幾乎放棄了在 Plurk 上的活動,此作為連帶使得卡馬值在短短幾天就從 98.x 掉到 97.y,在發現這種情形時原本一度考慮要使用凍結卡馬的方式來欺瞞自己。但此刻一個由 Google Plus 同步訊息到 Facebook 的 Publish Sync 擴充功能上線到線上應用程式商店,經過簡單試用後就有了『不然我也來寫一個從 Google Plus 將訊息同步發送到 Plurk 的擴充功能』的念頭並真正的開始研究 Plurk API ,隔了幾天後突然到 Chrome 線上應用程式商店付了 US$5 的入場券,然後還拗了 <a href="http://tatit.pixnet.net/blog" target="tatit">他踢</a> 幫忙拉了一個 ICON,最後還賺了一場由 <a href="http://www.plurk.com/mingsheu" target="mingsheu">火焰銘王</a> 提供的美國隊長電影,終於在 08/02 開始了募集測試人員的測試流程,然後就是因為一時恍神而在 08/11 莫名其妙的正式把它給弄上 <a href="https://chrome.google.com/webstore/detail/lmkedcilhgjhbgnjkjonkbiddheohfbk?hl=zh-TW" target="plusplurk">Chrome 線上應用程式商店</a> 。 </div>
<h4>
核心思想</h4>
<div class="paragraph">
和 Publish Sync 的規劃不同,這個擴充套件是基於使用者以 Google Plus 為唯一發言人,並想將相關資訊散佈到 Plurk 上的散播模式而開發。換句話說如果您是希望以 Plurk 為主要發言來源,但想將訊息同步到 Google Plus 上訊息傳播模式的話,那這個套件就不會適合您的需要。在安裝前請先理解此一核心思想所造成的設計上的差異。 </div>
<h4>
功能特色</h4>
<div class="paragraph">
本擴充套件 / 功能的主要特色如下: <br />
<ul>
<li>直接對 Plurk 發送訊息:所有的訊息都直接對 Plurk 進行操作,訊息分享沒有延遲</li>
<li>訊息分享限制:本擴充功能支援『僅限朋友閱讀』之私噗模式,也能設限回噗對象的範圍</li>
<li>訊息分享格式:依訊息內容的差異,提供 5 種轉噗到 Plurk 上的訊息格式</li>
<li>訊息長度預覽:Plurk 屬微網誌系統,本套件可以預判訊息長度,提前避免傳送失敗的情形</li>
<li>多段訊息轉噗:擔心個人感想太長無法轉送到 Plurk 嗎?沒關係,只要您分段得宜,本套件會自動將各段轉成回噗送上 Plurk</li>
</ul>
</div>
<h4>
安裝與授權</h4>
<div class="paragraph">
本套件為 Google 瀏覽器 Chrome 所屬的擴充套件,如果您尚未使用 Google 瀏覽器可以在 <a href="http://www.google.com.tw/chrome" target="chrome">Google 瀏覽器</a> 產品頁面下載安裝。另外提醒的是 Google 瀏覽器安裝並不需要系統管理者權限,只要作業系統為 Windows XP 以上的使用者都能直接下載安裝。 </div>
<h5>
安裝 Plus Plurk</h5>
<div class="paragraph">
請使用您已安裝的 Google 瀏覽器連接到 <a href="https://chrome.google.com/webstore/detail/lmkedcilhgjhbgnjkjonkbiddheohfbk?hl=zh-TW" target="plusplurk">Plus Plurk - Chrome 線上應用程式商店</a> 上並按下『加到 Chrome』按鈕即可,如附圖:<br />
<img src="https://lh5.googleusercontent.com/-a67hrB6UloA/Tlo0MMhyH4I/AAAAAAAADZs/NgqR3GY7YW8/INSTALL.png" /> </div>
<h5>
權限要求</h5>
<div class="paragraph">
本擴充功能僅存取以下三個網站資料:<br />
<ol>
<li>www.plurk.com: 將資料傳輸給 Plurk</li>
<li>plus.google.com: 擷取在 Google Plus 上預定發佈的訊息、在 Google Plus 上啟用本擴充套件</li>
<li>www.googleapis.com: 將預定分享到 Plurk 的網址預先進行網址為 http://goo.gl/xxxxx 之用</li>
</ol>
<img src="https://lh3.googleusercontent.com/-7FLoK4rhgvQ/TmeFRegKaeI/AAAAAAAADek/jF-MY8O93d0/Permissions.png" /></div>
<h5>
重新載入 Google Plus</h5>
<div class="paragraph">
完成安裝後套件會自動將相關程式載入 Google Plus 頁面中,不過您也可以重新載入 Google Plus 頁面,確保相關程式正確的嵌入 Google Plus。只要相關程式已正確嵌入,那麼在輸入訊息時會在分享鈕右側看到多出一個 Plurk Share 圖示。但是因為目前還沒有取得 Plurk 服務授權,所以此刻暫時無法點選。如附圖:<br />
<img src="https://lh4.googleusercontent.com/-pWYF6JbJJmg/Tlo5WM5dmFI/AAAAAAAADZ4/9RWhY2Aq3f8/auth_required.png" /> </div>
<h5>
取得 Plurk 服務授權</h5>
<div class="paragraph">
套件安裝後會自動開啟 Plus Plurk 選項設定頁面以利噗友進行 Plurk 服務授權,另外您也可以按下 Chrome 右上角的 Plus Plurk 圖示,它會直接開啟 Plus Plurk 選項設定頁面,如附圖:<br />
<img src="https://lh6.googleusercontent.com/-eElyLjNc9lc/TmeKplA0HLI/AAAAAAAADe0/stYCHrSuTzE/icon.png" /><br />
<a href="https://picasaweb.google.com/111339507987885509119/PlusPlurk#5649631542568236370" target="options" title="點圖可放大"><img src="https://lh3.googleusercontent.com/-ULJjt_OQ1UI/TmeF9HafNVI/AAAAAAAADes/KIwpfwHbYB4/s640/options.png" /></a></div>
<div class="paragraph">
點選『進行授權』鈕後會開啟 Plurk 服務授權存取頁面,不同意的話是沒辦法發送訊息給 Plurk 的喲~~ <br />
<img src="https://lh6.googleusercontent.com/-Y28EyRoi2q8/TkTHWCvZafI/AAAAAAAADSk/o-dUStdqmks/plurk_auth.png" /> </div>
<div class="paragraph">
授權完成後會自動關閉該頁面回到 Plus Plurk 選項設定頁面,其中『授權狀態』欄位會變更為『已完成授權』,同時『授權人』欄位會取得 Plurk 的使用者名稱資訊,如附圖。特別注意的是<b>一旦更換電腦,這個授權動作就要執行一次!</b><br />
<img src="https://lh6.googleusercontent.com/-EfqrTuL-Dkg/TkTHWJb5WoI/AAAAAAAADSo/TlCtSSbjqNc/auth_complete.png" /> </div>
<div class="paragraph">
如果授權後發現授權人的名字不是您的名字請先登出 Plurk 後再重新進行授權;如果這是一台公用電話的話請在使用完畢並登出 Google Plus 後一併記得登出 Plurk 及<b>清除 Plus Plurk 授權設定</b>(請注意:Plus Plurk 並非透過 Plurk 帳號及密碼登入 Plurk ,故光是登出 Plurk 並不會取消 Plus Plurk 存取 Plurk 的權限),清除授權設定後則『受權狀態』欄位會恢復為『尚未授權』,如附圖。<br />
<img src="https://lh4.googleusercontent.com/-flCvp5VT7TI/TkTLz8ScapI/AAAAAAAADS4/eappkFkKaVQ/auth_remove0.png" /><br />
<img src="https://lh3.googleusercontent.com/-FbnMFOXNrTE/TkTLz9HjRUI/AAAAAAAADS0/02gpZcVUrVI/auth_remove1.png" /> </div>
<h4>
一般使用</h4>
<div class="paragraph">
Plus Plurk 只要完成 Plurk 服務存取授權後,就可以將訊息同步分享到 Plurk 上。不管是心情碎碎念、文章心享、心得感言、照片紀念、還是影音記錄等等等,只要沒有超過 Plurk 內文長度限制,Plus Plurk 都可以幫你噗到 Plurk 上。以下都是將 Google Plus 上輸入的資訊與 Plurk 實際獲得的噗文結果合併後的圖例。</div>
<h5>
心情碎碎念 / 純文字訊息</h5>
<div class="paragraph">
<img src="https://lh5.googleusercontent.com/-k1y01KXQOHo/Tlo9SnaodjI/AAAAAAAADaI/BVo7ZF-f_oQ/message.png" /> </div>
<h5>
心得分享</h5>
<div class="paragraph">
<img src="https://lh4.googleusercontent.com/-oceqPxlTM6I/TlpB4g3n7fI/AAAAAAAADaQ/eJoe-EJvNwg/share.png" /> </div>
<h5>
純文章分享</h5>
<div class="paragraph">
與『心得分享』最大的差異就是... 沒有心得... (被毆) <br />
<img src="https://lh5.googleusercontent.com/-wefS_twiGQ4/TlpKdH4i9vI/AAAAAAAADaY/t7D9oAYikXM/article.png" /> </div>
<h5>
內嵌文章分享</h5>
<div class="comment">
0.3.2.2 調整功能</div>
<div class="paragraph">
如果是 Plurk 支援的文章連結,則 Plurk 會以部落格區塊轉貼方式呈現,如附圖。<br />
<img src="https://lh5.googleusercontent.com/-n3yJgenkwOs/Tlpbkf6duyI/AAAAAAAADag/7atSd-roFIg/oembed.png" /></div>
<div class="paragraph">
目前 Plurk 支援的 oEmbed 網站列表如下(請參考 <a href="http://zh.blog.plurk.com/plurk-labs" target="_blank">Plurk Labs (Chinese)</a>):<br />
<ul>
<li>YouTube</li>
<li>Vimeo</li>
<li>Slideshare</li>
<li>Wordpress.com</li>
<li>PIXNET痞客邦部落格、相片/相簿</li>
<li>未來事件交易所</li>
<li>ted.com</li>
<li>itunes.apple.com</li>
<li>Flickr</li>
<li>scribd</li>
<li>Xuite 隨意窩部落格、相片/相簿</li>
<li>蘋果日報新聞</li>
</ul>
</div>
<h5>
圖片分享</h5>
<div class="paragraph">
<img src="https://lh5.googleusercontent.com/-Yg6qixhoEgk/Tlpk3eL9hfI/AAAAAAAADa0/kb3cXbKM1A0/picture.png" /> </div>
<h4>
噗文管理</h4>
<div class="paragraph">
Plus Plurk 一開始預設的 Plurk 訊息是可在河道上自由被檢視及回噗的,但是人生總有些訊息並不想如此大方的公開或是讓人家插花回覆的,有一些開關可以應付這方面的需求。 </div>
<h5>
檢視限制</h5>
<div class="paragraph">
可以選擇是公開給所有人檢視或僅朋友能檢視。<br />
<img src="https://lh3.googleusercontent.com/-OPUFksp5rFY/TkTpYglM55I/AAAAAAAADTc/nN-f-gHJLiM/plurk.png" /> </div>
<h5>
回噗限制</h5>
<div class="paragraph">
可以限制是否同意任何人皆可回噗,僅限朋友可以回噗、或完全不能回噗!<br />
<img src="https://lh4.googleusercontent.com/-OcR_rJVTmP8/TkTqWtbtqCI/AAAAAAAADTg/NzjDehBQ_BQ/response.png" /> </div>
<h5>
同步限制</h5>
<div class="comment">
0.3.1.0 新增功能</div>
<div class="paragraph">
應該有不少噗友是利用 Plurk 提供的 Facebook 同步功能將訊息同步到 Facebook 上的,而 Plurk 其實也提供了如何不同步到 Facebook 的方式。Plus Plurk 自 0.3.1.0 版起也提供了指定是否開放讓 Plurk 自動同步臉畫的選項開關,如附圖。<br />
<br />
<img src="https://lh6.googleusercontent.com/-zE_dQsVYisw/TkdqxjbcgNI/AAAAAAAADUY/8NnJBCPivLg/switch-3.png" /></div>
<h4>
訊息格式管理</h4>
<div class="paragraph">
和 Twitter 不同(應該吧),Plurk 本身並不是純文字型態的微網誌系統,因此 Plus Plurk 在分享訊息到 Plurk 時依訊息種類提供不同的訊息分享格式。這些設定可以在 Plus Plurk 的選項設定頁中進行修改,修改完後記得要『儲存』後相關設定才會生效。至於那些變數所對應的資料項目可透過點選 <img class="inline" src="https://lh3.googleusercontent.com/-j9Kp8Wd0nu4/TkTxLFFu6CI/AAAAAAAADTo/Y2O_iPqnCYU/question.png" /> 符號查閱之。<br />
<img src="https://lh3.googleusercontent.com/-50z1paDIY1g/TlPIexlYz7I/AAAAAAAADXQ/KLHrYkkQuVc/pattern.png" /> </div>
<div class="paragraph">
<ul>
<li>戳記:在 Facebook 上我們可以看到每一筆訊息的來源為何,但是 Plurk 上卻沒有這方面的設定,所以格揆很堅持的希望在 Plurk 上能一眼的看出來這筆噗文的來源為何。它的預設值為『[fr. G+]』,但因為會佔用到噗浪內文的空間所以格揆已自行改成『[G+]』,您也可以直接設為空白。</li>
<li>訊息 / 純文字分享:如果某筆訊息沒有包含文章連結、影像連結、或圖片連結時,視為單純的訊息分享。此時能使用的變數只有代表訊息的 ${MESSAGE} 及戳記 ${STAMP} 兩種。 </li>
<li>心得分享:為預設的分享模式,一份完整的心得分享中會包含個人的心得、感想(${MESSAGE})、文章連結(${LINK})、文章標題(${TITLE})、以及文章圖片(${PICTURE})。</li>
<li>內嵌文章分享:針對 Plurk 能自動讀取特定網站資訊所採取的對應格式,只需文章連結(${LINK})即可由 Plurk 自動帶出連結網址標題及第一張圖片。</li>
<li>文章分享:少了個人心得、感想(${MESSAGE})的訊息分享屬之。</li>
<li>影片分享:目前以連結 ${LINK} 為 Youtube 或 Vimeo 的網址時視為影片分享,Google Plus 在捉取影片資訊時會提供影像連結(${LINK})及影像擷圖(${PICTURE})兩種資訊,由於 Plurk 也會自行捉取影像內的資訊,故通常不會使用到影像擷圖(${PICTURE})這個變數。</li>
<li>圖片分享:當訊息中不含文章連結(${LINK})及文章標題(${TITLE})時即屬圖片分享。您可自行決定圖片要放前面還是放後面。</li>
</ul>
</div>
<div class="paragraph">
另外『${DESCRIPTION}』這個變數主要是指一篇文章或影片的內容描述,但因為它本身經常超出 Plurk 內文的上限,所以不建議各位使用。 </div>
<div class="paragraph">
<div class="comment">
0.3.3.2 新增功能</div>
自 2011-08-23 起 Plurk 支援訊息斷行顯示,因此在格式設定上也新增了斷行的符號『|』,如上圖中的『訊息分享』即使用了這個斷行符號,斷行的輸入範例如下圖:<br />
<br />
<img src="https://lh4.googleusercontent.com/-rgKZ3vx_gSI/TlPMBpQuYnI/AAAAAAAADXU/twyyJJ0i9rE/newline.png" /><br />
<br />
需要特別注意的是 Plurk 官方允許的斷行行數是 4 行,如果在格式設定中使用了斷行符號『|』,那麼實際能輸入的訊息行數就只剩下 3 行,下圖即為超過上限行數時的檢查結果,出現第 5 行的原因就是因為 | 多產生了一行戳記(${STAMP})列所導致。。<br />
<br />
<img src="https://lh3.googleusercontent.com/-SEcRyNZkTSs/TlPNZlJB3NI/AAAAAAAADXY/kDcuowc8qAo/overrows.png" /></div>
<h4>
多段式噗文</h4>
<div class="paragraph">
因應 Plurk 單則訊息 140 個字的限制,Plus Plurk 支援將訊息分成數段噗在同一筆噗浪主文下成為回噗。但這並<b>不是自動分段</b>,Plus Plurk 的分段依據是透過使用者預先安排的。 </div>
<div class="paragraph">
Plus Plurk 在處理 ${MESSAGE} 時會針對連續兩個 ENTER 鍵進行訊息切割,訊息切割之後再依序將訊息內容送往 Plurk 河道,這個發送的時間間隔是每秒一筆,以下介紹的兩種應用方式,它們之間的差異只在於有沒有先空個兩行再輸入個人的心得或意見而以。<br />
<br />
<img src="https://lh4.googleusercontent.com/-kMKJCxYxQTw/TkVbv5-_vSI/AAAAAAAADTs/y9-c9eHFAuY/s640/multiple-type0.png" /><br />
<br />
<img src="https://lh5.googleusercontent.com/-0x1ZvPzGEKc/TkVe0rJ9TOI/AAAAAAAADTw/BXD4xQ5QK9I/s640/multiple-type1.png" /></div>
<h4>
訊息長度檢測</h4>
<div class="paragraph">
有時候在下筆如神助、文思如泉湧時的摸門特是很難有心思力氣去一個個數每一段落各有多少字。每次數的結果都不一樣也就罷了,就怕是還沒數完前就讓原本澎湃的思緒化為枯竭的溝流,這樣怎麼有資格當文青呢?</div>
<div class="paragraph">
沒關係,Plus Plurk 可以透過某種<b>不明確</b>、<b>不科學</b>、<b>沒有保證</b>的計算公式提前告知這一篇文章中最長的那一段總共有幾個字,如附圖。特別注意的是這裡的第一段指的是文章的連結、標題、文章內附圖的連結等等的綜合計算結果,並不是心得部份的文字字數。<br />
<br />
<img src="https://lh5.googleusercontent.com/-Gv7UfJ5V-9Y/TkVkFomNUyI/AAAAAAAADT0/TBl2z3xYy3s/s512/checkLength.png" /></div>
<div class="paragraph">
另外這個燈泡的顏色會隨著文字長度是否超過 140 字上限或是 Plurk 斷行上限而變色,綠色(通常)表示可安心噗文,紅色(幾乎確定)表示有某一段訊息過長或行數過多請予修正。特別注意的是這個檢查結果並不會阻止『分享』鈕的功能,而 Plus Plurk 在收到 Plurk 拒絕噗文的回覆時則會停止後續訊息的發送以便有辦法一行行手動將訊息補進河道內。</div>
<h4>
常見問題與說明</h4>
<div class="paragraph">
<ol>
<li><div class="question">
問:為什麼在 Google Plus 上明明只是換行,但在 Plurk 上卻成多段式噗文呢?</div>
<div class="answer">
這通常是發生在訊息內容是從剪貼簿貼到 Google Plus,Google Plus 雖然顯示上看起來像換行,但實際上捉出來的訊息卻是每行一段,故轉送到 Plurk 時就變成多段式噗文了。</div>
</li>
</ol>
</div>
<h4>
成果示範</h4>
<div class="paragraph">
在本文剛撰寫時格揆提過當時的卡馬值一度落到 97.y ,經過本套件的協助後在三週內竟然已提升到 99.81,您看看,這套件是不是真的很有用?<strike>廢話!老是把 Google+ 上的資料倒進 Plurk 當然會提高卡馬值啊,而且三週才提升 2 似乎有點...</strike><br />
<br />
<img src="https://lh5.googleusercontent.com/-abtgS3DQrBo/TlPPci4T-lI/AAAAAAAADXk/k-sF0T_w4TE/karma.png" /></div>
<h4>
多語系支援</h4>
<div class="paragraph">
<b>目前並未支援其他語系,非常歡迎有意願者協助翻譯!</b></div>
<h4>
感謝</h4>
<div class="paragraph">
感謝以下網友介紹本擴充套件:<br />
<ol>
<li>就是教不落:<a href="http://steachs.com/archives/2127" target="_blank">Google Chrome擴充套件【Plus Plurk】同步Google+訊息到噗浪,支援圖片及影片連結</a></li>
<li>于老師教室討論版:<a href="http://yunol.com.tw/phpbb3/viewtopic.php?f=24&t=25389" target="_blank">好用的Google Chrome同步擴充---Plus Plurk</a></li>
<li>WEBOK部落格:<a href="http://webok.tw/2011/12/googleplus-facebook-plurk-twitter.html" target="_blank">省時省力的社群與微網誌訊息擴散行銷技巧</a></li>
<li>Tech - Kuma:<a href="http://tech-kuma.blogspot.com/2012/02/plus-plurk.html" target="_blank">同步你的社群網站 - Plus Plurk</a></li>
</ol>
</div>
<h4>
改版記錄</h4>
<div class="paragraph">
<iframe frameborder="0" height="600" src="https://docs.google.com/spreadsheet/pub?hl=zh_TW&hl=zh_TW&key=0Amf8RZAgU3andEhmTjVsaDByN2t1R1ctX0R1NlBNa1E&single=true&gid=0&output=html&widget=true" width="700"></iframe> </div>
Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com17tag:blogger.com,1999:blog-909727791061240227.post-87307029831582732352011-07-25T15:23:00.001+08:002011-07-26T15:49:20.390+08:00一個恐龍法條 + 一個愛現的官僚 = 什麼?<div class="paragraph">基本上這原本是在 Google+ 上針對台北市政府法規會與 Google 對 Android Market 7 日鑑賞期事件所留的一段心得,不過因為近日又多了一點心得,加上北市府額外奉送的兩週延議期也快到了,所以趁機把它搬到部落格中作為歷史遺跡,順便為這個荒廢多時的部落格灌點水... :p</div><div class="paragraph">整個故事的發展演進請直接參閱 『<a href="http://www.techbang.com.tw/posts/6239-google-android-market-apple-app-store-events-lazy-bag">Google Android Market、Apple App Store 7日鑑賞期事件懶人包</a>』 及 『<a href="http://www.techbang.com.tw/posts/6430-north-city-cut-penalty-incident-google-legal-interpretation-in-doubt">北市府裁罰事件,Google:法律解讀有疑慮,app 繼續下架</a>』 兩篇文章說明而不再贅述,以下即為個人的看法:</div><div class="paragraph"><ol><li>台灣消費者從此與世界豐富的應用程式無緣</li>
<li>和中國一樣出現一大堆山寨版應用程式在電信公司的市集上騙錢</li>
<li>因為台灣看不到付費軟體,所以也不會有人幫作者翻譯使用者界面為正體中文</li>
<li>iPhone/iPad 使用者也不用太高興,別以為世界各地的應用軟體開發者就會認同或支持台灣 Apple Store 的特別條款;也不要天真的以為 iOS 軟體開發者都有那種力氣來面對、統計、或處理台灣的退費條款<sub>(狀態可能有所改變,容後述)</sub></li>
<li>以目前的狀況來看,恐怕也讓某些原本想要寫 Android App 的開發人員陷入躊躇不前的困擾中,iOS 的開發人員可能就稍好一點,至少可以樂觀的相信被退款的機率應該不會太高。但總體來看似乎並不利於行動應用軟體業的發展</li>
<li><strong>免費軟體的使用一併受到影響</strong>:這是近日的感想,應該也會是 iPhone 軟體開發者比 Android 軟體開發者有利的地方</li>
</ol></div><div class="paragraph">基本上到了 07/15 後,Apple 正式增列台灣專屬條款『<a href="http://www.apple.com/legal/itunes/appstore/tw/terms.html#SALE">您得自產品收受之日起七日內,取消對產品之購買。在您通知iTunes您已刪除產品所有備份之前提下,iTunes將會退還您已支付之價款。自您取消購買時起,您不再被授權繼續使用該產品。此項權利不可拋棄。</a>』,但是軟體內 (In-App) 購買、訂閱部份目前看來是無法退費的。這個差異可能會轉移軟體開發者對於軟體功能的規劃:『表面上是免費軟體,但是多數功能都要另行在軟體內付費啟用』,而且此作法某種程度下還能對抗盜版軟體。 </div><div class="paragraph">有趣的地方就在這兒,在 iTunes / Apple Store 下雖然付費軟體有七日退費條款,但是開發者可以讓軟體免費下載,之後再透過 In-App 方式付費購買擴充功能,這些付費功能無法退費,所以 iOS 開發人員其實也不見得需要特地處理台灣地區軟體的退費事宜;但與過去比較起來消費者可能會發現連寫信退費的權利恐怕也沒了。</div><div class="paragraph">Android Market 也提供所謂的 In-App 付費功能,也有許多軟體開始透過此付費模式提供購買特殊裝備或啟用特別功能(個人覺得這些也算是騙子軟體),不過因北市府法規會介入的關係導致 Market 整個付費功能被 Google 關閉後,自此每次在開啟這類具 In-App 付費功能的軟體時就會看到一個很刺眼的訊息:『Can't make purchases』且一而再、再而三的提醒台灣的使用者因為一個愛現的官僚所造成無法付費購買軟體的窘境。</div><div class="paragraph">距上次北市府美其名對 Google 釋出善意再給兩週寬限期的時間又快到了,不知道這個號稱天龍國的地方政府有沒有任何方案足以應對 Google 不接受七日退費期費要求的因應作為?</div><div class="paragraph">還要用 <strong>Google 有挾消費者以令天子之嫌</strong> 那招開罰嗎?</div><br />
<div class="paragraph">其他討論:<br />
<ul><li><a href="http://wiselysong.blogspot.com/2011/06/2011-06-27-googleandroid-market.html">小歪碎碎念: 2011-06-27 偉哉台北市政府幹掉了Google台灣的Android Market付費區</a></li>
<li>INET6 - <a href="http://blog.gasolin.idv.tw/2011/06/googleandroid-marketapp.html">對Google關掉台灣Android Market付費App下載的觀察</a></li>
<li>連 Market 都有這種東西 - <a href="https://market.android.com/details?id=tw.takol.android.protesttaipeibovmeddleandroidmarket">抗議臺北市政府干預Android市場</a></li>
</div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-8368574833309747162011-03-23T16:29:00.000+08:002011-03-23T16:29:03.418+08:00本格文章詞頻分析<div class="paragraph">看了 <a href="http://blog.timc.idv.tw/">timdream</a> 的 <a href="http://blog.timc.idv.tw/posts/wordcloud/">文字雲工具</a> 後,也把這個部落格的資料給餵進去看看,然後就出現了以下這個分析圖... </br>
<img src="https://lh5.googleusercontent.com/_W-ixktUlAf8/TYmtuLxHg7I/AAAAAAAACrM/GgIkBknTQhA/blog.jpg"></div>
<div class="paragraph">簡單的說,格揆我對『可以』這個詞兒的使用頻率實在太高啦~~ 同時這也更加明確的確認出這個部落格確如其名的只是一份胡思亂想鬼扯蛋的雜記而以... <img src="https://lh3.googleusercontent.com/_W-ixktUlAf8/SsTW7dRZBpI/AAAAAAAABp4/PrKiEarVWzQ/XD.gif"></div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-39488704308985788312011-02-19T23:45:00.028+08:002011-06-20T22:43:57.121+08:00智慧型手機綁約方案選擇<div class="paragraph">電信業者透過一定程度的補貼手段以爭取用戶的方式其來由自,但早期功能型手機世代時其實並不是那麼划算而在這方面沒有太多的困擾。但是直到 <a href="http://www.apple.com/tw/iphone/iphone-3gs/">iPhone 3G/3Gs</a> 登陸台灣後,因為合約中綁定了無線數據上網的部份,所以開創了鄉民們針對電信業者智慧型手機綁約方案的研究與心得整理。這一篇也是網海中注定會浮沉的一個片段,但在它還尚未沉沒前應該還是有一絲絲的參考價值... 吧!</div>
<h4>同手機、同上網資費但不同話務資費比較</h4>
<div class="paragraph">格揆我曾在 <a href="http://www.plurk.com/adahsu">噗浪/Plurk</a> 上隨手寫了一段 <a href="http://www.plurk.com/p/an0v7w">綁約資費方案的選擇條件</a>,這篇文章算是進一步對這些條件加以說明。先來看看當時留的選擇條件如下:<ol><li>網路使用習慣:隨時隨時要取得朋友的各種資訊、只需要行事曆/天氣/郵件通知、還是完全不使用</li><li>各資費下的總支出金額:並不是低資費就一定會繳的少</li><li>該資費下的免費通話量:有些資費方案是能月租折抵通信費用,有些甚至是直接贈送固定金額的通信費用</li><li>個人的通話量:把自己過去 6 個月的平均通話量套到前述條件內,看看那一個方案的額外花費最少。</li></ol></div>
<div class="paragraph">前兩個條件很容易數據化,下表即為假設在中華電信辦理 iPhone 4 32G 手機,選擇 mPro 950 上網吃到飽方案時(即前述第一條件)分別選擇大家講-589及大家講-289(前述第二條件)時不同資費的支出試算。這個試算表中把話務月租費分成兩段的原因在於某些優惠方案可以在滿足一定月份(通常是 12 個月)後調降話務月租費,不過此表中的這兩個 iPhone4 超值方案都無此選項。</div>
<div class="paragraph">至於數據上網月租費方面也有分吃到飽和限量飲食的選擇,由於 mPro 950 是屬於一個價碼吃到飽的模式,所以上、下限都是 NT$950 元打八折的 NT$760 元。</div>
<div class="paragraph">仔細看看這份試算表可以發現:雖然表面上看來『大家講-289』方案的每月支出只要 NT$1,049 元,但若加上手機費用及預繳折扣後反而比『大家講-589』方案的總支出要再貴上 NT$500 元。這就是為什麼網路上及格揆我所一再強調的 <strong>並不是低資費就一定會繳的少</strong> 的原因啊!</div>
<div class="paragraph"><iframe width='780' height='920' frameborder='0' src='https://spreadsheets.google.com/pub?hl=zh_TW&hl=zh_TW&key=0Amf8RZAgU3andEtwdHM5Y0h0WlU5ZFJsZm5hOWR2R2c&single=true&gid=7&range=A1%3AD47&output=html&widget=true'></iframe></div>
<div class="paragraph">
這裡簡單說明一下各項數值的來源吧,然後就可以看看其他幾種方案的比較。當然如果覺得這些數據有什麼疑問之處歡迎一起討論。
<ol>
<li>話務月租費總支出:就兩年下來總共要繳多少通話費</li>
<li>數據上網月租費總支出:一樣是指兩年下來總共要繳多少上網費,不過因為某些上網方案並不是吃到飽的,所以這裡分成上、下限兩個數據。注意:通常這個上限值不應該發生才對。
<li>購機準備金:這是指要領到手機所必須先付出的費用,通常是手機優惠價加上購機預繳費用。若電信公司有推出免預繳方案(通常是 VIP 或 NP)時,購機準備金就會降低。不過看了幾個方案後發現電信公司不管什麼方案要準備的預算都一樣... XD</li>
<li>綁約期內月支出:這是指帳面上每個月要繳給電信公司的費用,但是目前這個試算表沒辦法精確區分出話務費及上網費都會變動的情形。例如,如果話費為先 589 後 289 而上網費則是先 450 後 950 時,這個試算表只會捉出下限為 289 + 450 = 739 的數字而不是實際的 589 + 450 = 1039 這個數值。</li>
<li>綁約期內總支出:話務月租費總支出 + 上網費用總支出 - 預繳贈送金額。中華電信以前的方案是折抵預繳金額的 20%,現在的方案只剩下 10% 而以。</li>
<li>賣出價格:若綁約所取得的手機不為自用的話,可以透過售出方式減少費用支出</li>
<li>另購新機價格:若把綁約手機賣了又需要另一隻手機的話,就得另外花一筆費用。6. 和 7. 之前的價差即俗稱為洗機所得,後續會談到</li>
<li>洗機後最低總支出:洗機的目的是要壓低約期內的總支出,所以此處就只考慮最低總支出費用</li>
</ol>
</div>
<h4>同資費但不同手機間比較</h4>
<div class="paragraph">上一段內容是以同手機但不同資費作為比較,這段則改成同資費但手機分別選擇 iPhone 4 32G 及 HTC Desire HD 時各自會有什麼不同?</div>
<div class="paragraph">基本上 HTC Desire HD 的空機價格本來就比 iPhone 4 32G 要便宜 NT$8,000 上下,所以單單從總支出來看的話選擇 HTC Desire HD 一如預期的必然會比選擇 iPhone 4 32G 的花費要少。但是不對啊?為什麼 HTC Desire HD 的總支出只比 iPhone 4 32G 便宜約 NT$1,000 而以呢?不是說價差約 NT$8,000 嗎?於是有人想到了是不是可以辦 iPhone 4 32G 後,把 iPhone 4 稍微降個價、打個折賣了再到通訊行買隻 HTC Desire HD 來貼補一下月租費的支出呢?</div>
<div class="paragraph">是啊,這方式就是大家常常聽到的洗機。又因為有電信公司是否受制於各家手機制造商的微妙關係,iPhone 系列手機通常會享有電信公司較高的貼補金額,這也是為什麼網路上都建議洗 iPhone 的原因。</div>
<div class="paragraph">下表就是以中華電信『大家講-589』為基礎,在分別選擇 iPhone 4 32G 及 HTC Desire HD 時的各項支出數據。其中 iPhone 4 32G 空機價依 <a href="http://shopping.pchome.com.tw/?mod=item&func=exhibit&IT_NO=DGAS4Q-A50292448&SR_NO=DGAS4Q&ROWNO=4">PChome 報價為 NT$32,900 元</a>,但為了要能脫手以免造成庫存壓力(什麼跟什麼啊)所以此處料敵從嚴的把售價訂在 NT$25,000。當然兩者間的差距不算小,能夠賣的愈高價則所能貼補的月租費就愈多,總支出也會跟著下調,這部份就要看個人機運了。如何賣掉 iPhone 的方式很多,不少人是透過網路拍賣進行競價,但是也有部份的人因為懶惰或其他原因而選擇直接把手機賣給通訊行吧?至於 HTC Desire HD 也依 <a href="http://shopping.pchome.com.tw/?mod=item&func=exhibit&IT_NO=DGAL03-A50595895&c=A05">PChome 報價的話是 NT$20,900 元</a>,不過通訊行的價格應該不會這麼硬才對!</div>
<div class="paragraph"><iframe width='800' height='940' frameborder='0' src='https://spreadsheets.google.com/pub?hl=zh_TW&hl=zh_TW&key=0Amf8RZAgU3andEtwdHM5Y0h0WlU5ZFJsZm5hOWR2R2c&single=true&gid=8&range=A1%3AD47&output=html&widget=true'></iframe></div>
<h4>其他不同方案的比較</h4>
<div class="paragraph">這篇是以智慧型手機綁約為前提所寫的介紹文,那麼有沒有單純針對通話為唯一要件的方案建議呢?</div>
<div class="paragraph">答案可能讓人失望,格揆我會建議 <strong>直接用空機價格購買功能型手機,然後向電信商辦理通信費用補貼</strong> 即可。</div>
<div class="paragraph">以下繼續對各種不同基礎所進行的方案比較,但各比較表僅僅只能作為參考、計算示範之用。任何方案的付費細節請參閱各家電信公司官網或聯絡其客服以取得最新、最正確的資訊。</div>
<div class="paragraph">
<iframe width='800' height='940' frameborder='0' src='https://spreadsheets.google.com/pub?hl=zh_TW&hl=zh_TW&key=0Amf8RZAgU3andEtwdHM5Y0h0WlU5ZFJsZm5hOWR2R2c&single=true&gid=9&range=A1%3AD47&output=html&widget=true'></iframe><div class="memo" style="margin-left: 0; width: 780px">是否一定要選擇 mPro 950 吃到飽方案實際取決於每個月的上網傳輸量是否僅少量甚至是不超過方案上限值。不過可以確定的是如果有 7 個月以上因傳輸爆量達 mPro 450 收費上限 NT$1,200 的話,那麼選用 mPro 450 的費用支出就會開始超過 mPro 950 了。</div></div>
<div class="paragraph"><iframe width='800' height='940' frameborder='0' src='https://spreadsheets.google.com/pub?hl=zh_TW&hl=zh_TW&key=0Amf8RZAgU3andEtwdHM5Y0h0WlU5ZFJsZm5hOWR2R2c&single=true&gid=10&range=A1%3AD47&output=html&widget=true'></iframe><div class="memo" style="margin-left: 0; width: 780px">如果比較一下各家電信業者的資費方案,可以做為是否 NP 的決策。不過各家對 NP 的補貼倒是不一定能享受到就是了!另外這份表中的遠傳資費不一定正確,因為格揆不太瞭解遠傳資費的解讀方式,有可能因為認知錯誤給了一個不正確的數值。</div></div>
<h4>結論</h4>
<div class="paragraph">其實整個評估作業最簡單的方式不過就是計算月租費及手機費用的總支出,少數電信公司的預繳費用會有更多的折扣,那就再扣除這些多的折扣就是最終取得手機的實際支出。聰明的你應該馬上能計算出自己所需的優惠方案了吧?</div>
<h4>追加報導 - 《 中華電信 - 平板+智慧新機成對帶著走!「天生一對」方案 》</h4>
<div class="paragraph"><iframe width='800' height='460' frameborder='0' src='https://spreadsheets.google.com/spreadsheet/pub?hl=zh_TW&hl=zh_TW&key=0Amf8RZAgU3andEtwdHM5Y0h0WlU5ZFJsZm5hOWR2R2c&single=true&gid=11&range=A1%3AE24&output=html'></iframe><div class="memo" style="margin-left: 0; margin-top: 0; width: 780px">個人看法:<ul><li>個人覺得綁約三年的各種合約都儘量少碰,尤其像手機這種半年就一款旗艦機的情形下更沒有再堅持一年的必要性</li><li>mPro 450 每月有 500MB 的額度,和 mPro 750 相比上限值雖然多 NT$100,但是一般以 WI-FI 環境為主的情形下月租費卻可以少掉 NT$300,個人認為是買空機情形下比較划算的選擇</li><li>個人認為如果真有行動平板電腦的需求,透過洗手機(目前效果差很多)的方式可能比較划算</li><li>對了,除非辦了兩組上網門號,不然 Flyer 要上 3G 時要拔 SIM 卡進行交換... XD</li></ul></div></div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com1tag:blogger.com,1999:blog-909727791061240227.post-84448861842355188882011-01-28T15:22:00.000+08:002011-01-28T15:22:56.703+08:00次世代主機的體感創意落差<div class="paragraph">我是看了 『<a href="http://chinese.engadget.com/2011/01/28/nintendo-q3-profits-down-46-percent-slashes-console-sales-proje/">老任第三季營收掉了46個百分比,狂賣缺貨的日子已是往日榮光?</a>』 這篇文章時突然覺得老任營收會下調營收預測似乎是必然的,畢竟這是一台老主機,加上 XBox 360 Kinect 的出現明顯搶了 Wii 的風采。</div>
<div class="paragraph">以下是格揆我對三大主機在體感創意方面的自我主張,大家可以參考參考:
<ul>
<li>任天堂 Wii Remote/Remote Plus:這玩意兒無疑是對體感遊戲的可能性具有重大貢獻,但是年代已久早顯疲乏;不過在某些需要精準控制的遊戲需求上仍有其重要性存在。</li>
<li>微軟 Kinect:可視為自 Wii Remote 發表以來的重大演進,不光是少了遊戲過程中額外控制器的需求,還能被應用在各種 <strike>肉</strike> 人體動作補捉上。</li>
<li>索尼電腦娛樂 PS Move:雖然看來有一些和 Wii Remote/Remote Plus 不同的運用方式,但原始創意來源怎麼看都覺得是抄自任天堂的,所以目前看不出有何氣勢似乎也是很合情合理的。</li>
</ul>
</div>
<div class="paragraph">所以,格揆我不小心在過年前從 <a href="http://shopping.pchome.com.tw">電腦家</a> 訂了一組 XBOX 360 + Kinect 同綑包要回家孝敬爹娘了... XD</div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-40344473222116331212011-01-19T17:52:00.004+08:002011-01-20T17:23:00.382+08:00如何在 Shell Script 中捉取 MySQL 資料庫中的指定記錄值<div class="paragraph">很久沒寫 Blog 了,也許是因為撞牆期吧?</div>
<div class="paragraph">總之,來寫個跟 Shell Script 及 MySQL 有關的東西吧:如何在 Shell Script 中直接取得 MySQL 資料庫中某記錄的值!</div>
<h4>需求起因</h4>
<div class="paragraph">事情的發展是這樣的:為了確保系統發出的 EMAIL 能有效的送達用戶手上,所以懶人如格揆我就很順手的把 /var/log/maillog 中的郵件寄送記錄給解出來了,反正不需要我每天動手做的任何方式都是最佳的方式。但是,代誌毋係憨人想ㄟ哈呢甘單,沒多久就有人寄信來希望能加上信件主旨,於是格揆很快的又回到每日人工查資料的機械生活中,這完全是忤逆懶人天性,違乎常理的發展啊。</div>
<div class="paragraph">就因為『懶散要超越懶散』,格揆我其實一直希望能把這動作併入 Shell 中自動補完,終於在今天找出了正確的解法,先記錄一下以免腦殘之後忘了該怎麼辦!</div>
<h4>編碼問題</h4>
<div class="paragraph">在讀取資料庫中的資訊前有一點很重要:系統編碼!</div>
<div class="code"><pre>mysql> status
--------------
mysql Ver 14.12 Distrib 5.0.77, for redhat-linux-gnu (i686) using readline 5.1
Connection id: 2468601
Current database: *** 不要問 ***
Current user: *** 很恐怖 ***
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.0.86-community-log MySQL Community Edition (GPL)
Protocol version: 10
Connection: *** 您知道的 ***
Server characterset: latin1
Db characterset: <span style="color: red; font-weight: bolder;">utf8</span>
Client characterset: <span style="color: blue; font-weight: bolder;">latin1</span>
Conn. characterset: <span style="color: blue; font-weight: bolder;">latin1</span>
TCP port: 3306
Uptime: 428 days 21 hours 44 min 57 sec
Threads: 8 Questions: 115577998 Slow queries: 8 Opens: 81015 Flush tables: 1 Open tables: 64 Queries per second avg: 3.119
--------------</pre></div>
<div class="paragraph">如果登入 MySQL 時看到了像是上圖中顯示了不同的編碼狀態,那麼任何 select 到的中文字都會變成亂碼!這問題不難處理,在使用 MySQL Command line Tools 加上 --default-character-set=encodename 即可,如上例即應改由以下方式登入 MySQL:</div>
<div class="code">[ada@myhost ~]$ mysql --default-character-set=utf8</div>
<div class="paragraph">加上了預設編碼設定後後,再到 mysql 命令列工具中下達 status 指令就會看到編碼設定已經被改過了,如下:</div>
<div class="code"><pre>Server characterset: latin1
Db characterset: <span style="color: red; font-weight: bolder;">utf8</span>
Client characterset: <span style="color: red; font-weight: bolder;">utf8</span>
Conn. characterset: <span style="color: red; font-weight: bolder;">utf8</span></pre></div>
<h4>Select 取值方式</h4>
<div class="paragraph">之前在對 Oracle 進行操作時,它有提供如何<a href="http://www.orafaq.com/wiki/Unix_FAQ">在 Shell 中去讀取資料庫內容</a>的作法,這裡用讀取資料庫系統時間作為例子:</div>
<div class="code"><pre>
[ada@ora ~]$ NOW=$(sqlplus -s << END
> set heading off
> set feedback off
> select sysdate from dual;
> exit;
> END)
[ada@ora ~]$ echo $NOW
2011-01-19 17:02:48</pre></div>
<div class="paragraph">但如果想要在 MySQL 中如法泡製的話,輸出結果顯然需要額外再加工才行,如下所示:</div>
<div class="code"><pre>[ada@myhost MYSQL]$ NOW=$(mysql --default-character-set=utf8 --silent -E <<END
select now();
END)
[ada@myhost MYSQL]# echo $NOW
*************************** 1. row *************************** now(): 2011-01-19 16:40:25</pre></div>
<div class="comment">靠杯,為什麼兩台的時間差這麼多?</div>
<div class="paragraph">還好 MySQL 另外提供一個方式可以讓我們只看到實際輸出資料而沒有欄位名稱什麼的,如下例:</div>
<div class="code"><pre>[ada@myhost MYSQL]$ NOW=$(echo "select now()" | mysql --default-character-set=utf8 --silent)
[ada@myhost MYSQL]# echo $NOW
2011-01-19 17:07:56</pre></div>
<div class="paragraph">好啦,想要在 Shell 中去讀取 MySQL 中的某個值就是這麼簡單。如果要撈的是多筆、多欄位的資料呢?沒有問題,系統會用空白串接所有擷取出的欄位值,這樣會比較難處理,但它確確實實還是能夠加以操作。</div>
<div class="code"><pre>[ada@myhost MYSQL]# LIST=$(echo "select status, time_start, creator from epaper" | mysql --silent)
[ada@myhost MYSQL]$ echo $LIST
0 2012-08-03 00:00:00 admin 1 2010-09-01 00:00:00 admin 0 2011-09-08 00:00:00 admin 0 2011-09-03 00:00:00 admin 1 2010-10-02 00:00:00 admin 1 2010-10-05 00:00:00 admin 1 2010-10-05 00:00:00 admin 1 2010-10-05 00:00:00 admin 0 2011-11-11 00:00:00 admin 1 2010-11-03 00:00:00 admin 0 2011-11-05 00:00:00 admin 0 2011-11-07 00:00:00 admin 1 2010-11-05 00:00:00 admin 1 2010-12-01 00:00:00 admin 1 2010-12-02 00:00:00 admin 0 2012-12-06 00:00:00 admin 1 2011-01-15 00:00:00 admin</pre></div>
<div class="paragraph">其實也可以改成以下這樣啦,只不過這樣會多出欄位標題出來,需要自行濾除...</div>
<div class="code"><pre>[ada@myhost MYSQL]$ mysql --default-character-set=utf8 --silent -e 'select status, time_start, creator from epaper'
status time_start creator
0 2012-08-03 00:00:00 admin
1 2010-09-01 00:00:00 admin
0 2011-09-08 00:00:00 admin
0 2011-09-03 00:00:00 admin
1 2010-10-02 00:00:00 admin
1 2010-10-05 00:00:00 admin
1 2010-10-05 00:00:00 admin
1 2010-10-05 00:00:00 admin
0 2011-11-11 00:00:00 admin
1 2010-11-03 00:00:00 admin
0 2011-11-05 00:00:00 admin
0 2011-11-07 00:00:00 admin
1 2010-11-05 00:00:00 admin
1 2010-12-01 00:00:00 admin
1 2010-12-02 00:00:00 admin
0 2012-12-06 00:00:00 admin
1 2011-01-15 00:00:00 admin
[ada@myhost MYSQL]$</pre></div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com1tag:blogger.com,1999:blog-909727791061240227.post-52371351897638302372010-11-28T23:03:00.004+08:002010-11-29T21:17:39.181+08:00五都選舉馬後砲<h4>前言</h4>
<div class="paragraph">
台灣首場五都首長選舉已於 11/27 晚上拍板定案,就上榜率而言藍軍以過半的 60% 大勝綠營的 40%,但以得票率來看的話則是綠營以近 5 成的 49.87% 大勝藍營的 44.54% 共 40 餘萬票。於是照慣例,格揆我一定要放個馬後砲留點紀念,反正格揆我也只會放放馬後砲以免惹上 <a href="http://www.google.com.tw/search?aq=0&oq=%E6%84%8F%E5%9C%96%E4%BD%BF&sourceid=chrome&ie=UTF-8&q=%E6%84%8F%E5%9C%96%E4%BD%BF%E4%BA%BA%E4%B8%8D%E7%95%B6%E9%81%B8">意圖使人不當選</a> (沒想到它還是目前的 Google Suggestion 呢)的麻煩。
</div>
<h4>台北市</h4>
<div class="paragraph">
就個人情感上對台北市是希望蘇貞昌當選的,不過個人一向對天龍人的民主養成教育沒啥信心,選舉結果也如預期般由在新生高及花博等工程中浪費人民血汗錢的現任市長連任。對司法一向沒啥信心的格揆我也只能說這些爭議案件都將不會有什麼結果了。
</div>
<div class="paragraph">
另外蘇貞昌在整個竸選期間曾親到台北市各處探查民情,但似乎找不到類似個 Issue Tracker 的問題追踪系統並公開給大眾監管執政者是否已解決問題?個人倒是挺建議蘇這邊把相關資料整理後移交給民進黨台北市議會黨部(或是移交給 <a href="http://tba.tw/map">TBA</a> 也行?),不只可以讓議員們持續追踪這些問題,搞不好四年後還能用來翻舊帳呢!
</div>
<div class="paragraph">
對了,每次看到好冰冰市長的台北起飛、Fly High 選舉手勢時總會莫名其妙的想到國家地理頻道中的 <a href="http://www.ngc.com.tw/Programmes/Main.aspx?Id=1836">空中浩劫</a> 節目,為什麼?因為空難事件絕大多數都發生在起降時刻呀~~
</div>
<h4>新北市</h4>
<div class="paragraph">
老實說在過去民進黨多任縣長的先例下,本來並不覺得新北市是一個藍色為主的政治環境,但從此次的選舉結果看來新北市大概就此被劃入藍色版圖內了吧?
</div>
<div class="paragraph">
至於對這兩位候選人而言,個人沒有太多意見。對小英而言其實本來就不太贊成她出來竸選,至於老是批評小英是選假的的朱市長個人則覺得實在過於小鼻子小眼睛就是了。讓一個現任的新北市長去選總統搞不好可以讓任內已規劃的所有建設一次到位,對新北市民搞不好受益更多呢!再說為什麼每次都只能由選台北市長的人去競選總統呢?這明顯是對其他縣市的一種歧視嘛... <img src="http://lh5.ggpht.com/_W-ixktUlAf8/SsQi0EyUkOI/AAAAAAAABjY/GrKai7ClNXM/anger.gif">
</div>
<div class="paragraph">
不過,其實北二都失守也不一定要那麼悲觀到又要勞駕精神科醫師 <a href="http://www.wretch.cc/blog/billypan101">Billy Pan</a> 大叔再辦一次 <a href="http://www.wretch.cc/blog/billypan101/11729431">療傷網聚</a> 啦,阿Q點想,也許這是因為北二都的民眾們比較希望兩位市長候選人能專心準備 2012 總統大選也說不定呢~
</div>
<h4>台中市</h4>
<div class="paragraph">
個人是覺得台中市最近幾年實在是沒啥發展,不過反正又不住那邊所以不需要太過在意。只是這次再由胡志強當選讓人好奇台中市民過去九年來對胡市長的臉都不覺得膩嗎?
</div>
<div class="paragraph">
說到胡志強他這次猛推不少競選廣告,<a href="http://www.youtube.com/watch?v=gIlPAgGKf9s">吹牛被捉包的</a> 就不管了,反到是在 <a href="http://www.youtube.com/watch?v=P3yfDiUNra4">大台中 大未來</a> 所提的 <strong>與香港競爭、追趕新加玻</strong> (這樣看起來新加破贏香港)口號應該先問問胡市長把台北市放那邊去了吧?
</div>
<div class="paragraph">
另外胡市長還有一個在競選末期某幾天內曾強力放送的廣告中不知為何總覺得他口齒不清,不知原因是不是我耳朵生繭的關係?
</div>
<h4>台南市</h4>
<div class="paragraph">
基本上我對這兩位候選人都不熟悉,但比較想說的是台南縣蘇縣長接受初選結果且即表態支持黨提名人這件事比較有印像;而許市長雖然最後也放棄脫黨參選,但總覺得他本來也想循高雄縣長模式脫黨的,只是不知什麼原因使其放棄而以!
</div>
<h5>高雄市</h5>
<div class="paragraph">
對高雄市而言比較有印象的並不是花媽陳菊,反倒是脫黨參選的現任高雄縣長讓人印象深刻。雖然他後期極力訴求不分藍綠、政治中道的企圖明顯,可惜顯然大家對他的『昨是今非、昨非今是』非常有意見。但在這種情形下仍有 40 餘萬票其實力也算是異常雄厚,只不過我覺得他這次真的是賭輸了,未來如果想再走政治這條路應該是會異常艱困吧?
</div>
<h5>政治光譜的改變</h5>
在假圖天圖有篇 <a href="http://sophist4ever.pixnet.net/blog/post/27548908">【台灣觀察】藍綠光譜的改變!</a> 提到現今的政治光譜已不光是藍綠而以,由於騜式詐騙集團的快速傾中導致這群詐騙集團的政治光譜比較像是紅色而不是國民黨黨徽上的藍色。本來以為在六年級上段班之前這些受過國民黨反共抗俄教育的這一代應該會全力反抗騜的傾中現象,不過實際上看來似乎還有很多人只是單純的效忠黨徽而不是去看領導人有沒有在亂搞的嘛,顯然過去國民黨的愚民教有真是成功呢!
<h5>大話新聞</h5>
<div class="paragraph">
呃,大話新聞不屬於五都的成員,只是因為就幾次選舉下來發現大話新聞的成員總會認為騜式詐騙集團即然這麼糟糕,相信所有台灣人都已經覺醒,必然會給騜一個嚴正的教訓!但每次的期昐的結果總是與預期相去甚遠,這究竟是什麼原因呢?也許就只是別高估台灣民主教育成就而以吧?
</div>
<h5>意圖使人不當選</h5>
<div class="paragraph">
以下是網路上討論到的相關文章:
<ul>
<li><a href="http://applepig.idv.tw/archives/557">[廣告] 法律教室:「意圖使人不當選」</a></li>
<li><a href="http://blog.ijliao.info/archives/2010/11/26/4229/">選舉奧步與 "意圖使人不當選"</a></li>
<li><a href="http://blog.roodo.com/bigburger/archives/14384819.html">「意圖使人不當選」之罪?</a></li>
</ul>
</div>
<h5>選後第三天最新心得</h5>
<div class="paragraph">
<ul>
<li>今天聽說民進黨那些老灰呀全部跑出來批評小英,呃... 這群人實在該乖乖退休比較好... <img src="http://lh6.ggpht.com/_W-ixktUlAf8/SsRJOAiF8ZI/AAAAAAAABnU/3jo3P7v2lU8/nothing.gif"></li>
<li>還有人批評都是蘇光頭執意參選台北市長才會打亂原本的必勝配置,呃... 我也不認為新北市民願意看到回鍋的新市長... </li>
<li>個人一直不覺得那顆子彈對選情有啥影響,不過似乎全台灣都認為影響可大了?</li>
</ul>
</div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-43311657705037170512010-11-26T16:41:00.004+08:002010-11-27T01:29:20.611+08:00Maven、Java 1.5 與 xdoclet 的相處之道<div class="paragraph">
最近幾年來的 Java 專案都使用 <a href="http://maven.apache.org">Maven 2</a> 進行自動化部署程序,講白一點就是不想每次都要依環境差異而透過手工進行設定調整及打包程序。不過有趣的是還是有很多軟體開發人員仍然堅持手工打造然後因為一點疏失就上錯程式捅下漏子!
</div>
<div class="paragraph">
但是不知道為什麼,整個 Maven 中的 xdoclet plugin 預設一直使用舊版的 xjavadoc 套件,導致在處理 JDK 1.5 新增的泛型特性(Generics)時因為不認識角括號 < 而吐出一大堆錯誤訊息,並連帶使的 Maven 原本提供的 javadoc 操作失敗(產生的 javadoc 不完整),對開發公用程式庫且必須提供 javadoc 的人員來講就變的很困擾。
</div>
<div class="paragraph">
一直逃避不是辦法,所以今天花了點時間找了網路上的資料後試出了解決方法。基本上是參考 <a href="http://blog.xuite.net/godisren/blog/15082189">解決xdoclet-maven-plugin於jdk5上跑發生問題</a> 的說法,但文中所提的 plugin 來源 http://quebbemann.kicks-ass.net/maven2/repository/ 被 <a href="http://tw.trendmicro.com/tw/products/enterprise/officescan-client-server-edition/">威猛的趨勢科技世界級創新Smart Protection Network主動式雲端截毒技術</a> 擋在門外... 只好另外找其他的 plugin 來源。
</div>
<div class="paragraph">
總之,要讓 xdoclet 叫用新版的 xjavadoc 模組的方法是覆寫 xdoclet-maven-plugin 的相依性設定,使 xdoclet-maven-plugin 正確叫用新版的 xjavadoc 1.5 去解析 Java 原始碼,因此需要在 xdoclet-maven-plugin 設定區塊下新增相依性設定如下:
<div class="code">
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xdoclet-maven-plugin</artifactId>
<version>1.0</version>
<strong><dependencies>
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>xdoclet</groupId>
<artifactId>xjavadoc</artifactId>
<version>1.5-snapshot050611</version>
</dependency>
</dependencies></strong>
<executions>
<execution>
<id>xdoclet</id>
<phase>generate-sources</phase>
<goals>
<goal>xdoclet</goal>
</goals>
<configuration>
<outputEncoding>UTF-8</outputEncoding>
<tasks>
<webdoclet destDir="${basedir}/src/main/webapp/WEB-INF" encoding="UTF-8" docencoding="UTF-8"
mergeDir="${basedir}/src/main/resources/webdoclet" verbose="true" force="true">
<fileset dir="${basedir}/src/main/java" includes="**/*.java" />
<deploymentdescriptor displayname="${project.name}"
xmlencoding="UTF-8" description="${project.description}">
</deploymentdescriptor>
</webdoclet>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</div>
</div>
<div class="paragraph">
但是光這樣還不夠,因為 Maven 官方的套件庫中並未包含 xjavadoc 1.5 相關資訊,所以必須另外指定去那邊下載 xjavadoc 套件,這只要在 pom.xml 中加入以下設定區塊即可。唯一要注意的是這個套件庫有可能隨時不見... XD
<div class="code">
<pluginRepositories>
<pluginRepository>
<id>jahia</id>
<url>http://maven.jahia.org/maven2/</url>
</pluginRepository>
</pluginRepositories>
</div>
</div>
<div class="paragraph">
好了,經由以上設定後 xdoclet 就不會因為程式碼使用到 JDK1.5 的泛型功能時只會吐出一堆 warning 了!
</div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-74928465769621104692010-11-04T00:14:00.000+08:002010-11-04T00:14:10.852+08:00試乘捷運蘆洲線<div class="paragraph">聽說今天是捷運蘆洲線試營運的第一天,格揆我也湊個熱鬧調整了下班路線跑去試試看免費的蘆洲線究竟如何?</div>
<div class="paragraph">整個回家所需時間約為 80 分鐘,比原本路線的時間差不多得多花個 20 分鐘以上才行,為了早點兒奔向溫暖的床舖我相信蘆洲線應該只會搭這麼一次吧?</div>
<div class="paragraph">
從 18:57 離開辦公室到回到家裡的時間 20:15 各種狀態(咦?狀態圖?)如下:<br/>
<div class="table">
<table>
<tr><th style="width: 150px">狀態</th><th style="width: 70px">時刻</th><th style="width: 90px">花費分鐘數</th><th>原路線所花時間</tr>
<tr><td>離開辦公室</td><td class="center">18:57</td><td class="center">-</td><td class="center">-</td></tr>
<tr><td>出辦公大樓</td><td class="center">19:00</td><td class="center">3</td><td class="center">3</td></tr>
<tr><td>搭上南港展覽館接駁公車</td><td class="center">19:09</td><td class="center">9</td><td class="center">9</td></tr>
<tr><td>到達捷運南港站下公車</td><td class="center">19:13</td><td class="center">4</td><td class="center">4</td></tr>
<tr><td>捷運南港站發車</td><td class="center">19:17</td><td class="center">4</td><td class="center">4</td></tr>
<tr><td>捷運忠孝新生站下車</td><td class="center">19:31</td><td class="center">14</td><td class="center">-</td></tr>
<tr><td>捷運蘆洲線忠孝新生站發車</td><td class="center">19:37</td><td class="center">6</td><td class="center">-</td></tr>
<tr><td>捷運三重國小站到達</td><td class="center">19:50</td><td class="center">13</td><td class="center">-</td></tr>
<tr><td>出捷運三重國小站</td><td class="center">19:53</td><td class="center">3</td><td class="center">-</td></tr>
<tr><td>出捷運台北車站</td><td class="center">-</td><td class="center">-</td><td class="center">17</td>
<tr><td>台北車站-忠孝候車站</td><td class="center">-</td><td class="center">-</td><td class="center">3 ~ 5</td></tr>
<tr><td>等待公車(藍1/39)</td><td class="center">-</td><td class="center">-</td><td class="center">3 ~ 5</td></tr>
<tr><td>扺達三重大同路口</td><td class="center">-</td><td class="center">-</td><td class="center">10 ~ 20</td></tr>
<tr><td>開家門</td><td class="center">20:15</td><td class="center">21</td><td class="center">5</td></tr>
<tr><td colspan="2" class="center">合計</td><td class="center">77</td><td class="center">67</td></tr>
</table>
</div>
</div>
<div class="paragraph">
其實從南港轉捷運蘆洲線回三重所需時間不算很多,但是從三重國小站要回到天台這一帶的話是要花上一點時間的。如果晚餐想在三和夜市中解決的話是可以考慮這一條回家路線,不然的話從台北車站經忠孝橋回三重通常會比較快才是!
</div>
<div class="paragraph">
還有從上表中可以發現在忠孝新生站轉車的等待時間偏久,不過如果以上班不遲到為考量的話搭乘捷運上班有其優勢存在(但是捷運三不五時會突槌,那叫做<strong>正常能量釋放</strong>)。最後整條蘆洲線的月台設計似乎都給人一種空間上的壓迫感,在等車的時候可能會造成心情上的不快!
</div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-58959579087287296752010-10-30T22:59:00.000+08:002010-10-30T22:59:25.599+08:00[公告] 切換部落格網址原本就計畫將目前的 adahsu0521.blogspot.com 網址連結到原本使用的 blog.adahsu.net 上,今天正式完成了這個設定。不過因為 DNS 同步的問題可能最遲會到一星期後才能正常訪問。Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-56868969223679110642010-09-30T00:12:00.002+08:002010-10-08T17:49:27.632+08:00Android Froyo 2.2.1 升級失敗前陣子 Google 䆁出了 Froyo 2.2.1 的小升級,身為 Nexus One 持有者當然會優先收到 OTA 通知,只是這次的升級... 失敗了... <img border="0" src="http://2.bp.blogspot.com/_W-ixktUlAf8/SsR5LryjGGI/AAAAAAAABpw/jL5c8kNZzWs/s1600/XD.gif" />
<br />
<br />
因為使用過一鍵 ROOT 工具,所以早早就以節省 ROM 空間的理由把 /system/app 中的東西砍的砍、搬的搬,而這個沒有官方更新資訊的 Froyo 2.2.1 除了已知的解決了一鍵 ROOT 所使用的系統漏洞外還順便更新了系統內建的 GMail.apk 到 2.3 版。<br />
<br />
問題在於 GMail 2.3 這個升級版本來就可以從 Android Market 中下載,所以我也早就把原始的 GMail.apk 給弄走換成新版的 GMail ,於是 Froyo 2.2.1 在更新的過程中因為找不到 GMail.apk 的關係所以 patch failed ... 想當然,於是 OTA 就這麼莫名其妙的失敗了...
還好雖然 OTA 失敗但系統仍然可以透過組合鍵重新開機,只是 OTA 更新就這麼不見了... <img src="http://lh6.ggpht.com/_W-ixktUlAf8/SsQsQ2EqpOI/AAAAAAAABk4/WiDfSQc-5m0/despondent.gif" /><br />
<br />
重新開機後原始的 ROOT 環境還在(呼~~ 好佳在),趕快把 GMail.apk 搬回去再把 GMail 2.3 移除後,至今為止(才過了一天而以啦)還沒重新收到 OTA ,也許我得堅守在 Froyo 2.2 了吧?<br />
<br />
※如果還有更新其他套件的話,那下次 OTA 應該還是會失敗吧... <img src="http://lh5.ggpht.com/_W-ixktUlAf8/SsQmNbhz9_I/AAAAAAAABkM/GaaTNOl1cfs/cheerful.gif" />
<br />
<br />
<div>
<strong>2010-10-03 補充:</strong><br/>
昨天再次收到 Froyo 2.2.1 升級通知,這次也沒太多考量就莫名其妙給它按下更新... 然後... 又失敗了... XD<br/>
<br/>
這次它去更新 Google Goggles,但... 我移掉了... XD
</div>
<div>
<strong>2010-10-08 補充:</strong><br/>
今天三次收到 Froyo 2.2.1 升級通知,這次也沒太多考量就莫名其妙給它按下更新... 然後... 又失敗了... XD<br/>
<br/>
這次它去更新 Amazon MP3,但... 我移掉了... 而且是沒備份的移除了... XD
顯然只能重刷 Froyo 2.2 後再進行升級了... @@
</div>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-11540589557816276642010-08-26T01:02:00.000+08:002010-08-26T01:02:07.514+08:00促銷價格的背後有家超商喜歡用第二件六折的方式拉抬產品銷量,也有一家超商總是以二件 79 折方式來吸引消費者的眼光,畢竟第二件六折的實際意義就是二件八折,這個 79 折策略聽起來就是有那麼一點佔人家便宜的感覺。
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://lh3.ggpht.com/_W-ixktUlAf8/THIGbMPwb_I/AAAAAAAACYM/ftGuS3Lbuhs/s1600/IMG_20100823_132401.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img "="" src="http://lh3.ggpht.com/_W-ixktUlAf8/THIGbMPwb_I/AAAAAAAACYM/ftGuS3Lbuhs/s640/IMG_20100823_132401.jpg" /></a></div>
<br />
上圖就是 79 折的實際案例,只是這個整箱特價似乎有點問題... <img border="0" src="http://lh6.ggpht.com/_W-ixktUlAf8/SsRJ9pmPuUI/AAAAAAAABoI/h_eF5OCO0Hs/scared.gif" />
<br />
<br />
以一罐鋁泊包飲料 10 元來計算,192 元其實是打八折時的價格,如果以 79 折來計算的話應該是 189.6 元,只是超商是否會進位到 190 元則不太確定,而且超商的 POS 會刷出多少錢出來也有待測試。 <br />
<br />
嗯,不過在這邊計較這兩塊錢會不會顯的太窮酸樣了呢... <img src="http://lh6.ggpht.com/_W-ixktUlAf8/SsQtD6oGX4I/AAAAAAAABlk/wypRz9_ipno/gee.gif" border="0" />Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-36764485436608998472010-08-14T15:06:00.000+08:002010-08-14T15:06:37.222+08:00昨日的冒險旅程昨日 ( 2010/08/13 ) 下班所搭乘的公車在剛過新莊思源路時,忽聞司機伯伯一聲廣播:『抱歉,請各位準備更換車輛,本車爆胎了... 』!正當大家還莫名其妙摸不著頭緒時,車身一震,原本轟隆(這是誇飾法)的引擎聲嘎然而止.... 我想,再怎麼狀況外的人也都知道該下車了... XD<br />
<br />
不過,下車後所看到的景像可就讓人心驚膽顫了...<br />
<br />
<table style="width: auto;"><tbody>
<tr><td><a href="http://picasaweb.google.com/lh/photo/EfwNRaN38gTDMWQ8OAnsMQ?feat=embedwebsite"><img src="http://lh6.ggpht.com/_W-ixktUlAf8/TGY9tNdbfiI/AAAAAAAACVg/dUyNwd0pveM/s800/IMG_20100813_180546.jpg" /></a></td></tr>
<tr><td style="font-family: arial,sans-serif; font-size: 11px; text-align: right;">寄件者 <a href="http://picasaweb.google.com/hungwei.hsu/JONUYI?feat=embedwebsite">危險</a></td></tr>
</tbody></table>
<br />
<br />
那麼它的右後退呢? <br />
<table style="width: auto;"><tbody>
<tr><td><a href="http://picasaweb.google.com/lh/photo/SSv4oR_z3pTF978bDOmx5g?feat=embedwebsite"><img src="http://lh3.ggpht.com/_W-ixktUlAf8/TGY9wo_6R-I/AAAAAAAACVk/sCbks281S9Q/s800/IMG_20100813_180556.jpg" /></a></td></tr>
<tr><td style="font-family: arial,sans-serif; font-size: 11px; text-align: right;">寄件者 <a href="http://picasaweb.google.com/hungwei.hsu/JONUYI?feat=embedwebsite">危險</a></td></tr>
</tbody></table>
點選照片可以連到有地圖標示的 Picasa 相簿!Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-29301567661562759402010-06-07T22:00:00.000+08:002010-06-07T22:00:25.120+08:00最佳英文翻譯獎這個翻譯真是超贊的... <img src="http://lh4.ggpht.com/_W-ixktUlAf8/SsQxwHu75EI/AAAAAAAABl4/pXSrrSInTao/goodjob.gif"><br>
<img src="http://lh5.ggpht.com/_W-ixktUlAf8/TAw_FdLrmFI/AAAAAAAACEY/xZQnTsLA2yY/s800/2010-06-03%2018.27.15.jpg">Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-11545427060348329162010-04-14T17:16:00.003+08:002010-09-02T15:12:21.249+08:00如何在下載動作中正確顯示中文檔名?<p>
總而言之,除了為人垢病的 CSS 問題外,各家瀏覽器在下載中文檔名時也有各自的脾氣...
</p>
<p>
以下是 JAVA 程式碼範例,大致上就分成兩派:支援 <a href="http://greenbytes.de/tech/webdav/rfc2231.html">RFC-2231</a> 的 Firefox/Opera 系和不支援的 IE /Webkit 系兩種,在 <a href="http://greenbytes.de/tech/tc2231/">Test Cases for HTTP Content-Disposition header and RFC 2231/2047 Encoding</a> 網站中有對各家瀏覽器是否支援 <a href="http://greenbytes.de/tech/webdav/rfc2231.html">RFC-2231</a> 規範的測試記錄,就結果來看除了純 ASCII 編碼的檔名頗受大家都支援外 (?),其他混雜有各地語言的檔案名稱就得依瀏覽器的派別個別處理了。
<div class="code">
<pre>
if ( StringUtils.contains( userAgent, "MSIE" ) || StringUtils.containsIgnoreCase( userAgent, "AppleWebKit" ) ) {
res.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode( fileName, "UTF-8" ) + "\"");
} else {
res.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode( fileName, "UTF-8" ) );
}
</pre>
</div>
</p>
<p>
就目前測試結果得知:
<ol>
<li>IE 6:可以正確彈出下載視窗,但存檔時的不一定能顯示正確的中文檔名</li>
<li>IE 7/8:可以正確彈出下載視窗及中文檔名</li>
<li>Chromium 5.0.360.5 / Chrome 5.0.375.3 dev:可以正確彈出下載視窗及中文檔名,其 AppleWebKit 核心版本分別為 533.3 及 533.4 </li>
<li>Safari 4.0.5:在 AppleWebKit/531.22.7 時兩種方式都不行,但因 Chrome 的經驗猜測更新 AppleWebKit 到 5.33 以後版本即可正確顯示中文檔名</li>
<li>Firefox 3.x:可以正確彈出下載視窗及中文檔名</li>
<li>Opera 10.51:可以正確彈出下載視窗及中文檔名</li>
</ol>
</p>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-78284188151318880142010-03-18T11:58:00.004+08:002010-05-02T02:26:22.481+08:00OpenTTD 簡單心得<p>
最近不務正業的在玩 <a href="http://www.openttd.org/en/">豪華運輸大亨</a> ,都忘了要趕快規畫倒底要寫那類型的 Android 軟體了... <img src="http://lh3.ggpht.com/_W-ixktUlAf8/SsQoYvd0koI/AAAAAAAABko/m4xO08sekIY/coyly.gif"> 不過還是簡單記錄一下大亨的入門心得好了。
</p>
<p>
這個遊戲的重頭大戲其實在鐵道規劃上,如何利用鐵道號誌讓一大堆的火車可以在雙向兩條軌道上正常運行而不會有對撞、追撞等事故算是最簡單的入門(雙軌雙向軌道真的比單軌雙向軌道簡單多了)。雖說只是入門,但看著二、三十輛車在軌道上依序運行卻總能帶給玩家滿滿的成就感。以下是釀成多起追撞、對撞事故後的注意事項清單!
</p>
<p>
<ol>
<li>如果要賺錢的話可以搞航空運輸,不過個人覺得很空虛... </li>
<li>如果要搞鐵道貨運的話網友都會建議以媒炭為主</li>
<li>雙軌鐵道要先統一是左出右進還是右出左進,像台灣的鐵道記得都是左出右進的!</li>
<li>雙軌鐵道在分歧點時都需要設置號誌,簡單的概念是左邊出口處要放<strong>入口號誌</strong>,右邊進(入)口處則放置<strong>閉塞號誌</strong>,號誌應設置在前進方向的右側,以左出右進來看號誌就會集中在鐵道中央。有興趣者可以參考 <a href="http://www.badongo.com/pic/8969230?size=original">這裡</a> !</li>
<li>如果軌道上有多輛車次的話則視鐵道長短酌量設置<strong>閉塞號誌</strong>,不然的話車子會卡在車站出口處。而車站出口處一被卡死就會造成同軌道上的車輛要不就跟著卡死,要不然就是追、對撞事故。</li>
<li>維修機場不要設在離車站太近的地方,距離至少要超過車輛長度(7格14節)及號誌設置區,不然有很大的機會出現車輛卡在車站與機場之間動彈不得的情形。
</ol>
</p>
<p>
嗯,有新的心得會繼續補充!圖片的部份再想辦法生出來...
</p>
<p>陷入無限迴圈的火車... <div class="image"><img src="http://lh6.ggpht.com/_W-ixktUlAf8/S6R5mvErm_I/AAAAAAAAB6c/_WKkdtpArj0/%E8%BF%B7%E8%B7%AF%E7%9A%84%E7%81%AB%E8%BB%8A.png"></div>
</p>
<p>敢搶我礦產者,必阻之!<div class="image"><a href="http://picasaweb.google.com/hungwei.hsu/OpenTTD#5466368754992252034"><img src="http://lh3.ggpht.com/_W-ixktUlAf8/S9xxa6ybhII/AAAAAAAAB_s/wRaGLFVOR6s/s800/CCC.png"></a></div>
</p>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-39388508875241359712010-03-03T21:18:00.001+08:002010-07-17T11:58:00.328+08:00Android Developer Lab 參加心得<p>
好吧,我承認這一篇是炫耀文,其實沒啥心得可言!
</p>
<p>
忘記是去年底還是今年初在噗浪上看到葉教授發佈 Android Developer Lab 台北場開放報名時,因為天真的幻想能在 Android 平台上撰寫自己需要的軟體,於是莫名其妙的就填完單子完成報名手續。因為 Google 沒有立即回覆任何訊息,所以也差不多忘了這件事,直到過年前收到 Android Developer Lab 報到通知時才想起來要留一天年假去參加這個我戲稱為 Android 開發者聯誼會的活動。
</p>
<p>
聯誼會的日子很快的到來,因為入場時間是在 12:30 這個挺微妙的時間,所以早上硬是逼著自己不可太晚吃早餐以免中午吃不下結果在會場內昏倒的蠢事發生。還好,當葉教授說要出發前往會場時確認沒有供應午餐後,我也在 11:15 時分出門搭乘 638 前往六福皇宮會場。午餐是先在附近的小吃店以榨菜米粉湯(真的沒有肉絲)解決。
</p>
<div>
<p>
這是今天 Android Developer Lab 的入場券,並且憑券得兌換小禮物乙份!<br>
<a href="http://www.flickr.com/photos/adahsu/4403912728/" title="Google Android Developer Lab 入場券"><img src="http://farm5.static.flickr.com/4005/4403912728_1f1b8152aa.jpg" width="500" height="375" alt="入場券" /></a>
</p>
</div>
<p>
到了 12:37 時活動正式開始,然後就聽到令人振奮的一句話:『今天活動要以英語為主』... 雖說插大時英文考的比國文好,但好像我的國語遠比英語像樣很多,於是老灰呀注意力無法長時間集中的問題就發作了,時而恍神、時而回魂是今天活動中最主要的精神運作模式... <img src="http://lh6.ggpht.com/_W-ixktUlAf8/SsR5LryjGGI/AAAAAAAABpw/jL5c8kNZzWs/XD.gif">
</p>
<p>
總而言之,第一段是葉教授簡短介紹 Google Taiwan 及 <a href="http://www.taipei-gtug.org/">Taipei GTUG</a>,接下來換人介紹手機上網的趨勢;然後是 Android Marketplace 的上架辦法及一些注意事項。這部份雖然大致聽懂講者的內容大意,但全程英語還是有一定的催眠效果。就在恍神模式下時忽然看到這個 <a href="http://www.google.co.jp/">Google Japan</a> 所拍的 <a href="http://www.youtube.com/watch?v=f_ETSvTAo4A">Nexus One 忍者開箱動畫</a> 。正沉浸在影片中 KUSO 的宣傳手法時竟然聽到要送手機的字眼,你知道的,有東西吃或是有禮物拿時總是可以讓人眼睛為之一亮,於是所有人就全部擠出門去排隊領 <strike>長崎蛋糕</strike> Nexus One 禮盒。在等待的過程中不少人還抱持懷疑態度以為手機只是借用,會後需要歸還的。但一切都在有人按耐不住的詢問工作人員後獲得解答:『不用還,手機真的是送的』!Google 大神啊,您真是佛心來著呢!
</p>
<p>
因為在領取手機前有說到接下來的兩堂課會實作,如果電量不足的話腳邊有插座可用(後來覺得應該是聽錯了),於是大部份人都在現場玩起開箱遊戲。不過最後發現其實手機可以原封拎回家好好開箱的,現場實作用模擬器就可以了。這也是我覺得之前提到的插座應該是為了給筆電沒電的人使用的,並非說是對手機充電之用。
</p>
<p>
這就是憑入場券所兌換的長崎蛋糕禮盒(誤)<br>
<a href="http://www.flickr.com/photos/adahsu/4403012159/" title="長崎蛋糕 (誤)"><img src="http://farm5.static.flickr.com/4022/4403012159_665ee5fc4a.jpg" width="500" height="375" alt="和長崎蛋糕很像的 Nexus One 禮盒" /></a>
</p>
<p>
由於聽說第三節開始是實作說明,所以有個笨蛋就把筆電開機了。可是搞了半天原來是介紹 Android SDK 2.1 的許多新特性,於是白白浪費了 50% 的電量在這堂課中(6 cells 電池是撐不久的),等到真正 Coding 練習時我的筆電就在低電量警告訊息中沉沉睡去........ <img src="http://lh4.ggpht.com/_W-ixktUlAf8/SsRxruzx3DI/AAAAAAAABpM/dcZDhJJIt5M/uncommunicative.gif">
</p>
<p>
CodeLab 練習的題目是動態桌面的實作,講師提供了一個 <a href="tinyurl.com/adlwallpaper">基礎 Eclipse 專案設定作為練習</a> ,但因為投影片的字是真的有夠小所以最後我下載 FINAL 版進行比對,在程式碼確認的差不多時當然會想要執行看看,然後就在模擬器啟動途中看到低電量警告,原本以為來的及看到程式效果的幻想則在筆電自我感覺沒電不太好自動關機的情形下完全破滅...
</p>
<p>
還好這時候講師也實作完畢,時間進入 Q&A 時段... 看著鄰兵打包走人後,我也開始找地方塞剛領到的長崎蛋糕禮盒,然後出門去搭車回家。
</p>
<p>
搭車時有在想,動態桌面這個題目是不是有點雞肋呢?我以為大部份開發人員應該不會對這種不以實用為目的的特色有太多關注,那麼今天這個 CodeLab 範例選擇這個題材是否有啥特殊意義呢?和 Widgets 搶食桌面空間?其實到現在我還是沒有任何答案就是了...
</p>
<p>
對了,今天領到 Google 高科技小禮物雖然很 High ,但是 5800XM 上原本同步來的通訊錄整個不見也令人很駭... 回家第一件事是上 Google 看看通訊錄內容有沒有跟著消逝,還好,它們還在!
</p>
<p>全劇終... !</p>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-26657053797753930112010-02-07T23:44:00.003+08:002010-07-17T11:57:26.968+08:00ONE PIECE: STRONG WORLD<p>
上週到國際書展時才發現原來 <a href="http://www.onepiece-movie-tw.ch/">ONE PIECE 電影版 STRONG WORLD 強者天下</a> 已經上映後(剛好上映的隔天去書展的),就幻想著一定要趁過年前先看一看。今天是過年前最後一個假日,我也很努力的在京站威秀售票口前排了將近一小時的隊。不知道為什麼 <a href="http://www.google.com.tw/movies?hl=zh-TW&near=San-ch'ung&theater=京+站+威+秀&ei=QchuS_RIi-jsA-XYuWs&mid=18ba12659fd99a87">場次的安排</a> 似乎不是連續的,還好大家顯然都跑去看 <a href="http://mongathemovie.pixnet.net/blog">MONGA</a> 而沒來和我搶 ONE PIECE 的座次。雖然尚未滿座,但是這個可容納百餘人的小場地其實在輪到我購票時也沒剩幾個位置可以選了,此刻倒是有一種為什麼早上不先多花 20 元手續費直接網路購票的悔恨... (泣)
</p>
<p>
就劇情上來講可能要扯到 OnePiece 第 0 卷,另外在動畫版部份魯夫於到達海底監獄『推進城』時也有加入一段金獅子的故事(426話開始)。總而言之,這是一場世界政府的危機但最後世界政府啥都不能做的故事。至於為什麼世界政府啥都不能做的理由還請進電影院瞧瞧!
</p>
<p>
另外在各橋段中總是一直穿插著各式各樣的笑點,不過印象最深刻的應該是布魯克被食肉蟻小看時說的那句『我只是局部型肥胖』吧!這真是中廣型阿宅最需要的一句救世密令啊... XD
</p>
<p class="foot">
<ul>
<li>沒想到 WIKI 上已經有人整理了 <a href="http://zh.wikipedia.org/wiki/ONE_PIECE_FILM_STRONG_WORLD">電影相關資料</a> 了!</li>
<li>除了娜美的裸露演出外,羅賓的馬尾 + 眼鏡娘造型倒也是讓人印象深刻,雖然她最後沒啥表現機會!<br/><a href="http://www.flickr.com/photos/adahsu/4337750002/" title="羅賓的新造型"><img src="http://farm5.static.flickr.com/4008/4337750002_9ed6455112_o.jpg" alt="羅賓的新造型" /></a></li>
<li><a href="http://mongathemovie.pixnet.net/blog">MONGA</a> 發音要正確,不然會變成 <a href="http://en.wikipedia.org/wiki/Manga">MANGA</a>。</li>
<li>對了,這是 <a href="http://www.youtube.com/watch?v=BgyWwkWUSIU">MONGO</a> 預告片!</li>
<li>如果有人想請客的話,我還很願意再進電影院看一遍.... XD </li>
<li>啊對了!個人覺得本劇場版應該歸為輔導級,因為裡面抽煙的人太多了卻沒有打馬賽克... <br><img src="http://images.plurk.com/20988_cb4d04057790ed436088e2a9a24b4f55.jpg"></li>
</ul>
</p>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-72265935835431969042010-01-15T16:21:00.004+08:002010-01-16T01:37:59.989+08:00把 SFTP 關起來 (CHROOTED)<h3>前言</h3>
<p>為了提供少量的檔案共享但又不願意特地去設定 FTP 服務的話,通常第一個想到的會是附屬在 SSH 服務下的 SFTP 傳輸模式,事實上 SFTP 這個服務雖然因為加密的關係會導致傳輸時間略長,但卻一直是格揆我作為檔案傳輸的唯一方式。但這方式雖方便卻有個大問題:登入的使用者可以看到所有的檔案目錄甚至直接下載檔案內容。這在多人使用的環境下顯然會有資安上面的困擾,有沒有辦法把 SFTP 服務關在某個指定的目錄下呢?</p>
<p>格揆經由 Google 大神的協助並多方測試後終於實作出可行方案,就... 再貢獻回給大神吧... XD </p>
<h3>設定步驟</h3>
<p>※ 本文以 OpenSSH 5.2_p1-r3 為設定環境!</p>
<ol>
<li>選定封鎖目錄:如果對像是單一個人時即為該用戶登入 SFTP 時的根目錄;如果對像是一個群組時則該目錄為這群使用者目錄的根目錄。</li>
<li>在 /etc/ssh/sshd_config 中啟用 sftp subsystem:特別注意要啟用的是 internal-sftp 這個 Subsystem。
<div class="code"><pre># override default of no subsystems
#Subsystem sftp /usr/lib64/misc/sftp-server # 系統中原來的設定
Subsystem sftp internal-sftp # 改用 internal-sftp
</pre>
</div>
<li>一樣在 sshd_config 中指定需要被關起來的使用者資訊及要關到什麼地方去,請在前述修改處之後加上以下設定:
<div class="code"><pre>Match User ada # 要被關起來的使用者,如果是群組的話則將 User 改為 Group 再接群組名稱
# 例如: Match Group rootedSFTP
ChrootDirectory /chroot # 要關在什麼地方,如果對像是個群組且群組內的每個人有個別目錄設定時,
# 可以加上 PATTERNS (man ssh_config) 做區隔,如 /chroot/%u ,
# /chroot 為這群使用者目錄的根目錄。
ForceCommand internal-sftp # 一樣要使用 internal-sftp 這個 Subsystem
</pre></div></li>
<li>設定 Chroot 目錄權限:錯誤的目錄權限設定會導致在 log 中出現 "fatal: bad ownership or modes for chroot directory XXXXXX" 的訊息。根據 <a href="http://www.tenshu.net/archives/2008/10/09/openssh-51-chrootdirectory-permissions-issue/">openssh 5.1 chrootdirectory permissions issue</a> 這篇文章的資訊顯示,目錄的權限設定有兩個要點:
<ul>
<li>由 ChrootDirectory 指定的目錄開始一直往上到系統根目錄為止的目錄擁有者都只能是 root</li>
<li>由 ChrootDirectory 指定的目錄開始一直往上到系統根目錄為止都不可以具有群組寫入權限 </li>
</ul>
</li>
<li>重新載入 sshd 後即可透過 FileZilla 等支援 SFTP 的軟體測試有無被關起來了...</li>
</ol>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-58120275276684386852009-12-15T16:09:00.000+08:002009-12-15T16:09:02.111+08:00Gentoo Linux 與 Windows 7 安裝心得這幾天一直在安裝 Windows 7 和 Gentoo Linux 10.1 之間奮戰,浪費了不少時間踩了不少的地雷,恰好可作為部落格的文章以為紀念... XD
<h3>Dual Boot</h3>
<p>首先因為 Windows 7 在安裝時會在硬碟中產生兩個 Primary Partition ,這讓我在評估是否雙系統共存時有了很慎重的考慮,並為此選擇在 VirtualBox 3.1 中先行試驗確認。不過,經過多次測試總無法經 Grub 對 Windows 7 開機,在最後關頭時決定直接上機測試成功時,才驚覺整整浪費了 2 個工作天在無任何產值的測試作業中... (嘆)</p>
<p>
另外對於 Dual Boot 這件事,Gentoo 其實沒有先 Windows 再 Linux 之類的條款,因為它不會幫你建立預設的開機環境設定。Grub 裝在 MBR 也無所謂,反正 Windows 7 開機是從第一個 Partition 中的特定檔案啟動的。最後我還放棄了 SWAP 分割區的設置,將 4 個 Primary Partition 平均分給兩個作業系統,Gentoo 就一個 / partition 及一個 /home partition 。</p>
<h3>發行套件的選擇</h3>
<p>基本上這是因為安裝過程不太順利下,為什麼還選擇 Gentoo 的原因說明</p>
<p><a href="http://www.gentoo.org" target="gentoo">Gentoo</a> 之所以在某些群體中受到歡迎經常受到誤解,認為這些愛用者是因為迷信自行編譯所帶來的無上效能。其實在目前的中、高階 CPU 及便宜的記憶體市場下,自行編譯所帶來的效能改善情形非常有限,很多人應該也不是那麼心甘情願的願意浪費 1 ~ 2 天的時間進行系統編譯的工作(尤其 Windows 7 安裝一遍只要 20 分鐘),只因為目前還沒有看到更有彈性的軟體套件管理機制,導致短時間內無法轉投入另套發行套件。像格揆本人我就一直想要知道 <a href="http://www.archlinux.org" target="archlinux">Arch Linux</a> 究竟有沒有類似 <a href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=2&chap=1" target="portage">Portage</a> <a href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=2&chap=2" target="use">USE</a> 選擇的機制,只是說從所有的範例中似乎嗅不出類似機制的可能性,我也只好繼續使用 Gentoo 系統了!</p>
<h3>基楚系統建置</h3>
<p>在進行 Gentoo 基礎系統建置時切記不要過早投入 <a href="http://www.gentoo.org/proj/en/overlays/userguide.xml" target="overlay">Portage Overlay</a> 的設定,雜亂的套件相依設定是造成系統編不出來的主要原因,尤其在桌面管理系統上影鄉尤為深遠。</p>
<p>另外為了簡化系統的複雜度,一開始也不宜過早加入 ACCEPT_KEYWORDS 的設定,儘量先以系統預設的、穩定的套件版本為基礎完成配置後再加以強化為宜。Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com2tag:blogger.com,1999:blog-909727791061240227.post-26678090182121452952009-11-16T01:48:00.007+08:002009-11-16T10:11:53.588+08:00ExtJS 筆記 - EXTJS 的事件處理函式和 <a href="http://jquery.com/" tooltip="linkalert-tip">jQuery</a> 不同,<a href="http://extjs.com/" tooltip="linkalert-tip">ExtJS</a> 的事件處理函式略顯複雜了些!原因在於 <a href="http://jquery.com/" tooltip="linkalert-tip">jQuery</a> 的事件綁定機制永遠只作用於 <a href="http://jquery.com/">jQuery</a> 物件,但 <a href="http://extjs.com/" tooltip="linkalert-tip">ExtJS</a> 的事件綁定機制卻必須先確定事件綁定對象的種類。<br />
<br />
在 ExtJS 中有兩種類型的 Ext 物件可以進行事件綁定,一種是 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Component" tooltip="linkalert-tip">Ext.Component</a>,另一種是 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element" tooltip="linkalert-tip">Ext.Element</a>。雖然它們都會對應到頁面上的 HTML Element ,但實際上來看 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Component" tooltip="linkalert-tip">Ext.Component</a> 算是以 Ext.Element 為基礎進行擴充的衍生物件,常因為特別需要而自行提供許多自定的事件,例如 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.form.Checkbox" tooltip="linkalert-tip">Ext.form.Checkbox</a> 這個 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Component" tooltip="linkalert-tip">Ext.Component</a> 物件會額外提供 check 事件,當然你可以把這個 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.form.Checkbox#Ext.form.Checkbox-check" tooltip="linkalert-tip">check</a> 事件當成原本 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element#Ext.Element-click" tooltip="linkalert-tip">click</a> 事件的再包裝。<br />
<br />
所以說只要弄清楚事件綁定的對象後也就能夠確定所使用的事件處理函式的參數型態,對 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element" tooltip="linkalert-tip">Ext.Element</a> 而言它的事件處理函式參數格式為:<br />
<div class="code">
<pre>
/* 此的處 element 是一個 HTML Element ,也就是原本的 HTML DOM 物件 */
function eventHandler( event, element, object ) { }
</pre>
</div>
但若是 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Component" tooltip="linkalert-tip">Ext.Component</a> 的話它的事件處理函式則為:<br />
<div class="code">
<pre>
function eventHandler( component [, value/state ] ) { }
</pre>
</div>
其實寫 ExtJS 應用系統很容易遇到事件處理函式未能如預期反應的情況,這是因為搞錯了事件作用的對象以及事件處理函式的參數匹配不正確所導致,要不是因為此次的系統開發時用到了<a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.form.Checkbox"> Ext.form.Checkbox</a> 這個元素,也許格揆我還沒發現原來 ExtJS 的事件模型有分成兩種情形,而大致搜尋了一下也沒有啥文章特別提到這個明明就在 API 文件中,但工程師顯然不會特別注意到的情形。<br />
<br />
但我們該怎麼取得 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Component" tooltip="linkalert-tip">Ext.Component</a> 或 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element" tooltip="linkalert-tip">Ext.Element</a> 物件呢?只要記住除了 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext#Ext-getCmp">Ext.getCmp()</a> 外,其他的 DomQuery 函式都只會傳回 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element" tooltip="linkalert-tip">Ext.Element</a> 或 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.CompositeElement" tooltip="linkalert-tip">Ext.CompositeElement</a>(可把它當成多個 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element" tooltip="linkalert-tip">Ext.Element</a> 物件的集合) 物件。<br />
<br />
以下的範例可看出<a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Component" tooltip="linkalert-tip"> Ext.Component</a> 及 <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element" tooltip="linkalert-tip">Ext.Element</a>/<a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.CompositeElement" tooltip="linkalert-tip">Ext.CompositeElement</a> 在注冊事件處理函式時的差異:
<div class="code">
<pre><html>
<head>
<link rel="stylesheet" type="text/css" href="http://www.extjs.com/deploy/dev/resources/css/ext-all.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.extjs.com/deploy/dev/adapter/jquery/ext-jquery-adapter.js"></script>
<script type="text/javascript" src="http://www.extjs.com/deploy/dev/ext-all.js"></script>
<script text="text/javascript">
function init() {
var viewport = new Ext.Viewport({
layout: 'form'
,defaults: {
xtype: 'checkbox'
,labelWidth: 70
,labelAlign: 'right'
}
,items: [
{
fieldLabel: '選項一'
,id: 'chbox1'
}
,{
fieldLabel: '選項二'
,id: 'chbox2'
}
,{
fieldLabel: '按鈕一'
,id: 'btn1'
,xtype: 'button'
,text: '按鈕一'
}
]
});
// 對 Ext.Component:chbox1 物件注冊 check 事件處理函式
Ext.getCmp( 'chbox1' ).on( 'check', function ( chbox, checked ) {
alert( chbox.getId() + ' is ' + checked );
});
// 對所有的 Ext.CompositeElement:Checkbox 物件注冊 click 事件處理函式
// 實際上有兩個物件被注冊了事件處理函式
// 如果想在 Ext.Element 物件上綁定 check 事件的話,它是不會生效也不會有錯誤的喔!
Ext.select( 'input[type=checkbox]' ).on( 'click', function( evt, el ) {
Ext.Msg.alert( 'Event Tester', el.id + ' is ' + el.checked );
});
// 對 Ext.Component:btn1 物件注冊 click 事件處理函式
Ext.getCmp( 'btn1' ).on( 'click', function( button ) {
alert( button.getId() + ' clicked' );
});
// 對所有的 Ext.CompositeElement:button 物件注冊 click 事件處理函式
// 實際上有一個物件被注冊了事件處理函式
Ext.select( 'button' ).on( 'click', function( evt, el ) {
Ext.Msg.alert( 'Event Tester', el.id );
});
return viewport;
}
$( document ).ready( init );
</script>
</head>
<body>
</body>
</html></pre>
</div>
<br />
參考資訊:<br />
<ul>
<li><a href="http://www.cnblogs.com/beginor/archive/2008/03/07/1095887.html" target="_blank">ExtJS入门之二 事件</a></li>
</ul>Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com0tag:blogger.com,1999:blog-909727791061240227.post-30991578245648340502009-10-26T01:12:00.000+08:002009-10-26T01:12:31.178+08:00閃擊點行動 - 龍之堀起 ( Operation Flashpoint - Dragon Rising )閃擊點行動 - 龍之堀起 ( <a href="http://www.flashpointgame.com/index.php?page=homepage-uk" tooltip="linkalert-tip">Operation Flashpoint - Dragon Rising</a> ) 是 <a href="http://www.codemasters.com/index.php?territory=EnglishUSA" tooltip="linkalert-tip">CodeMasters </a>公司前陣子新堆出的遊戲,同時支援 PC / XBox 360 / PS3 三平台。<br />
<br />
總括而言,這是一套除了畫面遠勝 2001 年首次推出的 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">閃擊點行動 - 冷戰危機</a> 外其他部份都完敗的失敗作,甚至嚴格而言本遊戲也不算是 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 的續作,至少從遊戲命名中是完全看不到 <b>2</b> 這個字眼的。<br />
<br />
簡單條列個人覺得這套遊戲和 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 相比失敗的地方:<br />
<ol>
<li>從班戰鬥縮水成小隊戰鬥:沒錯,這是個精英小隊 ,但是一次 12 個人可以有更多的戰術配置。沒記錯的話在 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 中有一個關卡還是一整個排去打敵人的設定呢!這項改變大致上可以猜到是因為 PS3 / XBox 360 操控手把所做的限制。<br /></li>
<li>戰術指令缺乏細節設定:記得 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 中可以命令隊友去撿拾槍枝和補充彈藥,也可以把整個班透過撿拾殂擊槍的命令而變成殂擊班。本遊戲中似乎電腦隊員都沒有缺彈危機?把戰術指令大幅刪減的原因大概也是為了配合遊戲機的操控吧!對了,我曾對隊員下達接敵指定對象的命令,但是... 他們都不鳥我... (怒)<br /></li>
<li>可遠觀而不可褻玩焉的載具:在 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 及其資料片中有一大堆的載具(飛機、輪型車輛、民車、以及裝甲車等)可以操作,但到了 <a href="http://www.flashpointgame.com/index.php?page=homepage-uk" tooltip="linkalert-tip">龍之堀起</a> 時真的開過的只剩下悍馬車和最後關卡的直昇機而以。不過看電玩快打介紹的影片中有戰鬥直升機可以操作,但我的軍旅生涯回憶錄中只有被戰鬥直升機追殺的慘烈而以.... (嘆) </li>
<li>過關條件的限縮: <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 最為人所贊頌的是他無特定規則的過關選擇,在 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 中除了從外圍一路殺進敵營外,還可以先溜進敵營偷一台裝甲車或雌鹿攻擊機後再殺出來,這是 <a href="http://www.flashpointgame.com/index.php?page=homepage-uk" tooltip="linkalert-tip">龍之堀起</a> 總是走進去敵營又一路打出來的固定模式難以超越的。</li>
<li>隊員養成:在 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 是可以透過經驗值累積以提昇班兵的能力的,但是 <a href="http://www.flashpointgame.com/index.php?page=homepage-uk" tooltip="linkalert-tip">龍之堀起</a> 中每次帶的隊員都一定不同,隊員陣亡也只需等到檢查點後就會重新復活,當然也就少了經驗值作為隊員養成的依據了。</li>
<li>關卡的變化性不足:在 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 中有防禦、有攻擊、有步行機動、有車輛接送、也有裝甲車專屬關卡,還有直昇機攻擊,而 <a href="http://www.flashpointgame.com/index.php?page=homepage-uk" tooltip="linkalert-tip">龍之堀起</a> 則是突擊後防禦為主。其中雖然有一關是監控解放軍將領 - 韓將軍逛大街的特殊關卡,但最後用 JDAM 轟掉房子的設定其實覺得挺空虛的... (默)</li>
<li>關卡過短,故事性不足:記得 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 約有 20 關... 吧,<a href="http://www.flashpointgame.com/index.php?page=homepage-uk" tooltip="linkalert-tip">龍之堀起</a> 只有 10 關的樣子,搞的玩家還沒融入故事情節時遊戲就結束了.... -.- </li>
</ol>
認為 <a href="http://www.flashpointgame.com/index.php?page=homepage-uk" tooltip="linkalert-tip">龍之堀起</a> 不如原本 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 的原因大致如上,如果不是 CodeMasters 和原開發 <a href="http://zh.wikipedia.org/zh-tw/%E9%97%AA%E7%82%B9%E8%A1%8C%E5%8A%A8%EF%BC%9A%E5%86%B7%E6%88%98%E5%8D%B1%E6%9C%BA" tooltip="linkalert-tip">冷戰危機</a> 的波西米亞工作室鬧僵的話,也許真正的 Operation Flashpoint 2 早就推出了。<br />
<br />Ada Hsuhttps://plus.google.com/111339507987885509119noreply@blogger.com2