Quantcast
Channel: 小惡魔 – 電腦技術 – 工作筆記 – AppleBOY
Viewing all 325 articles
Browse latest View live

在 Chrome 瀏覽器使用 Terminal 終端機

$
0
0
Google Chrome

簡介

不知道大家有無在瀏覽器內直接連上 Terminal 終端機,今天來介紹 DevTools Terminal,這是一套 Chrome extension,它可以讓您在 Chrome 瀏覽器直接使用 Terminal,平常開發程式,一定會常常切換瀏覽器及 Terminal 軟體,現在開發者可以直接在瀏覽器連上 Terminal,並且開始使用 Git, Grunt, wget 甚至 Vim 等指令。

Screenshot from 2014-01-05 20:36:26

為什麼要在瀏覽器內使用 Terminal

在開發網站過程,你一定會用到底下工具:

  • 編輯器 Sublime, Vim 用來撰寫程式
  • 瀏覽器 Chrome 用來 debug 看結果
  • Terminal 終端機用來 update package 等

現在 Terminal 甚至用到 Grunt 等開發工具,每天都在這三種介面切換,是不是很浪費時間,雖然 Chrome 推出了 Workspace 讓開發者可以直接在瀏覽器內寫程式,但是這還不夠阿。所以 DevTools Terminal 幫你完成了這個故事,開發者可以直接用 Chrome 瀏覽器完成上述三件事情。

安裝方式

底下測試環境為 Ubuntu 系統,首先安裝 Chrome extension,完成後,請按下 Ctrl + Shift + I,會開啟 DevTools,會看到多一個 Terminal tab。如果系統並非為 Mac OS,那就必須透過 Node.js Proxy 才可以連上 Terminal。

$ npm install -g devtools-terminal

安裝完成後,開啟新的 Terminal console 並執行底下指令:

$ devtools-terminal

預設會開啟 8080 port,帳號為 admin,如果要改變預設值,請建立新檔案 terminal.js (檔案名稱可以自行更換),內容寫入

exports.config = {
    users: {
        admin: {
            password: "",
            cwd: process.cwd() //working directory
        }
    },
    port: 8080
};

透過指令:

$ devtools-terminal --config terminal.js

可以在 Terminal 介面執行 Grunt,畫面如下

Screenshot from 2014-01-05 21:22:15

總結

Chrome Developer Tools 實在是太強大了,我個人比較期待是否有整合 Compass,現在只有支援 Sass 3.0 版本以上,當然如果能在瀏覽寫程式是很方便,但是有時候開啟 DevTools 時候,記憶體都會被吃的很高,導致 Chrome 當機,所以其實還是要看狀況使用,但是能透過 chrome 來連接其他伺服器 Terminal,此功能對於常使用 console 的開發者是一大福音。


Sysbench 測試 Percona XtraDB Server 效能

$
0
0
mysql_logo

今天拿 MySQL benchmark tool – Sysbench 來測試看看 Percona XtraDB Server + Haproxy 效能如何,實驗主機是執行在 CentOS 6.4 版本,記憶體 128 G,在 CentOS 本身用 Yum 安裝 Sysbench 時,內建的版本為 0.4.12,單機測試 MySQL 效能不會出現任何錯誤,但是只要是透過 Haproxy,並且有兩台以上的 Server,就會噴出底下錯誤訊息:

ALERT: failed to execute mysql_stmt_execute(): Err1317 Query execution was interrupted

碰到這問題,在網路上找到一篇 sysbench duplicate entries,裡面提到請使用 Sysbench 0.5.0 版本就不會噴出此錯誤,直接看 sysbench 0.5 for CentOS 6 這篇,裡面有 CentOS 64 打包好的 rpm package,下載後透過 rpm 指令安裝即可

$ rpm -ivh sysbench-0.5-3.el6_.x86_64.rpm

安裝完成,實際底下測試看看

建立測試用資料庫

請先建立 sbtest 資料庫

mysql> create database sbtest;

產生測試用資料

$ sysbench --test=oltp --db-driver=mysql --mysql-engine-trx=yes --mysql-table-engine=innodb --mysql-host=127.0.0.1 --mysql-port=3307 --mysql-user=xxxx --mysql-password=xxxxx --oltp-auto-inc=off --test=/usr/share/doc/sysbench/tests/db/oltp.lua --oltp-table-size=1000000 prepare

請注意 mysql-port 請務必填寫 Haproxy port,--oltp-table-size 用來產生多少筆資料,先產生 100 萬筆資料,大小大概是 270 MB

開始測試

$ sysbench --test=oltp --db-driver=mysql --mysql-engine-trx=yes --mysql-table-engine=innodb --mysql-host=127.0.0.1 --mysql-port=3307 --mysql-user=xxxx --mysql-password=xxxxx --oltp-auto-inc=off --test=/usr/share/doc/sysbench/tests/db/oltp.lua --oltp-table-size=100000 --num-threads=100 run

差別在於最後執行的步驟 run,上一個步驟則是 prepare

看結果

會跑出底下的數據給您參考

OLTP test statistics:
    queries performed:
        read:                            172102
        write:                           48943
        other:                           22293
        total:                           243338
    transactions:                        10000  (46.37 per sec.)
    deadlocks:                           2293   (10.63 per sec.)
    read/write requests:                 221045 (1025.00 per sec.)
    other operations:                    22293  (103.37 per sec.)

General statistics:
    total time:                          215.6540s
    total number of events:              10000
    total time taken by event execution: 21427.5778s
    response time:
         min:                                 53.45ms
         avg:                               2142.76ms
         max:                              22097.26ms
         approx.  95 percentile:            5689.02ms

Threads fairness:
    events (avg/stddev):           100.0000/43.42
    execution time (avg/stddev):   214.2758/0.75

清除測試資料

