2013年4月24日 星期三

socket.io scaling out solution

socket.io scaling out solution

socket.io 一直以來都是在 node.js 許多 module 當中,受人注目的一個項目,自己也不例外,從 socket.io 6 進展到目前 socket.io 9 都一直持續關注他的發展。
長期以來這種 Comet 連線模式的環境,最讓人質疑的部份有幾個,
  1. server extend (scaling issue)
  2. message lost *. user connection
首先拿 server exetend 來說,最簡單的解法,同時也是 socket.io 支援的模式,
  1. 設定 socket.io redis config
  2. 使用 load balancer like 的機制
  3. 將 socket.io 服務視為一個 Application
因此就可以如下圖,所表示



http://blog.davidmisshula.com/images/4.png

使用者透過連線到 load balancer 之後,透過 load balaner 將資源分散到每個不同的 Application 機器,每個機器最終將會去向同一個 DB (SQL/ NoSql) 機器取得 session, user, message … 資訊回到應用程式當中。
讓每個使用者的資訊不致於斷線,在這邊 socket.io 預設的使用方式就是採用 redis。
這種連線方式其實有幾篇文章已經說明的相當清楚,
這邊的方式都是採用如同上述表示的規劃架構,可以達到 socket.io scaling 的機制。
當然聰明的各位也想到了,有需求就會有解決方案,因此也有廠商提供了類似的解決方案,
這兩間廠商都是提供 real time web service 給予 Web App provider ,當然這是一件好事情,對於開發者來說正是這個 provider。

可是其中有個問題就是,對於開發者來說這些服務都需要先熟悉他的 API 以及架構,假設…如果今天這個服務商倒了,或者使用者變少之後,那是不是就又成了另外一個科技孤兒。
當然我相信這是一種 trade-off ,對於開發者及廠商都是,話說回來如果我們今天針對的目標族群是 Node.js 開發者,那情況是不是又不太一樣。

針對 Socket.io 開發者


如果是 Node.js 開發者,族群上是針對 socket.io 開發者的話,似乎又有另外一個新的選擇。
沒錯,就在本月份 Widnows Azure(沒錯,就是你知道的那個微軟),目前也提供了類似的服務稱為 Windows Azure service bus,
http://ntotten.com/2013/04/05/scaling-out-socket-io-with-windows-azure-service-bus/
文章中提到了,如何去 scale out socket.io 服務,當做自己的後端服務。

how you can scale out Socket.IO to multiple servers in order to handle many simultaneous connections by using Windows Azure Service Bus as a backing store.

總之這是目前 real time service 當中,少數一個以 socket.io API 為基礎的一個服務(當然之後會不會偷改,我不曉得),不過對於長期關注 Socket.io 的開發者來說,是一個優勢。

從此之後我不需要再持續去注意 socket.io scale out 的問題,只需要去關注 deploy 的問題。

實際情況?

實際上,卻好像不是這麼簡單,如果真的要做到一個 real time service 實際上,對於服務背後幫你做的事情,身為一個開發者還是要可以知道後面的 log 狀況。

message lost

目前線上到底有多少 session connect 有哪些已經 fail, 哪些還是 alive ,這些都是需要被關注,而且需要可以查看 log 的部份。

如果真的要確保訊息都有被完善的發送到每個使用者手上,似乎 Queue 的機制也不得不製作,讓每個訊息不管是針對特定使用者,或者是廣播訊息都能夠使用 queue (例如 rabbitMQ, ZeroMQ),能夠確保訊息的傳遞,以及 log 的檢視。

似乎這樣的服務才足以讓開發者有十分強度的信任,不需要自己建立自己的服務,將整個 Web App 移植到某個 Service Provider。

對於開發者

其實親善開發者真的不難,要做到的就是幾個
  1. 統一的介面(API)
  2. 足夠的訊息回顧(Log)
  3. 穩定的網路
  4. 開源的程式
這四點,每個其實都打到許多廠商的要害,總之說很簡單,做很難,但是不論怎樣,做就對了,我們知道距離目標還有千萬公里遠,但是一步一腳印,就慢慢把步伐向前邁進吧!

