SeaWeedFS的简单使用

使用环境:由于要存储用户上传的很多小文件,比如照片附件等。

插件Github地址:https://github.com/chrislusf/seaweedfs

下载好releases对应的安装包即可在本机进行搭建

搭建步骤:

1.通过cmd进入weed.exe对应目录

2.搭建主节点(master节点):

weed master

 提示如上图即可在浏览器中输入

localhost:9333

 出现此图即主节点搭建成功。

3.搭建数据节点,数据节点的搭建和主节点类似,只是参数不相同。

weed volume -dir="/seaweedfs/tmp" -max=5  -mserver="localhost:9333" -port=9090 -index=leveldb

volume代表是数据节点,dir是相对路径,mserver主节点地址,port为数据节点端口,-index的级别设置为leveldb将会设置为固化到硬盘,而不是文件都存储在内存中。

 数据节点搭建成功后,localhost:9333的页面将会展示数据节点的端口等信息。

 可以设置多个数据节点,端口不一致即可。

如上设置第二个数据节点的命令如下

volume -dir="/seaweedfs/tmp" -max=5  -mserver="localhost:9333" -port=9091 -index=leveldb

运行后截图:

 至此,主节点和数据节点都搭建完毕。

为了方便实现,之前从github上面拷贝了一个项目,进行了简单的一下修改,可以完成文件的一般操作。