$ sysbench --test=oltp --db-driver=mysql --mysql-engine-trx=yes --mysql-table-engine=innodb --mysql-host=127.0.0.1 --mysql-port=3307 --mysql-user=xxx --mysql-password=xxx --oltp-auto-inc=off --test=/usr/share/doc/sysbench/tests/db/oltp.lua --oltp-table-size=1000000 cleanup

請直接下 cleanup 即可

參考資料: MySQL benchmark tool – sysbench

Percona XtraDB Server 出現 read only issue

$
0
0
mysql_logo

最近在整理 Percona XtraDB Server 將 Read Write 全部拆開,寫入部份只開一台 Node,讀取機器 Replica 則是越多越好,當然如果預計 write 都不會有任何 conflict 的話,那就不用拆開,read write 都可以在同一台即可,拆開的目的要解決 Innodb transaction locking 問題。今天遇到的是將機器讀寫都放在同一台,然後同時多台 Master 架構,結果跑在 CodeIgniter 上面出現底下錯誤訊息

The MySQL server is running with the –read-only option so it cannot execute this statement

出現這問題的時候,第一時間去看一下 Percona cluster mysql 版本,發現不是踩到 read-only blocks SELECT statements in PXC 雷,這雷在 Percona XtraDB Cluster 5.5.33-23.7.6 被解掉了

Server version: 5.5.34-55-log Percona XtraDB Cluster (GPL), wsrep_25.9.r3928

後來查到原因是 MySQL User 權限不足,請將 SUPER Privilege 權限開啟。這樣 MySQL 使用者就可以忽略 read_only = on 參數,執行 SQL Command。

GRANT SUPER ON *.* TO 'ustv'@'%'

Percona XtraDB Cluster 搭配 HAProxy

$
0
0
percona

本篇文章紀錄安裝 Percona XtraDB Cluster (簡稱 PXC) 及搭配 HAProxy 做分散流量系統,其實在業界已經很常看到 HAProxy + MySQL Cluster Database 解決方案,HAProxy 幫您解決負載平衡,並且偵測系統是否存活,管理者也就不用擔心 MySQL 服務是否會掛掉。本篇會著重於 HAProxy 設定部份,並且紀錄每一步安裝步驟。之前本作者寫過一篇 Galera Cluster for MySQL Multi-master Replication,也可以參考。今天測試系統都會以 CentOS 為主,各位讀者可以直接開 Amazone EC2 來測試,測試完成再關閉即可。

安裝 Percona XtraDB Cluster

我們會使用官方 PerconaEPEL repositories 進行軟體安裝,底下是 Yum 安裝步驟

$ yum -y install Percona-XtraDB-Cluster-server Percona-XtraDB-Cluster-client Percona-Server-shared-compat percona-xtrabackup

如果系統已經有安裝過 MariaDB + Galera,請務必先移除套件

完成安裝 PXC 套件後,接著設定 my.cnf 設定檔

[mysqld]
server_id=1
wsrep_provider=/usr/lib64/libgalera_smm.so
wsrep_cluster_address="gcomm://"
wsrep_sst_auth=username:password
wsrep_provider_options="gcache.size=4G"
wsrep_cluster_name=Percona
wsrep_sst_method=xtrabackup
wsrep_node_name=db_01
wsrep_slave_threads=4
log_slave_updates
innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2

再開啟第 2 台或第 3 台 PXC 服務的時候,務必確認第 1 台已經正確開啟成功。上面設定檔是針對第 1 台做設定,之後新增 Node,請務必修改 wsrep_cluster_address 填上你想要 Join 的 Cluster Server IP Address,另外每台的 server_idwsrep_node_name 也會不同,請務必注意

第 2 台設定值

server_id=2
wsrep_cluster_address=gcomm://192.168.1.100 # replace this with the IP of your first node
wsrep_node_name=db_02

第 3 台設定值

server_id=3
wsrep_cluster_address=gcomm://192.168.1.100 # replace this with the IP of your first node
wsrep_node_name=db_03

根據 State Snapshot Transfer (簡稱 SST),我們使用 Xtrabackup,當新的 Node 連上時,就會開始複製資料到新的 Node 上,成功複製完成,可以看到底下 Log 訊息

140117 11:56:05 [Note] WSREP: Flow-control interval: [28, 28]
140117 11:56:05 [Note] WSREP: Shifting OPEN -> PRIMARY (TO: 678691)
140117 11:56:05 [Note] WSREP: State transfer required:
        Group state: 28e87291-da41-11e2-0800-34a03cad54a7:678691
        Local state: 28e87291-da41-11e2-0800-34a03cad54a7:678684
140117 11:56:05 [Note] WSREP: New cluster view: global state: 28e87291-da41-11e2-0800-34a03cad54a7:678691, view# 33: Primary, number of nodes: 3, my index: 1, protocol version 2
140117 11:56:05 [Warning] WSREP: Gap in state sequence. Need state transfer.
140117 11:56:07 [Note] WSREP: Running: 'wsrep_sst_xtrabackup --role 'joiner' --address '122.146.119.102' --auth 'username:password' --datadir '/var/lib/mysql/' --defaults-file '/etc/my.cnf' --parent '965''
WSREP_SST: [INFO] Streaming with tar (20140117 11:56:07.517)
WSREP_SST: [INFO] Using socat as streamer (20140117 11:56:07.519)
WSREP_SST: [INFO] Evaluating socat -u TCP-LISTEN:4444,reuseaddr stdio | tar xfi - --recursive-unlink -h; RC=( ${PIPESTATUS[@]} ) (20140117 11:56:07.531)
140117 11:56:07 [Note] WSREP: Prepared SST request: xtrabackup|122.146.119.102:4444/xtrabackup_sst
140117 11:56:07 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
140117 11:56:07 [Note] WSREP: Assign initial position for certification: 678691, protocol version: 2
140117 11:56:07 [Note] WSREP: Prepared IST receiver, listening at: tcp://122.146.119.102:4568
140117 11:56:07 [Note] WSREP: Node 1 (db_01) requested state transfer from '*any*'. Selected 0 (db_02)(SYNCED) as donor.
140117 11:56:07 [Note] WSREP: Shifting PRIMARY -> JOINER (TO: 678692)
140117 11:57:36 [Note] WSREP: Synchronized with group, ready for connections
140117 11:57:36 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
140117 11:57:36 [Note] WSREP: 1 (db_02): State transfer from 0 (db_01) complete.
140117 11:57:36 [Note] WSREP: Member 1 (db_02) synced with group.

