《ASP.NET Core 6框架揭秘》實例演示[21]:如何承載你的后臺服務

借助 .NET提供的服務承載(Hosting)系統,我們可以將一個或者多個長時間運行的后臺服務寄宿或者承載我們創建的應用中。任何需要在后臺長時間運行的操作都可以定義成標準化的服務并利用該系統來承載,ASP.NET Core應用最終也體現為這樣一個承載服務。[本文節選《ASP.NET Core 6框架揭秘》第14章]

[S1401]利用承載服務收集性能指標(源代碼)
[S1402]依賴注入的應用(源代碼)
[S1403]配置選項的應用(源代碼)
[S1404]提供針對環境的配置(源代碼)
[S1405]日志的應用(源代碼)
[S1406]在配置中定義日志過濾規則(源代碼)

[S1401]利用承載服務收集性能指標

承載服務的項目一般會采用“Microsoft.NET.Sdk.Worker”這個SDK。服務承載模型涉及的接口和類型大都定義在“Microsoft.Extensions.Hosting.Abstractions”這個NuGet包,而具體實現在由NuGet包“Microsoft.Extensions.Hosting”來提供。我們演示的承載服務會定時采集當前進程的性能指標并將其分發出去。我們只關注處理器使用率、內存使用量和網絡吞吐量這三種典型的指標,為此我們定義了如下這個PerformanceMetrics類型。我們并不會實現真正的性能指標收集,定義的靜態方法Create會利用隨機生成的指標來創建PerformanceMetrics對象。

public?class?PerformanceMetrics
{private?static?readonly?Random?_random?=?new();public?int?????Processor?{?get;?set;?}public?long?Memory?{?get;?set;?}public?long?Network?{?get;?set;?}public?override?string?ToString()?=>?@$"CPU:?{Processor?*?100}%;?Memory:?{Memory?/?(1024*?1024)}M;?Network:?{Network?/?(1024?*?1024)}M/s";public?static?PerformanceMetrics?Create()?=>?new(){Processor?=?_random.Next(1,?8),Memory?????=?_random.Next(10,?100)?*?1024?*?1024,Network?=?_random.Next(10,?100)?*?1024?*?1024};
}

承載服務通過IHostedService接口表示,該接口定義的StartAsync和StopAsync方法可以啟動與關閉服務。我們將性能指標采集服務定義成如下這個PerformanceMetricsCollector類型。在實現的StartAsync方法中,我們一個定時器每隔5秒調用Create方法創建一個PerformanceMetrics對象,并將它承載的性能指標輸出到控制臺上。作為定期的Timer對象會在StopAsync方法中被釋放。

public?sealed?class?PerformanceMetricsCollector?:?IHostedService
{private?IDisposable??_scheduler;public?Task?StartAsync(CancellationToken?cancellationToken){_scheduler?=?new?Timer(Callback,?null,?TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(5));return?Task.CompletedTask;static?void?Callback(object??state)=>?Console.WriteLine($"[{DateTimeOffset.Now}]{PerformanceMetrics.Create()}");}public?Task?StopAsync(CancellationToken?cancellationToken){_scheduler?.Dispose();return?Task.CompletedTask;}
}

服務承載系統通過IHost接口表示承載服務的宿主,該對象在應用啟動過程中采用Builder模式由對應的IHostBuilder對象來構建。HostBuilder類型是對IHostBuilder接口的默認實現,所以我們采用如下方式創建一個HostBuilder對象,并調用其Build方法來提供作為宿主的IHost對象。在調用Build方法構建IHost對象之前,我們調用了ConfigureServices方法將PerformancceMetricsCollector注冊成針對IHostedService接口的服務,并將生命周期模式設置成Singleton。

using?App;
new?HostBuilder()
.ConfigureServices(svcs?=>?svcs.AddSingleton<IHostedService,?PerformanceMetricsCollector>()).Build().Run();

我們最后調用Run方法啟動通過IHost對象表示的承載服務宿主,進而啟動由它承載的PerformancceMetricsCollector服務,該服務將以圖1所示的形式每隔5秒在控制臺上輸出“采集”的性能指標。

