Nginx集群之WCF大文件上传及下载

目录

目录

一       差不多思路… 1

1       大致思路… 一

贰       Nginx集群之WCF大文件上传及下载… 1

二       Nginx集群之WCF大文件上传及下载… 一

三       BasicHttpBinding相关配置解析… 二

三       BasicHttpBinding相关配置解析… 二

四       编写WCF服务、客户端程序… 三

四       编写WCF服务、客户端程序… 三

5       URL保留项… 8

5       URL保留项… 8

陆       布署WCF服务程序到局域网内1台PC机… 八

6       安排WCF服务程序到局域网内一台PC机… 八

7       Nginx集群配置搭建… 九

七       Nginx集群配置搭建… 九

8       WCF客户端程序的周转结果… 1一

八       WCF客户端程序的运维结果… 11

9       总结… 13

9       总结… 13

 

 

一       大概思路

l  Nginx集群之WCF大文件上传及下载

l  BasicHttpBinding相关配置分析

transferMode、messageEncoding、maxReceivedMessageSize、receiveTimeout、sendTimeout

l  编写WCF服务、客户端程序

l  URL保留项

l  铺排WCF服务程序到局域网内1台PC机

l  Nginx集群配置搭建

l  WCF客户端程序的周转结果

l  总结

一       大致思路

l  Nginx集群之WCF大文件上传及下载

l  BasicHttpBinding相关配置分析

transferMode、messageEncoding、maxReceivedMessageSize、receiveTimeout、sendTimeout

l  编写WCF服务、客户端程序

l  URL保留项

l  布置WCF服务程序到局域网内一台PC机

l  Nginx集群配置搭建

l  WCF客户端程序的运营结果

l  总结

2       Nginx集群之WCF大文件上传及下载

Nginx的相配规则,很不难帮忙大家分开WCF服务的网段,从而达成公司数据新闻体系多区域划分,如小数指标微服务、传输数据文件的劳动、即时通讯服务、大概邮件服务,相当于构建了一条公司中间音讯化的数据总线(DataBus)。

以下是本文讲述的首要结构图:

客户端以BasicHttpBinding访问Nginx的域名zhyongfeng.com/fileupload,然后Nginx举办负荷均衡,将音讯分发到后端任意一台WCF上传下载服务器的PC机,然后实行上传文件至“冷数据”处,又从“冷数据”处下载文件。

本着“冷数据”能够分开目录,建立单独的FTP服务器及WCF服务器,实行操作处理。如下图所示:

图片 1

以下是WCF上传下载服务器的框架结构:

 图片 2

二       Nginx集群之WCF大文件上传及下载

Nginx的合作规则,很简单支持大家分开WCF服务的网段,从而达成公司数量消息类别多区域划分,如小数码的微服务、传输数据文件的劳务、即时通信服务、只怕邮件服务,相当于创设了一条公司内部新闻化的数额总线(DataBus)。

以下是本文讲述的严重性组织图:

客户端以BasicHttpBinding访问Nginx的域名zhyongfeng.com/fileupload,然后Nginx实行负荷均衡,将新闻分发到后端任意壹台WCF上传下载服务器的PC机,然后开始展览上传文件至“冷数据”处,又从“冷数据”处下载文件。

针对“冷数据”可以划分目录,建立独立的FTP服务器及WCF服务器,进行操作处理。如下图所示:

图片 3

以下是WCF上传下载服务器的架构:

 图片 4

三       BasicHttpBinding相关配置分析

basicHttpBinding相关配置,具体参考:

https://msdn.microsoft.com/zh-cn/library/system.servicemodel.basichttpbinding.aspx

以下是至关心保护要行使到的布置

transferMode

获取或设置一个值,该值指示是通过缓冲处理还是流处理来发送消息。(继承自 HttpBindingBase。)

messageEncoding

获取或设置是使用 MTOM 还是文本对 SOAP 消息进行编码。

maxReceivedMessageSize

获取或设置最大大小,以字节为单位,可以使用此绑定配置的通道上接收的消息。(继承自 HttpBindingBase。)

receiveTimeout

获取或设置连接在撤消之前保持非活动状态的最大时间间隔,在此时间间隔内未接收任何应用程序消息。(继承自 Binding。)

sendTimeout