繼續開發 MiCloud ...

2013年4月11日 星期四

Chef的學習資源



實作過Chef的流程後,也跟大家分享一下一些網際網路上的資源:

MiCloud Chef Server Dataset

說明:

MiCloud Chef Server主機為Joyent所包裝,提供預設Chef Server相關功能,讓您可以透過網路上所提供的各式Cookbook/Recepie來快速部屬您的雲端環境。以下文章以MiCloud Chef Server為Chef Server,並透過user cookbook來進行Chef Client: Ubuntu server上的user設定部屬...

訂購:



在MiCloud上,您可以透過Web選單(或API)訂購Chef Server主機:
主機建立完成後,您可透過SSH連線進入主機...檢查chef套件,包含以下服務:
[root@Chef-Server-01 /opt/chef-local]# svcs -a | grep chef
online          7:16:47 svc:/pkgsrc/chef-expander:default
online          7:16:49 svc:/pkgsrc/chef-solr:default
online          7:16:50 svc:/pkgsrc/chef-server:default
online          7:16:50 svc:/pkgsrc/chef-server-webui:default

設定Chef Server

搞定KEY

設定Chef Server之private key相關檔案,這邊會用到的包含validation.pem與webui.pem,作用為webui服務與驗證使用。預設MiCloud Chef Server將設定檔案放置在/etc/chef中,這邊複製到~/.chef下,作為系統預設讀取用...
[root@Chef-Server-01 ~]# mkdir ~/.chef && cp /etc/chef/*.pem ~/.chef/

Knife設定

[root@Chef-Server-01 ~]# knife configure -i
WARNING: No knife configuration file found
Where should I put the config file? [/root/.chef/knife.rb] <--預設位置就ok
Please enter the chef server URL: [http://Chef-Server-01.local:4000] http://211.78.xxx.xxx:4000 <--在MiCloud開立的主機IP,Port預設為4000
Please enter a clientname for the new client: [root] Chef-Server-01  <-- 該chef server名稱,自取,但是之後PEM要以此命名
Please enter the existing admin clientname: [chef-webui]
Please enter the location of the existing admin client's private key: [/etc/chef/webui.pem] .chef/webui.pem
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef/validation.pem] .chef/validation.pem
Please enter the path to a chef repository (or leave blank):
Creating initial API user...
Created client[Chef-Server-01]
Configuration file written to /root/.chef/knife.rb
可透過knife client list檢視目前server上註冊的client數量
[root@Chef-Server-01 ~]# knife client list
  Chef-Server-01
  admin
  chef-validator
  chef-webui
方才的步驟,已經產生了一各叫做knife.rb的檔案,檢視一下,其實設定的部份...也可以手動修改
[root@Chef-Server-01 ~]# cat /root/.chef/knife.rb
log_level                :info
log_location             STDOUT
node_name                'Chef-Server-01'
client_key               '/root/.chef/Chef-Server-01.pem'
validation_client_name   'chef-validator'
validation_key           '/root/.chef/validation.pem'
chef_server_url          'http://211.78.xxx.xxx:4000'
cache_type               'BasicFile'
cache_options( :path => '/root/.chef/checksums' )
同時,程序中也建立了Chef-Server-01.pem檔案,這是剛剛設定的clientname加上附檔名.pem
[root@Chef-Server-01 ~]# cat ~/.chef/Chef-Server-01.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3rbftvEAqS1m6MRWvX6Xg3mjjQ0BZX0ycT+EVbSn9ZfOm97H
gDkWvfSVD59hBgfb0k6tTTlGUWeeHY37F4UVjwq2TFO+wWbUhgaXJWO0u/vseHD8
C/S2XqgyU6Qv3bMk3Ejl+wLlESQn5gGYLfs+7gDMJR6w99xubvNFQHUPUEQk+kvM
HT/U5DNwifvcmVodgdXUuEqG+Qv2ChDa24a4...................QhaLz1wNwRWzHolUtUx
OLZEbwKBgC1jpvjiCeaY+Qkp7qX5kqsJ+uF69KHEUP70gAmYfenVYmgfda8pBkWp
fa01GR/qF9WkMM2wbThaQmx/OqVD6uXI627rOhPVbUmUKWv/qLdhqwnlHSrS037o
Dxwh2L+0f7vNxFrbclpSVJ3GhldaMeRgIniMd2VaKtI4ghc9gABC
-----END RSA PRIVATE KEY-----
[root@Chef-Server-01 ~]#

