![4c6ea8cb08192071b799356beb09b973.png](https://i-blog.csdnimg.cn/blog_migrate/30c72da92025c5da94294cab0bf8de01.jpeg)
有任何疑问或者本文由任何不准确的地方,欢迎留言评论。
本文约3500字,操作时间约5分钟,阅读时间约7-15分钟。
先决条件:
(搭建图床)一个云服务商的账号及订阅, 例如微软Azure,阿里云及亚马逊AWS等。本文使用的是Azure for Students, 学生每年可以有100刀的额度,其他各个平台也有对应的学生订阅。如没有魔法上网的能力,建议使用国内的阿里云。关于注册账号请直接移步谷歌/必应。
(图片自动上传)支持自定义命令上传图片至图床的Markdown编辑器。本文使用的是Typora。
本文使用的系统是macOS 10.15, Python版本为3.8.5
如使用其他云服务商,可参照本文进行编程,需要更改调用的API,使用Azure可以直接复制本文的脚本。
在利用Markdown写博客时,应当避免直接引用本地的图片,因为本地的路径下的图片在网站上是不可见的。而逐个上传到各个平台和个人网站的话又浪费了markdown排版的便利性,我之前用的方法一直是手动将图片上传到我网站的WordPress的图库里然后再手动复制URL粘贴到md文件里, 但是这样的方法耗时又繁琐。了解到Typora支持图床自动上传之后,为了提高效率(/偷懒)便开始着手研究。考虑到马上会停止使用WordPress转而自己搭建网站,也就顺便把图床服务器一起搭了。至于为什么不用七牛云这类成熟的图床提供商,很简单,就是想用自己搭的图床(还有Azure的额度不用白不用)。
文章会分为两个部分,第一部分为操作步骤,按步骤可以直接完成项目的搭建,第二部分为细节讲解,主要讲解步骤中一些选项的选择方法和相关原理,不感兴趣可以直接跳过。
第一部分 操作
搭建图床
登录云服务商账号并进入相关的管理界面,选择储存Storage。
Azure为 右侧中Storage accounts, 阿里云为OSS存储或类似,其他云相似。
![88c620eb76a174d1964f71b4b8277c66.png](https://i-blog.csdnimg.cn/blog_migrate/836f53016a8d484a6dee2c6245f6980d.jpeg)
新建存储账号,对账号进行相关设置,服务器位置建议选一个离常用位置较近的。
Azure直接按照图片中设置即可,其他云可参照第二部分的讲解找到相关设置。
注意Azure Storage Account Name只能用小写字母和数字。
重要的设置已在图上显示出来,其他的保持默认即可。
![fb47b0c24be7449cfa0ef1c265a8ac29.png](https://i-blog.csdnimg.cn/blog_migrate/94fe72d69e35c5008c4f26f1676c8be3.jpeg)
![e434028497cb74a070ea0032fa51e0b2.png](https://i-blog.csdnimg.cn/blog_migrate/19930d20aabb83d51a29e279aae25619.jpeg)
获取相应Api的Access Key, 一般都在账户的设置中,并复制保存。
Access Key也可能有其他名称,总体来说就是一个用于验证访问时身份的密钥。
对于Azure来说,在调用Api时,Connection String比Access Key更好用,所以直接复制Connection String即可。
![193bd945d74036b25a667023d0ffd5ed.png](https://i-blog.csdnimg.cn/blog_migrate/77f80b6c536af36dc137fb412fed5560.jpeg)
获取相应的URL,一般都在账户的设置中,并复制保存。
![c8a1c6f2d746d27a95a59bc8ba660a97.png](https://i-blog.csdnimg.cn/blog_migrate/575ea391ee47f989d2ba0cc6a8d36e3c.jpeg)
自动上传
以下脚本仅支持Azure!其他云服务商的用户可参照更改。
Windows用户可能要稍作修改(主要为Split Path由'/'
改为''
.
获取相关API,一般可以在云服务商(Azure) 的文档中找到,并安装相关包。
以Azure为例,在终端中输入 pip install azure-storage-blob
或者 pip3 install azure-storage-blob
在本地新建一个.py文件,将以下代码写入并记住其路径。
#!/usr/local/bin/python3
# author: timkhuang
import argparse,re
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient, PublicAccess
from azure.core.exceptions import ResourceExistsError
# Parse commandline arguments
parser = argparse.ArgumentParser(description="Upload image to the Azure Image Host.")
parser.add_argument("-u", "--url", help="The public url to access the resources and the final url will be print.(Account Level)")
parser.add_argument("Container",help="The Container which the file will be uploaded to.")
parser.add_argument("ConnStr", help="The Azure Storage Account Connect String.")
parser.add_argument("File", nargs='+', help="The file to be uploaded. Must Include at least one.")
args = vars(parser.parse_args())
name_regex = re.compile('[^a-z0-9]') # Make sure container name follows the azure rule.
url = args["url"]
container_name = name_regex.sub('-', args["Container"].lower())
connection_string = args["ConnStr"]
file_collection = args["File"]
# Create container if not exist.
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
try:
container = blob_service_client.create_container(container_name)
container.set_container_access_policy({}, public_access=PublicAccess.Blob)
except ResourceExistsError:
pass
# Upload
for path in file_collection:
file_type = path.split(".")[-1]
blob_name = name_regex.sub('-', path.split("/")[-1].lower())+"."+file_type
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)
with open(path, "rb") as data:
blob_client.upload_blob(data)
if url:
print(url + container_name + "/" + blob_name)
进入Typora的偏好设置,在Image中选择Uploader为Custom Command,并在Command输入框输入以下文字。
相关内容需要根据账户内容进行修改
所有引号均为英文单引号,请勿省略或者使用双引号。python3 上文自动上传第二步的文件地址 -u '上文中搭建图床第四步URL' ${filename} '上文中搭建图床第三步Access Key'
![9c75241ae00dd55802ea4f4cde192c67.png](https://i-blog.csdnimg.cn/blog_migrate/b6e7c0bdb480be7d2894011c088b34f0.png)
在做完以上所有步骤之后就可以直接拖动到Typora正在写的文章中了,会自动将本地图片上传到图床并在本地使用相关URL引用。效果类似于下图。
![8fb3215b031af0be4d62f48db7d32513.png](https://i-blog.csdnimg.cn/blog_migrate/83d374b92a58443ee4781672e4afb0cb.png)
第二部分 详解
新建存储账号设置
Account Kind 账号种类
Azure Blob是微软的的对象存储方案,这是针对储存大量非结构化数据优化的云存储。非结构化指的是不符合特定的模型比如Table。文字和二进制数据就是典型的例子。(图片属于二进制数据)由于这个只是被用来搭建图床并不需要诸如Table或者Disk这样的存储,所以直接选择BlobStorage即可。
也有想过把图床变的和本地文件夹一样各个文件夹里有图片和子文件夹,然后同一个博客的图片都在同一个字文件夹里面,但是这就带来了几个问题。第一个就是每次截图之后都需要重新命名并摆放到对应文件夹,这就违背了自动上传的初衷,因为本质上拖动到本地文件夹和拖动到网站图库并没有操作上的区别。第二个是博客内的图片一般也不会用到第二次,也就是说很少会出现一张图片使用多次的情况,既然不会频繁使用那么按照文件夹结构化存储方便寻找的优势也就不大。并且,在Azure Blob中,每一个Storage可以有很多Container,不同的Blob文件可以归类在同一个Container中,这样以每篇文章为Container,文章内的图片都储存在此中,也做到了有序。
Replication 备份
![0ec171817ae66503e0c172e3ef7993a4.png](https://i-blog.csdnimg.cn/blog_migrate/151526909ea6508999b9760f69448569.png)
Azure Storage目前对于数据的备份有6种方案,但由于Blob不能选择Premium Performance,有些并不可用,在这里也一并讲下。
首先备份可以分为两大类:
-
- 只在一个区域进行储存和备份即Primary Region
- 在两个不同的区域进行储存和备份即Primary Region & Secondary Region
两种类型的区别就在于第二种会在数百英里外的第二个区域对数据进行备份,这样就可以保证及时在Primary Region遭受区域性的灾害的时候,Azure就会通过修改DNS让Secondary Region变成新的Primary Region。这样就把数据的安全性从第一类的至少99.999999999%(11个9)提升到了99.99999999999999%(16个9)。
然后每一类又可以分为两类:
-
- 只在同一个Zone进行3次备份
- 在用一个Region不同的3个Zone进行备份
这与刚刚的分类差别不大,只不过这一次不同的Zone距离较近,但也可以保证不同的Zone有独立的供电散热和网络。另外与之前不同的是这3个的备份是同步的,也就是即使是不同的Zone也是事实同步的数据。但Secondary Region的同步则会有延迟(这也就导致了如果还没有同步到Secondary Region的数据有可能会丢失)。另外,需要注意的是Secondary Region只能是在一个Zone进行三次备份。这次可以将安全从99.999999999%(11个9)提升到99.9999999999%(12个9)。
以上两种组合遍形成了4种不同的备份方案:
-
- Locally-redundant storage LRS
- Zone-redundant storage ZRS
- Geo-redundant storage GRS
- Geo-zone-redundant storage GZRS
geo为利用Secondary Region进行备份,zone-redundant为在3个不同的zone进行备份。在利用Secondary Region进行冗余备份的时候,Secondary Region是不可以直接被访问的,也就是说只能从Primary Region failover到Secondary Region。为了随时访问Secondary Region的需求,又衍生出了Read-Acces-geo-redundant storage(RAGRS) 和Read-access-geo-zone-redundant storage(RAGZRS)。由于所有的zone-redundant只对Premium Performance开放,故BlobStorage只能选择LRS,GRS 和 RAGRS。综合考虑数据安全和需求,上文选择的是GRS备份。
![20b7536578582926422e246ec1026fa6.png](https://i-blog.csdnimg.cn/blog_migrate/62c73e5d1eac85b4b2c6f8d7c68434c8.jpeg)
Blob Access Tier 访问等级
Blob对象存储被分为3种等级:
-
- Hot: 需要经常性的被访问,
- Cool:大约30天才需要被访问一次,
- Archive:大约180天才需要被访问一次。
在这三种里面,Cool和Archive是利用单次访问的延迟和成本去换取储存的成本。在账户设置时选择的Tier并非最终选择,只是在每次新储存内容并且没有指定具体Access Tier时的默认值。当储存内容并且指定了相关的Tier时,以具体的设置为准。
- Networking 网络
对于网络来说,最重要的就是一定要选择Public endpoint即所有公共网络均可访问,由于搭建的是图床,可能会在各个平台上使用,读者可能从各个IP去访问这个图片,所以指定IP访问和内网访问都是不可取的。
此处Network Routing是Azure的一个选项,区别就在于一个是从请求的地方尽快进入最近的微软网络并在微软网络里找到这个图片,而另一个是指通过互联网将请求发送到图床服务器所在位置再从那进入微软网络。对于图床这种延迟要求不高的来说,区别不大,保持默认即可,其他云服务商同理。 - 其他
Soft Delete等数据保护对于图床来说其实没那么重要,因为搭建的是自动上传的图床,其中基本没有涉及到任何的删除操作。偶尔上传错误的一两张图片也不用删除,直接删除文章里的引用即可,错误照片放在图床上也没什么大的影响。既然不会涉及到删除,那么删除之后一段时间内可恢复的功能也就不是特别需要。
脚本上传
上传流程
在用户将一张图片拖动到文章之后,Typora会运行上文中所写的Command, 并且在最后加上图片的路径。之后Python脚本开始运行,首先会解析Command里的参数,使用的是argparser
这个包,而参数中的Connection String和URL之所以不写入第一是为了保证安全,在分享脚本时不会包含相关的账户信息,第二也是保持了脚本的独立性,其他地方也可能会用到这个脚本。参数中${filename}
在实际运行时会被Typora转换成当前编辑文档的名称。之后脚本会通过Connection String建立连接然后试图创建一个新的Container,并通过set_container_access_policy
来将这个Container设置为public。(只公开Blob是值单独的Blob文件均可以被直接访问但是Container并不可以在未授权的情况下被遍历或者访问。)此步骤如果出错,就代表相关Container已经建立,后文直接使用即可。Regex的作用在此是确保名称符合Azure的相关规范, 即小写字母数字和连字符。上传后,会将URL输出在Stdio
中,Typora会读取URL并插入到文章中
Cool 操作
在脚本编写之后,可以用chmod a+x
对脚本做权限更改,但注意更改文件第一行的interpreter。好处是可以省去Typora Command中的第一个单词Python3
.(/摊手)
以上就是本文的全部内容,感谢阅读。欢迎关注支持点赞以获得后续更多的文章教程。
作者timkhuang,未经授权不得转载,如需转载请联系作者。
引用
- Create an Azure Storage account ( https://docs.microsoft.com/en-gb/azure/storage/common/storage-account-create?tabs=azure-portal )
- Azure Storage redundancy ( https://docs.microsoft.com/en-gb/azure/storage/common/storage-redundancy )
- Disaster recovery and storage account failover ( https://docs.microsoft.com/en-gb/azure/storage/common/storage-disaster-recovery-guidance )
- Azure Blob Storage: hot, cool and archive access tier ( https://docs.microsoft.com/en-gb/azure/storage/blobs/storage-blob-storage-tiers?tabs=azure-portal#pricing-and-billing )
- Manage Blobs with Python V12 SDK (https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-python )
- Azure Storage Blob Package ( https://docs.microsoft.com/en-us/python/api/azure-storage-blob/azure.storage.blob?view=azure-python )