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

用 Go 語言寫的 Github Git 服務

$
0
0
null

最近看到大陸那邊用 Go 語言寫了一套類似 Github 服務叫做 Gogs(Go Git Service),目前個人裝起來速度方面相當快,跟 GitLabRuby 寫的 Git Service 速度有差,以功能完整性來說,GitLab 還是大勝 Gogs,安裝方式則是 Gogs 勝於 GitLab,如果最後要推薦用 Gogs 還是 GitLab,我個人還是會選 GitLab 因為畢竟還是要搭配 Jenkins 等 CI 服務才能發揮作用,這次來筆記如何在 Ubuntu 上安裝 Gogs。

安裝 Go 環境

如果用 Ubuntu / Debian 系列,請不要透過 apt 方式安裝,因為安裝完成的 Go 版本會非常舊,請使用 tarball 方式安裝,首先到官方網站下載最新檔案

$ wget https://go.googlecode.com/files/go1.2.1.linux-amd64.tar.gz
$ export PATH=$PATH:/usr/local/go/bin

也可以把 $PATH 寫到 .bashrc 檔案內,這樣下次開 Shell 就不用重新打一次,接著下 go version 看到底下結果表示安裝成功

$ go version
go version go1.2.1 linux/amd64

最後將 $GOROOT$GOPATH 設定上去

$ export GOROOT=/usr/local/go
$ export PATH=$PATH:$GOROOT/bin
$ export GOPATH=/home/git/gocode

安裝 Gogs service

安裝非常容易,只要透過底下兩個指令就安裝完成了

# Download and install dependencies
$ go get -u github.com/gogits/gogs

# Build main program
$ cd $GOPATH/src/github.com/gogits/gogs
$ go build

原始目錄會在 /home/git/gocode/src/github.com/gogits/gogs 接著可以看到 conf/app.ini 原始設定檔,官方建議不要修改此檔案,使用者可以自行建立 custom/conf/app.ini 來取代原始設定內容。最後執行 ./gogs web

$ ./gogs web
Server is running...
2014/04/07 15:19:07 [conf.go:309]  Log Mode: Console(Trace)
2014/04/07 15:19:07 [conf.go:310]  Cache Service Enabled
2014/04/07 15:19:07 [conf.go:311]  Session Service Enabled
2014/04/07 15:19:07 [install.go:53]  Run Mode: Development
2014/04/07 15:19:07 [command.go:73]  Gogs: Go Git Service 0.2.0.0403 Alpha
2014/04/07 15:19:07 [command.go:73]  Listen: :3001

打開 http://localhost:3001 就可以看到下面畫面,代表安裝成功

Install - Gogs  Go Git Service

StartSSL 關閉註冊 OpenSSL CVE-2014-0160 Heartbleed Security

$
0
0
heartbleed

這幾天 OpenSSL 發出很嚴重的 CVE-2014-0160 Bug 叫做「Heartbleed」,台灣資安公司 DEVCORE 也直接發布了一篇文章,請大家儘快升級系統,並且通知全部會員修改密碼,目前看到 Github 等大型網站都已經先將使用者 Session 資料清除,另外個人憑證部份也必須要更換,所以這幾天免費提供申請的 StartSSL 服務,被大量的使用者來申請,目前看到官方網站直接關閉註冊給個暫時的 warning 訊息 XD 如下圖

startssl

OSDC 2014 Talk: Introduction to Percona XtraDB Cluster and HAProxy

$
0
0

OpenSSL CVE-2014-0160 (Heartbleed) 漏洞攻擊手法

$
0
0
heartbleed

DEVCORE 資安公司寫了一篇 OpenSSL Heartbleed 全球駭客的殺戮祭典,你參與了嗎? 內如介紹如何透過工具攻擊及測試現有網站,也提供如何修正 OpenSSL 漏洞,Debian,Centos,FreeBSD 等。要檢查機器是否更新到正確版本,可以透過底下指令

$ openssl version -a

如果看到底下結果