d694ce5ba2b71f2c7e72d0dff3ea0a50.png
圖1 承載指標采集服務

除了采用一般的服務注冊方式,我們還可以按照如下的方式調用IServiceCollection接口的AddHostedService<THostedService>擴展方法來對承載服務PerformanceMetricsCollector進行注冊。我們一般也不會通過調用構造函數的方式創建HostBuilder對象,而是使用定義在Host類型中的 工廠方法CreateDefaultBuilder創建來構建IHostBuilder對象。

using?App;
Host.CreateDefaultBuilder(args).ConfigureServices(svcs?=>?svcs.AddHostedService<PerformanceMetricsCollector>()).Build().Run();

[S1402]依賴注入的應用

服務承載系統整合依賴注入框架,針對承載服務的注冊實際上就是將它注冊到依賴注入框架中。既然承載服務實例最終是通過依賴注入容器提供的,那么它自身所依賴的服務當然也可以進行注冊。我們接下來將PerformanceMetricsCollector提供的性能指標收集功能分解到由四個接口表示的服務中,IProcessorMetricsCollector、IMemoryMetricsCollector和INetworkMetricsCollector接口代表的服務分別用于收集三種對應的性能指標,而IMetricsDeliverer接口表示的服務則負責將收集的性能指標發送出去。

public?interface?IProcessorMetricsCollector
{int?GetUsage();
}
public?interface?IMemoryMetricsCollector
{long?GetUsage();
}
public?interface?INetworkMetricsCollector
{long?GetThroughput();
}public?interface?IMetricsDeliverer
{Task?DeliverAsync(PerformanceMetrics?counter);
}

我們定義的MetricsCollector類型實現了三個性能指標采集接口,采集的性能指標直接來源于通過靜態方法Create創建的PerformanceMetrics對象。MetricsDeliverer類型實現了IMetricsDeliverer接口,實現的DeliverAsync方法直接將PerformanceMetrics對象承載的性能指標輸出到控制臺上。

public?class?MetricsCollector?:IProcessorMetricsCollector,IMemoryMetricsCollector,INetworkMetricsCollector
{long?INetworkMetricsCollector.GetThroughput()?=>?PerformanceMetrics.Create().Network;int?IProcessorMetricsCollector.GetUsage()?=>?PerformanceMetrics.Create().Processor;long?IMemoryMetricsCollector.GetUsage()?=>?PerformanceMetrics.Create().Memory;
}public?class?MetricsDeliverer?:?IMetricsDeliverer
{public?Task?DeliverAsync(PerformanceMetrics?counter){Console.WriteLine($"[{DateTimeOffset.UtcNow}]{counter}");return?Task.CompletedTask;}
}

由于整個性能指標的采集工作被分解到四個接口表示的服務之中,所以我們可以采用如下所示的方式重新定義承載服務類型PerformanceMetricsCollector。如代碼片段所示,我們在構造函數中注入四個依賴服務,StartAsync方法利用注入的IProcessorMetricsCollector、IMemoryMetricsCollector和INetworkMetricsCollector對象采集對應的性能指標,并利用IMetricsDeliverer對象將其發送出去。

public?sealed?class?PerformanceMetricsCollector?:?IHostedService
{private?readonly?IProcessorMetricsCollector?_processorMetricsCollector;private?readonly?IMemoryMetricsCollector?_memoryMetricsCollector;private?readonly?INetworkMetricsCollector?_networkMetricsCollector;private?readonly?IMetricsDeliverer?_MetricsDeliverer;private?IDisposable??_scheduler;public?PerformanceMetricsCollector(IProcessorMetricsCollector?processorMetricsCollector,IMemoryMetricsCollector?memoryMetricsCollector,INetworkMetricsCollector?networkMetricsCollector,IMetricsDeliverer?MetricsDeliverer){_processorMetricsCollector?=?processorMetricsCollector;_memoryMetricsCollector?=?memoryMetricsCollector;_networkMetricsCollector?=?networkMetricsCollector;_MetricsDeliverer?=?MetricsDeliverer;}public?Task?StartAsync(CancellationToken?cancellationToken){_scheduler?=?new?Timer(Callback,?null,?TimeSpan.FromSeconds(5),?TimeSpan.FromSeconds(5));return?Task.CompletedTask;async?void?Callback(object??state){var?counter?=?new?PerformanceMetrics{Processor?=?_processorMetricsCollector.GetUsage(),Memory???????=?_memoryMetricsCollector.GetUsage(),Network???=?_networkMetricsCollector.GetThroughput()};await?_MetricsDeliverer.DeliverAsync(counter);}}public?Task?StopAsync(CancellationToken?cancellationToken){_scheduler?.Dispose();return?Task.CompletedTask;}
}

