在现代微服务架构中,API 网关 是连接客户端与后端服务的重要组件,它负责请求的路由、负载均衡、身份验证、聚合等功能。随着微服务数量的增多,管理这些服务的复杂度也逐渐增加,而 Ocelot 作为一个轻量级的、基于 .NET 平台的 API 网关,能够简化这一过程,提供强大的功能。
本文将通过一个电商应用的示例,详细讲解如何使用 Ocelot API 网关,从基础配置到高级功能的实现,帮助开发者更好地理解和应用 Ocelot。
一、项目架构
在本示例中,我们假设开发了一个简单的电商系统,包含以下几个微服务:
- Product Service:提供产品信息(如获取产品列表和单个产品的接口)。
- Order Service:处理订单相关的操作(如创建订单和获取订单详情)。
- Customer Service:处理客户信息(如获取客户资料)。
Ocelot 将作为统一的 API 网关,对外暴露统一入口,接收客户端请求并路由到对应的微服务。同时,Ocelot 将处理一些高级功能,如请求聚合、身份验证、限流等。
系统架构图
scss
+-------------------+
| |
| Ocelot API |
| Gateway |
| |
+--------+----------+
|
+---------+---------+---------+
| | |
+------v-------+ +-------v-------+ +-------v-------+
| Product | | Order | | Customer |
| Service | | Service | | Service |
| (5001) | | (5002) | | (5003) |
+-------------+ +---------------+ +---------------+
二、创建微服务
我们将依次创建 ProductService
、OrderService
和 CustomerService
,这三个服务将为 Ocelot 提供数据支持。
1. Product Service
首先创建一个简单的 ProductService 微服务,它提供产品相关的信息。
创建 ProductService 项目
arduino
dotnet new webapi -n ProductService
在 Controllers
文件夹下创建 ProductController.cs
,提供获取产品列表和单个产品信息的接口:
csharp
using Microsoft.AspNetCore.Mvc;
namespace ProductService.Controllers
{
[ApiController]
[Route("api/v1/products")]
public class ProductController : ControllerBase
{
[HttpGet]
public IActionResult GetAllProducts()
{
var products = new[]
{
new { Id = 1, Name = "Product 1", Price = 100 },
new { Id = 2, Name = "Product 2", Price = 200 }
};
return Ok(products);
}
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
var product = new { Id = id, Name = "Product " + id, Price = id * 100 };
return Ok(product);
}
}
}
2. Order Service
接下来创建一个 OrderService 微服务,提供订单相关的接口。
创建 OrderService 项目
arduino
dotnet new webapi -n OrderService
在 Controllers
文件夹下创建 OrderController.cs
,提供获取订单信息的接口:
csharp
using Microsoft.AspNetCore.Mvc;
namespace OrderService.Controllers
{
[ApiController]
[Route("api/v1/orders")]
public class OrderController : ControllerBase
{
[HttpGet("{orderId}")]
public IActionResult GetOrderDetails(int orderId)
{
var order = new { OrderId = orderId, ProductId = 1, Quantity = 2, Total = 200 };
return Ok(order);
}
}
}
3. Customer Service
最后,创建一个 CustomerService 微服务,提供客户信息的接口。
创建 CustomerService 项目
arduino
dotnet new webapi -n CustomerService
在 Controllers
文件夹下创建 CustomerController.cs
,提供获取客户信息的接口:
csharp
using Microsoft.AspNetCore.Mvc;
namespace CustomerService.Controllers
{
[ApiController]
[Route("api/v1/customers")]
public class CustomerController : ControllerBase
{
[HttpGet("{customerId}")]
public IActionResult GetCustomerDetails(int customerId)
{
var customer = new { CustomerId = customerId, Name = "Customer " + customerId };
return Ok(customer);
}
}
}
三、创建 Ocelot API 网关
现在我们来创建 Ocelot API 网关,将来自客户端的请求路由到不同的微服务。
1. 创建 Ocelot 项目
创建 OcelotApiGateway 项目
arduino
dotnet new webapi -n OcelotApiGateway
安装 Ocelot 包
csharp
dotnet add package Ocelot
配置 Program.cs 文件
ini
var builder = WebApplication.CreateBuilder(args);
// 注册 Ocelot 服务
builder.Services.AddOcelot();
var app = builder.Build();
// 使用 Ocelot 中间件
app.UseOcelot().Wait();
app.Run();
2. 配置 ocelot.json 文件
在 Ocelot 项目根目录下创建 ocelot.json
配置文件,定义请求路由规则:
json
{
"ReRoutes": [
{
"UpstreamPathTemplate": "/product",
"DownstreamPathTemplate": "/api/v1/products",
"DownstreamHostAndPorts": [
{ "Host": "localhost", "Port": 5001 }
],
"UpstreamHttpMethod": ["GET"]
},
{
"UpstreamPathTemplate": "/order/{orderId}",
"DownstreamPathTemplate": "/api/v1/orders/{orderId}",
"DownstreamHostAndPorts": [
{ "Host": "localhost", "Port": 5002 }
],
"UpstreamHttpMethod": ["GET"]
},
{
"UpstreamPathTemplate": "/customer/{customerId}",
"DownstreamPathTemplate": "/api/v1/customers/{customerId}",
"DownstreamHostAndPorts": [
{ "Host": "localhost", "Port": 5003 }
],
"UpstreamHttpMethod": ["GET"]
}
]
}
解释:
/product
请求会被 Ocelot 转发到localhost:5001/api/v1/products
。/order/{orderId}
请求会被转发到localhost:5002/api/v1/orders/{orderId}
。/customer/{customerId}
请求会被转发到localhost:5003/api/v1/customers/{customerId}
。
3. 配置启动服务
在 Program.cs
文件中配置 Ocelot 服务,确保它在启动时加载 ocelot.json
配置:
scss
builder.Services.AddOcelot();
app.UseOcelot().Wait();
四、启动微服务和 Ocelot API 网关
- 启动 ProductService 、OrderService 和 CustomerService ,确保它们分别监听端口
5001
、5002
和5003
。 - 启动 OcelotApiGateway ,确保它监听端口
5000
。
五、访问 API 网关
通过浏览器或 Postman 访问 Ocelot API 网关:
- 访问产品信息 :
http://localhost:5000/product
- Ocelot 会将请求转发到
ProductService
,返回产品列表。
- Ocelot 会将请求转发到
- 访问订单详情 :
http://localhost:5000/order/1
- Ocelot 会将请求转发到
OrderService
,返回订单详情。
- Ocelot 会将请求转发到
- 访问客户信息 :
http://localhost:5000/customer/1
- Ocelot 会将请求转发到
CustomerService
,返回客户信息。
- Ocelot 会将请求转发到
六、高级功能:请求聚合和身份验证
1. 请求聚合
假设你想要通过一个 API 聚合多个微服务的数据。例如,当客户端请求 /order-details/{orderId}
时,你需要同时请求 OrderService
和 ProductService
,然后将它们的响应合并后返回给客户端。
更新 ocelot.json
文件以支持请求聚合:
json
{
"ReRoutes": [
{
"UpstreamPathTemplate": "/order-details/{orderId}",
"DownstreamPathTemplate": "/api/v1/orders/{orderId}",
"UpstreamHttpMethod": ["GET"],
"Aggregation": {
"RequestAggregations": [
{
"UpstreamPathTemplate": "/order-details/{orderId}",
"DownstreamPathTemplate": "/api/v1/orders/{orderId}",
"UpstreamHttpMethod": ["GET"]
},
{
"UpstreamPathTemplate": "/product-details/{orderId}",
"DownstreamPathTemplate": "/api/v1/products/{orderId}",
"UpstreamHttpMethod": ["GET"]
}
]
}
}
]
}
2. 身份验证
假设你需要在 Ocelot 中为某些服务配置 JWT 身份验证,确保只有授权用户可以访问相关服务。
更新 ocelot.json
文件配置身份验证:
json
{
"ReRoutes": [
{
"UpstreamPathTemplate": "/product",
"DownstreamPathTemplate": "/api/v1/products",
"DownstreamHostAndPorts": [
{ "Host": "localhost", "Port": 5001 }
],
"UpstreamHttpMethod": ["GET"],
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer"
}
}
]
}
在 Program.cs
中配置 JWT 认证:
ini
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
options.Authority = "https://your.auth.server";
options.Audience = "api1";
});
七、总结
通过这篇文章
,我们从创建微服务开始,到配置 Ocelot API 网关,再到实现高级功能(如请求聚合、身份验证),逐步完成了一个完整的微服务架构。Ocelot 的灵活性和强大功能使得它在微服务架构中扮演着至关重要的角色,它不仅帮助开发者集中管理服务路由,还能有效地处理身份验证、限流、负载均衡等关键任务。
希望本教程能够帮助你更好地理解和使用 Ocelot,提升你的微服务架构的可管理性和可扩展性。如果你有任何问题或进一步的需求,欢迎随时提出!