获取或设置在传输引发异常之前可用于完成写入操作的时间间隔。(继承自 Binding。)

 

本着MTOM编码和异步调用的质量改进,能够参考随想:

利用MTOM编码和异步调用立异流传输的品质.pdf

 

3       BasicHttpBinding相关配置分析

basicHttpBinding相关配置,具体参考:

https://msdn.microsoft.com/zh-cn/library/system.servicemodel.basichttpbinding.aspx

以下是非同一般行使到的布置

transferMode

获取或设置一个值,该值指示是通过缓冲处理还是流处理来发送消息。(继承自 HttpBindingBase。)

messageEncoding

获取或设置是使用 MTOM 还是文本对 SOAP 消息进行编码。

maxReceivedMessageSize

获取或设置最大大小,以字节为单位,可以使用此绑定配置的通道上接收的消息。(继承自 HttpBindingBase。)

receiveTimeout

获取或设置连接在撤消之前保持非活动状态的最大时间间隔,在此时间间隔内未接收任何应用程序消息。(继承自 Binding。)

sendTimeout

获取或设置在传输引发异常之前可用于完成写入操作的时间间隔。(继承自 Binding。)

 

本着MTOM编码和异步调用的习性革新,能够参考散文:

动用MTOM编码和异步调用立异流传输的质量.pdf

 

四       编写WCF服务、客户端程序

l  WCF服务程序

Program.cs

using System.ServiceModel;
using Service;
using System;

namespace FileTransferHosting
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(FileTransferOperation)))
            {
                host.Opened += delegate
                {
                    Console.WriteLine(host.Description.Endpoints[0].Address.Uri + "已经启动,按任意键终止服务!");
                };

                host.Open();
                Console.Read();
            }
        }
    }
}

FileTransferOperation.cs

using Service.Interface;
using System;
using System.IO;
using System.ServiceModel;

namespace Service
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class FileTransferOperation : IFileTransferOperation
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="remoteFile"></param>
        public void UploadLoad(RemoteFileInfo remoteFile)
        {
            StreamToFile(remoteFile);
        }

        /// <summary>
        /// 写文件
        /// </summary>
        /// <param name="remoteFile"></param>
        public void StreamToFile(RemoteFileInfo remoteFile)
        {
            string fileFullPath = Path.Combine(System.Environment.CurrentDirectory, remoteFile.FileName);
            Stream sourceStream = remoteFile.FileByteStream;
            if (sourceStream == null) { return; }
            if (!sourceStream.CanRead) { return; }
            //创建文件流,读取流中的数据生成文件
            using (FileStream fs = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                const int bufferLength = 4096;
                byte[] myBuffer = new byte[bufferLength];//数据缓冲区
                int count;
                while ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                {
                    fs.Write(myBuffer, 0, count);
                }
                fs.Close();
                sourceStream.Close();
            }
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public Stream DownLoad(string fileName)
        {
            string fileFullPath = Path.Combine(System.Environment.CurrentDirectory, fileName);
            if (!File.Exists(fileFullPath))//判断文件是否存在
            {
                return null;
            }
            try
            {
                Stream myStream = File.OpenRead(fileFullPath);
                return myStream;
            }
            catch { return null; }
        }
    }
}

服务端配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="FileTransferBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="FileTransferdBinding" receiveTimeout="00:30:00" sendTimeout="00:30:00" maxReceivedMessageSize="6442450944" transferMode="Streamed"
            messageEncoding="Mtom" />
      </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="FileTransferBehavior" name="Service.FileTransferOperation">
        <endpoint binding="basicHttpBinding" bindingConfiguration="FileTransferdBinding"
            contract="Service.Interface.IFileTransferOperation" />
        <host>
          <baseAddresses>
            <add baseAddress="http://127.0.0.1:5600/fileupload" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

l  客户端程序

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FileTransferClient.FileTransferService;

