本文只講步驟不講原理,先搭建成功再自行找資料看具體配置是什么意思!
環境:win10,vs2022 , .net6 ,neget包(Ocelot和Ocelot.Provider.Consul皆為18.0.0版本,Consul1.6.10.8版本),consul_1.14.2_windows_386
配置ocelot + consul花了一天時間,主要問題在于ocelot訪問的坑,consul注冊的時候,Node Name為計算機名稱,consul訪問直接的計算機名稱,而并非127.0.0.1或者localhost,導致報錯,提示目標計算機積極拒絕。同時注意你的訪問協議是https還是http,本文用的全是http
只需要將consul的Node Name改為127.0.0.1即可

還需要注意項目啟動和注冊的地址是否一致,如項目啟動用的是:localhost,注冊時使用的ip是:127.0.0.1,也會出現上述目標計算機積極拒絕的錯誤。
問題解決方案:
注意consul所在文件夾地址
第一種:在啟動consul的時候,node參數可以寫成 -node=127.0.0.1
如:consul agent -server -ui -bootstrap-expect=1 -data-dir=D:\Tools\consul_1.14.2_windows_386 -node=127.0.0.1 -client=0.0.0.0 -bind=127.0.0.1 -datacenter=dc1 -join 127.0.0.1
第二種:在啟動consul的時候,node參數可寫成"hostname",在Hosts文件中對,node參數添加dns解析.
consul agent -server -ui -bootstrap-expect=1 -data-dir=D:\Tools\consul_1.14.2_windows_386 -node=hostname -client=0.0.0.0 -bind=127.0.0.1 -datacenter=dc1 -join 127.0.0.1
win7 hosts文件位置:C:\Windows\System32\drivers\etc
在hosts文件中添加一行"127.0.0.1 hostname",即可
http://www.rzrgm.cn/huyougurenxinshangguo/p/15246313.html
https://blog.csdn.net/salty_oy/article/details/119636278
下面說一下實現


S1,S2引用了consul包,APIGateway引用了Ocelot包,Ocelot.Provider.Consul包
創建3個webapi,其中S1,S2為相同代碼,只修改了配置文件appsettings.json,一個端口為7000,一個端口為7001
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Consul": {
"IP": "127.0.0.1",
"Port": "8500"
},
"Service": {
"Name": "consul_test"
},
"ip": "127.0.0.1",
"port": "7000",
"AllowedHosts": "*"
}
launchSettings.json也把端口改一下,一個7000,一個7001,同時注意一下sslport這個key
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://127.0.0.1:7000",
"sslPort": 0
}
},
"profiles": {
"S2": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://127.0.0.1:7000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
webapi頁面WeatherForecastController
using Microsoft.AspNetCore.Mvc; namespace S1.Controllers { [ApiController] [Route("api/[controller]/[action]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly IConfiguration _IConfiguration; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration iConfiguration) { _logger = logger; _IConfiguration = iConfiguration; } [HttpGet] public string GetTest() { string ip = _IConfiguration["IP"]; string port = _IConfiguration["Port"]; return $@"{ip} {port}"; } //[HttpGet(Name = "GetWeatherForecast")] //public IEnumerable<WeatherForecast> Get() //{ // return Enumerable.Range(1, 5).Select(index => new WeatherForecast // { // Date = DateTime.Now.AddDays(index), // TemperatureC = Random.Shared.Next(-20, 55), // Summary = Summaries[Random.Shared.Next(Summaries.Length)] // }) // .ToArray(); //} } }
然后在S1,S2兩個api中注入consulhelper類
using Consul; namespace S2 { public static class ConsulHelper { /// <summary> /// 將當前站點注入到Consul /// </summary> /// <param name="configuration"></param> public static void ConsulRegister(this IConfiguration configuration) { //初始化Consul服務 ConsulClient client = new ConsulClient(c => { c.Address = new Uri("http://127.0.0.1:8500"); c.Datacenter = "dc1"; }); //站點做集群時ip和端口都會不一樣,所以我們通過環境變量來確定當前站點的ip與端口 string ip = configuration["ip"]; int port = int.Parse(configuration["port"]); client.Agent.ServiceRegister(new AgentServiceRegistration { ID = "service" + Guid.NewGuid(), //注冊進Consul后給個唯一id, Name = "consul_test", //站點做集群時,Name作為該集群的群名, //Address = ip, Address = "127.0.0.1", Port = port, Tags = null, //這個就是一個隨意的參數,文章后面做負載均衡的時候說 Check = new AgentServiceCheck { Interval = TimeSpan.FromSeconds(10), //HTTP = $"http://{ip}:{port}/api/health", HTTP = $"http://{ip}:{port}/api/WeatherForecast/GetTest", Timeout = TimeSpan.FromSeconds(5), DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5) } }); } } }
Program類中注入
using S2; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); app.Configuration.ConsulRegister(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseAuthorization(); app.MapControllers(); app.Run();
S1,S2代碼完全一樣,區別只修改了launchSettings.json,appsettings.json配置文件的端口號
再說一下ocelot吧,
Program類注入Ocelot
using Ocelot.DependencyInjection; using Ocelot.Middleware; using Ocelot.Provider.Consul; using Ocelot.Values; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddOcelot(new ConfigurationBuilder() .AddJsonFile("Ocelot.json") .Build()).AddConsul(); builder.Host.ConfigureLogging(c => { c.ClearProviders(); c.AddConsole(); }); //builder.Host.ConfigureAppConfiguration((context, config) => //{ // config.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true); //}).ConfigureWebHostDefaults(c => c.UseUrls("http://localhost:5000")); //builder.Services.AddSwaggerGen(); var app = builder.Build(); app.UseOcelot(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { //app.UseSwagger(); //app.UseSwaggerUI(); } app.UseAuthorization(); app.MapControllers(); app.Run();
Ocelot.json
{ "Routes": [ { "DownstreamPathTemplate": "/api/{url}", //下游服務地址--url變量 "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "127.0.0.1", "Port": 7000 } , { "Host": "127.0.0.1", "Port": 7001 } ], "UpstreamPathTemplate": "/{url}", //上游請求路徑,網關地址--url變量 "UpstreamHttpMethod": [ "Get", "Post" ], //consul "UseServiceDiscovery": true, //使用服務發現 "ServiceName": "consul_test", //consul服務名稱
"LoadBalancerOptions": { "Type": "RoundRobin" //輪詢 LeastConnection-最少連接數的服務器 NoLoadBalance不負載均衡 }, "GlobalConfiguration": { "RequestIdKey": "OcRequestId", "BaseUrl": "http://127.0.0.1:5000", //網關對外地址 //配置consul地址 "ServiceDiscoveryProvider": { "Host": "127.0.0.1", "Port": 8500, "Type": "Consul" //由consul提供服務發現,ocelot也支持etc等 } } } ] }
launchSettings.json
{ "$schema": "https://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://127.0.0.1:5001", "sslPort": 0 } }, "profiles": { "ApiGateway": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "http://127.0.0.1:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
完成之后,先啟動S1,S2,看看consul注入成功沒有,

然后啟動ApiGateway,使用其對外地址進行訪問,http://127.0.0.1:5000,注意看地址,這里和Ocelot.json里面的配置有關
"DownstreamPathTemplate": "/api/{url}", //下游服務地址--url變量
"UpstreamPathTemplate": "/{url}", //上游請求路徑,網關地址--url變量

沒配置成功請仔細看加粗加紅部分
源碼:https://gitee.com/yuanrang123/ocelot-consul
浙公網安備 33010602011771號