public interface ISeaweedFSService
    {
        FileHandleStatus SaveFileByStream(string fileName, Stream stream, out string errMsg);
        FileHandleStatus UpdateFileByStream(string fileId, string fileName, Stream stream, out string errMsg);
        BytesResponse GetFileBytes(string fileId);
        bool DeleteFile(string fileId,out string errMsg);

    }
    public class SeaweedFSService : ISeaweedFSService
    {
        IPkpmConfigService pkpmConfigService;
        //private HttpClient HttpClient { get; set; }
        //private RestClient client {get;set;}
        bool UsingPublicUrl;
        string masterUrl = string.Empty;
        public SeaweedFSService(IPkpmConfigService pkpmConfigService)
        {
            this.pkpmConfigService = pkpmConfigService;
            masterUrl = pkpmConfigService.SeaweedFSMasterUrl;
            UsingPublicUrl = pkpmConfigService.SeaweedFSUsingPublicUrl;
            var clientHandler = new HttpClientHandler
            {
                AllowAutoRedirect = true,
            };
            //HttpClient = new HttpClient(clientHandler);
            //var client = new RestClient(masterUrl);
        }


        private AssignFileKeyResult GetFileId()
        {
            var url = masterUrl + RequestPathStrategy.AssignFileKey;
            var client = new RestClient(url);
            var request = new RestRequest("");
            IRestResponse<AssignFileKeyResult> response = client.Execute<AssignFileKeyResult>(request);
            return response.Data;        }

        /// <summary>
        /// 存储文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public FileHandleStatus SaveFileByStream(string fileName, Stream stream, out string errMsg)
        {
            var TTL = string.Empty;
            var fileKeyResult = GetFileId();
            var uploadUrl = UsingPublicUrl ? fileKeyResult.PublicUrl : fileKeyResult.Url;
            uploadUrl = "http://" + uploadUrl;
            // Upload file
            return new FileHandleStatus(
                fileKeyResult.FId,
                 UploadFile(uploadUrl, fileKeyResult.FId, fileName, stream, TTL, out errMsg),
                uploadUrl
            );
        }

        /// <summary>
        /// 更新文件
        /// </summary>
        /// <param name="fileId"></param>
        /// <param name="fileName"></param>
        /// <param name="stream"></param>
        /// <returns></returns>
        public FileHandleStatus UpdateFileByStream(string fileId, string fileName, Stream stream, out string errMsg)
        {
            var targetUrl = GetTargetUrl(fileId);
            targetUrl = "http://" + targetUrl;
            var TTL = string.Empty;
            return new FileHandleStatus(
                  fileId,
                   UploadFile(targetUrl, fileId, fileName, stream, TTL, out errMsg),
                  targetUrl
              );
        }

        public BytesResponse GetFileBytes(string fileId)
        {
            var targetUrl = GetTargetUrl(fileId);
            targetUrl = "http://" + targetUrl;
            var request = new HttpRequestMessage(
                HttpMethod.Get,
                new Uri(targetUrl + "/" + fileId)
            );
            var result = FetchBytesByRequest(request);
            return result;
        }

        private BytesResponse FetchBytesByRequest(HttpRequestMessage request)
        {
            BytesResponse result = new BytesResponse();
            try
            {
                var client = new RestClient(request.RequestUri);
                var wrequest = new RestRequest("");
                var bytes = client.DownloadData(wrequest);
                result.bytes = bytes;
            }
            finally
            {
                request.Dispose();
            }
            return result;
        }

        private bool DeleteFile(string url, string fileId, out string errMsg)
        {
            var restRequest = new RestRequest(Method.DELETE);
            var client = new RestClient(url + "/" + fileId);
            var jsonResponse = client.Execute(restRequest);
            if (ConvertResponseStatusToException((int)jsonResponse.StatusCode, url, fileId, false, false, false, false, out errMsg))
            {
                return true;
            }
            else
            {
                return false;
            }                    
        }

        public bool DeleteFile(string fileId, out string errMsg)
        {
            var targetUrl = GetTargetUrl(fileId);
            targetUrl = "http://" + targetUrl;
            var result = CheckFileExist(targetUrl, fileId);
            if (result)
            {
                result = DeleteFile(targetUrl, fileId, out errMsg);
            }
            else
            {
                errMsg = "文件不存在";
            }
            return result;
        }

        private bool CheckFileExists(string fileId)
        {
            var targetUrl = GetTargetUrl(fileId);
            return CheckFileExist(targetUrl, fileId);
        }

        private HttpStatusCode FetchStatusCodeByRequest(HttpRequestMessage request)
        {
            HttpStatusCode statusCode = HttpStatusCode.Accepted;
            try
            {
                var restRequest = new RestRequest(Method.GET);
                var client = new RestClient(request.RequestUri);
               var response =  client.Execute(restRequest);
                statusCode = response.StatusCode;
                //response = HttpClient.SendAsync(request).Result;
                //statusCode = response.StatusCode;
            }
            finally
            {
                request.Dispose();
            }
            return statusCode;
        }


        private bool CheckFileExist(string url, string fileId)
        {
            var request = new HttpRequestMessage(
                HttpMethod.Head,
                new Uri(url + "/" + fileId)
            );
            var statusCode = FetchStatusCodeByRequest(request);
            try
            {
                string errMsg = string.Empty;
                if (ConvertResponseStatusToException((int)statusCode, url, fileId, false, true, false, false, out errMsg))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }


        /// <summary>
        /// 通过fileId查询是否存在此文件,获得相关的URL
        /// </summary>
        /// <param name="fileId"></param>
        /// <returns></returns>
        private LookupVolumeResult FetchLookupVolumeResult(string fileId)
        {
            var url = masterUrl + RequestPathStrategy.LookupVolume + "?volumeId=" + fileId;
            var request = new HttpRequestMessage(
                HttpMethod.Get,
                new Uri(url)
            );
            var restRequest = new RestRequest(Method.GET);
            var client = new RestClient(url);
            var response = client.Execute(restRequest);
            var content = response.Content;
            var jsonResponse = new JsonResponse(content, response.StatusCode);
            var obj = JsonConvert.DeserializeObject<LookupVolumeResult>(jsonResponse.Json, new JsonSerializerSettings() { MissingMemberHandling = MissingMemberHandling.Ignore });
            return obj;
        }

        private string GetTargetUrl(string fileId)
        {
            var volumeResult = FetchLookupVolumeResult(fileId);
            var result = volumeResult.Locations[0];
            return UsingPublicUrl ? result.PublicUrl : result.Url;
        }

        private bool ConvertResponseStatusToException(int statusCode, string url, string fileId,
             bool ignoreNotFound, bool ignoreRedirect, bool ignoreRequestError, bool ignoreServerError, out string ErrMsg)
        {
            ErrMsg = string.Empty;
            switch (statusCode / 100)
            {
                case 1:
                case 2:
                    return true;
                case 3:
                    if (ignoreRedirect)
                    {
                        return true;
                    }
                    ErrMsg = "Looks up a localized string similar to Fetch file from [{0}/{1}] has been redirected, response stats code is [{2}]".Fmt(url, fileId, statusCode);
                    return false;
                case 4:
                    if (statusCode == 404 && ignoreNotFound)
                    {
                        return false;
                    }
                    if (statusCode == 404)
                    {
                        ErrMsg = "Looks up a localized string similar to Fetch file from[{0}/{1}] has not been found, response stats code is [{2}]".Fmt(url, fileId, statusCode);
                        return false;
                    }
                    if (ignoreRequestError)
                    {
                        return false;
                    }
                    ErrMsg = "Looks up a localized string similar to Fetch file from[{0}/{1}] has returned request error, response stats code is [{2}]".Fmt(url, fileId, statusCode);
                    return false;
                case 5:
                    if (ignoreServerError)
                    {
                        return false;
                    }
                    ErrMsg = "Looks up a localized string similar to Fetch file from[{0}/{1}] has returned request error, response stats code is [{2}]".Fmt(url, fileId, statusCode);
                    return false;
                default:
                    ErrMsg = "Looks up a localized string similar to Fetch file from[{0}/{1}] has returned request error, response stats code is [{2}]".Fmt(url, fileId, statusCode);
                    return false;
            }
        }

        private long UploadFile(string url, string fileId, string filename, Stream inputStream, string ttl, out string outErrMsg)
        {
            outErrMsg = string.Empty;
            url = url + "/" + fileId;
            if (!string.IsNullOrEmpty(ttl))
                url = url + "?ttl=" + ttl;

            //var request = new HttpRequestMessage(
            //    HttpMethod.Post,
            //    new Uri(url)
            //);

            var restRequest = new RestRequest(Method.POST);
            byte[] bytes = new byte[inputStream.Length];
            inputStream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            inputStream.Seek(0, SeekOrigin.Begin);
            restRequest.AddFileBytes(filename, bytes, filename, "form-data");

            var response = FetchJsonResultByRequest(restRequest, url);

            JsonResponse jsonResponse = new JsonResponse(response.Json, response.StatusCode);

            string errMsg = string.Empty;
            if (ConvertResponseStatusToException((int)jsonResponse.StatusCode, url, fileId, false, false, false, false, out errMsg))
            {
                var obj = JsonConvert.DeserializeObject<JObject>(jsonResponse.Json);
                var jToken = obj.GetValue("size");
                return jToken.Value<long>();
            }
            else
            {
                outErrMsg = errMsg;
                return 0;
            }
        }

        private JsonResponse FetchJsonResultByRequest(RestRequest request, string url)
        {
            JsonResponse jsonResponse = null;
            try
            {
                var client = new RestClient(url);

                var response = client.Execute(request);
                //response = await HttpClient.SendAsync(request);
                var content = response.Content;
                jsonResponse = new JsonResponse(content, response.StatusCode);
            }
            catch (Exception)
            {

            }

            if (jsonResponse.Json.Contains(""error":""))
            {
                var obj = JsonConvert.DeserializeObject<JObject>(jsonResponse.Json);
                var jToken = obj.GetValue("error");
                if (jToken != null)
                {

                }
            }
            return jsonResponse;
        }
    }
View Code

基本上还是根据官网的文档来进行部署的,只是根据自己的使用情况进行了一点总结和修改。

记录一下方便后续使用

原文地址:https://www.cnblogs.com/Anthoney/p/12803068.html