namespace FileTransferClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入文件完整路径:");
            string fullFilePath = Console.ReadLine().Trim();


            using (FileTransferOperationClient proxy=new FileTransferOperationClient())
            {
                DateTime datetime1 = DateTime.Now;
                byte[] buffer = System.IO.File.ReadAllBytes(fullFilePath);
                Stream streamBuffer= new MemoryStream(buffer);
                //上传文件
                proxy.UploadLoad(buffer.Length, System.IO.Path.GetFileName(fullFilePath), streamBuffer);
                OutPutDiffTime(DateTime.Now, datetime1, "上传成功");


                Console.WriteLine("开始下载文件:");
                DateTime datetime2 = DateTime.Now;
                string filename = System.IO.Path.GetFileName(fullFilePath);
                //下载文件
                Stream sourceStream = proxy.DownLoad(filename);
                if (sourceStream == null) { return; }
                if (!sourceStream.CanRead) { return; }
                //创建文件流,读取流中的数据生成文件
                using (FileStream fs = new FileStream(Path.Combine(System.Environment.CurrentDirectory, filename), FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    const int bufferLength = 4096;
                    //数据缓冲区
                    byte[] myBuffer = new byte[bufferLength];
                    int count;
                    while ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                    {
                        fs.Write(myBuffer, 0, count);
                    }
                    fs.Close();
                    sourceStream.Close();
                }
                OutPutDiffTime(DateTime.Now, datetime2, "下载成功");
                Console.Read();
            }
        }
        public static void OutPutDiffTime(DateTime datetime2,DateTime datetime1,string mesg)
        {
            TimeSpan ts = (datetime2 - datetime1);
            string dateDiff = ts.Hours.ToString() + "小时"
                    + ts.Minutes.ToString() + "分钟"
                    + ts.Seconds.ToString() + "秒";
            Console.WriteLine(String.Format("花费了{0},{1}", dateDiff, mesg));
        }
    }
}

客户端配置文件(注意那里客户端transferMode=”Streamed”要运用流式数据开始展览拍卖,并且将endpoint
address改为” http://zhyongfeng.com/fileupload”):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IFileTransferOperation" receiveTimeout="00:30:00"
          sendTimeout="00:30:00" maxReceivedMessageSize="6442450944" transferMode="Streamed"
          messageEncoding="Mtom" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://zhyongfeng.com/fileupload" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IFileTransferOperation"
        contract="FileTransferService.IFileTransferOperation" name="BasicHttpBinding_IFileTransferOperation" />
    </client>
  </system.serviceModel>
</configuration>

如下图所示:

图片 5

图片 6

四       编写WCF服务、客户端程序

l  WCF服务程序

Program.cs

using System.ServiceModel;
using Service;
using System;

namespace FileTransferHosting
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(FileTransferOperation)))
            {
                host.Opened += delegate
                {
                    Console.WriteLine(host.Description.Endpoints[0].Address.Uri + "已经启动,按任意键终止服务!");
                };

                host.Open();
                Console.Read();
            }
        }
    }
}

FileTransferOperation.cs

using Service.Interface;
using System;
using System.IO;
using System.ServiceModel;

namespace Service
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class FileTransferOperation : IFileTransferOperation
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="remoteFile"></param>
        public void UploadLoad(RemoteFileInfo remoteFile)
        {
            StreamToFile(remoteFile);
        }

        /// <summary>
        /// 写文件
        /// </summary>
        /// <param name="remoteFile"></param>
        public void StreamToFile(RemoteFileInfo remoteFile)
        {
            string fileFullPath = Path.Combine(System.Environment.CurrentDirectory, remoteFile.FileName);
            Stream sourceStream = remoteFile.FileByteStream;
            if (sourceStream == null) { return; }
            if (!sourceStream.CanRead) { return; }
            //创建文件流,读取流中的数据生成文件
            using (FileStream fs = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                const int bufferLength = 4096;
                byte[] myBuffer = new byte[bufferLength];//数据缓冲区
                int count;
                while ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                {
                    fs.Write(myBuffer, 0, count);
                }
                fs.Close();
                sourceStream.Close();
            }
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public Stream DownLoad(string fileName)
        {
            string fileFullPath = Path.Combine(System.Environment.CurrentDirectory, fileName);
            if (!File.Exists(fileFullPath))//判断文件是否存在
            {
                return null;
            }
            try
            {
                Stream myStream = File.OpenRead(fileFullPath);
                return myStream;
            }
            catch { return null; }
        }
    }
}

