关于阿里云oss:golang使用阿里云OSS对象存储

概念Bucket:存储空间Object:文件ObjectKey:文件名,文件的惟一标识,与Key、ObjectName为同一概念Region:地区,OSS数据中心的地理位置Endpoint:域名AccessKey:密钥,由AccessKey ID和AccessKey Secret组成计费总费用 = 存储费 + 长期存储费 + 数据取回费 + 流量费 + 申请费 + 其他费用 一、存储费存储费 = 文件大小(GB) x 单价 ÷ 30 ÷ 24 x 存储时长(hour) 存储类型单价规范-本地冗余0.12规范-同城冗余0.15低频拜访-本地冗余0.08低频拜访-同城冗余0.10归档0.033冷归档0.015最贵的规范存储的单价是最便宜的冷归档存储的8倍。存储一个大小为1G的文件每月须要领取0.12元的存储费。二、长期存储费长期存储费 = 文件大小(GB) x 单价 ÷ 30 ÷ 24 x 冻结时长(hour) 存储类型单价冷归档0.12冷归档文件在冻结期间,须额定领取一笔依照规范存储单价计算的长期存储费用。三、数据取回费数据取回费 = 文件大小(GB) x 单价 存储类型单价规范0低频拜访0.0325归档0.06冷归档0.03~0.2四、流量费流量费 = 流量(GB) x 单价 流量方向单价上传0内网下载0外网下载(0-8)0.25外网下载(8-24)0.50CDN回源下载0.15跨区域复制(中国大陆)0.50外网下载(0-8)0.25上传收费,下载免费。一个大小为1G的文件,每下次1次,须要领取0.25元的流量费。五、申请费申请费 = math.Ceil(申请次数/10000) x 单价 申请类型规范低频拜访归档冷归档PUT0.010.10.10.1GET0.010.10.10.1取回///0.3 ~ 30冷归档文件的取回申请每一万次需领取30元的申请费。六、其他费用跨区域文件复制流量费、图片处理费、图片压缩费、视频截帧费、标签费、传输减速费、DDoS防护费、元数据管理费、敏感数据保护费等等。 存储类型规范 + 低频 + 归档 + 冷归档。 比照指标规范低频归档冷归档最小计量单位064KB64KB64KB最小存储时长030天60天180天拜访提早001min1-12hour数据取回费用030天60天180天URL公共:<Schema>://<Bucket>.<Endpoint>/<Object>公有:<Schema>://<Bucket>.<Endpoint>/<Object>?签名信息 BucketCRUDBucket创立后不反对批改,所以只有CRD,没有U。 package mainimport ( "fmt" "os" "github.com/aliyun/aliyun-oss-go-sdk/oss")func main() { // 创立OSSClient实例。 // yourEndpoint填写Bucket对应的Endpoint。 // 以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。 client, err := oss.New( "yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret", ) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // 新增 err = client.CreateBucket( "examplebucket", oss.StorageClass(oss.StorageIA), oss.ACL(oss.ACLPublicRead), oss.RedundancyType(oss.RedundancyZRS) ) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } /* StorageClass:存储类型。 StorageStandard=规范存储 StorageIA=低频拜访 StorageArchive=归档存储 StorageColdArchive=冷归档存储 ACL:拜访权限。 ACLPrivate=公有 ACLPublicRead=公共读 ACLPublicReadWrite=公共读写 RedundancyType:冗余类型。 RedundancyLRS=本地冗余 RedundancyZRS=同城冗余 */ // 查问 marker := "" for { lsRes, err := client.ListBuckets(oss.Marker(marker)) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } // 默认状况下一次返回100条记录。 for _, bucket := range lsRes.Buckets { fmt.Println("Bucket: ", bucket.Name) } if lsRes.IsTruncated { marker = lsRes.NextMarker } else { break } } // 查问Region ID regionID, err := client.GetBucketLocation("examplebucket") if err != nil { fmt.Println("Error:", err) os.Exit(-1) } fmt.Println("Bucket Location:", regionID) // oss-cn-shanghai /* Region ID能够了解为Endpoint的前缀: 外网Endpoint:oss-cn-shanghai.aliyuncs.com 内网Endpoint:oss-cn-shanghai-internal.aliyuncs.com */ // 删除 err = client.DeleteBucket("examplebucket") if err != nil { fmt.Println("Error:", err) os.Exit(-1) }}生命周期通过设置生命周期,能够实现定期将Bucket内的Object转换存储类型,或者将过期的Object和碎片文件删除,进而升高存储费用。 ...

