.NET 8 + Ocelot + Consul 实现代理网关、服务发现
.NET 8 + Ocelot + Consul 实现代理网关、服务发现
本文环境:.NET 8 + Ocelot 23.4.2 + Consul 1.7.14.6
1 实现网关
- 分别创建3个WebApi工程:
OcelotGw
、TestGwAService
、TestGwBService
; - 在
OcelotGw
工程中安装Ocelot
包:Install-Package Ocelot
- 添加JSON配置文件或直接在
appsettings.json
文件中添加配置;- 配置内容:
{ "Routes": [ { "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 5001 } ], "UpstreamPathTemplate": "/A/{url}", "UpstreamHttpMethod": [ "Get" ] }, { "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 5002 } ], "UpstreamPathTemplate": "/B/{url}", "UpstreamHttpMethod": [ "Get" ] }, { "DownstreamPathTemplate": "/todos/{id}", "DownstreamScheme": "https", "DownstreamHostAndPorts": [ { "Host": "jsonplaceholder.typicode.com", "Port": 443 } ], "UpstreamPathTemplate": "/todos/{id}", "UpstreamHttpMethod": [ "Get" ] } ], "GlobalConfiguration": { "BaseUrl": "https://localhost:5000/" } }
- 在测试服务中分别添加
HelloController
[Route("api/[controller]")] [ApiController] public class HelloController : ControllerBase { [HttpGet] public IActionResult Get() { return Ok("Hello from Service A!"); } }
- 同时启动三个工程,并访问
https://localhost:5000/B/Hello
和https://localhost:5000/B/Hello
测试。
2 服务发现
下面使用服务发现完成ServiceA
的配置;
- 下载Consul:Install Consul
- 运行Consul,启动命令:
consul.exe agent -dev
; - 修改
ServiceA
的Ocelot
配置:{ "UseServiceDiscovery": true, "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "ServiceName": "ServiceA", "UpstreamPathTemplate": "/A/{url}", "UpstreamHttpMethod": [ "Get" ] }
- 在
ServiceA
中添加健康监测接口:using Microsoft.AspNetCore.Mvc; namespace Hearth.TestGwAService.Controllers { [Route("[controller]/[action]")] [ApiController] public class HealthController : ControllerBase { [HttpGet("/healthCheck")] public IActionResult Check() => Ok("ok"); } }
- 在
ServiceA
的Program
中进行代理服务注册:var consulClient = new ConsulClient(x => { // consul 服务地址 x.Address = new Uri("http://localhost:8500"); }); var registration = new AgentServiceRegistration() { ID = Guid.NewGuid().ToString(), Name = "ServiceA",// 服务名 Address = "localhost", // 服务绑定IP Port = 5001, // 服务绑定端口 Check = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册 Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔 HTTP = "http://localhost:5001/healthCheck",//健康检查地址 Timeout = TimeSpan.FromSeconds(5) } }; // 服务注册 consulClient.Agent.ServiceRegister(registration).Wait(); var app = builder.Build(); // 应用程序终止时,服务取消注册 app.Lifetime.ApplicationStopping.Register(() => { consulClient.Agent.ServiceDeregister(registration.ID).Wait(); });
3 一些问题
- 在
Ocelot
配置文件中,旧版本可能用的是ReRoutes
,新版本中应该是Routes
; - 注意
DownstreamScheme
,如果使用ssl应为https
; - 在开发环境使用Consul服务发现时,需要注意是否使用SSL验证,无效的证书会导致502 Bad Gateway;
- 官方文档:ocelot.readthedocs.io