OpenSSL 1.0.1e-fips 11 Feb 2013
built on: Tue Apr  8 02:39:29 UTC 2014
platform: linux-x86_64
options:  bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/etc/pki/tls"
engines:  dynamic

更新時間為 4/7 號以後代表已經修正。透過 Heartbleed test page 可以查詢測試網站是否修正 Heartbleed,最後請記得重新產生 certificate signing request (CSR)。

$ openssl req -new -nodes -days 365 -keyout www.mydomain.com.key -out www.mydomain.com.csr

底下是 DEVCORE 錄製的攻擊手法 Demo 影片

Linode VPS 全面升級 Double RAM & SSD

$
0
0
linode_logo_gray

Linode 又來了驚人的舉動,現在開始支援 SSD 以及小時計費服務,可以參考官網最新發表的 The New Linode Cloud: SSDs, Double RAM & much more,內容講到硬碟現在全面升級為 SSD,而且是 native SSD servers。網路頻寬部份每個 Linode Host 都連接 40 Gbps 的頻寬,對外總頻寬為 160 Gbps,對內頻寬為 40 Gbps,當然根據個人買得 VPS 而有不同的對外頻寬。記憶體則是全面 Double 升級,原本最低的 1G 記憶體,現在都改為 2G 了,每個月才 20 美金,看起來又是被 DigitalOcean 刺激到,最小的 Linode 流量也改為 3 TB。來看看現在新的方案

小時計費服務最低為 0.03/hour,一個月 20 美金,蠻便宜的,對外頻寬也有到 250 Mbps。現在除了倫敦以外,都可以使用新的 Plan 了

最後可以參考最近 Linode 升級了哪些硬體或服務

gulp-imagemin 在 Ubuntu 出現錯誤

$
0
0
gulp

在 deploy 程式碼到 production server 前,透過 gulp-imagemin 工具將全部圖片優化,上傳到 Amazon S3,Windows 底下正常運作,到了 Ubuntu 環境之下噴出底下錯誤訊息

Error: Lossy operations are not currently supported

後來在 grunt-contrib-imagemin@issues/180 有提人出此問題,解決方案就是升級 OptiPNG,因為 Ubuntu 的 apt 套件只有支援到 0.6.4 版本,請到 OptiPNG 官網下載最新 tar 檔,編譯重新安裝

$ wget http://downloads.sourceforge.net/project/optipng/OptiPNG/optipng-0.7.5/optipng-0.7.5.tar.gz
$ tar -zxvf optipng-0.7.5.tar.gz
$ cd optipng-0.7.5.tar
$ ./configure && make && make install

附上 gulp-imagemin 設定方式

gulp.task('images', function() {
  return gulp.src('app/images/**/*.{jpg,jpeg,png,gif}')
    .pipe(imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest('dist/images'))
    .pipe(size());
});

在 Ubuntu 底下查詢記憶時脈體資訊

$
0
0
logo-Ubuntu

最近想升級 Notebook 記憶體到 16G,要查看 Ubuntu 底下記憶體時脈資訊,可以透過 dmidecode 指令來取的記憶體硬體裝置資訊,此指令不只是這樣而已,還可以得知整台電腦硬體 components 資訊,底下擷取如何得到記憶體裝置資訊

$ dmidecode --type 17 | more

輸出結果為

# dmidecode 2.11
SMBIOS 2.4 present.

Handle 0x0036, DMI type 17, 27 bytes
Memory Device
        Array Handle: 0x0035
        Error Information Handle: Not Provided
        Total Width: 64 bits
        Data Width: 64 bits
        Size: 2048 MB
        Form Factor: SODIMM
        Set: None
        Locator: DIMM0
        Bank Locator: BANK 0
        Type: DDR3
        Type Detail: Synchronous
        Speed: 1067 MHz
        Manufacturer: 80CE
        Serial Number: 621AD76C
        Asset Tag: Unknown
        Part Number: M471B5673FH0-CF8

可以看到目前其中一個記憶體插槽時脈為 1067 MHz,型態為 DDR3。這樣就可以直接去升級記憶體了 …