在調用IHostBuilder接口的Build方法將IHost對象構建出來之前,包括承載服務在內的所有服務都可以通過它的ConfigureServices方法進行了注冊。修改后的程序啟動之后同樣會在控制臺上看到圖1所示的輸出結果。

using?App;
var?collector?=?new?MetricsCollector();
Host.CreateDefaultBuilder(args).ConfigureServices(svcs?=>?svcs.AddHostedService<PerformanceMetricsCollector>().AddSingleton<IProcessorMetricsCollector>(collector).AddSingleton<IMemoryMetricsCollector>(collector).AddSingleton<INetworkMetricsCollector>(collector).AddSingleton<IMetricsDeliverer,?MetricsDeliverer>()).Build().Run();

[S1403]配置選項的應用

真正的應用開發基本都會使用到配置選項,比如我們演示程序中性能指標采集的時間間隔就應該采用配置選項來指定。由于涉及對性能指標數據的發送,所以最好將發送的目標地址定義在配置選項中。如果有多種傳輸協議可供選擇,就可以定義相應的配置選項。.NET應用推薦采用Options模式來使用配置選項,所以可以定義如下這個MetricsCollectionOptions類型來承載三種配置選項。

public?class?MetricsCollectionOptions
{public?TimeSpan?CaptureInterval?{?get;?set;?}public?TransportType?Transport?{?get;?set;?}public?Endpoint?DeliverTo?{?get;?set;?}
}public?enum?TransportType
{Tcp,Http,Udp
}public?class?Endpoint
{public?string?Host?{?get;?set;?}public?int?Port?{?get;?set;?}public?override?string?ToString()?=>?$"{Host}:{Port}";
}

傳輸協議和目標地址使用在MetricsDeliverer服務中,所以我們對它進行了如下的修改。如代碼片段所示,我們在構造函數中利用注入的IOptions<MetricsCollectionOptions>服務來提供上面的兩個配置選項。在實現的DeliverAsync方法中,我們將采用的傳輸協議和目標地址輸出到控制臺上。

public?class?MetricsDeliverer?:?IMetricsDeliverer
{private?readonly?TransportType?_transport;private?readonly?Endpoint??????????_deliverTo;public?MetricsDeliverer(IOptions<MetricsCollectionOptions>?optionsAccessor){var?options?=?optionsAccessor.Value;_transport?=?options.Transport;_deliverTo?=?options.DeliverTo;}public?Task?DeliverAsync(PerformanceMetrics?counter){Console.WriteLine($"[{DateTimeOffset.Now}]Deliver?performance?counter?{counter}?to?{_deliverTo}?via?{_transport}");return?Task.CompletedTask;}
}

承載服務類型PerformanceMetricsCollector同樣應該采用這種方式來提取表示性能指標采集頻率的配置選項。如下所示的代碼片段是PerformanceMetricsCollector采用配置選項后的完整定義。