最後我們可以透過 MySQL Status 來看看是否有建立成功

mysql> show global status like 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+
1 row in set (0.00 sec)

看到 wsrep_cluster_size 出現正確的 Server 數量,就代表設定成功。

設定 HAProxy 負載平衡

上述完成了 3 台 Cluster 設定,接著所有的 Application 服務都需要直接跟此 Cluster 溝通,為了完成此需求,我們必須將 HAProxy 安裝在其中一台伺服器來做負載平衡,今天會介紹兩種設定方式,第一種是採用 round robin 方式,意思就是說所有的 Application 都可以連上並且寫入資料到三台機器,這狀況其實沒有錯誤,但是如果同時寫入三台機器,難免會出現 optimistic locking 而產生 rollback,如果可以確定不會產生 conflict,其實這方案是不錯的。第2種設定方式就是只寫入單一 Node,但是可以讀取三台機器,也就是 insert, update 都是在同一台 Node 完成,所以 Application 不用擔心會產生 rollback 情形。第1種設定在大部份的狀況底下都是可以運作很好的,所以其實也不用擔心。

底下是 /etc/haproxy/haproxy.cfg 設定

frontend stats-front
bind *:8080
mode http
default_backend stats-back

frontend pxc-front
bind *:3307
mode tcp
default_backend pxc-back

frontend pxc-onenode-front
bind *:3308
mode tcp
default_backend pxc-onenode-back

backend stats-back
mode http
balance roundrobin
stats uri /haproxy/stats
stats auth username:password

backend pxc-back
mode tcp
balance leastconn
option httpchk
server c1 192.168.1.100:3306 check port 9200 inter 12000 rise 3 fall 3
server c2 192.168.1.101:3306 check port 9200 inter 12000 rise 3 fall 3
server c3 192.168.1.102:3306 check port 9200 inter 12000 rise 3 fall 3

backend pxc-onenode-back
mode tcp
balance leastconn
option httpchk
server c1 192.168.1.100:3306 check port 9200 inter 12000 rise 3 fall 3
server c2 192.168.1.101:3306 check port 9200 inter 12000 rise 3 fall 3 backup
server c3 192.168.1.102:3306 check port 9200 inter 12000 rise 3 fall 3 backup

從上述設定,可以看到我們定義了 3 個 frontend-backend,其中 stats-front 是 HAProxy Status Page,另外兩組則是針對 PXC 設定。看到此設定,可以知道系統會 Listen 3307 及 3308 兩個 port,其中 3308 會讓 App 使用一台 PXC Node 而已,此設定可以避免因為 optimistic locking 而產生 rollbacks,如果 Node 掛點,則會啟動其他 Node。然而如果是連接 3307 port,系統會直接對3台 node 寫入或讀取,我們使用 leastconn 取代 round robin,這代表著 HAProxy 會偵測所有機器,並且取得現在連線數目最少的 Node 來給下一個連線。最後 stats-front 是顯示 HAProxy 偵測及連線狀態,請務必設定帳號密碼。

完成設定,如何偵測 MySQL Server 是否存活,靠著就是 9200 port,透過 Http check 方式,讓 HAProxy 知道 PXC 狀態,安裝完 PXC 後,可以發現多了 clustercheck 指令,我們必須先給 clustercheckuser 使用者帳號密碼

# Grant privileges required:
$ GRANT PROCESS ON *.* TO 'clustercheckuser'@'localhost' IDENTIFIED BY 'clustercheckpassword!';

clustercheck 指令會在 Local 執行 SHOW STATUS LIKE 'wsrep_local_state' MySQL 指令,回傳值為 200503,指令確定成功執行,最後步驟就是透過 xinetd 產生 9200 port 的服務。底下先安裝 xinetd 服務

$ yum -y install xinetd

產生 mysqlchk 設定

# default: on
# description: mysqlchk
service mysqlchk
{
# this is a config for xinetd, place it in /etc/xinetd.d/
    disable = no
    flags = REUSE
    socket_type = stream
    port = 9200
    wait = no
    user = nobody
    server = /usr/bin/clustercheck
    log_on_failure += USERID
    only_from = 0.0.0.0/0
    # recommended to put the IPs that need
    # to connect exclusively (security purposes)
    per_source = UNLIMITED
}

上面步驟全部成功,請打開 URL 輸入 HAProxy Status 頁面,看到底下狀態,就是代表設定成功

Statistics Report for HAProxy

啟動 Percona XtraDB Cluster 注意事項

$
0
0
percona

Percona XtraDB Cluster 推出 5.5.28 以前,最簡單的啟動方式就是打開 my.cnf 設定 wsrep_urls[mysqld_safe] section 內。假設我們有三台 Node 分別為底下 IP:

  • node1 = 192.168.1.100
  • node2 = 192.168.1.101
  • node3 = 192.168.1.102

以前的設定方式為

wsrep_urls=gcomm://192.168.1.100:4567,gcomm://192.168.1.101:4567,gcomm://192.168.1.102:4567

當啟動 MySQL 時,Percona 會先去偵測 Cluster 內的 192.168.1.100 是否存在,如果不存在就在往下找,最後偵測 192.168.1.102 也不存在時,這時候 MySQL 就是啟動失敗,為了避免這情形,也就是全部的 Node Crash 狀況下,還是可以將 Cluster 啟動,可以改成底下設定

wsrep_urls=gcomm://192.168.1.100:4567,gcomm://192.168.1.101:4567,gcomm://192.168.1.102:4567,gcomm://