修復 Ubuntu 開機 boot loader

$
0
0
logo-Ubuntu

昨天下午本來想幫自己的筆電 (Ubuntu OS) 升級記憶體,結果因為機型過於老舊,以現在的記憶體時脈 1600 裝上去後,直接讓 Ubuntu 當機,反覆重新開機,無法向下相容,加上現在記憶體狂漲價,找不到更低階的記憶體安裝了,無奈的是,店員幫忙測試筆電,換個記憶體,結果連 Ubuntu 的 boot loader 都可以壞掉。我看店員很緊張的說,不好意思,可以幫忙備份,幫忙我重灌。結果我還是自己拿回家處理比較安心。自己也不知道為什麼換個記憶體,可以讓 boot loader 消失。底下是修復 boot loader 過程

製作 Ubuntu Live USB

請先準備好 Ubuntu Live USB,製作方式很簡單,在 Windows 底下請先下載 unetbootin,以及 Ubuntu 任何一版 Desktop OS,可以參考高登寫的教學: 如何製作 Ubuntu Live USB

修復開機磁區

完成上述步驟後,請使用 USB 開機,選擇 Try Ubuntu Desktop,這時候會進到桌面,接著開啟系統內建的 Terminal,打入 fdisk -l 看看系統磁碟分割狀態

$ fdisk -l

Disk /dev/sda: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders, total 625142448 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0002c315

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      194559       96256   83  Linux
/dev/sda2          196606   625141759   312472577    5  Extended
/dev/sda5          196608    78319615    39061504   82  Linux swap / Solaris
/dev/sda6        78321664   117381119    19529728   83  Linux
/dev/sda7       117383168   625141759   253879296   83  Linux

上述結果可以發現只有一顆硬碟 /dev/sda 開機磁驅為 /dev/sda1 這是 /boot,而根目錄則是 /dev/sda6,接著將這些磁驅掛載到 /mnt/

$ sudo mount /dev/sda6 /mnt
$ sudo mount /dev/sda1 /boot
$ sudo mount /dev/sda7 /home

使用 grub-install 指令重新製作開機 boot loader

$ sudo grub-install --root-directory=/mnt/ /dev/sda

最後重新啟動系統,將 USB 移除即可,就可以看到登入畫面了


免費下載 Percona MySQL eBooks

$
0
0
percona

玩 MySQL 的一定知道 Percona,這次 Percona MySQL 推出免費電子書,電子書內容是從 MySQLPerformanceBlog 裡面精心挑選文章收錄,文章內容也幾乎都是 MySQL 專家寫出來的,電子書內容包含了MySQL server, Percona Server, Percona XtraDB Cluster, MySQL performance, and MySQL troubleshooting,所有的電子書都是免費下載。

更多主題可以直接參考 MySQL eBooks

Gulp.js 工具包

$
0
0
gulp

本篇來整理關於 Gulp.js 的一些 GUI 工具,對於不瞭解 Gulp.js 可以參考之前我寫的 The streaming build system Gulp,會紀錄這篇最主要是看到有人在 Github 發了這篇 Is there any GUI tool for Gulp? 而 Gulp.js 底層作者 @robrich 跳出來列出了很多工具,整理如下

如果開發環境為 Apple Mac 你可以直接裝 @sindresorhus 寫的 gulp-app,或者是 g0v 作者 clkao 開發的 gullet。看大家喜歡哪些工具,請自行安裝。我比較推薦 Gulp Dev Tools for Chrome,可以在瀏覽器上直接執行 Gulp 所有 Task,如果之前有玩過 Grunt.js 大家應該都知道也有 Grunt Devtools

有使用 CoffeeScript 寫 Gulp.js 請務必在 gulpfile.coffee 加上

module.exports = gulp

接著修改 gulpfile.js 如下

require('coffee-script/register');
var gulp = require('./gulpfile.coffee');
module.exports = gulp;

程式碼可以直接參考 html5-template-engine

認識現今 Google 搜尋引擎

$
0
0

感謝 @Ly Cheng 針對第三點補充

