微服務對應的就是單體式開發,單體開發和微服務的優缺點:
單體式開發:

單體式開發簡單了解為所有服務都部署在一起(一台伺服器),比如電商系統,把訂單、财務、倉儲、物流、使用者等子產品放到一起。
優點:開發簡單,集中管理,不會重複開發,沒有分布式的管理和損耗。
缺點:不好維護,更新很難,擴充性不足,無法應對現代化的疊代節奏。
微服務架構:
微服務架構把多個子產品拆分成獨立的子產品,部署在一台或多台伺服器上。
優點:
- 微服務是松藕合的,無論是在開發階段或部署階段都是獨立的。
- 能夠快速響應, 局部修改容易, 一個服務出現問題不會影響整個應用。
- 易于和第三方應用系統內建, 支援使用不同的語言開發, 允許你利用融合最新技術。
- 每個微服務都很小,足夠内聚,足夠小,代碼容易了解。團隊能夠更關注自己的工作成果, 聚焦指定的業務功能或業務需求。
- 開發簡單、開發效率提高,一個服務可能就是專一的隻幹一件事, 能夠被小團隊單獨開發,這個小團隊可以是 2 到 5 人的開發人員組成。
缺點:
- 微服務架構帶來過多的運維操作, 可能需要團隊具備一定的 DevOps 技巧.
- 分布式系統可能複雜難以管理。因為分布部署跟蹤問題難。當服務數量增加,管理複雜性增加。
有關微服務概念的了解,可以參考文章:https://blog.csdn.net/kunyus/article/details/90670710
微服務、分布式、叢集概念的了解和差別參考文章:https://blog.csdn.net/qq_37788067/article/details/79250623
下面開始建立微服務的應用執行個體:
1.添加webapi服務(包括添加log4net、注冊到控制器、記錄日志) 微服務所有執行個體均基于.NetCore3.1
API程式建立好了以後添加log4net的相關配置,用于記錄日志。
操作步驟可以參考:https://blog.csdn.net/liangmengbk/article/details/107729402
在Controllers檔案夾中添加一個控制器values
代碼如下:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
#region 依賴注入
private readonly ILogger<ValuesController> _logger;
private IConfiguration _IConfiguration;
public ValuesController(ILogger<ValuesController> logger, IConfiguration configuration)
{
_logger = logger;
_IConfiguration = configuration;
}
#endregion
[HttpGet]
public IActionResult Get()
{
this._logger.LogInformation("ValuesController-Get執行");
return new JsonResult(
new
{
Id = 123,
Name = "張三",
Remark = this._IConfiguration["Consul:ServiceRemark"],
currentPort = this._IConfiguration["Port"],
CurrentPath = base.HttpContext.Request.Path
});
}
}
2.啟動webapi服務
使用指令行啟動兩個應用程式執行個體,端口分别為5726,5727(端口是随意指定的),操作步驟如下:
将項目編譯下,然後進入項目的程式目錄中(bin\Debug\xxxxxx)
在這個目錄裡面,按住鍵盤的Shift鍵,然後點選滑鼠右鍵,選擇“在此處打開指令視窗”
這時候指令視窗就打開,并自動定位到目前目錄下,在視窗中輸入指令:
dotnet NetCore.DemoProject.dll --urls="http://*:5726" --ip="127.0.0.1" --port=5726
NetCore.DemoProject.dll是程式集的名稱,不同的項目程式集不同。
指令輸入完成後,回車,就可以看到如下情況:
這就表示程式啟動成功,在浏覽器輸入 http://localhost:5726/api/values 就可以看到api傳回的資訊:
用同樣的操作再啟動一個執行個體,在項目檔案夾下按住Shift點選滑鼠右鍵,選擇“在此處打開指令視窗”,輸入指令:
dotnet NetCore.DemoProject.dll --urls="http://*:5727" --ip="127.0.0.1" --port=5727
注意這次是5727端口,其他的不變。
這樣就表示啟動成功,在浏覽器中通路5727端口:
到這一步為止,已經啟動了兩個執行個體(其實是同一個webapi程式)。
3.下載下傳并安裝Consul
下載下傳位址:
https://www.consul.io/downloads
下載下傳完成後直接運作consul.exe程式
啟動consul:
找到consul的安裝目錄,然後在目前檔案夾中打開cmd(和上面的操作一樣)
輸入指令:
consul agent -dev
看到這個表示consul啟動成功了。
在浏覽器輸入:http://localhost:8500/ui/dc1/services 便可看到相關服務資訊:(8500是consul預設端口)
到此為止,consul和剛才建立的webapi還沒有産生任何關系,下面就将webapi服務注冊到cousul。
3.使用consul對webapi服務進行注冊
首先在webapi項目中使用NuGet包管理器安裝Consul程式集
安裝完成後在項目中建立ConsulRegister.cs的類,類中寫一個擴充方法,用于将webapi服務注冊到consul中
代碼如下:
public static class ConsulRegister
{
/// <summary>
/// 擴充方法 将服務注冊到consul
/// </summary>
/// <param name="configuration"></param>
public static void RegisterConsul(this IConfiguration configuration)
{
#region 注冊consul
string ip = configuration["ip"] ?? "Localhost"; //configuration["ip"] 為null時取Localhost
//部署到不同伺服器的時候不能寫成127.0.0.1或者0.0.0.0,因為這是讓服務消費者調用的位址
//int port = int.Parse(configuration["Consul:ServicePort"]);//服務端口
int port = string.IsNullOrWhiteSpace(configuration["port"]) ? 44344 : int.Parse(configuration["port"]);
ConsulClient client = new ConsulClient(obj =>
{
obj.Address = new Uri("http://127.0.0.1:8500");
obj.Datacenter = "dcl";
});
//向consul注冊服務
Task<WriteResult> result = client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = "ApiServiceTest_" + Guid.NewGuid(),//服務編号,不能重複,用guid最簡單
Name = "ApiServiceTest",//服務名稱
Address = ip,
Port = port,
Tags = new string[] { },//可以用來設定權重
Check = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服務停止多久後取消
Interval = TimeSpan.FromSeconds(10),//健康檢查時間間隔,或者成為心跳間隔
HTTP = $"http://{ip}:{port}/api/health",//健康檢查位址
Timeout = TimeSpan.FromSeconds(5)//檢測時最長等待時間
}
});
#endregion
}
}
4.完成健康檢查(心跳檢查)
添加健康檢查的控制器
代碼如下:
[Route("api/[controller]")]
[ApiController]
public class HealthController : ControllerBase
{
#region 依賴注入
private readonly ILogger<HealthController> _logger;
private IConfiguration _IConfiguration;
public HealthController(ILogger<HealthController> logger, IConfiguration configuration)
{
_logger = logger;
_IConfiguration = configuration;
}
#endregion
[HttpGet]
public IActionResult Check()
{
this._logger.LogInformation($"{this._IConfiguration["port"]}- Health Check!");
return Ok();//200
}
}
5.在Startup.cs類中調用第三步建立的擴充方法RegisterConsul,在webapi程式啟動時将服務注冊到consul:
到此為止,代碼編寫完成。
重新編譯項目代碼,重新啟動webapi服務(多個應用程式執行個體),可以看到控制台輸出了健康檢查(心跳檢查)的日志資訊。
在浏覽器中進入consul預設頁面,可以看到比剛開始多了名稱為ApiServiceTest的服務:
進入ApiServiceTest的詳情頁面
到此為止,成功把webapi服務注冊到consul中。
接下去就是基于consul完成服務的調用......