這在網路上很常看到此設定,如果全部的 Node 都不存在,表示此 Cluster 也就不存在,這時候我們就重新啟動 Cluster。但是 wsrep_urls5.5.28 版本已經被列為 deprecated,所以請改用 wsrep_cluster_address 參數

wsrep_cluster_address=gcomm://192.168.1.100,192.168.1.101,192.168.1.102

大家看到此設定可以知道,不用在重複宣告 4567 port 以及 gcomm://,但是這時候也會遇到如果全部的 Node 都關閉了,這樣 Cluster 也就消失了,有兩種方式可以啟動 Cluster。

  • 使用任何一個 Node 將 wsrep_cluster_address 改成 gcomm://,但是這樣很麻煩,等其他 Node 啟動後,還是要在改回來
  • 使用底下的 command 來啟動
$ /etc/init.d/myslqd start --wsrep-cluster-address="gcomm://"

此方式不用修改 my.cnf 設定,其他 Node 啟動成功後,再將此 Node 重新啟動即可。

Reference: How to start a Percona XtraDB Cluster

MySQL 5.6 UUID 複製資料到 Slave Server

$
0
0
mysql_logo

MySQL Performance Blog 看到這篇 Beware of MySQL 5.6 server UUID when cloning slaves,裡面提到如果是要複製資料到 Slave 機器,大部分的使用者肯定是將 /var/lib/mysql 目錄整個 copy 到 Slave 機器上。如果是 MySQL 5.6 Server 目錄內會有 auto.cnf 設定檔,這是 MySQL 5.6 新的功能叫做 server_uuid,在啟動 MySQL 後,就會自動建立 auto.cnf 檔案,此檔案就像是 my.cnfmy.ini 設定檔一樣,只是內容只有支援 [auto] 並且只有支援 server_uuid 這 key 值,例如

[auto]
server_uuid=8a94f357-aab4-11df-86ab-c80aa9429562

注意的是此檔案是系統自動建立,請勿自行修改內容。如果將 /var/lib/mysql 複製到其他機器,就會出現 server uuid 衝突,所以請務必小心,複製到新的伺服器後,請把 auto.cnf 移除,讓系統重新建立新的 uuid,如果是用 Percona XtraBackup 就不會出現此問題。

前端工程師必看 JavaScript The Right Way

$
0
0

PHP The Right Way 出電子書