new-google-logo-knockoff

1995 年 JavaScript 第1版出現,到了 1998 年 Google 推出第一代搜尋引擎,當時的 Google 根本不用在乎網頁如何使用 CSS 或 JavaScript,而當時的網頁也顯少使用 JavaScript 及 CSS。轉眼間到現在 2014 年,如今現在的 Web,已經離不開 JavaScript 及 CSS 了,而目前 SPA (Single Page Application) 的流行,也造成 Google 搜尋引擎讀取資料的困擾,所以 Google 團隊目前也正在朝這方向努力邁進。

傳統的網頁,Google 根本不需要在乎 JavaScript 或 CSS,直接從 Http Response 拿到 Body 內的資料進行分析,然而 JavaScript 的盛行,已經改變了此作法,Google 再也不能從 Body 內準確的拿到資料,原因就是現今的網頁,都已經由 JavaScript 透過 AJAX 方式跟後端存取資料,這樣對於 Google 搜尋引擎是非常不好的結果。

Google 為了改善此問題,現階段也開始著手改善爬蟲,讓爬蟲可以正確執行 JavaScript,當然也要根據 Client 端是否有打開 JavaScript。由於現在大多數的網站已經漸漸變成 SPA 方式,看到如今盛行的 JavaScript Framework 像是 Backbone.jsAngularJS 等。Google Webmaster 也開始正視這問題。

為了能讓 Google 可以正確取得網頁資料,底下有些資訊可以提供給開發者,可以對 Google 爬蟲更友善

  • 請不要將 JavaScript 或 CSS 寫入 robots.txt,這樣只是讓 Google 無法正確拿到 JavaScript 檔案
  • 注意 Server 不要拒絕 crawl requests,也就是要有能力承受 crawl 讀取 XD
  • 讓網頁可以支援舊版瀏覽器或尚未實做 JavaScript 的搜尋引擎,一樣可以正確取得網頁內容
  • JavaScript 寫的太複雜,導致 Google crawl 無法正確執行
  • 使用 JavaScript 移除 content 遠大於新增 content,避免影響 Google 做 index

現在 Google Webmaster Tools 也著手進行後台開發,讓開發者可以正確看到 Google crawl 行為。

此篇文章參考 Understanding web pages betterIt took Google’s Web crawlers 15 years to come to terms with JavaScript

安全使用 JavaScript Global Variables

$
0
0

剛開始學習 JavaScript 時候,一定會大量使用 Global Variables。但是使用 Global Variables 的同時,請務必使用 var 宣告,而不是直接使用阿,否則會常常遇到 ReferenceError 的錯誤。

function addToBlockList (item) {
  block_List.push(item);
}

addToBlockList ("add 127.0.0.1");

執行後你可以發現 console 噴出 Uncaught ReferenceError: block_List is not defined,加上一個判斷試試看。程式碼改成底下

function addToBlockList (item) {
  if (block_list) {
    block_List.push(item);
  }
}

addToBlockList ("add 127.0.0.1");

會噴出一樣的錯誤訊息,原因也是 block_List is not defined,最後將程式碼換成底下

function addToBlockList (item) {
  if (window.block_list) {
    window.block_List.push(item);
  }
}

addToBlockList ("add 127.0.0.1");

就可以正常跑了,也不會出現任何錯誤訊息,建議大家不要寫這樣的程式碼,能夠少用 window.xxxx 這種全域變數就盡量少用,不要任意宣告或修改 window 全域變數,上面程式碼可以換成底下會更好

(function() {
  var block_list = [];
  var addToBlockList = function (item) {
    if (block_list) {
      block_list.push(item);
    }
  };
    
  addToBlockList("127.0.0.1");
  console.log(block_list);
  
})();

這樣可以避免渲染 window Global Variable。如果你是用 CoffeeScript 來寫,可以寫成底下

(->
  block_list = []
  addToBlockList = (item) ->
    block_list.push item  if block_list
    return

  return
)()

但是我建議可以使用 block_list? 寫法

