1、为了降低web服务器的压力,申请了2台文件服务器,用来存放图片文件。但是两台文件服务器如何让程序自己选择呢?

于是我用了一个算法,思路如下:

从状态表筛选出可用的图片服务器集合记作C,并获取集合的总记录数N,

然后用随机函数产生一个随机数R1与N进行取余运算记作I=R1%N,则c[I]即为要保存图片服务器。

然后我开始设计两个表,一个是图片文件服务器表、一个是图片信息表。1对多的关系。

表1:ImageServerInfo  图片文件服务器表

表2:ImageInfo   图片信息表

表脚本入下:

USE [MyImageServer]
GO /****** Object: Table [dbo].[ImageServerInfo] Script Date: 07/04/2020 21:17:15 ******/
SET ANSI_NULLS ON
GO SET QUOTED_IDENTIFIER ON
GO CREATE TABLE [dbo].[ImageServerInfo](
[ServerId] [int] IDENTITY(,) NOT NULL, --服务器id
[ServerName] [nvarchar]() NOT NULL, --图片服务器名称
[ServerUrl] [nvarchar]() NOT NULL, --图片服务器
[PicRootPath] [nvarchar]() NOT NULL, --图片存储的物理路径
[MaxPicAmount] [int] NOT NULL, ---图片存储的上限
[CurPicAmount] [int] NOT NULL, --图片当前存储的数量
[FlgUsable] [bit] NOT NULL, ---图片服务器的状态
CONSTRAINT [PK_ImageServerInfo] PRIMARY KEY CLUSTERED
(
[ServerId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO
----------------
----------------
----------------
----------------

USE [MyImageServer]
GO

/****** Object: Table [dbo].[ImageInfo] Script Date: 07/04/2020 21:16:57 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[ImageInfo](
[Id] [int] IDENTITY(1,1) NOT NULL,       ---该具体的id
[ImageName] [nvarchar](100) NOT NULL,    ---图片的路径名称
[ImageServerId] [int] NOT NULL,          ---存储到哪台服务器的id
CONSTRAINT [PK_ImageInfo] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[ImageInfo] WITH CHECK ADD CONSTRAINT [FK_ImageInfo_ImageServerInfo] FOREIGN KEY([ImageServerId])
REFERENCES [dbo].[ImageServerInfo] ([ServerId])
GO

ALTER TABLE [dbo].[ImageInfo] CHECK CONSTRAINT [FK_ImageInfo_ImageServerInfo]
GO

 

表结构建立好之后,开始打开 Microsoft Visual Studio 软件,新建一个 ImageSystem 解决方案,这里用来模拟web服务器。

1、web层我建立的是MVC进行演示 ImageSystem.WebApp。

2、然后建立一个实体层ImageSystem.Model 用来引用 Model1.edmx 作为EntityFramework做数据库连接。

3、建立两个空Web,用来做图片文件服务器。命名为 ImageSystem.ImageServeOne、ImageSystem.ImageServeTwo

4、项目结构如图:

web应用服务器的Controllers层的HomeController代码如下:

using ImageSystem.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc; namespace ImageSystem.WebApp.Controllers
{
public class HomeController : Controller
{
MyImageServerEntities db = new MyImageServerEntities();
// GET: Home
public ActionResult Index()
{
return View();
}
public ActionResult FileUpload()
{
HttpPostedFileBase file = Request.Files["fileUp"];
if (file != null)
{
string fileName = Path.GetFileName(file.FileName);
string fileExt = Path.GetExtension(fileName);
if (fileExt == ".jpg" || fileExt == ".png" || fileExt == ".gif")
{
//从状态表筛选出可用的图片服务器集合记作C,并获取集合的总记录数N,然后用随机函数产生一个随机数R1与N进行取余运算记作I=R1%N,则c[I]即为要保存图片服务器
var list=db.ImageServerInfo.Where(a => a.FlgUsable == true).ToList();
int count = list.Count();
Random random = new Random();
int r = random.Next();
int i = r % count;
ImageServerInfo imageServiceInfo = list[i];//筛选出一个服务器
WebClient client = new WebClient();
string address = "http://" + imageServiceInfo.ServerUrl + "/FileUp.ashx?serverId=" + imageServiceInfo.ServerId + "&ext=" + fileExt;
client.UploadData(address, StreamToByte(file.InputStream));
return Content("文件上传成功!");
}
else
{
return Content("文件类型错误!!");
}
}
else
{
return Content("文件不能为空!!");
}
} private byte[] StreamToByte(Stream inputStream)
{
byte[] buffer = new byte[inputStream.Length];
inputStream.Read(buffer, , buffer.Length);
inputStream.Seek(, SeekOrigin.Begin);
return buffer;
}
public ActionResult ShowImage()
{
var list = db.ImageServerInfo.Where(a => a.FlgUsable == true).ToList();
ViewData["list"] = list;
return View(); }
}
}

HomeController对应的view视图Index页面如下:

@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>分布式图片上传</title>
</head>
<body>
<div>
<form method="post" action="/Home/FileUpload" enctype="multipart/form-data">
<input type="file" name="fileUp" />
<input type="submit" value="上传图片" />
</form>
</div>
</body>
</html>

HomeController对应的view视图ShowImage页面如下:

这个页面是辅助查看上传的图片进行展示

@{
Layout = null;
}
@using ImageSystem.Model
<!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ShowImage</title>
</head>
<body>
<div>
@if (ViewData["list"] != null)
{
foreach (var ImageServerInfo in (List<ImageServerInfo>)ViewData["list"])
{
foreach (var ImageInfo in ImageServerInfo.ImageInfo)
{
<img src="@string.Format("http://{0}{1}",ImageServerInfo.ServerUrl,ImageInfo.ImageName)" alt="" width="200px" height="170px" />
@ImageServerInfo.ServerName
@ImageServerInfo.ServerUrl
@ImageInfo.ImageName
@ImageInfo.ImageServerId
<br />
}
}
}
</div>
</body>
</html>

以上便是模拟的web服务器,下面插入Web服务器要部署的代码,我只展示一台,另外一台除了ip端口不同,代码都一样的:

在根目录建立images文件夹,然后新增一个FileUp.ashx一般处理程序,用来接收图片的自己数组,处理程序的代码如下:

using ImageSystem.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web; namespace ImageSystem.ImageServeTwo
{
/// <summary>
/// FileUp 的摘要说明
/// </summary>
public class FileUp : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string ext = context.Request["ext"];
int serverId = int.Parse(context.Request["serverId"]);
string dir = "/images/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/";
Directory.CreateDirectory(Path.GetDirectoryName(context.Request.MapPath(dir)));
string newfileName = Guid.NewGuid().ToString();
string fullDir = dir + newfileName + ext;
using (FileStream stream = File.OpenWrite(context.Request.MapPath(fullDir)))
{
//将文件流写到指定的文件下
context.Request.InputStream.CopyTo(stream);
MyImageServerEntities db = new MyImageServerEntities();
ImageInfo imageInfo = new ImageInfo();
imageInfo.ImageName = fullDir;
imageInfo.ImageServerId = serverId;
db.ImageInfo.Add(imageInfo);
db.SaveChanges();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}

这个处理程序会把接收的图片存储到服务器上,并且把途径插入数据库的表中,这里要引用一下EF实体层的ImageSystem.Model

,此时,就可以启动3个项目了,然后主web服务器上传图片,此时就根据随机算法存储图片。

以上便是利用C#和sqlserver数据库做的图片文件分布式存储方案设计模式!

图片文件分布式存储方案设计模式(c#--sqlserver)的更多相关文章

  1. IIs 网站应用程序与虚拟目录的区别及高级应用说明(文件分布式存储方案)

    原文 IIs 网站应用程序与虚拟目录的区别及高级应用说明(文件分布式存储方案) 对于IIS网站,大伙用的比较多,就不啰嗦了.   今天和说说大伙比较少使用的"IIS应用程序”和虚拟目录的区别 ...

  2. lucene大索引文件分布式存储方案

    这几天实现了个Lucene分布式检索的模块,采用的分布式方案是将数据分块,分别生成N个索引文件,放到N个节点上运行.检索时,对每一个节点发出查询请求,将N个节点返回的结果归并,然后生成一个新的结果.如 ...

  3. MongoDb gridfs-ngnix文件存储方案 - 图片

    http://www.cnblogs.com/wintersun/p/4622205.html 在各类系统应用服务端开发中,我们经常会遇到文件存储的问题. 常见的磁盘文件系统,DBMS传统文件流存储. ...

  4. MongoDb gridfs-ngnix文件存储方案

          在各类系统应用服务端开发中,我们经常会遇到文件存储的问题. 常见的磁盘文件系统,DBMS传统文件流存储.今天我们看一下基于NoSQL数据库MongoDb的存储方案.笔者环境 以CentOS ...

  5. Apache日志不记录图片文件设置方法和来源日志的配置

    Apache日志不记录图片文件设置方法 <FilesMatch "\.(ico|gif|jpg|swf)">SetEnv IMAG 1</FilesMatch&g ...

  6. C#技术分享【PDF转换成图片——13种方案】(2013-07-25重新整理)

    原文:C#技术分享[PDF转换成图片--13种方案](2013-07-25重新整理) 重要说明:本博已迁移到 石佳劼的博客,有疑问请到 文章新地址 留言!!! 写在最前面:为了节约大家时间,撸主把最常 ...

  7. Hadoop小文件存储方案

    原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...

  8. EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象

    EF+LINQ事物处理   在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...

  9. Android从本地选择图片文件转为Bitmap,并用zxing解析Bitmap

    如何从本地选择图片文件 使用Intent调用系统相册后,onActivityResult函数返回的是Uri格式的路径 /** * 打开系统相册 */ private void openSysAlbum ...

随机推荐

  1. PAT 人口普查

    某城镇进行人口普查,得到了全体居民的生日.现请你写个程序,找出镇上最年长和最年轻的人. 这里确保每个输入的日期都是合法的,但不一定是合理的,假设已知镇上没有超过 200 岁的老人,而今天是 2014 ...

  2. TZOJ 复习时间

    描述 为了能过个好年,xhd开始复习了,于是每天晚上背着书往教室跑.为了追求更高的效率,xhd要根据难度值来选择合适的课程进行复习,复习后一门课的效率为前一门课之间的难度差的平方,而复习第一门课的效率 ...

  3. Git Gui工具从远程克隆代码总是提示路径已经存在。问题完美解决!

    最近使用Git Gui工具从远程克隆代码总是提示路径已经存在,提示如下图, 原因是使用Git Guii克隆代码时的路径不能是选择一个已经建好的目录(D盘的project下的test文件夹是我提前建好的 ...

  4. DirectX11 With Windows SDK--31 阴影映射

    前言 阴影既暗示着光源相对于观察者的位置关系,也从侧面传达了场景中各物体之间的相对位置.本章将起底最基础的阴影映射算法,而像复杂如级联阴影映射这样的技术,也是在阴影映射的基础上发展而来的. 学习目标: ...

  5. PHP文件包含 整理

    文件包含 目录 文件包含 1. 概述 1.1 常见的引发漏洞的函数: 1.2 利用条件 1.3 分类和利用思路 2. 利用方法 2.1 配合文件解析漏洞来包含 2.2 读取系统敏感文件(路径遍历) 2 ...

  6. MyBatis运行流程及入门第一个程序

    1. mybatis是什么? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...

  7. 阻塞队列一——java中的阻塞队列

    目录 阻塞队列简介:介绍阻塞队列的特性与应用场景 java中的阻塞队列:介绍java中实现的供开发者使用的阻塞队列 BlockQueue中方法:介绍阻塞队列的API接口 阻塞队列的实现原理:具体的例子 ...

  8. IE6、IE7兼容querySelectorAll和querySelector方法

    querySelector 和 querySelectorAll 方法是 W3C Selectors API 规范中定义的.他们的作用是根据 CSS 选择器规范,便捷定位文档中指定元素. 目前几乎主流 ...

  9. PAI-AutoLearning 图像分类使用教程

    概述 PAI AutoLearning(简称PAI AL)自动学习支持在线标注.自动模型训练.超参优化以及模型评估.在平台上只需准备少量标注数据,设置训练时长即可得到深度优化的模型.同时自动学习PAI ...

  10. Android学习笔记数组资源文件

    在android中我们可以通过数组资源文件,定义数组元素. 数组资源文件是位于values目录下的 array.xml <?xml version="1.0" encodin ...