public?sealed?class?PerformanceMetricsCollector?:?IHostedService
{private?readonly?IProcessorMetricsCollector?_processorMetricsCollector;private?readonly?IMemoryMetricsCollector?_memoryMetricsCollector;private?readonly?INetworkMetricsCollector?_networkMetricsCollector;private?readonly?IMetricsDeliverer?_metricsDeliverer;private?readonly?TimeSpan?_captureInterval;private?IDisposable??_scheduler;public?PerformanceMetricsCollector(IProcessorMetricsCollector?processorMetricsCollector,IMemoryMetricsCollector?memoryMetricsCollector,INetworkMetricsCollector?networkMetricsCollector,IMetricsDeliverer?metricsDeliverer,IOptions<MetricsCollectionOptions>?optionsAccessor){_processorMetricsCollector?=?processorMetricsCollector;_memoryMetricsCollector?=?memoryMetricsCollector;_networkMetricsCollector?=?networkMetricsCollector;_metricsDeliverer?=?metricsDeliverer;_captureInterval?=?optionsAccessor.Value.CaptureInterval;}public?Task?StartAsync(CancellationToken?cancellationToken){_scheduler?=?new?Timer(Callback,?null,?TimeSpan.FromSeconds(5),?_captureInterval);return?Task.CompletedTask;async?void?Callback(object??state){var?counter?=?new?PerformanceMetrics{Processor?=?_processorMetricsCollector.GetUsage(),Memory?=?_memoryMetricsCollector.GetUsage(),Network?=?_networkMetricsCollector.GetThroughput()};await?_metricsDeliverer.DeliverAsync(counter);}}public?Task?StopAsync(CancellationToken?cancellationToken){_scheduler?.Dispose();return?Task.CompletedTask;}
}

配置文件配置選項的常用來源,所以我們在根目錄下添加了一個名為appsettings.json的配置文件,并在其中定義如下內容來提供上述三個配置選項。由Host類型的CreateDefaultBuilder工廠方法創建的IHostBuilder對象會自動加載這個配置文件。

{"MetricsCollection":?{"CaptureInterval":?"00:00:05","Transport":?"Udp","DeliverTo":?{"Host":?"192.168.0.1","Port":?3721}}
}

我們接下來對演示程序做相應的改動。之前針對依賴服務的注冊是通過調用IHostBuilder對象的ConfigureServices方法利用作為參數的Action<IServiceCollection>對象完成的,該接口還有一個ConfigureServices方法重載,它的參數類型為Action<HostBuilderContext, IServiceCollection>,作為輸入的HostBuilderContext上下文可以提供表示應用配置的IConfiguration對象。

using?App;
var?collector?=?new?MetricsCollector();
Host.CreateDefaultBuilder(args).ConfigureServices((context,?svcs)?=>?svcs.AddHostedService<PerformanceMetricsCollector>().AddSingleton<IProcessorMetricsCollector>(collector).AddSingleton<IMemoryMetricsCollector>(collector).AddSingleton<INetworkMetricsCollector>(collector).AddSingleton<IMetricsDeliverer,?MetricsDeliverer>().Configure<MetricsCollectionOptions>(context.Configuration.GetSection("MetricsCollection"))).Build().Run();

我們利用提供的Action<HostBuilderContext, IServiceCollection>委托通過調用IServiceCollection接口的Configure<TOptions>擴展方法從提供的HostBuilderContext對象中提取出配置,并對MetricsCollectionOptions配置選項做了綁定。我們修改后的程序運行之后在控制臺上會輸出如圖2所示結果。

6f147ea3eba81fb76db622833cf64f9f.png
圖2 引入配置選項

[S1404]提供針對環境的配置

應用程序總是針對某個具體環境進行部署的,開發(Development)、預發(Staging)和產品(Production)是三種典型的部署環境,這里的部署環境在服務承載系統中統稱為承載環境(Hosting Environment)。一般來說,不同的承載環境往往具有不同的配置選項,下面我們將演示如何為不同的承載環境提供相應的配置選項。具體的做法很簡單:將共享或者默認的配置定義在基礎配置文件(如appsettings.json)中,將差異化的部分定義在針對具體環境的配置文件(如appsettings.staging.json和appsettings.production.json)中。對于我們演示的實例來說,我們可以采用圖3所示的方式添加額外的兩個配置文件來提供針對預發環境和產品環境的差異化配置。

11b37870282677ccc3a80ce38f56d215.png
圖3 針對承載環境的配置文件