(->
  block_list = []
  addToBlockList = (item) ->
    block_List?.push item
    return

  return
)()

轉成的 JavaScript 會是

(function() {
  var addToBlockList, block_list;
  block_list = [];
  addToBlockList = function(item) {
    if (typeof block_List !== "undefined" && block_List !== null) {
      block_List.push(item);
    }
  };
})();

用 Google PageSpeed Insights 計算 Desktop 或 Mobile 網站分數

$
0
0
new-google-logo-knockoff

相信工程師在調整網站效能一定會使用 Google PageSpeed Insights 來得到測試效能數據報表,但是這僅限於使用 Chrome 或 Firefox 瀏覽器。每次跑 PageSpeed 時候,Chrome 就會出現哀號,並且吃下許多記憶體。有沒有 command line 可以直接用 Google PageSpeed Insights 測試 Desktop 或 Mobile 的分數。Google 工程師 @addyosmani 寫了一套 PageSpeed Insights for Node – with reporting 稱作 PSI,可以直接透過 Node 來產生基本 report,這 report 真的算很基本,跟 Chrome 的 extension 跑起來的 report 是不一樣的。這工具可以用來紀錄每次 deploy 網站時的一些數據變化。底下附上 Google 網站報告

google_psi_report

此工具是透過 gpagespeed 完成,如果你有用 GruntJS 可以直接參考 grunt-pagespeed。使用 psi command line 非常簡單,透過底下指令就可以正確產生出上面報表

$ npm install -g psi
$ psi http://www.google.com

如果有用 GulpJS 可以寫成兩個 Task 來跑

var gulp = require('gulp');
var psi = require('psi');
var site = 'http://www.html5rocks.com';
var key = '';

// Please feel free to use the `nokey` option to try out PageSpeed
// Insights as part of your build process. For more frequent use,
// we recommend registering for your own API key. For more info:
// https://developers.google.com/speed/docs/insights/v1/getting_started

gulp.task('mobile', function (cb) {
  psi({
    // key: key
    nokey: 'true',
    url: site,
    strategy: 'mobile'
  }, cb);
});

gulp.task('desktop', function (cb) {
  psi({
    nokey: 'true',
    // key: key,
    url: site,
    strategy: 'desktop'
  }, cb);
});

上面程式碼來自 psi-gulp-sample,psi 有提供 callback function

function(err, data){
  console.log(data.score);
  console.log(data.responseCode);
  console.log(data.id );
}

上面的 Task 可以改成

gulp.task('desktop', function (cb) {
  psi({
    nokey: 'true',
    // key: key,
    url: site,
    strategy: 'desktop'
  }, function(err, data){
    console.log(data.score);
    console.log(data.responseCode);
    console.log(data.id );
    cb();
  });
});

用此工具來紀錄每次網站更新後的測試數據,對於調整 Web Performance 來說是一個可以參考的指標。如果 API 使用量很大,請記得申請 Google API Key。

Linode 推出每月 10 美金方案

$
0
0
linode_logo_gray

Linode 慶祝 11 週年慶,推出每月只要 10 美金的 VPS 方案,其實這方案就是原本最低的 Linode 2GB 直接打對折啦。流量每月 2TB,記憶體 1G,24GB SSD 硬碟空間,對外頻寬到 125 Mbps,總對外骨幹還是維持在 40 Gbps。重點是 Linode 現在可以用小時付費,但是每個月只要 10 美金,其實真的很便宜,草創時期用 Linode 真的是最好的方案,看來 DigitalOcean 的出現,這兩年讓 Linode 成長不少,也代表的以前的 Linode 賺很大 XD,補上現在的方案表

Plans and Pricing - Linode

Ngnix 搭配 PHP-FPM 噴 php5-fpm.sock failed (13: Permission denied)

$
0
0
nginx-logo

Nginx 搭配 PHP-FPM 已經是架設 PHP 伺服器基本入門款了,這次升級 CentOS 機器完後,發現 Log 一直噴出底下訊息

nginx error connect to php5-fpm.sock failed (13: Permission denied)