August 19, 2022 · 7 min · jiezi

关于阿里云oss:如何设计一条稳定的应用交付流程

大家好,我叫王泊,负责云效应用交付AppStack的开发。把利用部署到各个环境、一步步进行集成测试,最终公布到生产环境,是程序员工作中必不可少的组成部分;而云原生技术引入的容器化、IaC(基础设施即代码,Infrastructure as Code)等等技术与理念,为继续交付的过程提供了规范化的可能,但也引入了让人不断埋首于配置文件的小山里的麻烦。咱们无妨从一次略有挫折、稍显隐患的集成部署案例开始,看看如何着手设计一条更为稳固的利用交付流程。 一次挫折的部署许多个迭代后,面对陪风扇一起嘎吱嘎吱转着的流水线,程序员阿伟会回忆起把零碎部署到预发环境、提交最初一轮验收,而后被打回来的那个并不边远的下午。过后他有一个酷炫的Java SpringBoot利用要上线,实现了酷炫的“在不同部署环境下、发送带环境路由标签的业务音讯”的接口: 日常环境的镜像构建、部署和验收测试一路OK,然而在再次构建部署到预发环境后,阿伟发现音讯丢了:预发环境的生产方并没有生产到音讯。通过一系列不论黑屏白屏康到bug就是好屏的排查,发现问题起源于在预发环境应用的SpringBoot配置文件application-staging.yaml中漏配了routing.env属性,利用启动时应用了缺省配置application.yaml中的兜底值,导致音讯tag打错。 具体的问题倒是解决了,不过多少会留下点顾虑:当前写配置项的时候,免不了翻来覆去diff一下,是不是漏了什么,会不会导致各个环境里的产物有奥妙的构造差别引发bug…… 旧交付形式的潜在问题依然以SpringBoot利用为例,一部分开发者将利用从传统的虚机部署迁徙到Kubernetes上的容器化部署时,会应用相似上面的思路: 框架提供了为不同环境编写不同application.yaml配置文件的机制,用以达到环境差异化部署的成果。咱们不难构陷出小故事的主人公阿伟也应用了相似的思路: ● 应用application.yaml提供所有环境的共性(和一部分兜底)配置;● 各环境的差异化配置由独自的application-xxx.yaml给出,笼罩兜底配置;各差异化配置不作特地的标准要求,容许属性取值不同,也容许引入某个环境特有的属性值;● 为不同环境的镜像编写不同的Dockerfiles, 环境配置方面的差别次要在于启动利用时指定的参数不同。 一个典型的工程目录看起来像是这样: 看起来很规整,但其实也引入了一些问题: ● 环境差异化配置须要靠人工核查来缩小错漏,编写application.yaml这类基准配置的时候也须要慎重考虑提供什么样的兜底值,一旦有过错则排查老本绝对高;● Dockerfile往往没有很大的差别,但构建进去的产物是和具体环境强绑定的,没方法复用;屡次编译可能因为某些隐患(最典型的比方依赖版本不严格)导致不同环境下的交付内容并不统一,有引入bug、导致线上问题的危险。  ○ 比方在日常环境下实现构建后,某个(可能是间接)依赖的快照包被更新了(可能是不标准的快照包更新,也可能是平安包之类抉择偏向于让接入方无感降级而应用快照版本当作release);尔后部署到预发环境时,构建援用了新版本的依赖包,导致日常环境下的测试验收论断可信度降落。 单利用逐环境升级计划的考量吃一堑长一智,咱们无妨帮阿伟的利用公布计划列出上面的考量: ● 产物对环境中立:环境差异化配置在部署时注入,一份镜像能够用于所有环境的部署。● 环境配置对立:所有环境应用同样格局的配置模板和差异化的值注入,防止“兜底+笼罩”引入的配置模板差异。 具体来说,在“日常-预发-生产”的整条集成公布流程中,应用的镜像和编排只有一份;镜像中的SpringBoot利用里,也只应用application.yaml,不再引入其余差异化配置。 这样做看起来限度了一些灵活性,但外围思考在于:通常状况下很难标准配置文件和编排的具体格局;一旦存在“一份配置兜底+多份差异化调整”的状况,了解利用代码逻辑和部署细节的老本会变高,保护、验证应用逻辑所需了解的内容也随配置文件的减少而线性增长。即便是利用的设计者或是owner,也不免随着时过境迁而遗记一些细节(“我过后为什么要加这个环境变量来着”),更不必提中途退出进行性能迭代的其余开发人员了。 理论部署到Kubernetes集群中时,环境变量通过编排中容器的环境变量注入。接下来须要对立Deployment编排——如果为不同的环境应用多份编排文件,依然会引入无意义的反复。这里咱们能够应用Helm chart的模式,诸如镜像、环境变量等等在构建部署时能力决定的差异化配置,都能够通过values配置进行注入: 须要定制化的局部,则是CICD零碎中动静生成Values.yaml配置的脚本。这部分的复杂性绝对容易管制,具体的实现则依据应用的CICD工具不同而略有差别,咱们将会在后文中看到一个概况的示例。 计划革新例当初能够回到阿伟的服务上进行革新了。 Step 1: 对立application.yaml和Dockerfile 首先咱们要压缩服务中的SpringBoot application yaml配置,只留下一份: 这里应用了占位符${DEPLOY_ENV},要求环境变量提供routing.env的值。 Dockerfile则能够去掉所有环境差异化的环境变量定义、对立为一份配置,并假设环境变量都曾经正确注入。 Step 2: 编写Helm chart 从创立一份空的helm chart开始: 接下来,能够把原先的编排文件依照helm模板的格局简略改写,搁置到cool-service-chart/templates/目录下。以Deployment为例: 咱们应用.Values.image这一helm占位符将镜像注入容器。环境变量注入的形式则有多种——变量较少的状况下能够在pod template中间接定义name和value;不过如果思考到更久远的扩展性,也能够采纳关注点拆散的形式,独自定义一份ConfigMap用于定义环境变量;这样做的益处,则是增加环境变量的开发者无需了解Deployment的具体构造,甚至只须要了解“往ConfigMap的数据定义里写一个键值对就能实现环境变量注入”就能够了。 基于这些思考,咱们定义容器应用上面的ConfigMap提供键值对、注入环境变量: Chart里的模板编写实现后,记得推送到一个git库里,不便前面应用。 Step 3: 编写Values.yaml生成脚本 在筹备好Helm chart的动态模板局部之后,须要为CICD工具编写部署时生成Values.yaml的脚本。咱们无妨假如阿伟的团队抉择应用Jenkins建设CICD流水线: 这里咱们次要关注chart-complete.sh,它须要实现如下的工作: ● 从git仓库克隆chart库的骨干;● 从环境变量中,生成values.yaml. ...