對于演示實例提供的三個配置選項來說,假設針對承載環境的差異化配合僅限于發送的目標終結點(IP地址和端口),我們就可以采用如下方式將它們定義在針對預發環境的appsettings.staging.json和針對產品環境的appsettings.production.json中。

appsettings.staging.json:

{"MetricsCollection":?{"DeliverTo":?{"Host":?"192.168.0.2","Port":?3721}}
}

appsettings.production.json:

{"MetricsCollection":?{"DeliverTo":?{"Host":?"192.168.0.3","Port":?3721}}
}

由于我們在調用Host的CreateDefaultBuilder方法時傳入了命令行參數(args),所以默認創建的IHostBuilder會將其作為配置源。也正因為如此,我們可以采用命令行參數的形式設置當前的承載環境(對應配置名稱為“environment”)。如圖4所示,我們分別指定不同的承載環境先后四次運行我們的程序,從輸出的IP地址可以看出,應用程序確實是根據當前承載環境加載對應的配置文件的。輸出結果還體現了另一個細節,那就是默認采用的是產品(Production)環境。

cb9f48b3ccf1b2f76de43383f805ee8e.png
圖4 針對承載環境加載配置文件

[S1405]日志的應用

應用開發中不可避免地會涉及很多針對“診斷日志”的應用,我們接下來就來演示承載服務如何記錄日志。對于我們的演示實例來說,用于發送性能指標的MetricsDeliverer對象會將收集的指標數據輸出到控制臺上,下面將這段文字以日志的形式進行輸出,為此我們將這個類型進行了如下的修改。

public?class?MetricsDeliverer?:?IMetricsDeliverer
{private?readonly?TransportType?_transport;private?readonly?Endpoint?_deliverTo;private?readonly?ILogger?_logger;private?readonly?Action<ILogger,?DateTimeOffset,?PerformanceMetrics,?Endpoint,?TransportType,?Exception?>?_logForDelivery;public?MetricsDeliverer(IOptions<MetricsCollectionOptions>?optionsAccessor,?ILogger<MetricsDeliverer>?logger){var?options?=?optionsAccessor.Value;_transport?=?options.Transport;_deliverTo?=?options.DeliverTo;_logger?=?logger;_logForDelivery?=?LoggerMessage.Define<DateTimeOffset,?PerformanceMetrics,?Endpoint,?TransportType>(LogLevel.Information,?0,?"[{0}]Deliver?performance?counter?{1}?to?{2}?via?{3}");}public?Task?DeliverAsync(PerformanceMetrics?counter){_logForDelivery(_logger,?DateTimeOffset.Now,?counter,?_deliverTo,?_transport,?null);return?Task.CompletedTask;}
}

如上面的代碼片段所示,我們利用構造函數中注入了的ILogger<MetricsDeliverer>對象并來記錄日志。為了避免對同一個消息模板的重復解析,我們可以使用LoggerMessage類型定義的委托對象來輸出日志,這也是MetricsDeliverer中采用的編程模式。運行修改后的程序會控制臺上的輸出如圖5所示的結果。由輸出結果可以看出,這些文字是由我們注冊的ConsoleLoggerProvider提供的ConsoleLogger對象輸出到控制臺上的。由于承載系統自身在進行服務承載過程中也會輸出一些日志,所以它們也會輸出到控制臺上。

44f2960d2e8e1cd92f7fde3d51f9abf7.png
圖5 將日志輸出到控制臺上

[S1406]在配置中定義日志過濾規則

如果需要對輸出的日志進行過濾,可以將過濾規則定義在配置文件中。為了避免在“產品”環境因輸出過多的日志影響性能,我們在appsettings.production.json配置文件中以如下的形式將類別以“Microsoft.”為前綴的日志(最低)等級設置為 Warning。

{"MetricsCollection":?{"DeliverTo":?{"Host":?"192.168.0.3","Port":?3721}},"Logging":?{"LogLevel":?{"Microsoft":?"Warning"}}
}

如果此時分別針對開發(Development)環境和產品(Production)環境以命令行的形式啟動修改后的應用程序,就會發現針對開發環境控制臺會輸出類型前綴為“Microsoft.”的日志,但是在針對產品環境的控制臺上卻找不到它們的蹤影。