$
0
0
PHP  The… by Phil Sturgeon et al. [Leanpub PDF iPad Kindle

最近看到前 CodeIgniterFuelPHP 作者 Phil SturgeonPHP The Right Way 發起人 Josh Lockhart 合力推出電子書,目前一本定價為 4 塊美金,當然作者也不一定要使用者付錢,您可以直接線上看。這本線上 PDF 很適合丟給剛進來公司的新人,此新人當然對 PHP 有一定程度的了解,團隊內最重視的就是整個專案素質,也就是如果能達到多人維護同一個專案,讓其他人檢視的時候,不會覺得是好多人共同維護一個專案,也就是要求大家寫法一致 (Code Style Guide)。


在 Ubuntu 或 Debian 上跑 Ruby on Rails + Nginx

$
0
0
Ruby_logo

本篇用來紀錄學習 Ruby on Rails 所需要的開發環境,請不要輕易嘗試使用 Windows 當開發環境,因為真的很不好裝,又很難除錯,所以作者建議開發環境一定要有 Linux 機器,如果是個人電腦用 Mac 也沒這問題。用 Rails 可以快速開發 Web 搭配 MySQL 資料庫,完成後可以透過 Capistrano 工具幫助 Deploy 到 Production Server。底下會一一介紹如何在 Debian 機器上架設好 Ruby + Nginx 環境

安裝 RVM

相信大家如果開發過 Node.js 一定聽過 nvm 這套 Node.js 版本管理工具,那 Ruby 呢,就是透過 RVM 來管理 Ruby 版本,安裝方式如下:

$ aptitude install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion pkg-config
$ \curl -sSL https://get.rvm.io | bash -s stable
# install 2.0.0 version and set default version
$ rvm install 2.0.0 --default

安裝好之後可以使用 rvm ls 來看看本地端裝了哪些版本

rvm rubies

=* ruby-2.0.0-p353 [ x86_64 ]
   ruby-2.1.0 [ x86_64 ]

# => - current
# =* - current && default
#  * - default

如果不需要 gem 安裝 rdoc 和 ri 可以透過底下設定

$ echo "gem: --no-ri --no-rdoc" > ~/.gemrc

最後安裝 railsbundler

$ gem i bundler rails

建立 Rails 專案

透過 rails 指令就可以快速初始化專案

$ cd /var/www
$ rails new web_01
$ cd web_01

如果搭配 MySQL 服務請務必安裝底下套件

$ aptitude install -y libmysqlclient-dev
$ gem install mysql2

這時候就可以修改 config/database.yml 資料庫連線資訊,並且在 ./Gemfile 內容加入 gem 'mysql2'

安裝 Thin

Ruby 有好幾套伺服器在業界都非常多人用,像是 Passenger, Mongrel, Thin, Unicorn 等,這次會介紹 Thin 安裝方式

$ gem install thin
$ thin install
$ /usr/sbin/update-rc.d -f thin defaults

完成上述設定後,系統會產生 /etc/init.d/thin 其實跟一般伺服器很像,設定檔都是放在 /etc/thin 目錄下,下面 command 用來產生各網站設定檔,假設有網站根目錄在 /var/www/web_01

$ thin config -C /etc/thin/web_01 -c /var/www/web_01 --servers 3 -e development # or: -e production for caching, etc

打開 /etc/thin/web_01

chdir: /var/www/web_01
environment: development
address: 0.0.0.0
port: 3000
timeout: 30
log: /root/log/thin.log
pid: tmp/pids/thin.pid
max_conns: 1024
max_persistent_conns: 100
require: []
wait: 30
threadpool_size: 20
servers: 3
daemonize: true

啟動 thin 伺服器

$ /etc/init.d/thin start

你可以看到跑了 3 個 port 分別是 3000, 3001, 3002

安裝 Nginx

這是最後一步驟,只完成這項就大功告成,首先建立 nginx vhost 檔案 /etc/nginx/sites-available/ 並且 link 到 /etc/nginx/sites-enable/,內容為

upstream web.localhost {
  server 127.0.0.1:3000;
  server 127.0.0.1:3001;
  server 127.0.0.1:3002;
}
server {
  listen   80;
  server_name web.localhost;

  access_log /var/www/web_01/log/access.log;
  error_log  /var/www/web_01/log/error.log;
  root     /var/www/web_01;
  index    index.html;

  location / {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  Host $http_host;
    proxy_redirect  off;
    try_files /system/maintenance.html $uri $uri/index.html $uri.html @ruby;
  }

  location @ruby {
    proxy_pass http://web.localhost;
  }
}

存檔後透過 link 啟動此設定

$ ln -nfs /etc/nginx/sites-available/web_01 /etc/nginx/sites-enabled/web_01

最後重新啟動全部伺服器

$ /etc/init.d/thin restart
$ /etc/init.d/nginx reload
$ /etc/init.d/nginx restart

打開瀏覽器鍵入 http://web.localhost 就可以成功看到網站了

Git Server 噴 git upload-pack: git-pack-objects died with error

$
0
0
Git-Logo-2Color

透過 Gitlab 架設 Git Server 來放一些 Document 資料,由於個人 Document 都是 pdf 檔案,所以整個 Git Repository 就非常肥大,今天在 Clone 下來的時候,不僅是主機 CPU 飆高,然後記憶體被吃到快沒了,最後還噴出底下錯誤訊息

remote: Counting objects: 4912, done.
remote: fatal: Out of memory, malloc failed
error: git upload-pack: git-pack-objects died with error.
fatal: git upload-pack: aborting due to possible repository corruption on the remote side.
remote: aborting due to possible repository corruption on the remote side.
fatal: early EOF
fatal: index-pack failed

網路上查到這篇 Git clone error + remote: fatal: Out of memory, malloc failed + error: git upload-pack: git-pack-objects died with error. 解法,裡面提到在每次 clone 專案時,Git 都會將資料壓縮並且存放到記憶體,所以如果 Repository 超過 100MB,你就會發現記憶體漸漸減少,然後整個炸掉,解法就是設定此 Repository 讓大家直接下載檔案,不要先丟到記憶體內,所以請打開 config 設定檔案,裡面寫入

[pack]
    window = 0

Percona XtraDB Cluster 5.6 找合適 IST Donor

$
0
0
percona

Gcache 是用來紀錄 MySQL 最近所使用的 SQL Command,其本身是佔用記憶體空間,大小可以由 wsrep_provider_options 定義,如果有任何 MySQL Node 重新啟動,那麼可以經由 Live Node 內的 Gcache 將尚未同步的資料補上,同步資料的方式分為兩種一種為 IST(Incremental State Transfer) 另一種為 SST(State Snapshot Transfer),但是同步資料時,管理者無法決定同步方式。先來看看 Gcache 一些特性

  • node 重新啟動,Gcache 資料會全部消失
  • Gcache 大小為固定,如果超過大小,則回刪除最早資料
  • 選擇 Donor node 會直接忽略 Gcache 狀態
  • Node 重新啟動,需要同步的資料並非在指定 Node Gcahe 內,則會啟動 SST 同步
  • 到目前版本為止,沒有任何方式可以知道 Gcache 狀態

根據以上特性可以知道,當 Node 重新啟動,很容易就執行 SST 模式,舉例子來說,當有 Node crashed 超過一個晚上,你要如何知道其他 Node 內的 Gcache 資料大於需要同步的資料量?或者是當 Cluster 內只有兩台機器,那重新啟動任何一台 Node 都會是跑 SST 同步。

PXC 5.6.15 RC1

去年 Percona XtraDB Cluster 推出 PXC 5.6.15 版本,此版本可以知道 Gcache 狀態,透過 wsrep_local_cached_downto 變數可以知道目前 Gcache 狀態,現在管理者就可以透過此參數來決定特定的 Node 進行 IST 同步,而不是 SST 同步。底下透過三台機器做實驗,並依照下面步驟。

  1. 停用 Node 2
  2. 停用 Node 3
  3. 啟用 Node 2

看到第3步驟,我們可以知道因為重新啟動的速度很快,所以 Node 2 肯定透過 IST 同步資料,最後從新啟動 Node 3 之前,我們可以透過 mysql 指令來看 wsrep_local_cached_downto 資料

[root@node1 ~]# mysql -e "show global status like 'wsrep_local_cached_downto';"
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| wsrep_local_cached_downto | 889703 |
+---------------------------+--------+
[root@node2 mysql]# mysql -e "show global status like 'wsrep_local_cached_downto';"
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| wsrep_local_cached_downto | 1050151 |
+---------------------------+---------+

可以看到 Node 2 的值大於 Node 1,這代表 Node 2 有些資料尚未跟 Node 1 同步上,此時看看 Node 3 資料,也可以透過 /var/lib/mysql/grastate.dat 檔案來知道

[root@node3 ~]# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid:    7206c8e4-7705-11e3-b175-922feecc92a0
seqno:   1039191
cert_index:

這時候會發現,node 3 資料比 node 2 資料還新,node 3 重新啟動後,如果是跟 node 2 同步的話,那就是會走 SST 機制,如果是跟 Node 1 則是走 IST 機制,當然走 IST 才是我們想要的結果,但是在 PXC 5.6.15 版本之前並非有參數可以讓系統管理者決定。所以這時候可以透過指定方式來跟 Node 1 同步

$ service mysql start --wsrep_sst_donor=node1

目前至少可以透過 wsrep_local_cached_downto 來知道 Gcache 狀態。本篇數據來自於 Finding a good IST donor in Percona XtraDB Cluster 5.6

Backbone.js 1.1.1 Release 釋出 AMD 版本

$
0
0
backbone

Backbone.js 在 2014.02.13 推出 1.1.1 版本,此次改版沒有推出重大功能,距離上次 1.1.0 版本只有經過四個月,時間也沒有很長。之前版本尚未支援 AMD,所以都是使用 amdjs/backbone 版本,但是這次 Backbone 官方直接釋出 AMD 版本,那之後就照官方版本走就可以了,底下是這次改版 Release note

  • 釋出 AMD (require.js) 版本
  • 新增 execute hook 讓開發者可以處理特定 route arguments
  • Backbone Event 效能改善
  • 處理相容舊瀏覽器 URL Unicode

近幾年 Javascript Framework 串起,似乎現在大家瘋狂的跟 Angularjs,所以 Backbone 似乎進度也沒有很快了,就像 PHP Framework 一樣,Laravel 的出現,讓其他 Framework 變得比較少討論了

Laravel 搭配 Memcached Cross Domain Session

$
0
0
Laravel PHP Framework

Laravel 提供了 filecookiedatabasememcachedarray 五種方式來存取 Session,預設的使用方式會是 file 存取,如果要跨 Domain 存取 Session 基本上只要設定 php.ini 裡面的 Session 相關參數即可,請注意底下 3 個參數。

完成後,只要是相同主網域內的 sub domain session 都可以互相存取,然而在 Laravel 內該如何設定,請先打開 app/config/session.php 檔案,Laravel 預設使用 Native File Session Driver,看看原本設定

'files' => storage_path().'/sessions',
'cookie' => 'laravel_session',
'domain' => null,

這三個參數都必須修改成底下

'files' => 'your session folder path',
'cookie' => 'PHPSESSID',
'domain' => '.domain.com',

PHP 預設 Session cookie name 是 PHPSESSID,另外 Laravel Session 存放位置請跟 php.ini 內設定位置一樣。到這邊設定倒是沒有什麼問題,如果改成使用 Memcached 來存放 Session,會發生無法存取同一個 Session。請先將 php.ini 改成底下設定

php_value[session.save_handler] = memcached
php_value[session.save_path] = "192.168.1.102:11211"
php_value[session.cookie_domain] = ".example.com"

另外 Laravel Session 設定請改成

'driver' => 'memcached',
'cookie' => 'PHPSESSID',
'domain' => '.example.com',

要設定 Memcached Server 請修改 app/config/cache.php

'memcached' => array(
    array('host' => '192.168.1.102', 'port' => 11211, 'weight' => 100),
),

但是這樣是不會通的,因為如果改成 Laravel Memcached Session Driver,那麼寫入跟讀出的 Session handle 將會被 Laravel Driver 取代,所以永遠拿不到一樣的 Session,此解法就是將 Session Driver 調回 Native Driver,並且修改 HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.php 檔案,此檔案放在 vendor/symfony/http-foundation/Symfony/Component/ 將底下兩行程式碼註解掉即可。

ini_set('session.save_path', $savePath);
ini_set('session.save_handler', 'files');

這不是很正規的解法,不過提供給有需要搭配 Memcached 的開發者一個方向。

Ruby 安裝 debugger package 發生 No source for ruby 錯誤

$
0
0
Ruby_logo

當您在特定 Ruby 版本下安裝 debugger gem 套件,會碰到底下錯誤訊息

Using debugger-ruby_core_source (1.2.4) 
Installing debugger-linecache (1.2.4) with native extensions 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native
extension.

checking for vm_core.h... no
checking for vm_core.h... no
Makefile creation failed
**************************************************************************
No source for ruby-2.0.0-p451 provided with debugger-ruby_core_source
gem.
**************************************************************************

會發生此錯誤的最大原因是在 debugger-ruby_core_source 原始碼內,只有包含特定少數的 Headers,解決此錯誤也非常簡單,可以直接將目前的 ruby 版本 headers 安裝到 debugger-ruby_core_source 目錄內即可,透國 rake 就可以完成

$ cd /usr/local/rvm/gems/ruby-2.0.0-p451/gems/debugger-ruby_core_source-1.2.4/lib/debugger/ruby_core_source
$ rake add_source VERSION=2.0.0-p451 --trace

執行完成後,就可以回到原專案目錄透過 bundle install 繼續安裝套件。

Percona Cloud Tools for MySQL 介紹及安裝

$
0
0
percona

Percona 去年推出一套 Cloud Tools for MySQL,藉由這套雲端服務可以幫忙分析 MySQL 系統內全部 Slow Query,並且計算出時間,畫出統計圖,此套系統目前還在 Beta 版,並且有些限制,只能開 3 個 organizations,每個 organizations 只能有 5 agents,最後資料只會保留 8 天,超過就會清除。這套系統後端是由 GO Language 完成,前端則是由 AngularJS 串起來,上個月 Percona 還在 MySQL Performance Blog 徵求 GO 的開發者,可見 Percona 也看好此服務,大膽使用 Google 推的 GO Language。

Percona Cloud Tools 由三個部份組成,分別是 Slow log filesPercona ToolkitPercona CloudSlow log files 就是系統要將 slow query 紀錄到檔案,經由 Percona Toolkit 將檔案分析好,最後透過 https 上傳到 Percona Cloud。所底下安裝就是這三個部份。

安裝方式

CentOS 安裝方式如下:

$ yum install percona-toolkit perl-JSON

請用 Google 帳號登入 https://cloud.percona.com/ 取得 API Key,畫面如下

Percona Cloud Tools 2014-03-06 15-42-34

接著用 pt-agent 指令安裝 Daemon

$ pt-agent --install --user={mysql username} --password={password} --api-key={API Key copied from web site}

也可以簡化成

$ pt-agent --install

執行後可以看到底下結果

$ pt-agent --install
Step 1 of 12: Verify the user is root: OK
Step 2 of 12: Check Perl module dependencies: OK
Step 3 of 12: Check for crontab: OK
Step 4 of 12: Verify pt-agent is not installed: OK
Step 5 of 12: Verify the API key:
Enter your API key: 631f9cc0c54a41248300cbc16a047ad6
Step 5 of 12: Verify the API key: OK
Step 6 of 12: Connect to MySQL: OK
Step 7 of 12: Check if MySQL is a slave: NO
Step 8 of 12: Create a MySQL user for the agent: OK
Step 9 of 12: Initialize /etc/percona/agent/my.cnf: OK
Step 10 of 12: Initialize /root/.pt-agent.conf: OK
Step 11 of 12: Create the agent: OK
Step 12 of 12: Run the agent: pt-agent has daemonized and is running as PID 22791:

  --lib /var/lib/pt-agent
  --log /var/log/pt-agent.log
  --pid /var/run/pt-agent.pid

These values can change if a different configuration is received.
OK
INSTALLATION COMPLETE
The agent has been installed and started, but it is not running any services yet.  Go to https://cloud.percona.com/agents#xxx to enable services for the agent.

最後到 cloud.percona 看執行結果,就算大功告成了,只要等個半小時就會有資料進來了

Percona Cloud Tools 2014-03-06 15-47-13

Percona Cloud 成功收到資料就會變成綠色標記

Percona Cloud Tools 2014-03-06 15-50-39

點選 Report 可以看到執行效率很慢的 Query 結果

Percona Cloud Tools 2014-03-06 15-52-04


Sublime Text 2 在 Ubuntu 中文輸入問題

$
0
0
Sublime_Text_Logo

Sublime Text 是一個非常好用的文字編輯器,如果不喜歡 Vim Console 介面,我強烈推薦這套,因為可以透過 Package Control 安裝實用的 Plugin。安裝好 Sublime Text 軟體後,發現切換輸入法跟 Sublime 預設的快捷鍵衝突,所以將 gcin 切換的快捷鍵也換掉,但是似乎沒有作用,網路上找到此篇解法 Sublime Text 2 如何在 Ubuntu+iBus 下输入中文?,解法就是安裝 InputHelper Plugin 當然這方法是治標不治本,但是至少解決無法輸入中文的問題,底下是安裝方式

安裝方式

首先要先安裝 Package Control,兩種方式安裝,可以用 ctrl + ~ 或是透過 View > Show Console 選單打開 Console,將底下程式碼貼入並且按下 Enter

import urllib2,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404' + 'e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); os.makedirs( ipp ) if not os.path.exists(ipp) else None; urllib2.install_opener( urllib2.build_opener( urllib2.ProxyHandler()) ); by = urllib2.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); open( os.path.join( ipp, pf), 'wb' ).write(by) if dh == h else None; print('Error validating download (got %s instead of %s), please try manual install' % (dh, h) if dh != h else 'Please restart Sublime Text to finish installation')