April 18, 2022 · 1 min · jiezi

关于阿里云oss:阿里云OSS图床搭建

阿里云OSS图床搭建介绍过来介绍过Gitee的图床搭建,用了一年多都挺稳固了,访问速度尚可,然而2022年开始发现不是很稳固,并且局部网站会发现“图片隐没”的状况,F12看一下发现是很多外国网站给间接302长期重定向了。 所以为了保障数据安全,这里无奈只能掏钱买阿里云的 OSS做图床了,查了下价格也还能承受,规范LRS存储一年也就10块钱。 本文就依据OSS配置再联合集体罕用的几个软件来总结阿里云OSS相干配置和利用。 计费形式在理解具体的应用之前,这里简要介绍一下计费的形式。 阿里云有目前有两种计费形式,如果你不想买资源包等等操作,那么默认开明OSS之后就能够间接拿来用,间接按量计费的形式即可,先应用,后付费。 按量免费计费公式:OSS的应用费用每小时结算一次,计算公式为:费用=理论资源使用量×对应资源每小时单价。资源包:事后购买针对不同的计费项推出的优惠资源包,在费用结算时,优先从资源包抵扣用量,先购买,后抵扣,实用于业务用量绝对稳固的场景。留神:资源包肯定要依据本人创立和应用的Bucket进行购买,比方规范存储就买规范存储的,低频存储的就买低频存储的,千万不要买错了,买错了不能反悔。当然规范的LRS比拟便宜,然而粗略看了一下其余几个Burket选项都挺贵的,购买之前肯定要确认分明本人的需要和应用的Bucket类型。如果对于费用计费有顾虑,能够浏览“资源包治理“中的”购买了资源包为什么还会欠费?“,外面都有相干解释。这里假设读者都是给集体学习或者简略应用的状况,所以应用的是购买资源包计费形式。 存储类型官网做了一张表,其实个别应用“规范类型”就够了,可能有的读者还想图便宜会想要买一个“低频拜访”来玩玩,然而只有你去看一下低频拜访资源包价格就会发现你会被文字游戏给坑了。 新人优惠新人优惠很重要,查了一下很多文章不会说这个货色,这里有必要强调一下,阿里云的OSS对于新人来说有送3个月收费100GB流量,根本相当于让你收费用3个月,这一点还是挺香的(<s>到期了薅完阿里薅腾讯云的</s>),所以创立OSS之后先不要急着用,先把收费的资源包领一下: 地址:对象存储OSS_云存储服务_企业数据管理_存储-阿里云 (aliyun.com)。 滚动条下拉抉择套餐即可。 地区抉择大陆通用即可: 购买之后咱们创立相干的Burket而后上传的时候就会从资源包扣费了。留神你创立的Burket肯定要和你的资源包匹配!留神你创立的Burket肯定要和你的资源包匹配!留神你创立的Burket肯定要和你的资源包匹配! 很重要,否则不明不白的额定扣费让人恼火和悔恨。 阿里云 OSS根底配置进入官网:阿里云-上云就上阿里云 (aliyun.com),在产品中抉择 OSS,如果素来没开通过OSS,阿里云这里会给一份协定确认而后确认用户开明,这里就不截图了。 进入治理页面,刚进去看不晓得要干啥,所以间接点击左边的OSS新手入门来理解也是一种形式。OSS阿里云_ OSS是什么意思_对象贮存OSS_阿里云OSS学习门路图_OSS Learning Path - 阿里云 (aliyun.com) 咱们切换到Bucket列表,抉择“创立Bucket”。 进入页面之后,咱们填写上面的内容: Bucket名称,惟一命名,起个本人喜爱的名字即可地区:抉择和本人所在城市比拟近的城市,国内抉择国内的区域和节点即可。Endpoint:需要的话能够记录一下,比方我我抉择的是:oss-cn-shenzhen.aliyuncs.com存储类型:如果仅仅作为备份应用,低频拜访比拟适合,然而如果是对外应用不论流量多少还是倡议用规范的,归档存储个别用于永恒存储备份重要数据。同城冗余和版本控制没啥必要,不必开读写权限:如果咱们作为图床,须要用“公共读”容许匿名用户拜访数据。(和PicGo配置无关)实时日志和定期备份集体认为如果是本人用也是没有必要,骗钱玩意。购买资源包创立实现之后,咱们先不急着操作,咱们先买个资源包,这里集体应用了“新人优惠”不给买了,这里就不演示购买操作了。 AccessKey治理接着是用户配置局部,咱们须要在OSS中配置容许对外拜访的AccessKey,这里咱们点击右上角“头像”的"AccessKey治理“,这里其实用户体验不是很好。 因为图床会对外拜访,所以倡议不要应用主账户的AccessToken进行操作,而是应用子账户形式进行操作解决,这里进入之后能够看到RAM用户治理,点击“创立用户”。 “创立用户”其余都能够自在操作,然而肯定要抉择“Open API”,这里须要进行平安验证。创立残缺之后,咱们便领有了AccessKey ID,AccessKey Secret这两个要害配置,留神这两个配置只能查看一次,倡议复制到本人本地存储前面须要应用到。 Burke受权创立用户之后,咱们须要给创立的子用户受权,在治理页面抉择新建子商户之后抉择给商户增加权限。 而后回到刚刚创立的bucket,在文件治理内给新建的用户受权。 配置PicGoPicGo是什么这里就略过了,咱们间接来看PicGo的配置 要害局部:在软件中咱们抉择“阿里云OSS配置”而后依据参数填写上面的内容: keyId:这里用之前新建的子用户的 AccessKey。KeySecret:这里应用新建子用户的 AcessSecret。存储空间名称:这里依照下图填写Bucket域名,留神这里只须要.aliyuncs.com须要删除。默认存储区域:这里依照下图填写Endpoint,留神这里只须要.aliyuncs.com须要删除。 最初集体的配置如下: 配置Typera装置Typera这里就跳过了,咱们关上软件之后抉择“图像”,而后切换到PicGo,验证一把之后会提醒胜利信息,之后咱们批改下面“插入图片时....”的操作改为“上传图片”,当前图片都会往PicGo进行上传,不会呈现在本地的一个长期门路了。 这里不是很倡议间接执行上传操作,更倡议先放到一个指定文件夹而后确认无误之后进行复制粘贴的上传替换,当然OSS流量根本够用。 obsidian配置具体能够看作者的文章,基本上装置一个插件之后“Enable”即可间接应用,间接往Obsidian进行粘贴就会间接委托PicGo上传,而后出翔相干门路。在Obsidian中应用图床实现“一次上传、屡次搬运”省心又省力 - 教训分享 - Obsidian 中文论坛 最初,咱们截图粘贴查看是否触发PicGo上传,最终截图的门路如下: https://adong-picture.oss-cn-... 写在最初gitee的图床集体目前曾经不再进行上传,后续都将会改用OSS,另外集体倡议定期给图床做一下本地备份,尽管可能并没有特地大的意义。 另外如果对于图片的重要性不大,能够间接应用收费的图床。 ...