透過 Stackoverflow 查到這篇解答 nginx error connect to php5-fpm.sock failed (13: Permission denied),裡面提到兩種作法,其中一解法是直接修改 /var/run/php5-fpm.sock 為 666,讓其他使用者可以直接存取此檔案,但是此作法在下次重新開機後一樣會出現同問題,最終解法請修改 /etc/php-fpm.d/www.conf 如果是搭配 Nginx 請使用底下設定

user = nginx
group = nginx
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
;                 mode is set to 0666
listen.owner = nginx
listen.group = nginx
listen.mode = 0666

在 Ubuntu 建置 OpenWrt 編譯環境

$
0
0
openwrt-logo

紀錄一下如何在用 VirtualBox 架設 Ubuntu OpenWrt 編譯環境,請記住不要下載 Ubuntu Server Disk 來安裝,會遇到很多奇怪的問題,為了避免編譯出錯,請選擇 Ubuntu 12.04 Desktop 版本,安裝時空間請盡量調大,反正 VirtualBox 也不會吃掉這麼多空間,用多少吃多少。Ubuntu 安裝完成後,請先安裝 openssh server 套件。完成後透過 VirtualBox Network 開啟 22 port forwarding。

# 有 aptitude 指令
$ aptitude -y install openssh-server
# 無 aptitude 指令
$ apt-get -y install openssh-server

由於是安裝桌面版本,所以一開始就會直接打開 lightdm 服務,請透過之前寫的文章 Ubuntu 停止使用 GUI 介面 12.04 LTS 來把桌面停用,這樣開機就直接進去 Text mode 了,避免浪費記憶體在桌面。最後補上相依性套件安裝

$ aptitude -y install build-essential bison flex gettext g++ help2man help2man zlib1g-dev libssl-dev gawk unzip

如果編譯過程有看到 script 檔編譯不過,可能就要換 Bash 環境編譯,請先備份 /bin/sh

$ cp -r /bin/sh /bin/sh2
$ ln -sf /bin/bash /bin/sh

完整的 GCC 套件相依性安裝可以直接看 Github 上面的安裝紀錄

在 Debian 安裝 Percona Xtradb Cluster 5.5.34 注意事項

$
0
0
percona

最近幫公司安裝新的三台機器,全部上 Debian 7.5 Server 版本,統一安裝 Percona Xtradb Cluster 最新版本 5.5.37。設定完第一台 Node,並且透過底下指令 boot up 成第一台 PXC。

$ /etc/init.d/mysql bootstrap-pxc

後續第二台要啟動跟第一台進行 SST,寫到一半直接噴底下錯誤訊息

WSREP_SST: [ERROR] Cleanup after exit with status:32 (20140702 10:57:28.004) WSREP_SST: [INFO] Removing the sst_in_progress file (20140702 10:57:28.006) 140702 10:57:28 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup –role ‘joiner’ –address ’192.168.1.101′ –auth ‘xxxxx:xxxxxx’ –datadir ‘/var/lib/mysql/’ –defaults-file ‘/etc/mysql/my.cnf’ –parent ’16042′: 32 (Broken pipe) 140702 10:57:28 [ERROR] WSREP: Failed to read uuid:seqno from joiner script. 140702 10:57:28 [ERROR] WSREP: SST failed: 32 (Broken pipe)

MySQL Performance Blog 找到一篇 5.5.34 Release Note,裡面提到在 5.5.34 版本以後,請使用 xtrabackup-v2 這是之前的 xtrabackup 重新命名過來的。如果重新啟動,還是持續出現此問題的話,請將系統的 MySQL Data 目錄清空,重新跑 SST 拉資料。