最後在 Preference 找到 Package Control 選擇 Install Package,輸入 InputHelper 這樣就安裝完成,使用方式很容易,Ctrl + Shift + z 可以叫出 Input 視窗就可以輸入中文了。

Ruby Compass and Sass Auto Testing Environment

$
0
0
Compass Home   Compass Documentation

Compass 是一套 CSS Authoring Framework,也是基於 Sass 語法的一套 Framework,先前寫了 GulpCompass Plugin,在針對自動化測試時候出現版本相依性不同,造成無法自動測試成功。自動化測試目前跟 Github 最常搭配的就是 Travis CI 或者是 Codeship,當然如果非 Open source 專案可能就要自己架設 CI 伺服器,個人推薦就是 Jenkins。這次遇到的問題其實跟 Ruby Gem 版本相依性有關,由於要測試 Compass 所有 Command 語法,所以使用了 Susy + sass + compass,如果在 .travis.yml 內直接寫

language: node_js
node_js:
    - "0.10"
before_install:
    - gem update --system
    - gem install sass
    - gem install compass
    - gem install susy
    - gem install modular-scale

這樣編譯出來的結果會噴底下錯誤訊息

/home/rof/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:55:in `require’: cannot load such file — sass/script/node (LoadError) from /home/rof/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:55:in `require’ from /home/rof/.rvm/gems/ruby-1.9.3-p327/gems/compass-0.12.2/lib/compass/sass_extensions/monkey_patches/browser_support.rb:1:in `‘ from /home/rof/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/site_ruby/1.9.1/rubygems/core_ext/kernel_require.rb:55:in `require’