April 4, 2022 · 1 min · jiezi

关于阿里云oss:阿里云视频云-vPaaS-演绎了怎样的音视频应用开发未来图景

简介:前瞻音视频平台的演进将来 vPaaS是阿里云视频云最新推出的低代码音视频利用开发产品,其中,vPaaS低代码音视频工厂,彻底突破了音视频利用的繁冗技术开发壁垒;vPaaS视频原生利用开发平台,全新定义了音视频利用的开发方式。 而低代码音视频工厂正是视频原生利用开发平台的场景最佳实际。 如下图所示,1个底座+N个场景,即“一个视频原生利用开发平台+N个音视频业务场景”,正是vPaaS整体产品的外围逻辑。 在此基础上,vPaaS能够成长出更丰盛的场景、更多元的能力、更深厚的平台。 “vPaaS视频原生利用开发平台”所从新定义的音视频利用开发,在四大方向上全面引领将来音视频平台倒退的演进,展示了翻新而前瞻的产品与技术图景。 多重体验低代码开发,疾速打造多重体验利用多重体验技术通过构建Room Engine SDK,提供跨平台、跨终端的视频原生应用服务能力,为不同终端带来统一的利用开发体验。 低代码常见的形式聚焦于LCAP低代码利用开发,但针对音视频畛域更适宜先进的MXDP多重体验开发平台,Gartner也曾将“多重体验(Multiexperience)”和“全面体验(Total Experience)”别离列为2020和2021的十大策略技术趋势之一,而多重体验技术所展示的是音视频技术策略的将来,能真正实现数字世界与人类的交互体验。 阿里云视频云深度加载这样的多重体验技术,为vPaaS视频原生利用提供跨平台、跨终端的统一体验,平台会继续构建多重的终端能力,包含web网页利用、挪动端、智能设施、乃至更多的VR/AR终端,对这样的多重终端、多平台打造开发体验统一的RoomEngine SDK。同时开发平台提供智能robot的技术和产品,让客户可低门槛、疾速具备智能robot的能力,提供全方位的用户体验,赋能业务倒退。 通过利用低代码技术,多重体验技术同时可能升高开发门槛,将开发工作量从以周甚至月为单位,升高到以小时甚至分钟为单位。 对于场景化SDK集成,多重体验技术提供场景一体化SDK,一键打包所需性能,同时提供多种开发框架,适配不同场景的SDK,进步SDK兼容性和集成效率。 在此基础上,vPaaS低代码音视频工厂的场景样板间提供端到端的、带UI的规范样板实现,在规范实现的根底上提供了丰盛的API,满足业务扩大需要。 这正是因为在跟泛滥客户共创的过程中,洞察到其最大艰难在于研发能力的有余,没有业余的音视频研发人员。为了让客户疾速具备该能力,vPaaS推出了“场景样板间“,将已有齐备状态的场景产品给到客户,一键成型利用。 以电商直播间为例,在规范服务的根底上,开发者能够疾速扩大定制化服务,例如商品橱窗、热卖商品举荐等,也能够通过自定义音讯实现商品推送、红包等性能。 阿里云视频云团队心愿通过在多重体验的低代码技术方向上的一直演进,提供可灵便组装的组件以及丰盛的场景样板间产品,在满足多重体验的前提下,尽可能为企业自建利用降本提效。 vPaaS多重体验低代码开发 云原生托管,提供简略稳固的场景样板服务阿里云的云原生与音视频技术相结合,能够为平台利用提供简略稳固的云原生托管服务,反对全生命周期的治理。 低代码音视频工厂提供的场景样板间产品里,蕴含规范的场景样板间服务,其服务托管在ACK集群上。以电商直播样板间为例,直播间的开启、暂停、完结等操作,其服务端逻辑全副标准化,并且反对全生命周期的治理。 借助云原生技术,低代码音视频工厂可能提供企业级容器化服务,包含服务主动部署,以及极致的弹性扩容。 此外,低代码音视频工厂实现了样板间服务治理可视化,提供最简化的服务运维性能。企业客户能够依据业务规模,一键进行样板服务的扩容,例如将在线的服务能力从1千并发扩容到1万并发,整个扩容只须要点击一个按钮。 阿里云视频云心愿打造一个融和云原生技术的视频原生利用开发平台,为企业自建视频利用提供简略、稳固平台托管服务。 vPaaS云原生托管服务 场景化AI引擎,减速赋能业务智能化翻新多场景全媒体的AI加持,开箱即用的AI接入形式,云端一体的AI引擎将赋能音视频业务的继续智能化翻新。 vPaaS低代码音视频工厂在音视频利用开发平台中,提供云端一体的AI引擎作为整个平台的算法底座,可能疾速地接入平台、场景产品须要的各种算法,包含加强、超分、超分等视频解决算法,以及智能拆条、智能语音、自然语言等视频生产算法,提供雷同或者更低带宽耗费的状况下,更好的视频体验。 同时,通过场景适配、产品化后,零门槛地提供给利用集成,让没有AI算法开发能力的企业或开发者,都能轻松应用、智能翻新。 vPaaS AI算法场景化 音视频利用工厂,视频原生利用一站式开发平台丰盛而深厚的音视频利用工厂,打造视频原生利用引擎,生成可继续集成平台。 通过音视频利用工厂的状态,vPaaS提供多场景SDK的动静组装能力,以样板利用为实例实现。通过继续构建视频原生利用的底座引擎能力,在音视频技术、网络一体化交融、AI算法、场景组件、多端开发体验等重点方向上晋升平台的竞争力。 同时,通过继续建设动静SDK组装能力、适配更多开发框架和开发工具,为开发者提供更好的开发体验。通过在平台上实现视频集成、构建、调试、部署、散发、灰度等工作,让vPaaS低代码音视频工厂成为视频原生利用的一站式开发平台。 目前低代码音视频工厂套件曾经公布了互动直播和互动课堂等产品,还在继续丰盛企业培训、短视频等泛滥场景。低代码音视频工厂公布的每个场景产品均提供两种集成形式:场景样板间和场景化SDK。其中,场景样板间的集成形式更为简略易用,当所提供的样板间UI和性能无奈满足需要,企业用户也能够抉择场景化SDK集成。 将来,阿里云视频云心愿通过vPaaS的低代码音视频工厂,提供更多的低代码场景样板间供选择,助力企业用户疾速搭建丰盛的视频场景利用。 vPaaS视频原生利用引擎 因能包容,而成其大;因能调适,而成其久。 vPaaS作为低代码音视频利用开发产品,无论从技术底座的“视频原生利用开发平台”,还是在业务场景层的“低代码音视频工厂”, 都展示了相对的前瞻性、包容性和延展性,并在构建初期就奠定了将来演变的有限翻新空间,而vPaaS产品最终还是发轫于助力企业用户轻松、极速搭建真正高品质的专属音视频业务平台。 原文链接本文为阿里云原创内容,未经容许不得转载。

March 18, 2022 · 1 min · jiezi