前言,关于融合共有云平滑扩展Web服务器,是大多数中小互联网想要做到的一个功能。这个功能的实现方式有多种方式,这里仅分享基于阿里云镜像级平滑扩展。
像扩展服务器大多情况是手动部署扩展机器,复杂又繁琐出错概率又高且效率低下。为此,为不改动业务的基础之前,利用阿里云的OpenApi就可以简单的实现业务平滑扩展功能。减轻了运维和业务方面的业务量突增带来的问题服务器压力问题,在服务器成本控制上也有良好的效果(按分时计费)。
那么,为了实现以上设想的功能一般来说,可以把思路分为以下几个可操作的步骤:
0.通过阿里云OpenApi增加服务器资源
1.把当前生产的服务器版本自动的发布到已增加的服务器上
2.通过发布脚本或者服务Check服务检测即将要上线的服务器资源的服务可用性
3.服务器可用性检查通过,然后再将已增加的服务器资源动态的加载到生产的负载均衡上提供生产服务
为了实现以上设想的功能一般来说,可以把思路分为以下几个可操作的步骤:
0.通过阿里云OpenApi增加服务器资源
1.把当前生产的服务器版本自动的发布到已增加的服务器上
2.通过发布脚本或者服务Check服务检测即将要上线的服务器资源的服务可用性,再增加到Zabbix监控
3.服务器可用性检查通过,然后再将已增加的服务器资源动态的加载到生产的负载均衡上提供生产服务
上面已较粗略的描述了整个的扩展流程,那么我们就不多废话了。
下面就把关键的操作阿里云的部分OpenApi简略功能脚本分享出来。
让有需要做此功能的同学能够简化实践之路。
通过阿里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"
)
###按时
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:以上程序是较早前开发,仅供学习参考。)