會造成這樣的原因就是目前 sass、compass、susy 都不能安裝最新版本。Compass 目前版本是 0.12.3 只有支援 Sass 3.2.14 版本,但是 Sass 前幾天剛推出 3.3.1 版本,另外 Susy 也是一樣問題,由於 Susy 推出 2.0.0 版本需要 Sass 3.3.0 版本以上才可以使用,所以針對 Compass 變成只能指定版本測試,否則會得到上述錯誤訊息,請將 .travis.yml 修正為

language: node_js
node_js:
    - "0.10"
before_install:
    - gem update --system
    - gem install sass --version 3.2.14
    - gem install compass --version 0.12.3
    - gem install susy --version 1.0.9
    - gem install modular-scale

這樣就可以正常跑出測試結果。

在 Local 端處理 Github 專案 Pull Request

$
0
0
github-logo

這篇會筆記如何將 Github 上專案內的 Pull Request 拉到 Local 端電腦,雖然現在大部分的 Open Source 都會寫 Unit Test 並且搭配免費的 Travis CI 自動化測試,但是有時候也是需要把別人的 Pull Request 拉下來測試後再進行 Merge,而 Github 官方有提供一篇說明文件 Checking out pull requests locally,底下紀錄操作步驟。

clone 新專案,修改設定檔

gulp-compass 專案來測試

$ git clone https://github.com/appleboy/gulp-compass.git

接著打開 .git/config 可以看到底下設定檔