新增Chef Workstation

這邊將Chef Server與Workstation裝在同一台,因此有許多設定可以共用,這邊直接透過指令建立chef-workstation,指令執行完,系統會吐出workstation的Private Key內容,請將此內容存入”~/.chef/chef-workstation.pem”
[root@Chef-Server-01 ~]# knife client create chef-workstation -d -a
Created client[chef-workstation]
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsz53YHrkPE0RRIyzwuRfFdt6jv3U3GygL6Sjz2DgCDVN1IbC
puzkKJ9FEWZjdcfjitrtHnja8WcwTu3deoAtjR7NnMpB1LF+xh4MtR/6lkjo2Yyl
yObecFAwnNjxiNNx5ajmCEEfH5ZVrQpzPR0vMrnZ6VOmUjyWG7dJ5od+1HHae8/3
lC9O78By8crZ+xkTBblTc58eKi8j9tcphzPKeDNbryngA38o9HVmlrM3nGNMT6mz
POWWxftQKcmwXRaRQrJSSA9MqOk0Q/VkRMYmJvkzxkqNN7PSkJwuNadflZEilKH6
B1crIjusXW6hkaj9yb/MUwnplgm.......OSRP0KeI9zx8sUjKwciBW4X5s4dpyh
gEgE6qGg8up6tpFeUbm1v8kD6QY5WXRrnZ0hdwwEw/swSUyZCRxDMcsXy1sndWhC
ME/bAoGAYK1JF83X+X3fbTRrwcoY8tA+VVelIRFrLy3m9qK/UkIKeH9Q6JOmBgvd
U7kRXoo/oyHNmYj3uKGEbNulOLdNtq8jsJno/wawb+t38lAcoRJCiKARI8zYzeiW
AZo11HmAEp7ZcJifJdzNJlkFtTwrN/mCurGvdxApZbWZJFgz7XU=
-----END RSA PRIVATE KEY-----
[root@Chef-Server-01 ~]#
(Save the chef-workstation private key output to ~/.chef/chef-workstation.pem)
建立完workstation後,可以透過show來顯示workstation的相關資訊:
[root@Chef-Server-01 ~]# knife client show chef-workstation
_rev:        1-1df01ef4d0bea06e131baca050d156d1
admin:       true
chef_type:   client
json_class:  Chef::ApiClient
name:        chef-workstation
public_key:  -----BEGIN PUBLIC KEY-----
             MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsz53YHrkPE0RRIyzwuRf
             Fdt6jv3U3GygL6Sjz2DgCDVN1IbCpuzkKJ9FEWZjdcfjitrtHnja8WcwTu3deoAt
             jR7NnMpB1LF+xh4MtR/6lkjo2YylyObecFAwnNjxiNNx5ajmCEEfH5ZVrQpzPR0v
             MrnZ6VOmUjyWG7dJ5od+1HHae8/3lC9O78By8crZ+xkTBblTc58eKi8j9tcphzPK
             eDNbryngA38o9HVmlrM3nGNMT6mzPOWWxftQKcmwXRaRQrJSSA9MqOk0Q/VkRMYm
             JvkzxkqNN7PSkJwuNadflZEilKH6B1crIjusXW6hkaj9yb/MUwnplgmYe6TPPzBZ
             UQIDAQAB
             -----END PUBLIC KEY-----
至GitHub Clone一個chef repository專案

複製一個Chef Repository

