Nginx的匹配規則,很容易幫助我們劃分WCF服務的網段,從而實現企業數據信息系統多區域劃分,如小數據的微服務、傳輸數據文件的服務、即時通信服務、或者郵件服務,相當於構建了一條企業內部信息化的數據匯流排(DataBus)。Nginx的匹配原則能夠有效的分配URL,將流式數據分發給相應的服務處理,並且在... ...
目錄
1 大概思路... 1
2 Nginx集群之WCF大文件上傳及下載... 1
3 BasicHttpBinding相關配置解析... 2
4 編寫WCF服務、客戶端程式... 3
5 URL保留項... 8
6 部署WCF服務程式到區域網內1台PC機... 8
7 Nginx集群配置搭建... 9
8 WCF客戶端程式的運行結果... 11
9 總結... 13
1 大概思路
l Nginx集群之WCF大文件上傳及下載
l BasicHttpBinding相關配置解析
transferMode、messageEncoding、maxReceivedMessageSize、receiveTimeout、sendTimeout
l 編寫WCF服務、客戶端程式
l URL保留項
l 部署WCF服務程式到區域網內1台PC機
l Nginx集群配置搭建
l WCF客戶端程式的運行結果
l 總結
2 Nginx集群之WCF大文件上傳及下載
Nginx的匹配規則,很容易幫助我們劃分WCF服務的網段,從而實現企業數據信息系統多區域劃分,如小數據的微服務、傳輸數據文件的服務、即時通信服務、或者郵件服務,相當於構建了一條企業內部信息化的數據匯流排(DataBus)。
以下是本文講述的主要結構圖:
客戶端以BasicHttpBinding訪問Nginx的功能變數名稱zhyongfeng.com/fileupload,然後Nginx進行負載均衡,將消息分發到後端任意一臺WCF上傳下載伺服器的PC機,然後進行上傳文件至“冷數據”處,又從“冷數據”處下載文件。
針對“冷數據”可以劃分目錄,建立單獨的FTP伺服器及WCF伺服器,進行操作處理。如下圖所示:
以下是WCF上傳下載伺服器的架構:
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編碼和非同步調用的性能改善,可以參照論文:
4 編寫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 URL保留項
詳見:http://www.cnblogs.com/yongfeng/p/7851039.html
6 部署WCF服務程式到區域網內1台PC機
遠程部署WCF服務端程式到PC機
7 Nginx集群配置搭建
通過自主義功能變數名稱zhyongfeng.com:80埠進行負載均衡集群訪問,則訪問C:\Windows\System32\drivers\etc\hosts,添加下列“本機IP 自定義的功能變數名稱”:
10.93.85.66 zhyongfeng.com
使用Nginx匹配原則針對WCF部署的1台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,運行結果:
8 WCF客戶端程式的運行結果
啟動WCF客戶端程式,直接上傳Linux的ubuntu系統iso鏡像,總大小為1.5G左右,上傳時間區域網(伺服器線路是10Gpbs)花費7分鐘左右,下載時間大概是3分鐘。
客戶端伺服器的網路狀況,運行效果如下圖:
9 總結
Nginx的匹配原則能夠有效的分配URL,將流式數據分發給相應的服務處理,並且在區域網內能夠支持較大的上傳下載功能。通過BasicHttpBinding的相關配置,能夠控制流式數據上傳大小,同時支持流式數據的下載功能,達到WCF大文件上傳及下載的效果。
當然,具體的應用場景,還是要結合數據大小而言論的,這裡只是提供一個解決方案的參考。
例如一些處理視頻文件每天都是1TB,處理PB級的大數據文件,還是建議使用hadoop的HDFS實現比較好。
另一方面,數據大小達若幹MB或幾KB的發票、報表文件,這些文件主要在多而不在大,hadoop的MapReduce顯然有點大材小用了,可以採用“業務領域-年-月-日”的方式,建立自己一套數據結構存儲方式。
源代碼下載:
http://download.csdn.net/download/ruby_matlab/10131307
PDF下載:
Nginx集群之WCF大文件上傳及下載(支持6G傳輸).pdf