Distributed Image Storage and storage
Advantages: Image Distributed Storage mainly solves server storage pressure and improves query speed;
Solution: when a user initiates an upload request, the user searches for available servers based on the data in the Image Information table on the server that initiates the request. In this case, the user may find multiple servers, then, the available image server set is filtered out from the status table as C, and the total number of records in the set is N. Then a random number R1 is generated using the random function and the remainder operation is performed with R1 and N as I = R1 % N. C [I] is the image server for storing images. Select an available server and use WebClient to initiate a request to store images on the available server, as shown below:
Solution:
1. Create two tables in the database: ImageServerInfo and ImageInfo;
Table: ImageServerInfo
Create table [dbo]. [ImageServerInfo] (
[ServerId] [int] IDENTITY (1, 1) not null,
[ServerName] [nvarchar] (32) not null,
[ServerUrl] [nvarchar] (100) 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
Table: ImageInfo
Create table [dbo]. [ImageInfo] (
[Id] [int] IDENTITY (1, 1) not null,
[ImageName] [nvarchar] (100) not null,
[ImageServerId] [int] not null,
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
2. Create an mvc project, add a controller, and add the following methods:
Public ActionResult FileUpload ()
{
HttpPostedFileBase file = Request. Files ["ImgFile"];
String fileName = file. FileName;
String fileExt = Path. GetExtension (fileName );
If (fileExt = ". jpg" | fileExt = ". png ")
{
ImageServerEntities dbContext = new ImageServerEntities ();
Var isiList = dbContext. ImageServerInfo. Where (x => x. FlgUsable = true). ToList ();
Int countN = isiList. Count ();
// Filter the available image server set composite as C from the status table and obtain the total number of records N of the set. Then a random number R1 is generated using the random function and the remainder operation is performed with R1 and N as I = R1 % N. C [I] is the image server for storing images.
Random rand = new Random ();
Int r1 = rand. Next ();
Int I = r1 % countN;
ImageServerInfo isi = isiList [I];
String url = string. Format ("http: // {0}/FileUp. ashx? ServerId = {1} & ext = {2} ", isi. ServerUrl, isi. ServerId, fileExt );
WebClient wc = new WebClient ();
Wc. UploadData (url, StreamToByteArray (file. InputStream ));
Return Content ("success ");
}
Else {return Content ("Please note the file type! ");}
}
Private byte [] StreamToByteArray (Stream stream)
{
Byte [] buffer = new byte [stream. Length];
Stream. Read (buffer, 0, buffer. Length );
Stream. Seek (0, SeekOrigin. Begin); // you can specify the position of the current stream. The first parameter is the relative offset relative to the position specified by the second parameter.
Return buffer;
}
3. Create two web applications to represent applications distributed on different servers.
Add the following method to a general handler:
Public void ProcessRequest (HttpContext context)
{
Context. Response. ContentType = "text/plain ";
String imgExt = context. Request ["ext"]; // get the file extension
String serverId = context. Request ["serverId"]; // obtain the ID of the ImageServerInfo table in the database
String imgNewName = Guid. NewGuid (). ToString (); // rename a new file with Guid
String path = "/ImgFileUpload/" + DateTime. now. year + "/" + DateTime. now. month + "/" + DateTime. now. day + "/"; // create a new folder every Day of every month every year to avoid freezing the file because a large number of image files are in the same folder.
Directory. CreateDirectory (Path. GetDirectoryName (context. Server. MapPath (path); // create a folder. At this time, the Directory class has determined whether the file exists and does not need to be judged again.
String imgFullPath = path + imgNewName + imgExt; // concatenate the file path
Using (FileStream fs = File. OpenWrite (context. Request. MapPath (imgFullPath )))
{
Context. Request. InputStream. CopyTo (fs); // copy the Request file stream to the file stream to be written
ImageServerEntities dbContext = new ImageServerEntities ();
ImageInfo img = new ImageInfo (){
ImageName = imgFullPath,
ImageServerId = Convert. ToInt32 (serverId)
};
DbContext. ImageInfo. Add (img );
DbContext. SaveChanges ();
}
}
4. Start the corresponding applications to upload files and Test