服务端配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="FileTransferBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="FileTransferdBinding" receiveTimeout="00:30:00" sendTimeout="00:30:00" maxReceivedMessageSize="6442450944" transferMode="Streamed"
            messageEncoding="Mtom" />
      </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="FileTransferBehavior" name="Service.FileTransferOperation">
        <endpoint binding="basicHttpBinding" bindingConfiguration="FileTransferdBinding"
            contract="Service.Interface.IFileTransferOperation" />
        <host>
          <baseAddresses>
            <add baseAddress="http://127.0.0.1:5600/fileupload" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

l  客户端程序

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FileTransferClient.FileTransferService;

namespace FileTransferClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入文件完整路径:");
            string fullFilePath = Console.ReadLine().Trim();


            using (FileTransferOperationClient proxy=new FileTransferOperationClient())
            {
                DateTime datetime1 = DateTime.Now;
                byte[] buffer = System.IO.File.ReadAllBytes(fullFilePath);
                Stream streamBuffer= new MemoryStream(buffer);
                //上传文件
                proxy.UploadLoad(buffer.Length, System.IO.Path.GetFileName(fullFilePath), streamBuffer);
                OutPutDiffTime(DateTime.Now, datetime1, "上传成功");


                Console.WriteLine("开始下载文件:");
                DateTime datetime2 = DateTime.Now;
                string filename = System.IO.Path.GetFileName(fullFilePath);
                //下载文件
                Stream sourceStream = proxy.DownLoad(filename);
                if (sourceStream == null) { return; }
                if (!sourceStream.CanRead) { return; }
                //创建文件流,读取流中的数据生成文件
                using (FileStream fs = new FileStream(Path.Combine(System.Environment.CurrentDirectory, filename), FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    const int bufferLength = 4096;
                    //数据缓冲区
                    byte[] myBuffer = new byte[bufferLength];
                    int count;
                    while ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                    {
                        fs.Write(myBuffer, 0, count);
                    }
                    fs.Close();
                    sourceStream.Close();
                }
                OutPutDiffTime(DateTime.Now, datetime2, "下载成功");
                Console.Read();
            }
        }
        public static void OutPutDiffTime(DateTime datetime2,DateTime datetime1,string mesg)
        {
            TimeSpan ts = (datetime2 - datetime1);
            string dateDiff = ts.Hours.ToString() + "小时"
                    + ts.Minutes.ToString() + "分钟"
                    + ts.Seconds.ToString() + "秒";
            Console.WriteLine(String.Format("花费了{0},{1}", dateDiff, mesg));
        }
    }
}

客户端配置文件(注意那里客户端transferMode=”Streamed”要动用流式数据进行拍卖,并且将endpoint
address改为” http://zhyongfeng.com/fileupload”):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IFileTransferOperation" receiveTimeout="00:30:00"
          sendTimeout="00:30:00" maxReceivedMessageSize="6442450944" transferMode="Streamed"
          messageEncoding="Mtom" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://zhyongfeng.com/fileupload" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IFileTransferOperation"
        contract="FileTransferService.IFileTransferOperation" name="BasicHttpBinding_IFileTransferOperation" />
    </client>
  </system.serviceModel>
</configuration>

如下图所示:

图片 7

图片 8

5       URL保留项

详见:http://www.cnblogs.com/yongfeng/p/7851039.html

5       URL保留项

详见:http://www.cnblogs.com/yongfeng/p/7851039.html

陆       计划WCF服务程序到局域网内一台PC机

长途布署WCF服务端程序到PC机

图片 9

图片 10

6       布置WCF服务程序到局域网内1台PC机

远程布置WCF服务端程序到PC机

图片 11

图片 12

7       Nginx集群配置搭建

经过自主义域名zhyongfeng.com:80端口举行负荷均衡集群访问,则访问C:\Windows\System32\drivers\etc\hosts,添加下列“本机IP
自定义的域名”:

10.93.85.66    zhyongfeng.com

选取Nginx相配原则针对WCF安排的一台PC机配置如下:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    upstream zhyongfeng.com {
        server    10.92.202.56:5600;
        server    10.92.202.57:5700; 
        server    10.92.202.58:5800;
    }
    server {
        listen       80;
        server_name  zhyongfeng.com;
        location / {
            proxy_pass   http://zhyongfeng.com;
            proxy_connect_timeout       10s;
        } 
    location /fileupload {
            proxy_pass   http://10.92.202.56:5600/fileupload;
            proxy_connect_timeout       10s;
        } 
    }
}