$ rm -rf /var/lib/mysql/* $ /etc/init.d/mysql restart

基本上這樣就可以了,另外 MySQL 裝好時,預設都沒有開啟任何 Log 紀錄,請務必將 Log 打開,不然怎麼 Debug,底下附上 Debian 的 my.cnf 設定

innodb_log_file_size = 64M
server-id               = 2
log_bin                 = /var/log/mysql/mysql-bin.log
log_error                      = /var/log/mysql/mysql-error.log
log_queries_not_using_indexes  = 1
slow_query_log                 = 1
slow_query_log_file            = /var/log/mysql/mysql-slow.log
long_query_time                = 1
default_storage_engine=InnoDB
binlog_format=ROW
log_slave_updates

另外 /etc/mysql/conf.d/wsrep.cnf

[MYSQLD]
wsrep_provider=/usr/lib/galera2/libgalera_smm.so
wsrep_cluster_address=gcomm://192.168.1.100,192.168.1.102
wsrep_sst_auth=xxxxx:xxxxx
wsrep_provider_options="gcache.size=2G"
wsrep_cluster_name=Percona
wsrep_sst_method=xtrabackup-v2
wsrep_node_name=db_02
wsrep_slave_threads=4
log_slave_updates
innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2

注意 wsrep_sst_method 務必使用 xtrabackup-v2,如果是 CentOS 系統無此 xtrabackup-v2 指令時,請透過 ln 指令 Link 過去即可。結論就是沒事別亂升級系統,另外第二台要啟動進行 SST 時,可以打開看 innobackupex.backup.log 內是否有錯誤訊息,後續 Node 無法啟動的原因也會紀錄在此。

Automating your workflow with Gulp.js

$
0
0
gulp

今年 2014 COSCUP 在 7/19,20 中研院舉辦,由於 JSDC 今年比往年還要晚半年舉辦,所以本來想投在 JSDC 的議程,就先拿到投到 COSCUP 議程。去年 JSDC 講了 Javascript command line tool GruntJS 介紹,講完經過半年,Gulp.js 就出來了,我馬上跳過去嘗試,用過之後,就像變了心的女朋友,回不來了,底下是 Gulp.js Slides。

最後提到 Slush.js 這套 streaming scaffolding system,我寫了 html5 template engine generator,產生最簡單的開發環境以及 Gulp.js 設定檔,大家可以透過底下安裝嘗試:

$ npm install -g slush bower
$ npm install -g slush-html5-template

產生專案檔案

$ slush html5-template

這套 Slush html5 generator 程式檔來自 html5-template-engine

升級 PHP Facebook SDK 到 4.0.x 版本

$
0
0
CodeIgniter

最近幫公司建立 Staging 環境,申請了新的 FB App 來,用原本 Facebook v3.2.3 SDK 發現已經不能 work 了,去翻了 Facebook Platform Changelog,看到今年 4 月 30 號以後申請的 App 會強制走 v2.0 Auth 機制,所以原本用 php sdk 3.2.3 版本的話,完全無法呼叫 Auth 2.0 API,導致整個網站爛掉,當然線上的網站是不會隨意換 App ID 及 secret,免得怎麼爆掉的都不知道。這次來教學在 CodeIgniter 轉換 PHP Facebook SDK,可以直接參考官方 4.0.0 的教學,原本 3.2.3 版本直接下載程式碼,放到 library 目錄,直接 include 就可以取得 Facebook 個人資料,4.0.0 版本以後,請先確認系統是否升級為 PHP 5.4 版本以上,並且支援 Composer 安裝,當然如果不用 Composer 也可以,只是要 include 很多檔案,真的比較麻煩。

先在根目錄建立 composer.json 內容填入

{
  "require" : {
    "facebook/php-sdk-v4" : "4.0.*"
  }
}

接著執行 composer install,系統會自動建立 vendor 目錄。在 application/libraries 建立 lib_login.php 檔案,並且寫入底下程式碼

<?php  if (! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Name: Facebook Login Library
*
* Author: appleboy
*
*/

require 'vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;

class Lib_login
{
    /**
     * CodeIgniter global
     *
     * @var string
     **/
    protected $ci;

    /**
     * __construct
     *
     * @return void
     * @author Ben
     **/
    public function __construct()
    {
        $this->ci =& get_instance();
        $this->ci->load->library('session');
        $this->ci->config->load('facebook');

        if (! isset($_SESSION)) {
            session_start();
        }
    }