Chef均是透過git的方式來維護一個一個的部屬設定,opscode提供一個基礎專案,讓Chef的使用者可以基於此專案開發後續的部屬設定...
[root@Chef-Server-01 ~]# git clone git://github.com/opscode/chef-repo.git /opt/chef-local
Cloning into '/opt/chef-local'...
remote: Counting objects: 209, done.
remote: Compressing objects: 100% (126/126), done.
Receiving objects:  71% (149remote: Total 209 (delta 75), reused 167 (delta 49)
Receiving objects: 100% (209/209), 35.05 KiB, done.
Resolving deltas: 100% (75/75), done.
檢視Clone下來的專案的內容:
[root@Chef-Server-01 ~]# cd /opt/chef-local/
[root@Chef-Server-01 /opt/chef-local]# ls -l
總計 33
drwxr-xr-x 2 root root     3 4月  11 08:06 certificates
-rw-r--r-- 1 root root   156 4月  11 08:06 chefignore
drwxr-xr-x 2 root root     3 4月  11 08:06 config
drwxr-xr-x 2 root root     3 4月  11 08:06 cookbooks
drwxr-xr-x 2 root root     3 4月  11 08:06 data_bags
drwxr-xr-x 2 root root     3 4月  11 08:06 environments
-rw-r--r-- 1 root root 10850 4月  11 08:06 LICENSE
-rw-r--r-- 1 root root  2171 4月  11 08:06 Rakefile
-rw-r--r-- 1 root root  3521 4月  11 08:06 README.md
drwxr-xr-x 2 root root     3 4月  11 08:06 roles
[root@Chef-Server-01 /opt/chef-local]# mkdir .chef
[root@Chef-Server-01 /opt/chef-local]# cp ~/.chef/validation.pem ~/.chef/chef-workstation.pem .chef/
(Chef workstation在執行建立Chef Client時候,需要連線Client作Client設定,因此這邊需產生 ssh key 並且寫到 chef clien的/root/.ssh/authorized_keys中....)

初始化Chef Client

透過knife bootstrap可以初始化Chef Client,其中最後一個參數為Chef Client的IP位置,這邊因為把ssh-kry認證加入,所以不用再帶入帳號與密碼
[root@Chef-Server-01 /opt/chef-local]# knife bootstrap 211.78.xxx.xxx
Bootstrapping Chef on 211.78.xxx.xxx
211.78.xxx.xxx [2013-04-11T08:10:45+00:00] INFO: *** Chef 10.18.2 ***
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Client key /etc/chef/client.pem is not present - registering
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: HTTP Request Returned 404 Not Found: Cannot load node Ubuntu-Chef-Client-01
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Setting the run_list to [] from JSON
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Run List is []
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Run List expands to []
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: HTTP Request Returned 404 Not Found: No routes match the request: /reports/nodes/Ubuntu-Chef-Client-01/runs
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Starting Chef Run for Ubuntu-Chef-Client-01
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Running start handlers
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Start handlers complete.
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] INFO: Loading cookbooks []
211.78.xxx.xxx [2013-04-11T08:10:46+00:00] WARN: Node Ubuntu-Chef-Client-01 has an empty run list.
211.78.xxx.xxx [2013-04-11T08:10:47+00:00] INFO: Chef Run complete in 0.471286644 seconds
211.78.xxx.xxx [2013-04-11T08:10:47+00:00] INFO: Running report handlers
211.78.xxx.xxx [2013-04-11T08:10:47+00:00] INFO: Report handlers complete
完成初始化後,可在Chef server上執行list,檢視Chef client是否加入
[root@Chef-Server-01 /opt/chef-local]# knife client list
  Chef-Server-01
  Ubuntu-Chef-Client-01
  admin
  chef-validator
  chef-webui
  chef-workstation
root@Ubuntu-Chef-Client-01:~# ls -l /etc/chef/
client.pem       client.rb        first-boot.json  validation.pem


安裝Cookbook