[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = https://github.com/appleboy/gulp-compass.git
[branch "master"]
        remote = origin
        merge = refs/heads/master

請增加一行 refspec 紀錄,修改狀態後為底下

[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = https://github.com/appleboy/gulp-compass.git
        fetch = +refs/pull/*/head:refs/pull/origin/*

抓取遠端 Pull request

接著請執行 git fetch origin,可以看到底下結果

$ git fetch origin
remote: Counting objects: 79, done.
remote: Compressing objects: 100% (46/46), done.
remote: Total 79 (delta 38), reused 59 (delta 28)
Unpacking objects: 100% (79/79), done.
From https://github.com/appleboy/gulp-compass
 * [new branch]      refs/pull/1/head -> refs/pull/origin/1
 * [new branch]      refs/pull/10/head -> refs/pull/origin/10
 * [new branch]      refs/pull/12/head -> refs/pull/origin/12
 * [new branch]      refs/pull/16/head -> refs/pull/origin/16
 * [new branch]      refs/pull/21/head -> refs/pull/origin/21
 * [new branch]      refs/pull/23/head -> refs/pull/origin/23
 * [new branch]      refs/pull/26/head -> refs/pull/origin/26
 * [new branch]      refs/pull/28/head -> refs/pull/origin/28
 * [new branch]      refs/pull/5/head -> refs/pull/origin/5
 * [new branch]      refs/pull/6/head -> refs/pull/origin/6
 * [new branch]      refs/pull/7/head -> refs/pull/origin/7
 * [new branch]      refs/pull/8/head -> refs/pull/origin/8
 * [new branch]      refs/pull/9/head -> refs/pull/origin/9

請注意 refs/pull/ 是唯讀狀態,你無法 commit 任何程式碼上去

讀取特定 pull request

上述步驟完成後,可以直接執行底下指令,來讀取特定的 Pull request

$ git checkout -b 28 pull/origin/28
Switched to a new branch '28'

最後我們來看看線圖

*  d0b3fc1 clear css folder before testing. (origin/master, origin/HEAD, master)
|  
*  22b6362 update readme.
|  
*  eaf0cdb add test import_path array option.
|  
*  9bc303c bump version. (1.1.6)
|  
*  7e94db6 fixed coding style.
|    
*    f9f0350 Merge branch '28'
|\  
| |   
| *  3fa510d Fix garbled output. (HEAD, refs/pull/origin/28, 28)
| |   
* |  c3d8c18 update jshin to 1.5.0 and remove default parameter ".jshintrc".
|/  
|    
*    0e87ccf Merge pull request #26 from theblacksmith/multiple-import-paths

我們可以看到現在專案內的 HEAD 已經指向 #28 的 Pull request,請注意 (HEAD, refs/pull/origin/28, 28),如果測試沒問題,就可以透過 git merge 回 master 分支

$ git checkout master
$ git merge pull/origin/28
$ git push origin master

Github 上面預設是使用 git merge,當然你自己也可以用 git rebase 方式讓分支不要這麼亂。完成後上傳回 Github,你會發現該 pull request 就會被關閉並且 merge 完成。

Using Capistrano to deploy current branch

$
0
0
CapistranoLogo

Capistrano 是一套用 Ruby 語言所寫的 Deploy Tool,可以用來管理多台伺服器自動化流程,在 Rails 專案內都會使用這套 Deploy Tool,也方便管理遠端機器。這次有個問題是,假設我們在 Staging 或 Production 設定檔分別定義了 :branch 變數如下

set :branch, "master"
set :env, "production"

這時候可以透過底下指令來 Deploy 到遠端伺服器

$ bundle exec cap production deploy

假設這次想要 deploy 不同 branch 到 Production Server,就必須修改 production.rb 設定檔,每次不同 branch 就要改一次,會比較麻煩,要解決此問題只需要將上述程式碼改成可以用 command line 方式管理

set :branch, fetch(:branch, "master")
set :env, fetch(:env, "production")

將指令換成

$ bundle exec cap -S branch="my-branch" production deploy

也就可以達成目的了。多人同時在開發專案時,一定會有很多 feature 或 issue branch,開發者會希望目前在哪個 Branch,程式碼 commit 後,就直接用 cap deploy,將現在的 Branch 程式碼 Deploy 到伺服器,方便其他人測試,要達成此功能,請修改 deploy.rb 加入底下程式碼

# Figure out the name of the current local branch
def current_git_branch
  branch = `git symbolic-ref HEAD 2> /dev/null`.strip.gsub(/^refs\/heads\//, '')
  branch
end

# Set the deploy branch to the current branch
set :branch, fetch(:branch, current_git_branch)

完成後,請將 config/deploy/*.rb 內的 set :branch 全部拿掉,這樣切到任何 Branch,就直接下 cap deploy 即可,,當然也可以透過 command line 方式指定 Branch 來 Deploy。最後附上 Capistrano 的目錄架構圖

├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
            └── tasks

參考文章:

html5-boilerplate 打算不支援 IE8 瀏覽器

$
0
0

html5 boilerplate 是一套免費前端 Html5 模板,裡面支援 Normalize.cssjQuery (透過 Google CDN 或本地端讀取) 及 Modernizr,目前支援 IE 8 以上瀏覽器,但是最近看到官方正在討論是否該拿掉 IE 8 支援,原因是 Microsoft 今年宣佈 2014 年 4 月 8 日以後將不再支援 Windows XP,討論中也提到目前 IE 8 的市占率,其實還不小,雖然大部分使用者可能來自亞洲

討論列也有人提到,是否可以跟 [Google 一樣直接捨棄 IE8 及 IE9],可以看到

As previously announced, Internet Explorer 11 launched on October 17, 2013, and as a result, we’ve discontinued support for Internet Explorer 9.

Google 的做法相當棒

At Google, we’re committed to developing web applications that go beyond the limits of traditional software. Our engineering teams make use of new capabilities available in modern, up-to-date browsers. That’s why we made the decision last year to support only modern browsers, which also provide improved security and performance.
Viewing all 325 articles
Browse latest View live