    public function facebook()
    {
        $facebook_default_scope = explode(',', $this->ci->config->item("facebook_default_scope"));
        $facebook_app_id = $this->ci->config->item("facebook_app_id");
        $facebook_api_secret = $this->ci->config->item("facebook_api_secret");

        // init app with app id and secret
        FacebookSession::setDefaultApplication($facebook_app_id, $facebook_api_secret);

        // login helper with redirect_uri
        $helper = new FacebookRedirectLoginHelper(site_url('login/facebook'));
        // see if a existing session exists
        if (isset($_SESSION) && isset($_SESSION['fb_token'])) {
            // create new session from saved access_token
            $session = new FacebookSession($_SESSION['fb_token']);

            // validate the access_token to make sure it's still valid
            try {
                if (!$session->validate()) {
                    $session = null;
                }
            } catch (Exception $e) {
                // catch any exceptions
                $session = null;
            }
        }

        if (!isset($session) || $session === null) {
            // no session exists

            try {
                $session = $helper->getSessionFromRedirect();
            } catch(FacebookRequestException $ex) {
                // When Facebook returns an error
                // handle this better in production code
                print_r($ex);
            } catch(Exception $ex) {
                // When validation fails or other local issues
                // handle this better in production code
                print_r($ex);
            }
        }

        // see if we have a session
        if (isset($session)) {
            // save the session
            $_SESSION['fb_token'] = $session->getToken();
            // create a session using saved token or the new one we generated at login
            $session = new FacebookSession($session->getToken());

            // graph api request for user data
            $request = new FacebookRequest($session, 'GET', '/me');
            $response = $request->execute();
            // get response
            $graphObject = $response->getGraphObject()->asArray();
            $fb_data = array(
                'me' => $graphObject,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);

        } else {
            $fb_data = array(
                'me' => null,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);
        }

        return $fb_data;
    }
}

最後寫簡單 controller

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Login extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library(array('session', 'lib_login'));
    }

    /**
     * facebook login
     *
     * @return void
     * @author appleboy
     **/
    public function facebook()
    {
        $fb_data = $this->lib_login->facebook();

        // check login data
        if (isset($fb_data['me'])) {
            var_dump($fb_data);
        } else {
            echo '<a href="' . $fb_data['loginUrl'] . '">Login</a>';
        }
    }
}

/* End of file login.php */
/* Location: ./application/controllers/login.php */

打開瀏覽器,直接執行 http://xxxx/login/facebook 就可以看到 Facebook 登入連結。所以程式碼都放在 Githubcodeigniter-facebook-php-sdk-v4,歡迎取用。

推薦 Sublime Text UI Theme Spacegray

$
0
0
Sublime_Text_Logo

不管在 Windows 或 Linux 環境,我都是使用 Sublime Text 編輯器,推薦這套編輯器的原因無非就是有強大的 Plugin 套件,這次來推薦撰寫程式碼的 UI Theme,好的 UI Theme 可以讓程式設計師的眼睛感覺到很舒服,Spacegray UI ThemeRGBA.tw 網站管理者 Even Wu 推薦。安裝方式很簡單 Ctrl + Shift + p 叫出命令列視窗,找到 Install Packages 後,搜尋 Theme - Spacegray

sublime_1

上面是安裝完成後,把底下設定加入到 User Settings (Sublime Text -> Preferences -> Settings - User)

"color_scheme": "Packages/Theme - Spacegray/base16-eighties.dark.tmTheme",
"spacegray_sidebar_font_xlarge": true,
"spacegray_sidebar_tree_xlarge": true,
"spacegray_tabs_auto_width": true,
"spacegray_tabs_font_xlarge": true,
"spacegray_tabs_xlarge": true,
"theme": "Spacegray.sublime-theme",

重新打開編輯器,就可以看到新的樣貌,左邊 sidebar 的字體及寬度整個變大,眼睛就不用這麼吃力了。

Viewing all 325 articles
Browse latest View live