Opscode提供一個cookbook的community:http://community.opscode.com/ 許多高手在此分享各式服務與架構的cookbook,下面展示安裝一個叫user的cookbook,相關資訊可以參考:http://community.opscode.com/cookbooks/user 
(cookbook folder need to be a git repository)
[root@Chef-Server-01 /opt/chef-local/cookbooks]# knife cookbook site install user
Installing user to /var/chef/cookbooks
ERROR: The cookbook repo /var/chef/cookbooks is not a git repository.
Use `git init` to initialize a git repo
預設的參數檔因為未指示cookbook放置的地方,因此執行時候會出錯,需修改knife.rb加入cookbook_path,並且要在cookbook folder完成git初始化的設定...
# vi ~/.chef/knife.rb
log_level                :info
log_location             STDOUT
node_name                'Chef-Server-01'
client_key               '/root/.chef/Chef-Server-01.pem'
validation_client_name   'chef-validator'
validation_key           '/root/.chef/validation.pem'
chef_server_url          'http://211.78.xxx.xxx:4000'
cache_type               'BasicFile'
cache_options( :path => '/root/.chef/checksums' )
cookbook_path [ '/opt/chef-local/cookbooks' ]  #<-- specify where the cookbooks
(first time install cookbook... need to do the first commit with the cookbook repostory)
[root@Chef-Server-01 /opt/chef-local/cookbooks]# knife cookbook site install user
Installing user to /opt/chef-local/cookbooks
ERROR: The default branch 'master' does not exist
If this is a new git repo, make sure you have at least one commit before installing cookbooks
(Error again, you need commit git....)
[root@Chef-Server-01 /opt/chef-local/cookbooks]# knife cookbook site install user
Installing user to /opt/chef-local/cookbooks
Checking out the master branch.
Creating pristine copy branch chef-vendor-user
Downloading user from the cookbooks site at version 0.3.0 to /opt/chef-local/cookbooks/user.tar.gz
Cookbook saved: /opt/chef-local/cookbooks/user.tar.gz
Removing pre-existing version.
Uncompressing user version 0.3.0.
removing downloaded tarball
1 files updated, committing changes
Creating tag cookbook-site-imported-user-0.3.0
Checking out the master branch.
Updating 337df3e..f8aaaf1
Fast-forward
 user/.gitignore                            |    2 +
 user/.travis.yml                           |    6 +
 user/CHANGELOG.md                          |   95 ++++++++++++
 user/README.md                             |  391 ++++++++++++++++++++++++++++++++++++++++++++++++
 user/Rakefile                              |   33 ++++
 user/attributes/default.rb                 |   42 ++++++
 user/metadata.json                         |   35 +++++
 user/metadata.rb                           |   14 ++
 user/providers/account.rb                  |  173 +++++++++++++++++++++
 user/recipes/data_bag.rb                   |   52 +++++++
 user/recipes/default.rb                    |   18 +++
 user/resources/account.rb                  |   40 +++++
 user/templates/default/authorized_keys.erb |    7 +
 13 files changed, 908 insertions(+)
 create mode 100644 user/.gitignore
 create mode 100644 user/.travis.yml
 create mode 100644 user/CHANGELOG.md
 create mode 100644 user/README.md
 create mode 100644 user/Rakefile
 create mode 100644 user/attributes/default.rb
 create mode 100644 user/metadata.json
 create mode 100644 user/metadata.rb
 create mode 100644 user/providers/account.rb
 create mode 100644 user/recipes/data_bag.rb
 create mode 100644 user/recipes/default.rb
 create mode 100644 user/resources/account.rb
 create mode 100644 user/templates/default/authorized_keys.erb
Cookbook user version 0.3.0 successfully installed
完成安裝”user”這個cookbook之後,會在cookbook目錄下多出一個user的目錄...

上傳Cookbook到Chef Server