5ca7e250881258c642df47f89893d547.png
圖6 根據承載環境過濾日志

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282965.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282965.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282965.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用DBCA工具創建自己的數據庫

ylbtech-Oracle&#xff1a;使用DBCA工具創建自己的數據庫 DBCA創建數據庫 默認安裝的Oracle數據庫一般不能滿足實際應用的需求&#xff0c;例如數據庫名稱、數據庫塊的大小等都需要修改&#xff0c;那么我們應該自己創建一個滿足實際應用系統需要的Oracle數據實例&#xff08;…

免去架構算法調優,如何讓你的系統風馳電掣?|圖說

通用計算場景下的云服務器領域從來都是兵家必爭之地&#xff0c;價格戰曾打了一波又一波&#xff0c;可用戶痛點卻依然是“頑疾”。由于采用的基礎硬件、架構和調優技術千差萬別&#xff0c;類似配置的云服務器之間存有較大的性能差異。 但市面上五花八門的云服務器不絕于耳&am…

PHP URL的處理函數,php中url處理函數總結

在php中url處理函數有很多,如有:http_build_query,compact,urldecode、urlencode,parse_url,rawurldecode等等函數。http_build_query(PHP 5) http_build_query — 生成 URL-encode 之后的請求字符串,實例代碼如下:$dataarray(foo>bar,baz>boom,cow>milk,php>hyper…

記一次 .NET 某數控機床控制程序 卡死分析

一&#xff1a;背景 1. 講故事前段時間有位朋友微信上找到我&#xff0c;說它的程序出現了卡死&#xff0c;讓我幫忙看下是怎么回事&#xff1f; 說來也奇怪&#xff0c;那段時間求助卡死類的dump特別多&#xff0c;被迫訓練了一下對這類問題的洞察力 &#x1f604;&#x1f60…

TODO-MVP-Loaders源碼體驗

大家好&#xff0c;我是蒼王。以下是我這個系列的相關文章&#xff0c;有興趣可以參考一下&#xff0c;可以給個喜歡或者關注我的文章。[Android]如何做一個崩潰率少于千分之三噶應用app--章節列表相信有關注我的人&#xff0c;都會看過我上一編介紹的Todo-mvp源碼體驗&#xf…

.NET Framework 4.8預覽

雖然人們的大多數關注點都在.NET Core上&#xff0c;但經典的.NET Framework仍然在開發中。.NET 4.8的“早期訪問”預覽版表明了微軟最關心的領域包括高DIP、可訪問性和并發性。\\.NET 4.8預計將于2019年發布。目前的預期是&#xff0c;它將在稍后的Windows 10 build 1607上運行…

java項目商品的排名,分析了5萬個開源項目,得出的排名前16的Java工具類

原文:https://www.jianshu.com/p/9e937d178203在Java中&#xff0c;工具類定義了一組公共方法&#xff0c;這篇文章將介紹Java中使用最頻繁及最通用的Java工具類。以下工具類、方法按使用流行度排名&#xff0c;參考數據來源于Github上隨機選取的5萬個開源項目源碼。一. org.ap…

IDEA遠程調試

參考鏈接&#xff1a;http://www.cnblogs.com/wy2325/p/5600232.html 調試端口是catlina.sh中的 JAVA_OPTS-agentlib:jdwptransportdt_socket,servery,suspendn,address5023 -Xms1024m -Xmx3072m -XX:MaxNewSize128m #!/bin/sh 配置的端口&#xff0c;是address ******&#…

ASP.NETCoreWeb開發之OptionsPattern

這節我們來講一下&#xff0c;在ASP.NET Core Web開發中&#xff0c;讀取配置文件信息的新方式&#xff1a;Options。前言 /Options在ASP.NET Web框架中&#xff0c;我們讀取配置文件中的數據&#xff0c;在不使用第三方框架的情況下&#xff0c;可能需要通過ConfigurationMana…

SpringMVC執行流程圖

2019獨角獸企業重金招聘Python工程師標準>>> 轉載于:https://my.oschina.net/u/2607324/blog/827946

CC框架實踐(1):實現登錄成功再進入目標界面功能

在掘金上看到這篇文章&#xff1a;android 關于先登錄成功后再進入目標界面的思考,作者對實現登錄成功后再跳轉到目標界面功能作了比較詳細的分析&#xff0c;對比了一些已有的實現方案并指出存在的問題。最終&#xff0c;作者實現了一個可同時添加多個條件判斷攔截的方案&…

yum search php7,yum install php7 in centos6

如果有安裝的PHP包&#xff0c;先刪除他們yum list installed | grep phpyum remove php.x86_64 php-cli.x86_64 php-common.x86_64 php-gd.x86_64 php-ldap.x86_64 php-mbstring.x86_64 php-mcrypt.x86_64 php-mysql.x86_64 php-pdo.x86_64yum 安裝我們需要的軟件1.安裝epel軟…

CentOS 7系統安裝配置圖解教程

操作系統&#xff1a;CentOS 7.3 備注&#xff1a; CentOS 7.x系列只有64位系統&#xff0c;沒有32位。生產服務器建議安裝CentOS-7-x86_64-Minimal-1611.iso版本 一、安裝CentOS 7.3 成功引導系統后&#xff0c;會出現下面的界面 界面說明&#xff1a; Install CentOS 7 #安裝…

這份《.NET/C#面試手冊》超神啦!

這幾天給.neter們整理了一份《.NET/C#面試手冊》&#xff0c;目前大約4萬字左右&#xff0c;初衷也很簡單&#xff0c;就是希望在面試的時候能夠幫助到大家&#xff0c;減輕大家的負擔和節省時間。對于沒有跳槽打算的也可以復習一下相關知識點&#xff0c;就當是查缺補漏&#…

Dinic算法----最大流常用算法之一

——沒有什么是一個BFS或一個DFS解決不了的&#xff1b;如果有&#xff0c;那就兩個一起。 最大流的$EK$算法雖然簡單&#xff0c;但時間復雜度是$O(nm^2)$&#xff0c;在競賽中不太常用。 競賽中常用的$Dinic$算法和$SAP$&#xff0c;其實也不太難。 那么&#xff0c;$Dinic$算…

springcloud~Eureka實例搭建

服務端 build.gradle配置 dependencies {compile(org.springframework.cloud:spring-cloud-starter-netflix-eureka-server)testCompile(org.springframework.boot:spring-boot-starter-test) }dependencyManagement {imports {mavenBom "org.springframework.cloud:sprin…

php5.3教程,Php 5.3發布

PHP 5.3.4 特性&#xff1a; 增加對zip 流的統計支持 新增 follow_location (默認啟用)支持 增加一個 3rd parameter to get_html_translation_table Implemented FR #52348, added new constant ZEND_MULTIBYTE to detect zend multibyte at runtime. Multiple improvements t…

javascript學習筆記 null和undefined

null是javascript語言的關鍵字&#xff0c;它表示一個特殊值&#xff0c;常用來描述“空值”。對null執行typeof預算&#xff0c;結果返回字符串“object”&#xff0c;也就是說&#xff0c;可以將null認為是一個特殊的對象值&#xff0c;含義是“非對象”。但實際上&#xff0…

C# 為什么高手都是用IsNullOrWhiteSpace對字符串判空?

判斷字符串為空有好幾種方法&#xff1a;方法一&#xff1a; 代碼如下&#xff1a;static void Main(string[] args){string str "";if (str ""){Console.WriteLine("a is empty"); ;}Console.ReadKey();}運行結果&#xff1a;a is empty這樣…

使用bcftools提取指定樣本的vcf文件(extract specified samples in vcf format)

1、下載安裝bcftools。 2、準備樣本ID文件&#xff0c;這里命名為samplelistname.txt&#xff0c;一個樣本一行&#xff0c;如下所示&#xff1a; sample1 sample2 sample3 3、輸入命令&#xff1a; bcftools view -S samplelistname.txt /1000genomes/ALL.chr16.phase3_shapei…