聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

二月 24, 2014

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» Laravel 搭配 Memcached Cross Domain Session

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 的開發者一個方向。

六月 13, 2013

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» How to install Gearman on Ubuntu or Debian with MySQL 安裝測試篇

Gearman 可以在背景幫忙處理繁瑣的工作,例如壓縮影片、處理縮圖、發送認證信…等,這次不會提到太多 Gearman 介紹,如果想瞭解 Gearman 可以參考小鐵兄寫的 Gearman 心得,此篇會筆記如何在 Ubuntu or Debian 安裝 Gearman 搭配 MySQL 服務,當然如果你不是使用 MySQL,也可以另外搭配 MemcachedSQLite 都可以

Ubuntu or Debian 安裝

其實安裝方式很簡單,只需要透過 apt-get 指令就可以安裝完成

$ aptitude -y install gearman gearman-job-server libgearman-dev libdrizzle0

安裝完成後,在命令列打入 gearmand -V 檢查版本,會發現預設的版本非常的舊,但是沒關係,Ubuntu 可以透過 Package Repository 來安裝到最新版

$ add-apt-repository ppa:gearman-developers/ppa
$ aptitude -y update

但是在 Debian 7.0 版似乎起不了任何作用,裝起來版本真的很低,爽度不夠,所以最終解法還是要透過 tar 方式安裝,安裝過程一定會遇到一些沒安裝的 develop library,只要把相對應的套件安裝即可

$ aptitude -y install libboost-program-options-dev gperf libcloog-ppl0 libpq-dev libmemcached-dev libevent-dev
$ wget https://launchpad.net/libdrizzle/5.1/5.1.4/+download/libdrizzle-5.1.4.tar.gz -O /tmp/libdrizzle-5.1.4.tar.gz
$ wget https://launchpad.net/gearmand/1.2/1.1.8/+download/gearmand-1.1.8.tar.gz -O /tmp/gearmand-1.1.8.tar.gz
$ cd /tmp && tar xvfz libdrizzle-5.1.4.tar.gz && cd libdrizzle-5.1.4 && ./configure --prefix=/usr && make && make install
$ cd /tmp && tar xvfz gearmand-1.1.8.tar.gz && cd gearmand-1.1.8 && ./configure --prefix=/usr && make && make install

安裝完成後,直接打 gearmand -h

builtin:

libmemcached:
  --libmemcached-servers arg List of Memcached servers to use.

Postgres:
  --libpq-conninfo arg       PostgreSQL connection information string.
  --libpq-table arg (=queue) Table to use.

MySQL:
  --mysql-host arg (=localhost)      MySQL host.
  --mysql-port arg (=3306)           Port of server. (by default 3306)
  --mysql-user arg                   MySQL user.
  --mysql-password arg               MySQL user password.
  --mysql-db arg                     MySQL database.
  --mysql-table arg (=gearman_queue) MySQL table name.

如果搭配 Mariadb 的話,請安裝 libmariadbclient-dev 才可以將 MySQL 功能編譯進去。從上面結果發現 Gearman 目前支援 libmemcached, Postgres, MySQL 串接方式,底下來一一介紹

搭配 memcached

Gearman 0.7 版本以上才支援,設定方式很簡單,開啟 /etc/default/gearman-job-server 找到底下字串

PARAMS="--listen=127.0.0.1"

改成

PARAMS="-q libmemcached --libmemcached-servers=localhost"

當然要先檢查系統有無啟動 memcached port 11211。重新啟動 gearmand

$ /etc/init.d/gearman-job-server restart

搭配 MySQL

設定前,請先將 Database 建立完成

$ mysql -u root -p -e 'CREATE DATABASE gearman;'

最後設定 /etc/default/gearman-job-server

PARAMS="-q mysql --mysql-host=localhost --mysql-user=xxxx --mysql-password=xxxxx--mysql-db=gearman --mysql-table=gearman_queue"

重新啟動後,Gearman 會在資料庫建立 gearman_queue 資料表

CREATE TABLE IF NOT EXISTS `gearman_queue` (
  `unique_key` VARCHAR(64) DEFAULT NULL,
  `function_name` VARCHAR(255) DEFAULT NULL,
  `priority` INT(11) DEFAULT NULL,
  `data` longblob,
  `when_to_run` INT(11) DEFAULT NULL,
  UNIQUE KEY `unique_key` (`unique_key`,`function_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

嗯嗯,非常好,但是你會發現一個問題,都已經在搞 InnoDB 竟然沒有 primary key,所以這就請系統管理者幫忙建立上去。

測試資料

首先 Gearman 支援任何程式語言 (Shell, Perl, Node.js, PHP, Python, Java ..等),先來介紹使用 PHP command line,請安裝 PHP Gearman API Extension

$ pecl install channel://pecl.php.net/gearman-1.1.0

建立 /etc/php5/cli/conf.d/gearman.ini,內容為

[gearman]
extension=gearman.so

重新啟動 php5 fpm

$ /etc/init.d/php5-fpm restart

用指令檢查

$ php -i | grep gearman
/etc/php5/cli/conf.d/gearman.ini,
gearman
gearman support => enabled
libgearman version => 1.1.8

撰寫 worker.php (copy from 小鐵部落格)

<?php
$worker = new GearmanWorker();
$worker->addServer(); // 預設為 localhost
$worker->addFunction('sendEmail', 'doSendEmail');
$worker->addFunction('resizeImage', 'doResizeImage');
while($worker->work()) {
    sleep(1); // 無限迴圈,並讓 CPU 休息一下
}
function doSendEmail($job)
{
    $data = unserialize($job->workload());
    print_r($data);
    sleep(3); // 模擬處理時間
    echo "Email sending is done really.\n\n";
}
function doResizeImage($job)
{
    $data = unserialize($job->workload());
    print_r($data);
    sleep(3); // 模擬處理時間
    echo "Image resizing is really done.\n\n";
}

Client.php

<?php
$client = new GearmanClient();
$client->addServer(); // 預設為 localhost
$emailData = array(
    'name'  => 'web',
    'email' => 'member@example.com',
);
$imageData = array(
    'image' => '/var/www/pub/image/test.png',
);
$client->doBackground('sendEmail', serialize($emailData));
echo "Email sending is done.\n";
$client->doBackground('resizeImage', serialize($imageData));
echo "Image resizing is done.\n";

到這裡直接先執行 Client 程式,如果安裝的 Gearman 吐出底下訊息:

PHP Warning: GearmanClient::doBackground(): _client_run_tasks(GEARMAN_SERVER_ERROR) QUEUE_ERROR:QUEUE_ERROR -> libgearman/client.cc:1581 in /root/client.php on line 11

表示 Server 沒有產生 unique key,所以造成第二次新增 job 的時候產生衝突,解決方式很解單,在 doBackground,第三個參數加上 unique key

$client->doBackground('sendEmail', serialize($emailData), md5(uniqid(rand(), true)));

這樣就可以完整測試了。

support:

biggo.com.tw

biggo.sg

A Django site.