上面Cookbook下載之後,需要依需求客製化欲建立的user及相關設定...當設定完成後,即可上傳該cookbook至Chef Server...
[root@Chef-Server-01 /opt/chef-local]# sudo knife cookbook upload user
Uploading user         [0.3.0]
Uploaded 1 cookbook.
此部份開始為user cookbook需進行的一些設定,詳細部分請參考user cookbook的github page:http://fnichol.github.io/chef-user/ 
設定server role...
[root@Chef-Server-01 /opt/chef-local]# cat -> /opt/chef-local/roles/ubuntu_servers.rb <<EOF
name "ubuntu_servers"
description "The base role applied to all nodes."
run_list(
    "recipe[user]",
    "recipe[user::data_bag]"
)
override_attributes(
    "users" => [ "ubuntu" ]
)
EOF
將server role上傳至Chef Server...
[root@Chef-Server-01 /opt/chef-local]# knife role from file roles/ubuntu_servers.rb
Updated Role ubuntu_servers!
建立user cookbook設定上需要的data_bag...
[root@Chef-Server-01 /opt/chef-local]# cd data_bags/
[root@Chef-Server-01 /opt/chef-local/data_bags]# mkdir users
[root@Chef-Server-01 /opt/chef-local/data_bags]# vim users/ubuntu.json
{
    "id"       : "ubuntu",
    "gid": "admin",
    "comment"  : "ubuntu",
    "home"     : "/home/ubuntu",
    "create_user_group":"false",
    "ssh_keygen": "false",
    "ssh_keys" : "ssh-rsa AAAAB3NzaC1yc2EAAAADAQASSAABAQDU+3VXGUANuuLVp3jeM3nQi23Odgz4mhiFI4PfDdlO3DtefSduikKC++PhvG2sdUxb+c7nxq+fq2GD8AEWltuUn3fYl0zdujr4zBbid/Blylp65PlT5ok5QwLuSwS8RtfQkyipocbAe3Jbtab13YLq/iUBlAkgD/GxfyZOaqs4tPdcn7DKfEuq81NjoKDkTV9GOUUpKi8ves4in/sB7eyFlrpm0+7mpwNh3cXNBRL8b3theIG3BLK7zbrUwTT6vcNETXt/wJAoO7cKQecFudhpqr8N/S?pSbflcRrw4GTjvkCZ58PylOXY1cUOfeeSvcxtNqsGPq8ZgtxRATlCBIAN simonsu@SimonAIR.local"
}
在data_bag下建立users databag...
[root@Chef-Server-01 /opt/chef-local/data_bags]# knife data bag create users
Created data_bag[users]
將上面建立的ubuntu.json文件上傳至databag...
[root@Chef-Server-01 /opt/chef-local/data_bags]# knife data bag from file users users/ubuntu.json
Updated data_bag_item[users::ubuntu]
在node run_list中建立ubuntu_servers的role...
[root@Chef-Server-01 /opt/chef-local/data_bags]# knife node run_list add Ubuntu-Chef-Client-01 "role[ubuntu_servers]"
run_list:  [role[ubuntu_servers]]

上述動作就完成Chef與Cookbook上之相關設定。

Client端拉取配置

當Chef Server上的設定完備後,client需要做的只有執行chef-client,將部屬設定拉下執行...
root@Ubuntu-Chef-Client-01:/etc/chef# chef-client
[2013-04-11T09:30:46+00:00] INFO: *** Chef 10.18.2 ***
[2013-04-11T09:30:47+00:00] INFO: Run List is [role[ubuntu_servers]]
[2013-04-11T09:30:47+00:00] INFO: Run List expands to [user, user::data_bag]
[2013-04-11T09:30:47+00:00] INFO: HTTP Request Returned 404 Not Found: No routes match the request: /reports/nodes/Ubuntu-Chef-Client-01/runs
[2013-04-11T09:30:47+00:00] INFO: Starting Chef Run for Ubuntu-Chef-Client-01
[2013-04-11T09:30:47+00:00] INFO: Running start handlers
[2013-04-11T09:30:47+00:00] INFO: Start handlers complete.
[2013-04-11T09:30:47+00:00] INFO: Loading cookbooks [user]
[2013-04-11T09:30:47+00:00] INFO: Storing updated cookbooks/user/resources/account.rb in the cache.
[2013-04-11T09:30:47+00:00] INFO: Storing updated cookbooks/user/providers/account.rb in the cache.
[2013-04-11T09:30:47+00:00] INFO: Storing updated cookbooks/user/recipes/default.rb in the cache.
[2013-04-11T09:30:47+00:00] INFO: Storing updated cookbooks/user/recipes/data_bag.rb in the cache.
[2013-04-11T09:30:47+00:00] INFO: Storing updated cookbooks/user/attributes/default.rb in the cache.
[2013-04-11T09:30:47+00:00] INFO: Storing updated cookbooks/user/metadata.json in the cache.
[2013-04-11T09:30:47+00:00] INFO: Storing updated cookbooks/user/README.md in the cache.
[2013-04-11T09:30:48+00:00] INFO: Storing updated cookbooks/user/metadata.rb in the cache.
[2013-04-11T09:30:48+00:00] INFO: Storing updated cookbooks/user/.gitignore in the cache.
[2013-04-11T09:30:48+00:00] INFO: Storing updated cookbooks/user/CHANGELOG.md in the cache.
[2013-04-11T09:30:48+00:00] INFO: Storing updated cookbooks/user/Rakefile in the cache.
[2013-04-11T09:30:48+00:00] INFO: Storing updated cookbooks/user/.travis.yml in the cache.
[2013-04-11T09:30:48+00:00] INFO: Processing user_account[ubuntu] action create (user::data_bag line 36)
...(Skip)

