前面寫(xiě)過(guò)
2篇文章介紹過(guò)OpenStack,今天介紹一下配合Haproxy實(shí)現Web application auto scaling。
在用OpenStack實(shí)施云計算之前,要實(shí)現應用的水平擴展,通常是用這樣的架構:
一臺Haproxy將動(dòng)態(tài)請求轉發(fā)到N臺nginx服務(wù)器,當流量增加的時(shí)候,我們需要手工安裝物理的服務(wù)器,將它添加到集群中去,然后再手工修改haproxy的配置,讓它生效。就算用自動(dòng)化的安裝管理工具,這樣擴展一臺機器也差不多要3~4小時(shí)。
用OpenStack實(shí)施云計算之后,整個(gè)架構和上圖是一樣的,但是我們可以通過(guò)幾十行代碼在5分鐘內實(shí)現auto scaling,來(lái)看一下具體的步驟:
首先,我們先在OpenStack上的一臺虛擬機安裝好nginx以及其他應用,然后對它做一個(gè)snapshot:
記錄一下這個(gè)snapshot的ID:
接下來(lái)寫(xiě)一個(gè)腳本,能夠用這個(gè)snapshot來(lái)自動(dòng)的創(chuàng )建實(shí)例,因為我對Ruby比較熟悉,這里用Ruby的
openstack-computegem 來(lái)寫(xiě)(OpenStack有多種客戶(hù)端可以調用API,比如python,php):
- require 'rubygems'
- require 'openstack/compute'
-
- username = 'quake'
- api_key = 'password'
- auth_url = 'http://10.199.21.210:5000/v2.0/'
- image_id = '9'
- flavor_id = '1'
-
- cs = OpenStack::Compute::Connection.new(:username => username, :api_key => api_key, :auth_url => auth_url)
- image = cs.get_image(image_id)
- flavor = cs.get_flavor(flavor_id)
-
- newserver = cs.create_server(:name => "rails#{Time.now.strftime("%Y%m%d%H%M")}", :imageRef => image.id, :flavorRef => flavor.id)
- p "New Server #{newserver.name} created"
-
- while newserver.progress < 100
- p "Server status #{newserver.status}, progress #{newserver.progress}"
- sleep 10
- newserver.refresh
- end
- p "Server status #{newserver.status}, progress #{newserver.progress}"
- p "Done"
當需要擴展一臺新的nginx instance時(shí)候,只需要執行上面的代碼:
- # ruby create_new_server.rb
- "New Server rails201112161042 created"
- "Server status BUILD, progress 0"
- "Server status ACTIVE, progress 100"
- "Done"
差不多30秒左右的時(shí)間(視你的鏡像大小和網(wǎng)絡(luò )速度),這臺虛擬機就創(chuàng )建好了,我們可以在dashboard看到這臺最新的機器:
接下去我們再寫(xiě)一個(gè)腳本,自動(dòng)更新haproxy的配置文件:
- cs = OpenStack::Compute::Connection.new(:username => username, :api_key => api_key, :auth_url => auth_url)
-
- `cp haproxy.cfg.template haproxy.cfg`
-
- File.open('haproxy.cfg', 'a') do |f|
- cs.servers.each do |s|
- server = cs.server(s[:id])
-
- if server.image['id'] == image_id
- ip = server.addresses.first.address
- p "Found matched server #{server.name} #{ip}, add to haproxy"
- f.puts " server #{server.name} #{ip}:80 maxconn 512"
- end
- end
- end
-
-
- `cp haproxy.cfg /etc/haproxy.cfg`
- p "Reload haproxy"
- `/etc/init.d/haproxy reload`
執行該代碼:
- # ruby update_haproxy.rb
- "Found matched server rails201112161042 10.199.18.6, add to haproxy"
- "Found matched server rails201112161003 10.199.18.5, add to haproxy"
- "Found matched server rails201112160953 10.199.18.4, add to haproxy"
- "Found matched server rails201112160924 10.199.18.8, add to haproxy"
- "Found matched server rails201112160923 10.199.18.7, add to haproxy"
- "Reload haproxy"
這樣就實(shí)現了將剛剛創(chuàng )建的 rails201112161042 實(shí)例添加到了haproxy集群。
通過(guò)不到50行的代碼,就實(shí)現了auto scaling,是不是很方便?我們還能夠更自動(dòng)化一些,配合監控腳本,設定一個(gè)指標,比如說(shuō)當整個(gè)集群的CPU用量達到70%的時(shí)候,自動(dòng)調用create_server,當CPU小于10%的時(shí)候,調用delete_server,這樣就實(shí)現了按需scaling up/down.