运行CMD:

D:\DTLDownLoads\nginx-1.10.2>start nginx

D:\DTLDownLoads\nginx-1.10.2>nginx -s reload

访问WCF服务端:http://zhyongfeng.com/fileupload,运行结果:

图片 13

柒       Nginx集群配置搭建

通过自主义域名zhyongfeng.com:80端口进行负荷均衡集群访问,则访问C:\Windows\System32\drivers\etc\hosts,添加下列“本机IP
自定义的域名”:

10.93.85.66    zhyongfeng.com

选拔Nginx相称原则针对WCF计划的一台PC机配置如下:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    upstream zhyongfeng.com {
        server    10.92.202.56:5600;
        server    10.92.202.57:5700; 
        server    10.92.202.58:5800;
    }
    server {
        listen       80;
        server_name  zhyongfeng.com;
        location / {
            proxy_pass   http://zhyongfeng.com;
            proxy_connect_timeout       10s;
        } 
    location /fileupload {
            proxy_pass   http://10.92.202.56:5600/fileupload;
            proxy_connect_timeout       10s;
        } 
    }
}

运行CMD:

D:\DTLDownLoads\nginx-1.10.2>start nginx

D:\DTLDownLoads\nginx-1.10.2>nginx -s reload

访问WCF服务端:http://zhyongfeng.com/fileupload,运行结果:

图片 14

八        WCF客户端程序的运作结果

早先WCF客户端程序,直接上传Linux的ubuntu系统iso镜像,总大小为一.五G左右,上传时间局域网(服务器线路是10Gpbs)开支八分钟左右,下载时间大致是三分钟。

客户端服务器的网络处境,运营作效果果如下图:

图片 15

图片 16

图片 17

图片 18

 图片 19

 

八        WCF客户端程序的运作结果

启航WCF客户端程序,直接上传Linux的ubuntu系统iso镜像,总大小为一.伍G左右,上传时间局域网(服务器线路是十Gpbs)费用八分钟左右,下载时间大体是叁分钟。

客户端服务器的互连网情形,运转作效果果如下图:

图片 20

图片 21

图片 22

图片 23

 图片 24

 

9       总结

Nginx的合作原则能够有效的分配U凯雷德L,将流式数据分发给相应的劳务处理,并且在局域网内能够协助较大的上传下载作用。通过BasicHttpBinding的连锁配置,能够决定流式数据上传大小,同时补助流式数据的下载效率,达到WCF大文件上传及下载的成效。

本来,具体的行使场景,依旧要整合数据大小而谈话的,那里只是提供1个化解方案的参阅。

诸如有些甩卖摄像文件每日都以一TB,处理PB级的大数据文件,依然建议利用hadoop的HDFS达成相比较好。

单向,数据大小达若干MB或几KB的发票、报表文件,这么些文件重大在多而不在大,hadoop的MapReduce显然有个别大材小用了,能够行使“业务领域-年-月-日”的章程,建立和谐一套数据结构存款和储蓄格局。

 

源代码下载:

http://download.csdn.net/download/ruby_matlab/10131307

 

PDF下载:

Nginx集群之WCF大文件上传及下载(帮忙陆G传输).pdf

9       总结

Nginx的相称原则能够有效的分配U奥迪Q5L,将流式数据分发给相应的劳务处理,并且在局域网内可以辅助较大的上传下载功效。通过BasicHttpBinding的相关配置,能够决定流式数据上传大小,同时帮忙流式数据的下载成效,达到WCF大文件上传及下载的法力。

本来,具体的利用场景,照旧要整合数据大小而谈话的,那里只是提供三个化解方案的参阅。

诸如某个拍卖录制文件每日都是1TB,处理PB级的大数据文件,照旧建议利用hadoop的HDFS达成相比较好。

单向,数据大小达若干MB或几KB的发票、报表文件,那么些文件注重在多而不在大,hadoop的MapReduce明显有个别黄钟毁弃了,可以使用“业务领域-年-月-日”的艺术,建立和谐壹套数据结构存款和储蓄格局。

 

源代码下载:

http://download.csdn.net/download/ruby_matlab/10131307

 

PDF下载:

Nginx集群之WCF大文件上传及下载(辅助陆G传输).pdf

相关文章

admin

网站地图xml地图