附註:

或許您會期望使用Cookbooks來部屬您的SmartOS或其他Linux Distribution,但是Cookbooks畢竟有支援上的限制,建議您詳細讀取Cookbook的提供說明與限制後,再實作於您的架構之上。



2013年4月10日 星期三



SmartOS - 分支自Solaris的IllumosMiCloud SmartOS在檢視系統資源部分與一般Linux比較不一樣,原因是因為Bare-Metal的虛擬化方式,讓GuestOS系統使用的指令必須重新設計,而透過 jinf 方式來檢視是不錯的方式,他可以帶入s: swap、m: memory、c: cpu等參數來做不同資源的查詢。


而該指令是Bash寫成的,透過原始碼可以了解底層是透過kstat, prstat等指令來抓取系統層的資源使用數值,然後再加以運算,可以滿足許多使用者於使用SmartOS時候的資源使用狀況查詢需求 :D


下面是查詢的結果:


[root@63dcec41 ~]# jinf -s
Swap cap: 1.0 GiB
Total swap used: 221.4 MiB
Total swap free: 802.5 MiB

[root@63dcec41 ~]# jinf -m
Memory cap: 512.0 MiB
Memory used: 145.2 MiB
Memory free: 366.7 MiB

[root@63dcec41 ~]# jinf -c
CPU Cap Used: 4 %
System CPU Utilized: 0 %

簡單的NodeJS Http Server實作


Noder - Simple HTTP Server

Noder是透過NodeJS的HTTP模組製作的簡單HTTP Server,讓使用者可以透過簡單的指令來啟動HTTP服務來提供本地端檔案的檔案瀏覽,支援npm安裝∼

Picture: Easy to use of noder!

安裝

透過npm指令安裝,因為這個安裝需要安裝指令,因此安裝時要指定"-g"來安裝到global
    # sudo npm install noder -g  
PS: 是不是要使用sudo...就看您電腦的使用者是不是有權限拉

使用

預設啟動會listen 1337 port,並且服務會啟動在127.0.0.1...
# noder --help

  Usage: noder [options]

  Options:

    -h, --help                     output usage information
    -V, --version                  output the version number
    -h, --host [ip]                Specific host, like 192.168.1.1, default is all ip listened
    -p, --port <port>              Specific port, like 80,3000,8080, default is 1337
    -a, --allow <allow file type>  Specific the allowed file types that seprate by ",", default is all
    -d, --deny <deny file type>    Specific the denied file types that seprate by ",", default is none

瀏覽

服務啟動後,您可以打開瀏覽器瀏覽: http://127.0.0.1:1337/test.html 

SmartOS Service Management Framework (SMF)



在SmartOS中,也有類似Linux的init.d的service架構,透過這部分的設定,系統可以在重新啓動的時候,自動帶入服務,也可以在異常crash的狀態下自動將服務帶起來,下面範例展示如何將自建的服務加入SMF中。

1. 下載SMF Manifest範例

wget --no-check-certificate http://github.com/isaacs/joyent-node-on-smart-example/raw/master/node-hello-world-service-manifest.xml

範例截取如下:



