緣起
在每次
master
bulid
後都要去阿里雲 後臺手動刷新|預熱,此文章旨在優化發包繁瑣步驟
流程
實現
1. pip install aliyun-python-sdk-cdn
ps:這個SDK 和 下面的 代碼 是基於 python2 推薦2.7.16
Mac 的話 默認版本就是 python2
- Refresh.py 實現
#!/usr/bin/env python
# coding=utf-8
# __author__ = 'hanli.zyb'
'''Check Package'''
try:
import os, sys, getopt, time, json
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkcdn.request.v20180510.RefreshObjectCachesRequest import RefreshObjectCachesRequest
from aliyunsdkcdn.request.v20180510.PushObjectCacheRequest import PushObjectCacheRequest
from aliyunsdkcdn.request.v20180510.DescribeRefreshTasksRequest import DescribeRefreshTasksRequest
from aliyunsdkcdn.request.v20180510.DescribeRefreshQuotaRequest import DescribeRefreshQuotaRequest
except:
sys.exit("[Error] Please pip install aliyun-python-sdk-cdn and aliyun-java-sdk-core ,please install now......")
class Refresh(object):
'''init func'''
def __init__(self):
self.lists = []
self.param = {}
'''
描述:調度的主函數
resP:檢測入參結果,如果類型不是 bool 說明有報錯
'''
def main(self, argv):
if len(argv) < 1:
sys.exit("\nusage: " + sys.argv[0] + " -h ")
try:
opts, args = getopt.getopt(argv, "hi:k:n:r:t:a:o:")
except Exception as e:
sys.exit("\nusage: " + sys.argv[0] + " -h ")
for opt, arg in opts:
if opt == '-h':
self.helps()
sys.exit()
elif opt == '-i':
self.param['-i'] = arg
elif opt == '-k':
self.param['-k'] = arg
elif opt == '-r':
self.param['-r'] = arg
elif opt == '-t':
self.param['-t'] = arg
elif opt == '-a':
self.param['-a'] = arg
elif opt == '-o':
self.param['-o'] = arg
elif opt == '-n':
self.param['-n'] = arg
else:
sys.exit("\nusage: " + sys.argv[0] + " -h ")
resP = self.doCheck(self.param)
if not isinstance(resP, bool): sys.exit(resP)
try:
client = AcsClient(self.param['-i'], self.param['-k'], 'cn-hangzhou')
except NameError:
sys.exit("[Error]: SDK module not detected")
for g in self.doProd(self.param):
self.lists = []
self.doRefresh(''.join(g), self.param['-t'], client)
'''
描述:檢測入參數
'''
def doCheck(self, param):
try:
for key1 in ('-i', '-k', '-r', '-t'):
if not key1 in param.keys():
return "[Error]: {0} Must be by parameter".format(key1)
try:
if not param.has_key('-n'):
self.param['-n'] = 50
if not (abs(int(param['-n'])) <= 100 and abs(int(param['-n'])) > 0):
return "[Error]: 0 < -n <= 100"
else:
self.param['-n'] = int(param['-n'])
except ValueError as e:
return "[Error]: -n Must be int Type ,{0}".format(str(e))
if not param['-t'] in ("push", "clear"): return "[Error]: taskType Error"
if param.has_key('-a') and param.has_key('-o'): return "[Error]: -a and -o cannot exist at same time"
if param.has_key('-a'):
if not param['-a'] in ("domestic", "overseas"):
return "[Error]: Area value Error"
if param['-t'] == 'clear':
return "[Error]: -t must be push and 'clear' -o use together"
if param.has_key('-o'):
if not param['-o'] in ("File", "Directory"):
return "[Error]: ObjectType value Error"
if param['-t'] == 'push':
return "[Error]: -t must be clear and 'push' -a use together"
except KeyError as e:
return "[Error]: Parameter {0} error".format(str(e))
return True
'''
描述:生成器切分文件,對每行文件進行處理 '\n'
gop:每次讀取 URL 數量
'''
def doProd(self, params):
gop = params['-n']
mins = 1
maxs = 7
with open(params['-r'], "r") as f:
for line in f.readlines():
if mins != maxs:
line = line.strip("\n") + "\n"
else:
line = line.strip("\n")
self.lists.append(line)
if mins >= maxs:
yield self.lists
mins = maxs
maxs = gop + maxs - 1
else:
mins += 1
if len(self.lists) > 0: yield self.lists
'''
描述:刷新/預熱任務
'''
def doRefresh(self, lists, types, client):
try:
if types == 'clear':
taskID = 'RefreshTaskId'
request = RefreshObjectCachesRequest()
if self.param.has_key('-o'):
request.set_ObjectType(self.param['-o'])
elif types == 'push':
taskID = 'PushTaskId'
request = PushObjectCacheRequest()
if self.param.has_key('-a'):
request.set_Area(self.param['-a'])
taskreq = DescribeRefreshTasksRequest()
request.set_accept_format('json')
request.set_ObjectPath(lists)
response = json.loads(client.do_action_with_exception(request))
print(response)
while True:
count = 0
taskreq.set_accept_format('json')
print ('------')
print (type(response[taskID]))
print ('------')
taskreq.set_TaskId(int(response[taskID]))
taskresp = json.loads(client.do_action_with_exception(taskreq))
print("[" + response[taskID] + "]" + "is doing... ...")
for t in taskresp['Tasks']['CDNTask']:
if t['Status'] != 'Complete':
count += 1
if count == 0:
break
else:
continue
time.sleep(5)
except Exception as e:
sys.exit("[Error]" + str(e))
'''
描述:幫助信息
'''
def helps(self):
print("\nscript options explain: \
\n\t -i <AccessKey> 訪問阿里雲憑證,訪問控制檯上可以獲得; \
\n\t -k <AccessKeySecret> 訪問阿里雲密鑰,訪問控制檯上可以獲得; \
\n\t -r <filename> 文件名稱,每行一條 URL,有特殊字符先做 URLencode,以 http/https 開頭; \
\n\t -t <taskType> 任務類型 clear 刷新,push 預熱; \
\n\t -n [int,[..100]] 可選項,每次操作文件數量,做多 100 條; \
\n\t -a [String,<domestic|overseas> 可選項,預熱範圍,不傳是默認是全球;\
\n\t domestic 僅中國大陸; \
\n\t overseas 全球(不包含中國大陸); \
\n\t -o [String,<File|Directory>] 可選項,刷新的類型; \
\n\t File 文件刷新(默認值); \
\n\t Directory 目錄刷新")
# TODO 入口
if __name__ == '__main__':
fun = Refresh()
fun.main(sys.argv[1:])
2. 同級目錄準備 cnd.lst
地址文件
例如:
https://xx.xxxxx.xx/
3. 編寫Shell
腳本 re_cdn.sh
#!/bin/bash\
AccessKey="<***AccessKey***>"
AccessKeySecret="***AccessKeySecret***"
# clear | push
action="clear"
echo "開始執行cdn預熱刷新"
# python2 Refresh.py -i AccessKey -k AccessKeySecret -r ./cdn.lst -t action
python2 Refresh.py -i $AccessKey -k $AccessKeySecret -r ./cdn.lst -t $action
echo "刷新完成"
- 這只是個基本版 可以根據SDK參數來增加更多選項 參數如下⬇️
\n\t -i <AccessKey> 訪問阿里雲憑證,訪問控制檯上可以獲得; \
\n\t -k <AccessKeySecret> 訪問阿里雲密鑰,訪問控制檯上可以獲得; \
\n\t -r <filename> 文件名稱,每行一條 URL,有特殊字符先做 URLencode,以 http/https 開頭; \
\n\t -t <taskType> 任務類型 clear 刷新,push 預熱; \
\n\t -n [int,[..100]] 可選項,每次操作文件數量,做多 100 條; \
\n\t -a [String,<domestic|overseas> 可選項,預熱範圍,不傳是默認是全球;\
\n\t domestic 僅中國大陸; \
\n\t overseas 全球(不包含中國大陸); \
\n\t -o [String,<File|Directory>] 可選項,刷新的類型; \
\n\t File 文件刷新(默認值); \
\n\t Directory 目錄刷新")
4. 修改 package.json
來 執行 腳本
在 script 中 增加 recdn
"scripts": {
"serve": "vue-cli-service serve --port 8888 ",
"build": "vue-cli-service build",
"oss": "echo \"開始上傳...\n正在上傳請稍後...\" && node app.js && echo \"成功\"",
"recdn": "bash ./re_cdn.sh"
},
當然也可以直接把腳本寫在oss後面
"oss": "echo \"開始上傳...\n正在上傳請稍後...\" && node app.js && echo \"成功\"bash ./re_cdn.sh",
這樣在我們每次構建後 都會自動執行 oss 和 cdn 刷新任務