分布式文件存储库MinIO可还行?

在传统的单体应用架构中,一个应用程序对应一台服务器,提供单进程服务。

但是随着业务的升级,技术的更新迭代,分布式、集群架构、微服务等现已俨然成为主流。

几乎所有的项目都会与文件挂钩,例如OA系统的报表文件,电商系统的商品图片等等...

我们来看一下传统的(单体应用)文件存储与读取方式

 一台主机对于N个客户端,如果是小项目还好,稍微大点的项目,服务器分分钟崩溃

进而演进为分布式架构

 将每一个大的模块进行拆分,以前单进程支撑的系统现在多进程协同。将文件操作也进行剥离,部署到不同的服务器进行维护,各司其职,减轻不同模块服务器的压力.

话又说回来了,怎样实现呢?

这里的话我主要说一下分布式文件的存储服务MinIO。当然还有其他的一些中间件及工具,大家随意即可。

首先介绍一下MinIO,MinIO是一款高性能的对象资源存储库,而且自身很轻量。

GitHub上start数已经有20多K了

官网:https://min.io
GitHub:https://github.com/minio

 而且MinIO支持多种语言,也提供了丰富的API.

OK!现在要动手了。

用它肯定要先安装它,我本次操作在Linux下。

首先在Docker中拉取一个镜像并运行

docker pull minio/minio
docker run -p 9000:9000 minio/minio server /data

它会分配给你密钥,用作登录。这个密钥在后续项目中也会用到。

windows下载:http://dl.min.io/server/minio/release/windows-amd64/minio.exe
进入到下载的包文件下执行:minio.exe server D:\minio\data --address 0.0.0.0:8009
D:\minio\data 表示文件上传所放位置
--address 0.0.0.0:8009 表示minio启动的端口为8009

在浏览器中输入ip:port如果正常显示,就证明你安装成功了。如下:

 我们可以点击加号,创建一个桶(文件夹)

 注意文件夹的名称不能大写

 我们可以上传一张图片

 找到它的链接就可以在浏览器中访问了

设置图片永久访问不过期

 

 

 Prefix输入 * ,右边下拉选择Read and Write.点击add即可

接下来在代码中进行CRUD了😅

 先在项目中引入Minio包

PM> Install-Package Minio

我的是webapi的项目,你可随意

上传文件:

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Upload(IFormFile file)
        {
            try
            {
                var minio = new MinioClient(_configuration["Minio:endpoint"], _configuration["Minio:accessKey"], _configuration["Minio:secretKey"]);
                var data = await FileUpload.Run(minio, file);
                return new JsonResult(new
                {
                    success = true,
                    fileUrl = data.fileUrl,
                    message = data.message
                });
            }
            catch (Exception ex)
            {
                return new JsonResult(new
                {
                    success = false,
                    fileUrl = default(string),
                    message = ex.Message
                });
            }
        }
        public async static Task<FileData> Run(MinioClient minio, IFormFile formFile)
        {
            var bucketName = "picfile";
            var location = "us-east-1";
            var objectName = $"pic/{DateTime.Now.ToString("yyyy-MM-dd")}/" + Guid.NewGuid().ToString().Replace("-", string.Empty);
            var contentType = "image/jpeg";
            try
            {
                //判断桶(文件夹)是否存在
                bool found = await minio.BucketExistsAsync(bucketName);
                if (!found)
                {
                    //新增桶(文件夹)
                    await minio.MakeBucketAsync(bucketName, location);
                }
                //文件大小
                var len = formFile.Length;
                //打开请求流以读取上传的文件
                var stream = formFile.OpenReadStream();
                //上传文件到桶(文件夹).
                await minio.PutObjectAsync(bucketName, objectName, stream, len, contentType, null, null);
                //返回url
                var url = await minio.PresignedGetObjectAsync(bucketName, objectName, 3600 * 24 * 7);
                //var data = await minio.StatObjectAsync("picfile", objectName);
                //... 对数据库进行操作,例如存入文件名与桶(文件夹)的名称
                return new FileData { success = true, fileUrl = url, message = "上传成功" };
            }
            catch (MinioException ex)
            {
                return new FileData { success = false, fileUrl = default(string), message = ex.Message };
            }
        }

密钥和ip这些配置项我们可以写在appsettings.json中

 在控制器中已注入的形式使用

 下载文件:

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="bucketName">桶(文件夹)名称</param>
        /// <param name="objextName">文件名称</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> DownLoadFile(string bucketName, string objextName)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName) && string.IsNullOrEmpty(objextName)) return new JsonResult(new { message = "桶(文件夹)名称和文件名称不能为空!" });
                //实例化minio客户端
                var minio = new MinioClient(_configuration["Minio:endpoint"], _configuration["Minio:accessKey"], _configuration["Minio:secretKey"]);
                //获得图片的链接
                var url = await minio.PresignedGetObjectAsync("picfile", objextName, 3600 * 24 * 7);
                //实例化WebClient 对象
                var webClient = new WebClient();
                //根据图片链接转成byte字节数组
                var dataByte = webClient.DownloadData(url);
Stream stream = new MemoryStream(dataByte); return File(stream, "application/vnd.android.package-archive", $"图片下载{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg");
} catch (Exception ex) { return new JsonResult(new { message = ex.Message, success = false }); } }

移除文件:

        /// <summary>
        /// 移除文件
        /// </summary>
        /// <param name="bucketName"></param>
        /// <param name="objextName"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<IActionResult> DeleteFile(string bucketName, string objextName)
        {
            try
            {
                if (string.IsNullOrEmpty(bucketName) && string.IsNullOrEmpty(objextName)) return new JsonResult(new { message = "桶(文件夹)名称和文件名称不能为空!" });
                //实例化minio客户端
                var minio = new MinioClient(_configuration["Minio:endpoint"], _configuration["Minio:accessKey"], _configuration["Minio:secretKey"]);
                //移除文件
                await minio.RemoveObjectAsync(bucketName, objextName);
                return new JsonResult(new
                {
                    message = "移除资源文件成功",
                    success = true
                });
            }
            catch (Exception ex)
            {
                return new JsonResult(new
                {
                    message = ex.Message,
                    success = false
                });
            }
        }

这里的话只列举以上几个较常用的api,MinIO其实还提供了很多api,大家可以慢慢研究。

到此MinIO就介绍完了,大家可以根据自己需要再进行扩展。

中文官网:http://docs.minio.org.cn

Smiling Face with Smiling Eyes on Microsoft Windows 10 May 2019 Update

posted @ 2020-05-19 19:17  江北、  阅读(12905)  评论(2编辑  收藏  举报