中小研發團隊架構實踐之生產環境診斷工具WinDbg 三分鐘學會.NET微服務之Polly 使用.Net Core+IView+Vue集成上傳圖片功能 Fiddler原理~知多少? ABP框架(asp.

中小研發團隊架構實踐之生產環境診斷工具WinDbg

生產環境偶爾會出現一些異常問題,WinDbg或GDB是解決此類問題的利器。調試工具WinDbg如同醫生的聽診器,是系統生病時作問題診斷的逆向分析工具,Dump文件相似於飛機的黑匣子,記錄着生產環境程序運行的狀態。本文主要介紹了調試工具WinDbg和抓包工具ProcDump的使用,並分享一個真實的案例。N年前不知誰寫的代碼,致使每一兩個月偶爾出現CPU飆高的現象。咱們先使用ProcDump在生產環境中抓取異常進程的Dump文件,而後在不瞭解代碼的狀況下經過WinDbg命令進行分析,最終定位到有問題的那行代碼。css

1、診斷工具簡介
1.1 WinDbg

WinDbg是在Windows平臺下的、強大的用戶態和內核態調試工具。相比較於Visual Studio,它是一個輕量級的調試工具,所謂輕量級指的是它的安裝文件大小較小,可是其調試功能,卻比VS更爲強大。它的另一個用途是能夠用來分析Dump數據。WinDbg是Microsoft公司免費調試器調試集合中的GUI的調試器,支持Source和Assembly兩種模式的調試。WinDbg不只能夠調試應用程序,還能夠進行Kernel Debug。結合Microsoft的Symbol Server,能夠獲取系統符號文件,便於應用程序和內核的調試。WinDbg支持的平臺包括x8六、IA6四、AMD64。雖然WinDbg也提供圖形界面操做,但它最強大的地方仍是有着強大的調試命令,通常狀況會結合GUI和命令行進行操做,經常使用的視圖有:局部變量、全局變量、調用棧、線程、命令、寄存器、白板等。其中「命令」視圖是默認打開的。html

1.2 DebugDiag

DebugDiag最初是爲了幫助分析IIS的性能問題而開發的,它一樣能夠用於任何其餘的進程。DebugDiag工具主要用於幫助解決如掛起、 速度慢、 內存泄漏或內存碎片,和任何用戶模式進程崩潰等問題。該工具包括附加調試腳本,側重於互聯網信息服務(IIS)應用程序、 Web數據訪問組件、 COM+和相關Microsoft技術、SharePoint和.NET。它提供可擴展對象模型中的COM對象的形式,並具備一個內置的報告框架提供的腳本主機。它由3 部分組成,包括調試服務、 調試器主機和用戶界面。前端

1.3 ProcDump

ProcDump是System Internal提供的一個專門用來監測程序CPU高使用率從而生成進程Dump文件的工具。ProcDump能夠根據系統的CPU使用率或者指定的性能計數器來針對特定進程生成一系列的Dump文件,以便調試者對事故緣由進行分析。vue

2、診斷工具下載
3、獲取異常進程的Dump文件

有如下四種方式獲取Dump文件,具體以下:node

3.1 經過【任務管理器】獲取Dump文件,這樣獲取的是MinDump

3.2 利用WinDbg的adplus獲取Dump文件,這樣獲取的是FullDump

3.3 經過DebugDiag建立.NET異常轉儲Dump文件

3.4 經過ProcDump抓取異常線程Dump文件

如今重點介紹經過ProcDump抓取異常線程Dump文件,使用方法以下:ios

a. 命令行:
procdump [-a] [[-c|-cl CPU usage] [-u] [-s seconds]] [-n exceeds] [-e [1 [-b]] [-f <filter,...>] [-g] [-h] [-l] [-m|-ml commit usage] [-ma | -mp] [-o] [-p|-pl counter threshold] [-r] [-t] [-d <callback DLL>] [-64] <[-w] <process name or service name or PID> [dump file] | -i <dump file> | -u | -x <dump file> <image file> [arguments] >] [-? [ -e]
b. 實例:

procdump -c 70 -s 5 -ma -n 3 w3wpgit

當系統CPU使用率持續5秒超過70%時,連續抓3個Full Dump。github

procdump outlook -p "\Processor(_Total)\% Processor Time" 80web

當系統CPU使用率超過80%,抓取Outlook進程的Mini Dump。redis

procdump -ma outlook -p "\Process(Outlook)\Handle Count" 10000

當Outlook進程Handle數超過10000時抓取Full Dump

procdump -ma 4572

直接生成進程號爲4572的Full Dump。

 

下圖是在WindgbHighCpu進程中形成High CPU時運行ProcDump命令的運行效果,能夠看到在CPU每次持續5秒達到5%後就會生成相應的Dump文件,共生成了3份Full Dump文件:

c. 注意:
  • ProcDump須要進程已經啓動,而且中途不能中止。好比須要抓取IIS Worker Process的High CPU Dump,因爲IIS Worker Process默認會配置Idle Timeout = 20 min,即該進程在20分鐘內沒有任何請求的話就會自動結束,這種狀況下ProcDump也會自動結束。須要從新運行命令。所以若是目標程序存在這樣的配置,須要暫時將該配置取消。
  • 有些系統管理員但願可以運行該工具後退出用戶session,ProcDump是作不到的,若是有這種需求能夠考慮使用DebugDiag。
  • 在調試High CPU問題的時候常常用到的一個命令是!runaway,可是有些時候!runway在ProcDump抓取Dump文件的過程當中運行不出來,報錯信息以下:
0:000> !runaway ERROR: !runaway: extension exception 0x80004002. "Unable to get thread times - dumps may not have time information"

解決的方法是將Debugging Tools for Windows (WinDbg)安裝目錄下的dbghelp.dll拷貝到procdump.exe所在目錄下,而後再運行命令抓取Dump。 

4、WinDbg使用方法

操做步驟以下:

4.1 抓取異常程序的Dump文件
4.2 設置符號表

符號表是WinDbg關鍵的「數據庫」,若是沒有它,WinDbg基本上就是個廢物,沒法分析更多問題。因此使用WinDbg設置符號表,是必需要走的一步。

a、運行WinDbg軟件,而後按【Ctrl+S】彈出符號表設置窗。

b、將符號表地址:SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols 粘貼在輸入框中,點擊肯定便可。點擊肯定以前,請先確認紅色字的文件夾是否已被新建。

注:紅色字表示符號表本地存儲路徑,建議固定路徑,可避免符號表重複下載。

4.3 學會打開第一個Dump文件

       

 

當你拿到一個Dump文件後,可以使用【Ctrl+D】快捷鍵來打開一個Dump文件,或者點擊WinDbg界面上的【File=>Open Crash Dump...】按鈕,來打開一個Dump文件。第一次打開Dump文件時,可能會收到以下提示,出現這個提示時,勾選「Don't ask again in this WinDbg session」,而後點否便可。

當你想打開第二個Dump文件時,可能由於上一個分析記錄未清除,致使沒法直接分析下一個Dump文件,此時你可使用快捷鍵【Shift+F5】來關閉上一個對Dump文件的分析記錄。

4.4 經過簡單的幾個命令學會分析Dump文件

分享一個數據庫鏈接超時的Dump案例的分析過程:

當你打開一個Dump文件後,可能由於太多信息,讓你無所適從,不過不要緊,咱們只須要關注幾個關鍵信息就能夠了。

a. 加載SOS擴展命令

加載SOS以前,先肯定SOS的位置和版本,肯定方法以下:

若是安裝了Visual Studio,那麼先按照以下步驟打開VS的命令行:

而後,在打開的VS命令行中輸入【where sos.dll】,使得到SOS的位置和版本:

 

肯定完SOS位置和版本號後,開始加載SOS擴展命令:

.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll

以下圖所示:

b. 使用!clrstack命令來查看當前的調用堆棧信息

以下圖所示:

c. 使用!dso命令來查看堆棧上的全部對象詳細信息

以下圖所示:

綜合以上分析能夠大膽地猜想Common.cs 中第16行「Data Source=***;Initial Catalog=***;Persist Security Info=True;User ID=sa;Password=***」的這個數據庫鏈接字符串應該有問題,而後到代碼中相應的地方進一步確認和修改就能夠了。        

5、一個真實案例

分享筆者工做過的一家公司某業務系統CPU飆高90%以上的Dump分析過程案例,步驟以下:

5.1 使用ProcDump抓包
5.2 加載SOS擴展命令
.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

5.3 分析

執行!runaway命令,查看線程使用CPU時間狀況,以下圖所示。着重分析前面幾個線程。 

執行~22s命令,進入到線程22,以下圖所示:

執行!clrstack命令查看當前線程堆棧變量值的信息,從圖中能夠猜出大概是ExecuteNonQuery()這方法有點問題,以下圖所示:

再執行!dso命令能夠查看堆棧上的全部對象詳細信息,以下圖所示:

從圖中看,形成CPU飆高的罪魁禍首多半由SQL Server執行

INSERT INTO [dbo].[tbl_Interface_ProcessLog] (IKey,Username,ClientIP,Module,OrderNo,LogType,Content) VALUES (@IKey,@Username,@ClientIP,@Module,@OrderNo,@LogType,@Content)

這條語句時產生異常引發,而後到源代碼中找出相應的語句,通過進一步的確認、修改和從新發布後就解決了CPU飆高的問題。

 

至此,掌握幾個簡單的WinDbg命令以後,基本上絕大多數Dump你們均可以獨立分析了。固然WinDbg是個強大的工具,同時產生CPU飆高和內存泄漏的緣由也有不少。若是想分析得足夠準確,那麼就只有多學多練,多去分析。由於掌握WinDbg分析除了須要懂得幾個命令以外,經驗更加劇要,最後再補充兩點:

  1. WinDbg不是專門用於調試.NET程序的工具,它更偏向於底層,可用於內核和驅動調試,特別是對於某些至關疑難的問題調試有所幫助,例如內存泄漏等問題。進行普通的.NET程序調試仍是使用微軟專爲.NET開發所提供的調試工具更方便一些。
  1. SOS擴展命令中最有用的命令是!help,使用該命令能夠列出全部可用的SOS擴展命令列表,使用!help [SOSCommandName]能夠查看每個具體擴展命令的詳細使用說明。例如!help dumpheap就能夠查看!dumpheap這個擴展命令的具體使用方法。多多利用!help命令能夠很快上手SOS。
6、Demo下載及更多資料

 

 

熔斷降級是一個很是重要的概念,咱們先說一下什麼是熔斷降級,我們都知道服務發現,一個有問題的服務器沒來得急註銷過一會就崩潰掉了,那麼咱們的請求就有可能訪問一個已經崩潰的服務器,那麼就會請求失敗,由於已經game over了。那麼這個問題怎麼解決呢,你必定要認可,這個問題是沒法避免的。沒有什麼方法說,我拿到的服務器都沒有問題,這事是不可能的,因此你要認可你會有機會拿到有問題的服務器。那麼熔斷降級就是來解決這種問題的。

 

 一.什麼是熔斷

熔斷就像是「保險絲」,當出現夢中情況時,切斷服務,從而防止應用程序不斷地嘗試形成雪崩,這和咱們農村的保險絲很像,天氣熱了防止火災,那保險絲會自動斷開,防止更大的損失。

降級的目的是當某個服務提供者發生故障的時候,向調用方返回一個錯誤響應替代響應。

好比咱們要作一個雙11活動的系統,那麼好比一個抽獎的模塊崩潰,這個時候呢廣大客戶端瘋狂F5,就會致使整個集羣雪崩,這個時候咱們就應該中斷。

還有一栗子,好比說電信和聯通,它們在穩定,有也不穩定的時候,那麼若是咱們用它們的接口,若是電信崩了,咱們就是用聯通,這種操做的行爲就叫作熔斷降級。

其使用場景呢,例如,咱們要展現商品信息,咱們先從數據庫讀取,讀取失敗了,咱們就經過cache/redis,若是再失敗,咱們經過固定的Javascript object 來綁定,若是再失敗那就返回一個錯誤的信息。這就是完美的下降了錯誤。

這種錯誤的機率就猶如0.01*way³  就是1000次纔會出現的機率。那若是是不熔斷降級 就是100.以上一些栗子,好好讀讀便可。

 

二.Polly介紹

.Net Core 中有一個被.Net基金會承認的k庫,能夠用來進行熔斷降級,主要功能:1.重試(retry);2.斷路器(circuit-breaker);3.超時檢測(timeout);4.緩存(cache);5.降級(fallback)

 官方:https://github.com/app-vnext/polly  nuget: install-package Polly-Version 6.0.1

 

三.使用

建立項目與安裝庫,爲了穩定仍是選擇6.0.1吧。

使用Policy的靜態方法建立ISyncPolicy實現類對象,建立方法j既有同步方法也有異步方法,根據本身的需求來選擇,下面先演示同步方法,異步的方法也相似。

複製代碼
複製代碼
static void Main(string[] args)
        {
            //handle 當發生argumentException的異常
            Policy policy = Policy.Handle<ArgumentException>()
                .Fallback(() =>
                {
                    //就幹什麼事情
                    Console.WriteLine("出錯了");
                });
       //有可能異常的時候 policy.Execute(() => { Console.WriteLine("開始執行"); throw new ArgumentException(); Console.WriteLine("執行結束"); }); }
 
複製代碼

咱們運行一下,是以下結果。

但若是書咱們故意寫一個拋出異常,咱們稍微修改一下代碼。

複製代碼
複製代碼
policy.Execute(() =>
            {
                Console.WriteLine("開始執行");
                throw new ArgumentException();
                Console.WriteLine("執行結束");
            });
 
複製代碼

上面呢,我麼捕捉的是ArgumentException異常,那麼咱們若是是報的其餘的錯誤應該會怎樣呢?

複製代碼
複製代碼
policy.Execute(() =>
            {
                Console.WriteLine("開始執行");
                throw new Exception();
                Console.WriteLine("執行結束");
            });
 
複製代碼

 FallBack中有不少不一樣的重載,咱們能夠根據重載獲取不一樣的報錯信息,如下是全部的方法。

咱們能夠簡單的去獲取一個對象,代碼以下:

複製代碼
複製代碼
 Policy policy = Policy.Handle<ArgumentException>()
                .Fallback(() =>
                {
                    //就幹什麼事情
                    Console.WriteLine("出錯了");
                },ex=> {
                    Console.WriteLine(ex.Message);
                });
            policy.Execute(() =>
            {
                Console.WriteLine("開始執行");
                throw new ArgumentException();
                Console.WriteLine("執行結束");
            });
 
複製代碼

由於我們的業務邏輯啊有多是帶返回值的,也有多是不帶返回值的。那若是你的業務邏輯是帶返回值的,你就得用一個Policy帶參的泛型來建立,那麼這個Policy也是泛型的,在FallBack中也要 提一個替代值,由於畢竟是降級嘛,確定要有一個值來進行替代。

複製代碼
複製代碼
Policy<string> policy = Policy<string>.Handle<Exception>()
                .Fallback(() =>
                {
                    return "降級後的值";
                });
           string value = policy.Execute(() => {
                return "正常值";
            });
 
複製代碼
 

四.重試處理

polly提供了重試處理機制,那麼這個RetryForever()的場景不可能會出現,我也不知道它是處於什麼個操做。我以爲這違背了熔斷降級,這不可能讓它重試的,那麼如下就是用法,可是這根本用不着~

仍是推薦使用Retry吧。Retry中能夠寫個int值進去,就是重試的次數,這個仍是不錯的!

複製代碼
複製代碼
Policy policy = Policy.Handle<Exception>().RetryForever();
            policy.Execute(() => {
                Console.WriteLine("play task!!");
                if (DateTime.Now.Second % 10 != 0)
                {
                    throw new Exception();
                }
                Console.WriteLine("完成任務!");
            });
 
複製代碼

不過仍是有比較正常點的方法,例如WaitAndRetry這個方法,等等再重試。這個很不錯!這個方法裏的重載很是之多。

複製代碼
複製代碼
Policy policy = Policy.Handle<Exception>().WaitAndRetry(100, i => TimeSpan.FromMinutes(100));
            policy.Execute(() => {
                Console.WriteLine("play task!!");
                if (DateTime.Now.Second % 10 != 0)
                {
                    throw new Exception();
                }
                Console.WriteLine("完成任務!");
            });
 
複製代碼
 

 五.短路保護Circuit Breaker

短路保護是什麼意思呢,這個單詞翻譯過來就叫作線路切斷器,出現N次連續錯誤,則把「熔斷器」(保險絲)熔斷,等待一段時間,等待這段時間內若是再Execute則直接拋出BrokenCircuitException異常,根本不會再去嘗試調用業務代碼。等待時間過去以後,再執行Execute的時候若是又錯了(一次就夠了),那麼繼續熔斷一段時間,不然就恢復正常。這樣就避免一個服務已經不可用了,仍是使勁的請求給系統形成更大壓力。

這樣就避免了一個服務不可用了還在使勁的請求。

複製代碼
複製代碼
 Policy policy = Policy
            .Handle<Exception>()
            .CircuitBreaker(3, TimeSpan.FromSeconds(5));//連續出錯3次以後熔斷5秒(不會再
            while (true)
            {
                Console.WriteLine("開始Execute");
                try
                {
                    policy.Execute(() =>
                    {
                        Console.WriteLine("開始任務");
                        throw new Exception("出錯");
                        Console.WriteLine("完成任務");
                    });
                }
                catch (Exception ex)
                {
                    Console.WriteLine("execute出錯" + ex);
                }
                Thread.Sleep(500);
            }
 
複製代碼

 這就像剛纔咱們說的,我設置了連續3次熔斷,那麼若是連續3次報錯,那麼直接再也不執行之後的內容,這無疑是很是不錯的機制。保證了服務器的性能丟失和不起眼的問題。

 

 六.策略封裝與超時處理

策略封裝使用的方法是Policy提供的Wrap方法,英譯叫作包裹,那麼從單詞的意思就知道,能夠經過策略包裹策略來進行封裝,即裏面的不行,就走外面的。

複製代碼
複製代碼
Policy policyRetry = Policy.Handle<Exception>()
                .Retry(3);
            Policy policyFallback = Policy.Handle<Exception>()
                .Fallback(() =>
                {
                    Console.WriteLine("降級");
                });
            Policy policy = policyFallback.Wrap(policyRetry);
            policy.Execute(() =>
            {
                Console.WriteLine("play task!!");
                if (DateTime.Now.Second % 10 != 0)
                {
                    throw new Exception();
                }
                Console.WriteLine("完成任務!");
            });
 
複製代碼

注意這個wrap的包裹順序的,外在後,內在前。再經過一個超時處理就能夠對消耗時間夠長的請求進行GG了。

那麼你就能夠經過超時處理來對咱們文章開頭的訴說進行一個很是生動形象的經過代碼來宣誓。下面說明超時異常的說明

複製代碼
複製代碼
Policy policytimeout = Policy.Timeout(3, TimeoutStrategy.Pessimistic);
            Policy policyFallBack = Policy.Handle<TimeoutRejectedException>()
                .Fallback(() =>
                {
                    Console.WriteLine("熔斷降級");
                });
            Policy policy = policyFallBack.Wrap(policytimeout);
            policy.Execute(() =>
            {
                Console.WriteLine("完成任務");
                Thread.Sleep(5000);
                Console.WriteLine("完成任務");
            });
            Console.ReadKey();
 
複製代碼

這玩膩的用途不過就是:請求網絡接口,避免接口長期沒有響應形成系統卡死。

 

 七.Polly的異步

複製代碼
複製代碼
     Test1().Wait(); //調用

        static async Task Test1()
        {

            Policy<byte[]> policy = Policy<byte[]>
           .Handle<Exception>()
           .FallbackAsync(async c => {
               Console.WriteLine("執行出錯");
               return new byte[0];
           }, async r => {
               Console.WriteLine(r.Exception);
           });
            policy = policy.WrapAsync(Policy.TimeoutAsync(20, TimeoutStrategy.Pessimistic,
            async (context, timespan, task) =>
            {
                Console.WriteLine("timeout");
            }));
            var bytes = await policy.ExecuteAsync(async () =>
            {
                Console.WriteLine("開始任務");
                HttpClient httpClient = new HttpClient();
                var result = await httpClient.GetByteArrayAsync("https://www.cnblogs.com/images/logo_small.gif");
                Console.WriteLine("完成任務");
                return result;
            });
            Console.WriteLine("bytes長度" + bytes.Length);
        }
 
複製代碼

使用Polly的異步,那麼全部的方法都必須是異步,除了Handle方法,由於handle就不須要異步,也沒有返回值。經過異步呢,全部的重載方法都構造了一遍,仍是能夠繼續用的。那麼這段代碼的意思是,經過異步的方式若是我經過httpclient獲取某站點的圖片的base值,若是在此期間我定義了一個policy,抓住一個異常,若是說兩秒以內尚未反應我就超時。直接終止。測試的時候 你能夠把值 改變下。

 

 

 

最近的項目裏有上傳圖片的功能,固然這個功能在項目裏是必需要有的,那麼目前這個項目是使用徹底的先後端分離,在選擇文件上傳的組件中仍是選擇了全面支持Vue的IView,任何上傳圖片都是經過HTTP請求,服務端從request中讀,那麼思路有了,直接建立webapi項目吧。

通常來講,在.net core中靜態文件應該放到wwwroot,在其中建立一個文件夾。

再作好跨域的東西,通常都是經過cors包。建立控制器,代碼以下:

複製代碼
複製代碼
    public class IndexController : ControllerBase
    {
        [HttpPost]
        public async Task<bool> InsertPicture([FromServices]IHostingEnvironment environment)
        {
            var data = new PicData();
            string path = string.Empty;
            var files = Request.Form.Files;
            if (files == null || files.Count() <= 0) { data.Msg = "請選擇上傳的文件。"; return false; }
            //格式限制
            var allowType = new string[] { "image/jpg", "image/png","image/jpeg"};
            if (files.Any(c => allowType.Contains(c.ContentType)))
            {
                if (files.Sum(c => c.Length) <= 1024 * 1024 * 4)
                {
                    foreach (var file in files)
                    {
                        string strpath = Path.Combine("Upload", DateTime.Now.ToString("MMddHHmmss") + file.FileName);
                        path = Path.Combine(environment.WebRootPath, strpath);

                        using (var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                        {
                            await file.CopyToAsync(stream);
                        }
                    }
                    data.Msg = "上傳成功";
                    return true;
                }
                else
                {
                    data.Msg = "圖片過大";
                    return false;
                }
            }
            else

            {
                data.Msg = "圖片格式錯誤";
                return false;
            }
        }

    }
    public class PicData
    {
        public string Msg { get; set; }
    }
 
複製代碼

代碼解讀:

讀取wwwroot是在IHostingEnvironment對象中的,若是不經過依賴注入,就須要直接寫成參數,那麼file上傳的參數開頭都應該[FromServices]來修飾,在代碼中判斷了響應的文件格式、文件大小,經過file.copy就把文件保存在了服務器。

須要跨域:

複製代碼
複製代碼
public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddCors(options =>
            {
                options.AddPolicy("hehe", p => p.AllowAnyMethod()// 容許任何方法 GET,POST,PUT,DELETE, OPTIONS
                            .AllowAnyHeader()       // 容許任何請求頭
                            .AllowAnyOrigin()       // 容許任何地址
                   );
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseStaticFiles(); app.UseCors("hehe");
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseMvc();
        }
 
複製代碼

前臺:

複製代碼
複製代碼
<template>
    <div>
        <Upload
        multiple
        type="drag"
        action="http://localhost:54331/api/Index">
        <div style="padding: 20px 0">
            <Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
            <p>點擊或將文件拖拽到這裏上傳</p>
        </div>
    </Upload>
    </div>
</template>
<script>
export default {

}
</script>
 
複製代碼

代碼解讀::

複製代碼
前臺是很是簡單的,在main.js中引用Iview,固然這一切的前提都須要Npm一下它.iview的這個組件,action就是你請求的方法,默認呢就是post請求。那麼Iview還有別的屬性,詳見下方。
 
屬性 說明 類型 默認值
action 上傳的地址,必填 String -
headers 設置上傳的請求頭部 Object {}
multiple 是否支持多選文件 Boolean false
data 上傳時附帶的額外參數 Object -
name 上傳的文件字段名 String file
with-credentials 支持發送 cookie 憑證信息 Boolean false
show-upload-list 是否顯示已上傳文件列表 Boolean true
type 上傳控件的類型,可選值爲 select(點擊選擇),drag(支持拖拽) String select
accept 接受上傳的文件類型 String -
format 支持的文件類型,與 accept 不一樣的是,format 是識別文件的後綴名,accept 爲 input 標籤原生的 accept 屬性,會在選擇文件時過濾,能夠二者結合使用 Array []
max-size 文件大小限制,單位 kb Number -

效果圖:

文末:

後來咱們團隊考慮到使用七牛這個在線儲存圖片站點,準備好實名的帳號和sdk,獲取AccessKey,SecretKey。登陸七牛管理後臺->我的信息->祕鑰管理

那麼官方給咱們提供了.net core 的版本直接nuget就能夠了。

 

代碼:

複製代碼
複製代碼
/// <summary>
         /// 實現將文件上傳到七牛雲
         /// </summary>
         /// <param name="stream">文件流</param>
         /// <param name="fileName">文件名稱</param>
         /// <returns></returns>
         public UploadQiNiuResult UploadImgToQiNiu(byte[] stream, string fileName)
         {
             Mac mac = new Mac(BlogStatic.QiNiuInfo_AccessKey, BlogStatic.QiNiuInfo_SecretKey);
             // 上傳策略,參見
             // https://developer.qiniu.com/kodo/manual/put-policy
             PutPolicy putPolicy = new PutPolicy();
             // 若是須要設置爲"覆蓋"上傳(若是雲端已有同名文件則覆蓋),請使用 SCOPE = "BUCKET:KEY"
             // putPolicy.Scope = bucket + ":" + saveKey;
             var saveKey = string.Format("BlogImg/{0}/", DateTime.Now.ToString("yyyy/MM/dd")) + fileName;
             putPolicy.Scope = "blog:" + saveKey;
             // 上傳策略有效期(對應於生成的憑證的有效期)
             putPolicy.SetExpires();
             // 上傳到雲端多少天后自動刪除該文件,若是不設置(即保持默認默認)則不刪除
             // putPolicy.DeleteAfterDays = 1;
             string jstr = putPolicy.ToJsonString();
             //獲取上傳憑證
             var uploadToken = Auth.CreateUploadToken(mac, jstr);
             UploadManager um = new UploadManager();
 
             HttpResult result = um.UploadData(stream, saveKey, uploadToken);
 
             )
             {
                 return JsonConvert.DeserializeObject<UploadQiNiuResult>(result.Text);
             }
             return null;
         }
 
複製代碼

UploadQiNiuResult類

複製代碼
public class UploadQiNiuResult
     {
         public string Hash { get; set; }
         public string Key { get; set; }
     }
 
 
 
 

Fiddler原理~知多少?

 

首先咱們學習Fidder這個工具,咱們就應該去了解它的基本東西,好比這個單詞的意思。Fiddler叫:小提琴、騙子的意思。

 

那麼它是幹什麼的呢?

Fiddler是一個http協議調試代理工具,它可以記錄並檢查全部你的電腦和互聯網之間的http通信,設置斷點,查看全部的「進出」Fiddler的數據(指cookie,html,js,css等文件)。 Fiddler 要比其餘的網絡調試器要更加簡單,由於它不只僅暴露http通信還提供了一個用戶友好的格式,Fiddler 是用C#寫出來的,它包含一個簡單卻功能強大的基於JScript .NET 事件腳本子系統,它的靈活性很是棒,能夠支持衆多的http調試任務,而且可以使用.net框架語言進行擴展。

那麼從簡介中能夠看到,他是一個http協議的調試工具,那HTTP協議是幹什麼呢?

HTTP(HyperText Transport Protocol)是超文本傳輸協議的縮寫,它用於傳送WWW方式的數據,關於HTTP協議的詳細內容請參考RFC2616。HTTP協議採用了請求/響應模型。客戶端向服務器發送一個請求,請求頭包含請求的方法、URL、協議版本、以及包含請求修飾符、客戶信息和內容的相似於MIME的消息結構。服務器以一個狀態行做爲響應,響應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以及可能的實體內容。

剛纔我說fiddler是個騙子,那它怎麼騙的啊,咱們來打開一下。

剛剛打開沒多久,這些列表就會慢慢的加進來,這是什麼呢?這是來自於你電腦上的http請求的信息。實際上fiddler打開以後就已經進行代理了。

 

Fiddler的原理

 

左側是咱們的客戶端,就是一些終端,那它訪問各類網站的時候,會經過http請求經過進行fiddler進行代理,而後再經過fiddler的轉發請求服務器,服務器再經過response進行響應,反正就是經過fiddler是個中間層。就是這麼個意思。固然,在打開fiddler的時候就已經打開代理了。它是如何進行代理的呢?

爲何咱們打開應用或者說軟件就會被fiddler進行代理呢?咱們隨便打開個頁面,例如百度新聞。

咱們發現,咱們只要幹什麼事,都被會被他們截取,他們到底是幹了什麼邪門的事情?咱們打開瀏覽器的設置-搞基-系統-代理。

以下圖,咱們逐一打開,發現其中的端口號和咱們的Fiddler工具中的設置端口一毛同樣,這就是代理工具關鍵。固然這也是fiddler修改的。意思就是中間通過了我的,就是這個代理工具,fiddler,因此它能抓到這個包。

其中須要注意的是,當fiddler一關閉,那麼這個代理就會被關閉,也就變成灰色的了。

若是是其餘瀏覽器,有可能打開fiddler那個代理可能不會自動開啓,須要你本身找,本身開,本身關。。。。

 

 

 

ABP框架(asp.net core 2.X+Vue)模板項目學習之路(一)

 

 

 

 

前言:

  第一次接觸ABP的項目是在2018年6月份,可是當時沒有深刻具體的研究,而今天由於工做的須要,須要學習、瞭解這個框架,在時隔半年以後,今天從新下載了這個項目,雖然在園子裏有不少前輩們寫的這類的文章,可是我仍是會在博客園中記錄一下學習的過程,一是但願可以幫助到有須要的人,二是也算是本身學習的一個歷程,雖然原先的時候,偶爾也會寫一些隨筆,因爲文采的緣由,寫的可能不是特別的詳細,主要也是以代碼爲主,可是在這個學習的過程當中,會發布一些代碼,發佈一些截圖,同時也會寫一些本身的心得!

 

正文:

本篇內容主要說的是從ABP官網下載項目到項目可以在瀏覽器中正式運行起來的一個過程!

  1. 前期準備工做,具體詳細的安裝步驟,在園子裏有不少大佬和前輩都有介紹,再次就不一一寫出來了
    • 根據本身系統的須要去選擇安裝Node.js(官網地址:https://nodejs.org/en/download/)驗證是否安裝成功,在windos命令窗口輸入:node -v
    • 經過npm安裝VUE腳手架(vue-cli):npm install -g vue-cli //-g是全局安裝,驗證是否安裝成功,在windos命令窗口輸入:vue -V
    • 安裝npm安裝yarn:npm install -g yarn,驗證是否安裝成功,在windos命令窗口輸入:yarn -v
  2. 從官網下載ABP項目(官網地址:https://aspnetboilerplate.com/Templates)

  3. 下載項目壓縮包後的文件列表展現
  4. 首先咱們先運行aspnet-core項目,經過vs2017打開後,會自動去下載相關的dll字符串,在項目從新生成所有成功後更改MyABPProject.Web.Host這個項目中appsettings.json中的數據庫鏈接字符串,改爲本身的字符串,而後進行數據庫還原。
  5. 數據庫還原方式:
    • 將MyABPProject.EntityFrameworkCore這個項目設置成啓動項目(不然會報錯:

      The specified framework version '2.1' could not be parsed
      The specified framework 'Microsoft.NETCore.App', version '2.1' was not found.

    • 打開程序包管理器控制檯(工具->NuGet包管理器->程序包管理器控制檯)
    • 通「Update-Database」這個命令進行數據庫還原,等待還原完成後,直接F5啓動,在端口號後面加上「/swagger」會在瀏覽器中看到如下界面運行到此,說明asp.net core服務器端項目已正式啓動完成
  6. 接下來咱們來運行vue的客戶端程序
    • vue項目的列表信息詳細如同所示:
    • 在終端中打開vue項目的目錄地址(D:\項目管理\MyABPProject\4.3.1\vue>),經過命令「yarn install」進行安裝項目依賴,恢復安裝完成後以下圖顯示:
    • 經過命令「yarn serve --open」直接運行客戶端項目,「--open」的做用是,項目啓動後,直接在瀏覽器中打開,不須要手動輸入地址,命令「yarn serve」也能夠啓動項目,可是須要手動在瀏覽器中輸入地址
    • 瀏覽器中打開客戶端項目地址(http://localhost:8080/#/)顯示如下界面:
    • 用戶名:admin  密碼:123qwe 點擊登陸後成功進入系統:

  直至到此,項目運行完成,在上面能夠根據本身的需求進行更改,在之後的日子裏,我會詳細的記錄這個項目的前端和後端,但願你們可以監督,若是在文章中發現錯誤信息,請您及時聯繫我,我收到後會第一時間進行改正,謝謝

 

 

 

C#程序中設置全局代理(Global Proxy)

1. HttpWebRequest類的Proxy屬性,只要設置了該屬性就可以使用代理了,以下:

複製代碼
1             //設置代理
2         WebProxy WP = new WebProxy("41.76.44.76", 3128);
3             ICredentials jxCredt = new NetworkCredential("proxy_username", "proxy_password");
4             WP.Credentials = jxCredt;
5             
6             HttpWebRequest webreq = HttpWebRequest.Create(uri);
7             webreq.Proxy = WP;//將代理賦值給HttpWebRequest的Proxy屬性    

複製代碼

2.可是程序中的每個HttpWebRequest都須要如此設置,是否存在更簡便的方法,例如在某個地方設置了代理,則整個程序的全部請求都使用代理呢。

   答案是:有這樣的方法。

   ===================================

   不過在此以前先來理解一下 C#的WebRequest類(即HtteWebRequest的父類)在發送前的一些處理:

          新建立一個WebRequest實例時(經過Create方法),會自動初始化其Proxy屬性,

    而它還有一個DefaultWebProxy屬性,當用戶沒有手動設置Proxy屬性時,

    則WebRequest會使用DefaultWebProxy做爲其Proxy;

    而DefaultWebProxy是讀取項目的app.config文件來進行初始化;

    當沒有app.config文件,或者沒有在app.config中配置Proxy時,

    DefaultWebProxy就會去讀取Internet Explorer (IE)的代理設置

   ============================================

    提示:

          怎麼查看當前的請求Rquest是否使用了代理?

3.因此設置全局代理的方式有如下幾種:

   第一種:程序不作任何處理,僅設置IE的代理;

   第二種:在程序的app.config文件進行相關的配置,官方文檔,如:

複製代碼
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <configuration>
 3   <system.net>
 4     <defaultProxy>
 5       <proxy
 6         proxyaddress="http://192.168.1.10:3128"
 7       />
 8     </defaultProxy>
 9   </system.net>
10 </configuration>
複製代碼

            使用app.config設置代理時,若是想在運行時修改代理,則須要編輯app.config文件,

            能夠參考:C#讀寫config配置文件

 第三種:在代碼中爲DefaultWebProxy從新賦值,以下:         

1 WebProxy WP = new WebProxy("41.76.44.76", 3128);
2 ICredentials jxCredt = new NetworkCredential("proxy_username", "proxy_password");//若是有用戶名和密碼須要設置
3 WP.Credentials = jxCredt;
4 
5 WebRequest.DefaultWebProxy = WP;

4.總結:

    第一種直接在IE上設置的,更多適合平時測試,由於讓用戶去做這種設置很不理智;

    第二種和第三種都相對簡單,只要設置好,整個程序的全部WebRequest都會使用代理,但第二種還須要對app.config文件進行編輯,因此非硬性要求,建議使用第三種,設置DefaultWebProxy的方式;

    假如不想使用代理,則將DefaultWebProxy設爲null,這樣即便IE或者app.config設置了代理也不會影響。

    代理的優先順序:手動設置WebRequest.Proxy屬性 > DefaultWebProxy > app.config > IE的代理設置;

 

轉原文地址:https://www.cnblogs.com/tommy-huang/p/5832998.html

 

 

 

 

WCF 4.0 使用說明

WCF 4.0開發說明,工具VS2013 ,IIS,使用http協議

 


  1. 打開VS2013,新建項目Visual C#>Web>Asp.NET Web應用程序,添加相關引用:

   System.ServiceModel、System.ServiceModel.Activation、System.ServiceModel.Web

  • 新增全局應用程序類Global.asax,文件內部代碼以下:

 

       

 

     

 

  • 配置web.config文件,具體代碼以下, 不詳細解釋

 

 

  • 配置完成後,在此項目中增長Routes.xml文件,內容以下

<?xml version="1.0" encoding="utf-8" ?> <routes>   <!--添加route定義,MyPublicWCF將自動加載下面定義的服務,並添加服務路由。       perfix爲服務的跟路徑,如http://localhost/MyWCF/GetData;       serviceType爲服務類名,如命名空間MyWCF下的服務MyFirst,爲MyWCF.MyFirst;       AssemblyFile爲服務生成的DLL文件名,全部服務的DLL文件均需放到MyPublicWCF的bin目錄中,如MyWCF.dll       -->   <route perfix="MyFirst" serviceType="MyWCF.MyFirst" AssemblyFile ="MyWCF.dll" />   </routes>

  1. 不一樣的WCF接口能夠建立不一樣的類庫:
  • 新建類庫MyWCF,添加類MyFirst.cs,添加dll引用

System.ServiceModel、System.ServiceModel.Web

添加完成後,分別添加Get和POST方法,代碼以下

 

 

 經過以上編寫,一個簡單的WCF小例子就這樣完成啦。 初學者,你們多多指教啦O(∩_∩)O~

 

 

 

IIS 部署WCF 4.0

上一章節講解如何新建WCF服務,此文講解如何在IIS上發佈,並能正常訪問 


  1. 本地部署IIS
    • 首先在本機安裝IIS,IIS如何勾選,哪些是必須的?不太清楚,有清楚的大牛請指正!目前個人基本配置以下:

     

     

  •  

配置完成後,重啓電腦,將會在C盤下自動生成IIS目錄,C:\inetpub\wwwroot

  • IIS安裝完成後,配置WCF網站   ,首先建立應用程序池,FramWork4.0

 

建立完應用程序池後,添加網站,指定物理路徑,應用程序池選擇剛剛建立的Net4,如圖:


 

  • C盤文件夾下內容包括WCF項目生成的DLL,Global.asax文件,Routes.xml文件,Web.config文件。如圖所示:

 

     

 

部署完成後,重啓IIS,選中應用程序MyWCF,在功能師徒中選擇目錄瀏覽,啓用。而後選中MyWCF,右鍵管理應用程序,瀏覽,能夠看到以下界面:


出現以下界面,證實WCF服務部署成功!

具體藉口路徑,以下:

http://localhost/MyWCF/MyFirst/Help

MyWCF爲應用程序名稱,MyFirst爲Routes.xml文件中的perfix,經過訪問Help能夠查看當前服務下有多少接口,以下:

 

 

 

那麼前端就能夠經過AJAX的POST或GET方法訪問接口,和數據庫通信啦!注意:此處接口均使用JSON格式。

相關文章
相關標籤/搜索