据用过阿里云、aws、vultr的朋友介绍,海外服务器现在比较推崇vultr,理由是按时计费合理,调用api创建/销毁/重启实例方便,每个实例可添加2个额外IP(适合爬虫等),售后服务不错。价格也可以,每月5刀那种配置能满足不少场景需求。
比较有经验的朋友会将vultr跟阿里云配合用,比如搞爬虫时,阿里云是调度、数据中心,vultr是提供资源干活的。开始用vultr源起于某段时间搞爬虫的痛点,各种被403/503,买了代理库的代理信息,但用着很不爽,可用率比较低,能用的没多久也down掉了。后来在知乎搜VPS用发现了vultr,开始试用。按小时计费,有比较完善的api,研究了下api用python写了管理脚本,批量创建、销毁实例十分方便,用起来实在太爽。跑过爬虫的应该知道IP的重要性,vultr干这个效率很高。每个实例可添加2个额外IP,不过额外收费,且需额外配置。
机房连接速度方面,如果用北京联通上网,一开始测了洛杉矶、日本的感觉日本的稍快些,用着也不错,过几天开第二个账号发现日本的各种连接问题,大致40%的实例创建后ping不通,开ticket跟工作人员沟通了很久,最终确认问题还是在我们这边,美国的也有类似问题;再后来发现悉尼的连接稳定性很好,且速度不错,用bypy往百度云传文件均速大约2M(不确定是我开的那台比较好还是普遍这样,后来没往百度云传过东西了),于是用api直接开了30台在悉尼,全部工作顺利。
python管理脚本,有意用的同学可以修改下用。我限制了只能在我阿里云机器的网段使用api,所以调用了代理(阿里云上的shadowsocks)访问api,再就是新建的实例会运行账号下的script脚本,脚本会完成环境配置、从阿里云上用git把代码clone下来、启动核心程序等工作。
script:
##### init setcp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime##### installapt-get update apt-get -y upgrade apt-get install -y gcc tmux vim git python-dev python-pip libxml2-dev libxslt1-dev libmysqld-dev pip install lxml beautifulsoup4 shadowsocks mysql-python pysocks netifaces pip install --upgrade requests##### dirscd /root##### ssh# pemwget http://example.com/skey.txt mv skey.txt id_rsa_1024_aliyun.pem chmod 0400 id_rsa_1024_aliyun.pem# configwget http://example.com/sshconfig.txt cat sshconfig.txt > ~/.ssh/config rm sshconfig.txt# known_hostswget http://example.com/knownhost.txt cat knownhost.txt > ~/.ssh/known_hosts rm knownhost.txt##### sswget http://example.com/sslocal.txt mv sslocal.txt sslocal.json sslocal -c sslocal.json &##### gitmkdir appcd app git clone ssh://aliyun/~/app/crawlercd crawler cp dat/cookie_tmpl.dat dat/cookie.dat##### workpython regHost.py reg python crawler.py 1 python regHost.py unreg
vultr.py
# coding: utf-8import sys, requests, socket# 自己写的日志类from Utils import loggingimport platformif platform.platform().startswith("Windows"):
import win_inet_ptonclass VultrManager():
def __init__(self, account):
self.name = socket.gethostname()
self.proxies = {"http": "socks5://127.0.0.1:1081", "https": "socks5://127.0.0.1:1081"}
if account == "account1":
key = "key of account1"
self.SSHKEYID = "57bbfc97ae887"
self.SCRIPTID = 21252
elif account == "account2":
key = "key of account2"
self.SSHKEYID = "57c8e90240e81"
self.SCRIPTID = 21554
self.api = {"API-KEY": key}
def listServers(self):
url = "https://api.vultr.com/v1/server/list"
res = requests.get(url, headers = self.api, proxies = self.proxies)
servers = res.json()
return servers
def getServerInfo(self, mid):
servers = self.listServers()
for server in servers:
serverId = server
hostname = servers[serverId]["label"]
hostId = hostname.split("-")[-1]
if hostId == mid:
for info in servers[serverId]:
print info + "\t" + str(servers[serverId][info])
def getServersInfo(self):
infos = []
servers = self.listServers()
for server in servers:
serverId = server
hostname = servers[serverId]["label"]
ip = servers[serverId]["main_ip"]
info = [serverId, hostname, ip]
infos.append(info)
print serverId + "\t" + hostname + "\t" + ip
return infos
def getOneId(self, mid):
servers = self.listServers()
for server in servers:
serverId = server
hostname = servers[serverId]["label"]
hostId = hostname.split("-")[-1]
if hostId == mid:
return serverId, hostname
return None, None
def createOne(self, mids):
if not type(mids) == list:
mids = [mids]
url = "https://api.vultr.com/v1/server/create"
serverId = None
for mid in mids:
name = hostGroup + "-" + str(mid)
argvs = {
"DCID": 19,
"OSID": 160,
"VPSPLANID": 29,
"SCRIPTID": self.SCRIPTID,
"SSHKEYID": self.SSHKEYID,
"hostname": name,
"label": name
}
res = requests.post(url, headers = self.api, data = argvs, proxies = self.proxies)
if res.status_code != 200:
log = "create server " + name + " failed, " + res.text
logging("e", log)
else:
serverId = res.json()["SUBID"]
log = "server " + name + " created, its id is " + serverId
logging("i", log)
return serverId
def createMany(self, start, end):
for i in range(start, end+1):
self.createOne(i)
def destroyOne(self, mids):
if not type(mids) == list:
mids = [mids]
result = None
for mid in mids:
serverId, hostname = self.getOneId(mid)
url = "https://api.vultr.com/v1/server/destroy"
data = {"SUBID": serverId}
res = requests.post(url, headers = self.api, proxies = self.proxies, data = data)
if res.status_code == 200:
log = hostname + " destroyed"
logging("i", log)
result = True
else:
log = "Failed, status code: " + str(res.status_code)
return result
def rebootOne(self, mids):
if not type(mids) == list:
mids = [mids]
result = None
for mid in mids:
serverId, hostname = self.getOneId(mid)
url = "https://api.vultr.com/v1/server/reboot"
data = {"SUBID": serverId}
res = requests.post(url, headers = self.api, proxies = self.proxies, data = data)
if res.status_code == 200:
log = hostname + " rebooted"
logging("i", log)
result = True
else:
log = "Failed, status code: " + str(res.status_code)
return result
def destroyMe(self):
hostId = self.name.split("-")[-1]
serverId, hostname = self.getOneId(hostId)
if not serverId:
log = "can not find you, misson failed"
logging("e", log)
return
else:
sd = self.destroyOne(hostId)
return sd
def destroyAll(self):
servers = self.getServersInfo()
for server in servers:
serverId, hostname, ip = server
hostId = hostname.split("-")[-1]
self.destroyOne(hostId)
def rebootAll(self):
servers = self.getServersInfo()
for server in servers:
serverId, hostname, ip = server
hostId = hostname.split("-")[-1]
self.rebootOne(hostId)
def updateScript(self):
url = "https://api.vultr.com/v1/startupscript/update"
with open("vultr.sh", "r") as f:
script = f.read()
data = {
"SCRIPTID": self.SCRIPTID,
"name": "default",
"script": script
}
res = requests.post(url, headers = self.api, proxies = self.proxies, data = data)
if res.status_code == 200:
log = str(self.SCRIPTID) + " updated"
logging("i", log)
else:
print res.status_codeif __name__ == "__main__":
hostGroup = "yourgroup"
account = sys.argv[1]
mode = sys.argv[2]
vultrManager = VultrManager(account)
if mode == "ia":
vultrManager.getServersInfo()
elif mode == "io":
mid = sys.argv[3]
vultrManager.getServerInfo(mid)
elif mode == "co":
mids = []
for i in range(len(sys.argv)-3):
mid = sys.argv[i+3]
mids.append(mid)
vultrManager.createOne(mids)
elif mode == "cm":
mid_s = int(sys.argv[3])
mid_e = int(sys.argv[4])
vultrManager.createMany(mid_s, mid_e)
elif mode == "do":
mids = []
for i in range(len(sys.argv)-3):
mid = sys.argv[i+3]
mids.append(mid)
vultrManager.destroyOne(mids)
elif mode == "dm":
vultrManager.destroyMe()
elif mode == "da":
vultrManager.destroyAll()
elif mode == "ro":
mids = []
for i in range(len(sys.argv)-3):
mid = sys.argv[i+3]
mids.append(mid)
vultrManager.rebootOne(mids)
elif mode == "ra":
vultrManager.rebootAll()
elif mode == "us":
vultrManager.updateScript()









442956988