<!-- node-hello-world-service-manifest.xml -->
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type="manifest" name="simon-test-service">
  <service name="site/simon-test-service" type="service" version="1">


    <create_default_instance enabled="true"/>


    <single_instance/>


    <dependency name="network" grouping="require_all" restart_on="refresh" 
      type="service">
      <service_fmri value="svc:/milestone/network:default"/>
    </dependency>


    <dependency name="filesystem" grouping="require_all" restart_on="refresh" 
      type="service">
      <service_fmri value="svc:/system/filesystem/local"/>
    </dependency>


    <method_context working_directory="/root/simon-test">
    <method_credential user="root" group="root" privileges=”basic,net_privaddr” />
    <method_environment>
      <envvar name="PATH" 
        value="/opt/node/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin"/>
        <envvar name="HOME" value="/root"/>
      </method_environment>
    </method_context>


    <exec_method
      type="method"
      name="start"
      exec="/opt/node/bin/node /root/simon-test/app.js"
      timeout_seconds="60"/>


    <exec_method
      type="method"
      name="stop"
      exec=":kill"
      timeout_seconds="60"/>

    <property_group name="startd" type="framework">
      <propval name="duration" type="astring" value="child"/>
      <propval name="ignore_error" type="astring" value="core,signal"/>
    </property_group>
    <property_group name="application" type="application">
    </property_group>

    <stability value="Evolving"/>
    <template>
      <common_name>
        <loctext xml:lang="C">node.js simon-test service</loctext>
      </common_name>
    </template>
  </service>
</service_bundle>



2. 匯入SMF


svccfg import node-hello-world-service-manifest.xml

3. 檢視匯入服務狀態
[root@MiCloudGW01 ~]# svcs -a | grep simon-test
disabled        2:26:46 svc:/site/simon-test-service:default

4. 啓動服務
[root@MiCloudGW01 ~]# svcadm enable simon-test-service
[root@MiCloudGW01 ~]# svcs -a | grep simon-test       
online          2:34:04 svc:/site/simon-test-service:default

5. 關閉服務
[root@MiCloudGW01 ~]# svcadm disable simon-test-service
[root@MiCloudGW01 ~]# svcs -a | grep simon-test        
disabled        2:34:48 svc:/site/simon-test-service:default

6. 檢視服務LOG記錄
# tail -f `svcs -L simon-test`
PS: svcs -L [service name] 將顯示記錄檔所在位置

7. 檢視其他人的manifest怎麼寫的

[root@MiCloudGW01 ~]# svccfg export mysql                     
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
<service_bundle type='manifest' name='export'>
 <service name='network/mysql' type='service' version='0'>
   <create_default_instance enabled='true'/>
   <single_instance/>
   <dependency name='fs' grouping='require_all' restart_on='none' type='service'>
     <service_fmri value='svc:/system/filesystem/local'/>
   </dependency>
   <dependency name='net' grouping='require_all' restart_on='none' type='service'>
     <service_fmri value='svc:/network/loopback'/>
   </dependency>
   <method_context working_directory='/var/mysql'>
     <method_credential group='mysql' user='mysql'/>
     <method_environment>
       <envvar name='LD_PRELOAD_32' value='/usr/lib/extendedFILE.so.1'/>
     </method_environment>
   </method_context>
   <exec_method name='start' type='method' exec='/opt/local/share/smf/mysql-server/method start' timeout_seconds='18446744073709551615'/>
   <exec_method name='stop' type='method' exec='/opt/local/share/smf/mysql-server/method stop' timeout_seconds='18446744073709551615'/>
   <stability value='Evolving'/>
   <template>
     <common_name>
       <loctext xml:lang='C'>MySQL RDBMS</loctext>
     </common_name>
     <documentation>
       <manpage title='MySQL 5.5' section='1'/>
       <doc_link name='mysql.com' uri='http://dev.mysql.com/docs'/>
     </documentation>
   </template>
 </service>
</service_bundle>

8. 刪除已匯入的SMF
# svccfg delete simon-test-service

9. 其它進階功能,請參考svccfg man page
# man svccfg



Reference: