.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", // 服务绑定IPPort = 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