前言,關(guān)于融合共有云平滑擴(kuò)展Web服務(wù)器,是大多數(shù)中小互聯(lián)網(wǎng)想要做到的一個(gè)功能。這個(gè)功能的實(shí)現(xiàn)方式有多種方式,這里僅分享基于阿里云鏡像級平滑擴(kuò)展。
像擴(kuò)展服務(wù)器大多情況是手動部署擴(kuò)展機(jī)器,復(fù)雜又繁瑣出錯概率又高且效率低下。為此,為不改動業(yè)務(wù)的基礎(chǔ)之前,利用阿里云的OpenApi就可以簡單的實(shí)現(xiàn)業(yè)務(wù)平滑擴(kuò)展功能。減輕了運(yùn)維和業(yè)務(wù)方面的業(yè)務(wù)量突增帶來的問題服務(wù)器壓力問題,在服務(wù)器成本控制上也有良好的效果(按分時(shí)計(jì)費(fèi))。
那么,為了實(shí)現(xiàn)以上設(shè)想的功能一般來說,可以把思路分為以下幾個(gè)可操作的步驟:
0.通過阿里云OpenApi增加服務(wù)器資源
1.把當(dāng)前生產(chǎn)的服務(wù)器版本自動的發(fā)布到已增加的服務(wù)器上
2.通過發(fā)布腳本或者服務(wù)Check服務(wù)檢測即將要上線的服務(wù)器資源的服務(wù)可用性
3.服務(wù)器可用性檢查通過,然后再將已增加的服務(wù)器資源動態(tài)的加載到生產(chǎn)的負(fù)載均衡上提供生產(chǎn)服務(wù)
為了實(shí)現(xiàn)以上設(shè)想的功能一般來說,可以把思路分為以下幾個(gè)可操作的步驟:
0.通過阿里云OpenApi增加服務(wù)器資源
1.把當(dāng)前生產(chǎn)的服務(wù)器版本自動的發(fā)布到已增加的服務(wù)器上
2.通過發(fā)布腳本或者服務(wù)Check服務(wù)檢測即將要上線的服務(wù)器資源的服務(wù)可用性,再增加到Zabbix監(jiān)控
3.服務(wù)器可用性檢查通過,然后再將已增加的服務(wù)器資源動態(tài)的加載到生產(chǎn)的負(fù)載均衡上提供生產(chǎn)服務(wù)
上面已較粗略的描述了整個(gè)的擴(kuò)展流程,那么我們就不多廢話了。
下面就把關(guān)鍵的操作阿里云的部分OpenApi簡略功能腳本分享出來。
讓有需要做此功能的同學(xué)能夠簡化實(shí)踐之路。
通過阿里SDK操作OpenApi腳步如下:
# -*- coding: utf8 -*-
''''
### author by 天擎
This's smooth expansion script.
'''
import json,time,sys
from deployutils import *
import json
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkecs.request.v20140526 import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526 import StopInstanceRequest
from aliyunsdkecs.request.v20140526 import CreateInstanceRequest
from aliyunsdkecs.request.v20140526 import DescribeInstanceStatusRequest
from aliyunsdkecs.request.v20140526 import StartInstanceRequest
### define request auth
client = AcsClient(
"xxx",
"xxx",
"xxx"
)
###按時(shí)
InstanceType = {
'1c_1g': 'ecs.n1.tiny',
'2c_8g': 'ecs.sn2.medium',
'2c_16g': 'ecs.se1.large',
'4c_16g': 'ecs.sn2.large'
}
###按月
# InstanceType = {
# '1c_1g': 'ecs.n1.tiny',
# '2c_8g': 'ecs.sn2.medium',
# '2c_16g': 'ecs.se1.large',
# '4c_16g': 'ecs.sn2.large',
# '4c_32g': 'ecs.se1.xlarge',
# '8c_32g': 'ecs.sn2.xlarge',
# '8c_64g': 'ecs.se1.2xlarge',
# }
### create ecs
def createInstance(insName,hostName,diskCapacity):
if insName or hostName or diskCapacity:
ci = CreateInstanceRequest.CreateInstanceRequest()
ci.set_ZoneId('xxx')
ci.set_accept_format('json')
ci.set_HostName(hostName)
ci.set_ImageId('xxx')
ci.set_InstanceName(insName)
ci.set_InstanceType(InstanceType['4c_16g'])
ci.set_KeyPairName('inner')
ci.set_VSwitchId('xxx')
ci.set_SecurityGroupId('xxx')
ci.set_SystemDiskSize(diskCapacity)
try:
result = client.do_action_with_exception(ci)
rest = json.loads(result)
InsId = rest['InstanceId']
return InsId
except Exception ,e:
print e
return False
### check Instance status
def checkInsStatus(instanceID):
if instanceID:
istat = DescribeInstancesRequest.DescribeInstancesRequest()
istat.set_accept_format('json')
istat.set_InstanceIds(json.dumps(instanceID))
try:
istat_Json = json.loads(client.do_action_with_exception(istat))
inst_list = istat_Json.get('Instances').get('Instance')
return inst_list
except Exception ,e:
print e
return False
### start ecs
def startInstance(instanceID):
if instanceID:
startInt = StartInstanceRequest.StartInstanceRequest()
startInt.set_accept_format('json')
startInt.set_InstanceId(instanceID)
try:
client.do_action_with_exception(startInt)
except Exception ,e:
print e
return False
### start Instance
def batchCreateInstance(createNum=1,hostName=None):
createInsID=[]
if createNum<=1 and createNum>20:
print 'Instance number, Greater than 1 less than 20'
else:
for i in range(0,createNum):
hn = hostName + str(time.strftime("-%y%m%d%H%M"))
try:
isid = createInstance(insName=hn, hostName=hn, diskCapacity=200)
createInsID.append(isid)
except Exception,e:
print e
if createInsID:
return createInsID
else:
return False
### check ecs result
def checkStartResult(InsList):
if InsList:
InsAdd = []
InsInnerIPAdd = []
ilist = checkInsStatus(InsList)
for iInstance in ilist:
InsID = iInstance.get('InstanceId')
InsInnerIP = iInstance.get('VpcAttributes').get('PrivateIpAddress').get('IpAddress')
print InsInnerIP
iInstanceStatus = iInstance.get('Status')
if iInstanceStatus == 'Pending':
print ( InsID +" Pending")
InsAdd.append(InsID)
elif iInstanceStatus == 'Stopped':
print ( InsID +" Now Starting ...")
InsAdd.append(InsID)
startInstance(InsID)
elif iInstanceStatus == 'Starting':
InsAdd.append(InsID)
print (InsID + " Starting ...")
elif iInstanceStatus == 'Running' and InsInnerIP:
InsInnerIPAdd.append(InsInnerIP[0])
print (InsID + " Running")
return InsAdd,InsInnerIPAdd
### Create More Instances
def startingMoreInstance(num,hostname):
hostname = hostname
nodeList = batchCreateInstance(num,hostname)
# check instance result
while True:
InsListStatus = checkStartResult(nodeList)
if InsListStatus[0]:
#print InsListStatus
time.sleep(15)
else:
break
# get instance ips
if InsListStatus[1]:
return InsListStatus[1]
else:
return False
def addMonitor(ip):
if ip:
try:
from zabbix_tools import zabbix_tools
zb = zabbix_tools ()
zb.user_login ()
gid = zb.get_any_id (zb.get_grouphost (), 'groupid', 'xx-Server')
tid_master = zb.get_any_id (zb.get_templates (), 'templateid', 'xxx_Linux')
tid_fgc = zb.get_any_id (zb.get_templates (), 'templateid', 'Templates_auto_jvm_gc_status')
tid = "%s,%s" % (tid_fgc, tid_master)
pxid = zb.get_any_id (zb.get_proxy_id (), 'proxyid', 'Aliyun-Proxy')
z_rlt = zb.create_host (hostip=ip, groupid=gid, templateid=tid, proxyid=pxid)
z_rlt = json.loads (z_rlt)
if z_rlt['result']['hostids']:
print 'Add zabbix host completed.'
return True
else:
print 'Error: add zabbix host failed.'
return True
except Exception, e:
print e
else:
print 'IP is empty.'
return False
(ps:以上程序是較早前開發(fā),僅供學(xué)習(xí)參考。)