免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4275 | 回复: 4
打印 上一主题 下一主题

用Haproxy+OpenStack实现web application auto scaling [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-18 17:03 |只看该作者 |倒序浏览

用Haproxy+OpenStack实现web application auto scaling











今天介绍一下配合Haproxy实现Web application auto scaling。

在用OpenStack实施云计算之前,要实现应用的水平扩展,通常是用这样的架构:



一台Haproxy将动态请求转发到N台nginx服务器,当流量增加的时候,我们需要手工安装物理的服务器,将它添加到集群中去,然后再手工修改haproxy的配置,让它生效。就算用自动化的安装管理工具,这样扩展一台机器也差不多要3~4小时。

用OpenStack实施云计算之后,整个架构和上图是一样的,但是我们可以通过几十行代码在5分钟内实现auto scaling,来看一下具体的步骤:

首先,我们先在OpenStack上的一台虚拟机安装好nginx以及其他应用,然后对它做一个snapshot:



记录一下这个snapshot的ID:



接下来写一个脚本,能够用这个snapshot来自动的创建实例,因为我对Ruby比较熟悉,这里用Ruby的openstack-computegem 来写(OpenStack有多种客户端可以调用API,比如python,php):

Ruby代码
  1. require 'rubygems'  
  2. require 'openstack/compute'  
  3.   
  4. username = 'quake'  
  5. api_key = 'password'  
  6. auth_url = 'http://10.199.21.210:5000/v2.0/' #OpenStack keystone auth url   
  7. image_id = '9' #前面记录的snapshot ID   
  8. flavor_id = '1' #你想用的flavor对应的ID,这里用1,就是默认最小的1cpu, 512M内存的规格   
  9.   
  10. cs = OpenStack::Compute::Connection.new(:username => username, :api_key => api_key, :auth_url => auth_url)   
  11. image = cs.get_image(image_id)   
  12. flavor = cs.get_flavor(flavor_id)   
  13. #创建一个新的instance   
  14. newserver = cs.create_server(:name => "rails#{Time.now.strftime("%Y%m%d%H%M")}", :imageRef => image.id, :flavorRef => flavor.id)   
  15. p "New Server #{newserver.name} created"  
  16. #刷新instance的状态,直到它创建成功   
  17. while newserver.progress < 100   
  18.   p "Server status #{newserver.status}, progress #{newserver.progress}"  
  19.   sleep 10   
  20.   newserver.refresh   
  21. end  
  22. p "Server status #{newserver.status}, progress #{newserver.progress}"  
  23. p "Done"  

  24. require 'rubygems'
  25. require 'openstack/compute'

  26. username = 'quake'
  27. api_key = 'password'
  28. auth_url = 'http://10.199.21.210:5000/v2.0/' #OpenStack keystone auth url
  29. image_id = '9' #前面记录的snapshot ID
  30. flavor_id = '1' #你想用的flavor对应的ID,这里用1,就是默认最小的1cpu, 512M内存的规格

  31. cs = OpenStack::Compute::Connection.new(:username => username, :api_key => api_key, :auth_url => auth_url)
  32. image = cs.get_image(image_id)
  33. flavor = cs.get_flavor(flavor_id)
  34. #创建一个新的instance
  35. newserver = cs.create_server(:name => "rails#{Time.now.strftime("%Y%m%d%H%M")}", :imageRef => image.id, :flavorRef => flavor.id)
  36. p "New Server #{newserver.name} created"
  37. #刷新instance的状态,直到它创建成功
  38. while newserver.progress < 100
  39.   p "Server status #{newserver.status}, progress #{newserver.progress}"
  40.   sleep 10
  41.   newserver.refresh
  42. end
  43. p "Server status #{newserver.status}, progress #{newserver.progress}"
  44. p "Done"
复制代码
当需要扩展一台新的nginx instance时候,只需要执行上面的代码:
Shell代码
  1. # ruby create_new_server.rb   
  2. "New Server rails201112161042 created"  
  3. "Server status BUILD, progress 0"  
  4. "Server status ACTIVE, progress 100"  
  5. "Done"  

  6. # ruby create_new_server.rb
  7. "New Server rails201112161042 created"
  8. "Server status BUILD, progress 0"
  9. "Server status ACTIVE, progress 100"
  10. "Done"
复制代码
差不多30秒左右的时间(视你的镜像大小和网络速度),这台虚拟机就创建好了,我们可以在dashboard看到这台最新的机器:




接下去我们再写一个脚本,自动更新haproxy的配置文件:
Ruby代码
  1. cs = OpenStack::Compute::Connection.new(:username => username, :api_key => api_key, :auth_url => auth_url)   
  2. #预先定义一个haproxy template文件,backed server集群部分定义留空,将它拷贝过来   
  3. `cp haproxy.cfg.template haproxy.cfg`   
  4.   
  5. File.open('haproxy.cfg', 'a') do |f|   
  6.   cs.servers.each do |s|   
  7.     server = cs.server(s[:id])   
  8.     #如果该实例的镜像等于我们之前做的snapshot,将它的IP加入配置文件   
  9.     if server.image['id'] == image_id   
  10.       ip = server.addresses.first.address   
  11.       p "Found matched server #{server.name} #{ip}, add to haproxy"  
  12.       f.puts "        server #{server.name} #{ip}:80 maxconn 512"  
  13.     end  
  14.   end  
  15. end  
复制代码
#覆盖旧的haproxy配置文件,reload haproxy
  1. `cp haproxy.cfg /etc/haproxy.cfg`   
  2. p "Reload haproxy"  
  3. `/etc/init.d/haproxy reload`  

  4. cs = OpenStack::Compute::Connection.new(:username => username, :api_key => api_key, :auth_url => auth_url)
复制代码
#预先定义一个haproxy template文件,backed server集群部分定义留空,将它拷贝过来
  1. `cp haproxy.cfg.template haproxy.cfg`

  2. File.open('haproxy.cfg', 'a') do |f|
  3.   cs.servers.each do |s|
  4.     server = cs.server(s[:id])
  5.     #如果该实例的镜像等于我们之前做的snapshot,将它的IP加入配置文件
  6.     if server.image['id'] == image_id
  7.       ip = server.addresses.first.address
  8.       p "Found matched server #{server.name} #{ip}, add to haproxy"
  9.       f.puts "        server #{server.name} #{ip}:80 maxconn 512"
  10.     end
  11.   end
  12. end
复制代码
#覆盖旧的haproxy配置文件,reload haproxy
  1. `cp haproxy.cfg /etc/haproxy.cfg`
  2. p "Reload haproxy"
  3. `/etc/init.d/haproxy reload`
复制代码
执行该代码:
Shell代码
  1. # ruby update_haproxy.rb   
  2. "Found matched server rails201112161042 10.199.18.6, add to haproxy"  
  3. "Found matched server rails201112161003 10.199.18.5, add to haproxy"  
  4. "Found matched server rails201112160953 10.199.18.4, add to haproxy"  
  5. "Found matched server rails201112160924 10.199.18.8, add to haproxy"  
  6. "Found matched server rails201112160923 10.199.18.7, add to haproxy"  
  7. "Reload haproxy"  

  8. # ruby update_haproxy.rb
  9. "Found matched server rails201112161042 10.199.18.6, add to haproxy"
  10. "Found matched server rails201112161003 10.199.18.5, add to haproxy"
  11. "Found matched server rails201112160953 10.199.18.4, add to haproxy"
  12. "Found matched server rails201112160924 10.199.18.8, add to haproxy"
  13. "Found matched server rails201112160923 10.199.18.7, add to haproxy"
  14. "Reload haproxy"
复制代码
这样就实现了将刚刚创建的 rails201112161042 实例添加到了haproxy集群。

通过不到50行的代码,就实现了auto scaling,是不是很方便?我们还能够更自动化一些,配合监控脚本,设定一个指标,比如说当整个集群的CPU用量达到70%的时候,自动调用create_server,当CPU小于10%的时候,调用delete_server,这样就实现了按需scaling up/down.

1.png (11.75 KB, 下载次数: 55)

1.png

2.jpg (8.79 KB, 下载次数: 42)

2.jpg

3.jpg (6.53 KB, 下载次数: 43)

3.jpg

4.jpg (18.22 KB, 下载次数: 52)

4.jpg

论坛徽章:
0
2 [报告]
发表于 2011-12-19 21:17 |只看该作者
谢谢分享哦...抱走了

论坛徽章:
0
3 [报告]
发表于 2011-12-20 08:54 |只看该作者
这个帖子排版很专业、很好的啊。

论坛徽章:
0
4 [报告]
发表于 2012-11-01 15:43 |只看该作者
思路不错,没人顶啊

论坛徽章:
3
寅虎
日期:2013-11-27 07:53:29申猴
日期:2014-09-12 09:24:152015年迎新春徽章
日期:2015-03-04 09:48:31
5 [报告]
发表于 2012-11-01 21:44 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP