什么是Ocelot?

Ocelot是一个开源的ASP.NET Core微服务网关,它提供了API网关所需的所有功能,如路由、认证、限流、监控等。

Ocelot是一个简单、灵活且功能强大的API网关,它可以与现有的服务集成,并帮助您保护、监控和扩展您的微服务。

以下是Ocelot的一些主要功能:

  1. 路由管理:Ocelot允许您定义路由规则,将请求路由到正确的微服务。
  2. 认证和授权:Ocelot支持多种认证机制,如JWT、OAuth等,并允许您定义访问控制策略,确保只有授权的用户才能访问特定的API。
  3. 限流和速率限制:Ocelot提供了一些内置的限流和速率限制功能,以确保您的服务不会受到过度的请求压力。
  4. 监控和日志:Ocelot可以收集和显示各种度量指标,帮助您了解您的服务的性能和行为。此外,它还可以将日志记录到各种日志源,以便您进行分析和故障排除。
  5. 集成:Ocelot可以与现有的服务集成,包括Kubernetes、Consul等。
  6. 易于扩展:Ocelot的设计使其易于扩展,您可以编写自己的中间件来处理特定的逻辑,例如修改请求或响应、添加自定义的认证机制等。
  7. 可扩展的配置:Ocelot使用JSON配置文件进行配置,这意味着您可以轻松地根据需要进行配置更改,而无需重新编译代码。

总之,Ocelot是一个功能强大且易于使用的API网关,可以帮助您保护、监控和扩展您的微服务。

Asp .Net Core 集成 Ocelot

要在ASP.NET Core中集成Ocelot,您可以按照以下步骤进行操作:

  1. 安装Ocelot NuGet包:

    在您的ASP.NET Core项目中,打开终端或NuGet包管理器控制台,并运行以下命令来安装Ocelot的NuGet包:
dotnet add package Ocelot
  1. 添加Ocelot配置文件:
{
"Routes": [ //这里注意一下版本(旧版本用ReRoutes)
{
"DownstreamPathTemplate": "/api/{controller}", //下游路径模板
"DownstreamScheme": "http", //下游方案
//"DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": "5014"
// }
//], //下游主机和端口
"UpstreamPathTemplate": "/api/product/{controller}", //上游路径模板
"UpstreamHttpMethod": [], //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
"ServiceName": "api-product-service", //请求服务名称
"LoadBalancerOptions": {
"Type": "LeastConnection" //负载均衡算法:目前 Ocelot 有RoundRobin 和LeastConnection算法
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5015", //进行标头查找和替换以及某些管理配置
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "127.0.0.1", //你的Consul的ip地址
"Port": 8500, //你的Consul的端口
"Type": "Consul" //类型
//"ConfigurationKey": "Consul" //指定配置键,键入您的配置
}
}
}
  1. 配置Ocelot服务:
builder.Services.AddOcelot();

Configure方法中配置请求管道并添加Ocelot中间件:

app.UseOcelot().Wait();

Ocelot 集成 Consul

要将Ocelot集成到Consul中,您可以按照以下步骤进行操作:

  1. 安装依赖项:

    在您的ASP.NET Core项目中,安装Ocelot和Consul的NuGet包。您可以使用以下命令来安装这些包:
dotnet add package Ocelot.Provider.Consul
  1. 配置Ocelot:

    在Ocelot的配置中,您需要指定Consul作为服务发现和配置的提供者。在Ocelot的配置文件(例如appsettings.json)中,添加以下内容:
{
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5015", //进行标头查找和替换以及某些管理配置
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "127.0.0.1", //你的Consul的ip地址
"Port": 8500, //你的Consul的端口
"Type": "Consul" //类型
//"ConfigurationKey": "Consul" //指定配置键,键入您的配置
}
}
}

确保将ConsulHostConsulPort设置为Consul服务器的正确地址和端口。

  1. 启动Ocelot:

    在您的ASP.NET Core应用程序中启动Ocelot。您可以在Startup.cs文件中添加以下代码:
builder.Services.AddOcelot().AddConsul();

全部代码

Consul相关代码

namespace MCode.Common.Extensions.Consul
{
public class ConsulOptions
{
/// <summary>
/// 当前应用IP
/// </summary>
public string IP { get; set; } /// <summary>
/// 当前应用端口
/// </summary>
public int Port { get; set; } /// <summary>
/// 当前服务名称
/// </summary>
public string ServiceName { get; set; } /// <summary>
/// Consul集群IP
/// </summary>
public string ConsulIP { get; set; } /// <summary>
/// Consul集群端口
/// </summary>
public int ConsulPort { get; set; } /// <summary>
/// 权重
/// </summary>
public int? Weight { get; set; }
}
}
using Consul.AspNetCore;
using Consul;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Builder; namespace MCode.Common.Extensions.Consul
{
public static class ConsulServiceExtensions
{
/// <summary>
/// 向容器中添加Consul必要的依赖注入
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <returns></returns>
public static IServiceCollection AddMCodeConsul(this IServiceCollection services)
{
var configuration = services.BuildServiceProvider().GetRequiredService<IConfiguration>();
// 配置consul服务注册信息
var consulOptions = configuration.GetSection("Consul").Get<ConsulOptions>();
// 通过consul提供的注入方式注册consulClient
services.AddConsul(options => options.Address = new Uri($"http://{consulOptions.ConsulIP}:{consulOptions.ConsulPort}")); // 通过consul提供的注入方式进行服务注册
var httpCheck = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔,或者称为心跳间隔
HTTP = $"http://{consulOptions.IP}:{consulOptions.Port}/health",//健康检查地址
Timeout = TimeSpan.FromSeconds(10)
}; // Register service with consul
services.AddConsulServiceRegistration(options =>
{
options.Checks = new[] { httpCheck };
options.ID = Guid.NewGuid().ToString();
options.Name = consulOptions.ServiceName;
options.Address = consulOptions.IP;
options.Port = consulOptions.Port;
options.Meta = new Dictionary<string, string>() { { "Weight", consulOptions.Weight.HasValue ? consulOptions.Weight.Value.ToString() : "1" } };
options.Tags = new[] { $"urlprefix-/{consulOptions.ServiceName}" }; //添加
}); return services;
} /// <summary>
/// 配置Consul检查服务
/// </summary>
/// <param name="app"></param>
/// <returns></returns>
public static IApplicationBuilder UseConsulCheckService(this IApplicationBuilder app)
{
app.Map("/health", app =>
{
app.Run(async context =>
{
await Task.Run(() => context.Response.StatusCode = 200);
});
}); return app;
}
}
}

Cors

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MCode.Common.Extensions.Cors
{
public static class CorsServiceExtensions
{
private readonly static string PolicyName = "MCodeCors"; /// <summary>
/// 添加跨域
/// </summary>
/// <param name="services">服务集合</param>
/// <returns></returns>
public static IServiceCollection AddMCodeCors(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));
//origin microsoft.aspnetcore.cors
return services.AddCors(options =>
{
options.AddPolicy(PolicyName, policy =>
{
policy.SetIsOriginAllowed(_ => true).AllowAnyMethod().AllowAnyHeader().AllowCredentials();
});
});
}
/// <summary>
/// 使用跨域
/// </summary>
/// <param name="app">应用程序建造者</param>
/// <returns></returns>
public static IApplicationBuilder UseMCodeCors(this IApplicationBuilder app)
{
return app.UseCors(PolicyName);
}
}
}

Swagger

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MCode.Common.Extensions.Swagger
{
/// <summary>
/// 网关Swagger配置
/// </summary>
public class OcelotSwaggerOptions
{
public List<SwaggerEndPoint> SwaggerEndPoints { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MCode.Common.Extensions.Swagger
{
/// <summary>
/// 网关Swagger配置
/// </summary>
public class OcelotSwaggerOptions
{
public List<SwaggerEndPoint> SwaggerEndPoints { get; set; }
}
}
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace MCode.Common.Extensions.Swagger
{
/// <summary>
/// Swagger配置
/// </summary>
public class SwaggerOptions
{
/// <summary>
/// 服务名称
/// </summary>
public string ServiceName { get; set; } /// <summary>
/// API信息
/// </summary>
public OpenApiInfo ApiInfo { get; set; } /// <summary>
/// Xml注释文件
/// </summary>
public string[] XmlCommentFiles { get; set; } /// <summary>
/// 构造函数
/// </summary>
/// <param name="serviceName">服务名称</param>
/// <param name="apiInfo">API信息</param>
/// <param name="xmlCommentFiles">Xml注释文件</param>
public SwaggerOptions(string serviceName, OpenApiInfo apiInfo, string[] xmlCommentFiles = null)
{
ServiceName = !string.IsNullOrWhiteSpace(serviceName) ? serviceName : throw new ArgumentException("serviceName parameter not config.");
ApiInfo = apiInfo;
XmlCommentFiles = xmlCommentFiles;
}
}
}
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models; namespace MCode.Common.Extensions.Swagger
{
/// <summary>
/// Swagger 服务扩展
/// </summary>
public static class SwaggerServiceExtensions
{
/// <summary>
/// 添加 Swagger 服务
/// </summary>
/// <param name="services"></param>
/// <param name="swaggerOptions"></param>
/// <returns></returns>
public static IServiceCollection AddMCodeSwagger(this IServiceCollection services, SwaggerOptions swaggerOptions)
{
services.AddSingleton(swaggerOptions); SwaggerGenServiceCollectionExtensions.AddSwaggerGen(services, c =>
{
c.SwaggerDoc(swaggerOptions.ServiceName, swaggerOptions.ApiInfo); if (swaggerOptions.XmlCommentFiles != null)
{
foreach (string xmlCommentFile in swaggerOptions.XmlCommentFiles)
{
string str = Path.Combine(AppContext.BaseDirectory, xmlCommentFile);
if (File.Exists(str)) c.IncludeXmlComments(str, true);
}
} SwaggerGenOptionsExtensions.CustomSchemaIds(c, x => x.FullName); c.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT",
Description = "请输入 bearer 认证"
}); c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" }
},
new string[] {}
}
});
}); return services;
} /// <summary>
/// 使用 Swagger UI
/// </summary>
/// <param name="app"></param>
/// <returns></returns>
public static IApplicationBuilder UseMCodeSwagger(this IApplicationBuilder app)
{
string serviceName = app.ApplicationServices.GetRequiredService<SwaggerOptions>().ServiceName; SwaggerUIBuilderExtensions.UseSwaggerUI(SwaggerBuilderExtensions.UseSwagger(app), c =>
{
c.SwaggerEndpoint("/swagger/" + serviceName + "/swagger.json", serviceName);
});
return app;
} public static IServiceCollection AddMCodeOcelotSwagger(this IServiceCollection services, OcelotSwaggerOptions ocelotSwaggerOptions)
{
services.AddSingleton(ocelotSwaggerOptions);
SwaggerGenServiceCollectionExtensions.AddSwaggerGen(services);
return services;
} public static IApplicationBuilder UseMCodeOcelotSwagger(this IApplicationBuilder app)
{
OcelotSwaggerOptions ocelotSwaggerOptions = app.ApplicationServices.GetService<OcelotSwaggerOptions>(); if (ocelotSwaggerOptions == null || ocelotSwaggerOptions.SwaggerEndPoints == null)
{
return app;
} SwaggerUIBuilderExtensions.UseSwaggerUI(SwaggerBuilderExtensions.UseSwagger(app), c =>
{
foreach (SwaggerEndPoint swaggerEndPoint in ocelotSwaggerOptions.SwaggerEndPoints)
{
c.SwaggerEndpoint(swaggerEndPoint.Url, swaggerEndPoint.Name);
}
});
return app;
}
}
}

MCode.ApiGateway.Program

using MCode.Common.Extensions.Swagger;
using MCode.Common.Extensions.Consul;
using MCode.Common.Extensions.Cors;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;
using Microsoft.AspNetCore.Hosting; var builder = WebApplication.CreateBuilder(args); builder.WebHost.UseUrls(builder.Configuration.GetValue<string>("Url") ?? ""); //builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("ocelot.json", false, true); // Add services to the container.
builder.Services.AddMCodeConsul(); builder.Services.AddMCodeCors(); builder.Services.AddMCodeOcelotSwagger(new OcelotSwaggerOptions { SwaggerEndPoints = new List<SwaggerEndPoint> { new SwaggerEndPoint { Name = "api-product-service", Url= "http://localhost:5014/swagger/api-product-service/swagger.json" } } }); builder.Services.AddOcelot().AddConsul(); builder.Services.AddControllers(); var app = builder.Build(); app.UseMCodeCors(); app.UseMCodeOcelotSwagger(); app.UseConsulCheckService(); // Configure the HTTP request pipeline. app.UseAuthorization(); app.UseOcelot().Wait(); app.Run();

appsettings.json

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Routes": [ //这里注意一下版本(旧版本用ReRoutes)
{
"DownstreamPathTemplate": "/api/{controller}", //下游路径模板
"DownstreamScheme": "http", //下游方案
//"DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": "5014"
// }
//], //下游主机和端口
"UpstreamPathTemplate": "/api/product/{controller}", //上游路径模板
"UpstreamHttpMethod": [], //上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法
"ServiceName": "api-product-service", //请求服务名称
"LoadBalancerOptions": {
"Type": "LeastConnection" //负载均衡算法:目前 Ocelot 有RoundRobin 和LeastConnection算法
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5015", //进行标头查找和替换以及某些管理配置
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "127.0.0.1", //你的Consul的ip地址
"Port": 8500, //你的Consul的端口
"Type": "Consul" //类型
//"ConfigurationKey": "Consul" //指定配置键,键入您的配置
}
},
"Url": "http://localhost:5015",
"Consul": {
"ConsulIP": "127.0.0.1",
"ConsulPort": "8500",
"ServiceName": "api-gateway",
"Ip": "localhost",
"Port": "5015",
"Weight": 1
},
"AllowedHosts": "*"
}

MCode.Product.Api.Program

using MCode.Product.Api;
using MCode.Common.Extensions.Consul;
using MCode.Common.Extensions.Cors;
using MCode.Common.Extensions.Swagger; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.WebHost.UseUrls(builder.Configuration.GetValue<string>("Url") ?? ""); builder.Services.AddControllers(); builder.Services.AddMCodeConsul(); builder.Services.AddMCodeCors(); builder.Services.AddMCodeSwagger(new SwaggerOptions("api-product-service", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "产品服务" }, new string[] { "MCode.Product.Api.xml" })); var app = builder.Build(); app.UseAuthorization(); app.UseMCodeCors(); app.UseMCodeSwagger(); app.UseConsulCheckService(); app.MapControllers(); app.Run();

appsettings.json

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Url": "http://localhost:5014",
"Consul": {
"ConsulIP": "127.0.0.1",
"ConsulPort": "8500",
"ServiceName": "api-product-service",
"Ip": "localhost",
"Port": "5014",
"Weight": 1
}
}

效果

Asp .Net Core 系列:集成 Ocelot+Consul实现网关、服务注册、服务发现的更多相关文章

  1. asp.net core系列 60 Ocelot 构建服务认证示例

    一.概述 在Ocelot中,为了保护下游api资源,用户访问时需要进行认证鉴权,这需要在Ocelot 网关中添加认证服务.添加认证后,ReRoutes路由会进行身份验证,并使用Ocelot的基于声明的 ...

  2. asp.net core系列 59 Ocelot 构建基础项目示例

    一.入门概述 从这篇开始探讨Ocelot,Ocelot是一个.NET API网关,仅适用于.NET Core,用于.NET面向微服务/服务的架构中.当客户端(web站点.ios. app 等)访问we ...

  3. asp.net core系列 61 Ocelot 构建服务发现简单示例

    一.概述 Ocelot允许指定服务发现提供程序,如Consul或Eureka. 这二个中间件是用来实现:服务治理或秒服务发现,服务发现查找Ocelot正在转发请求的下游服务的主机和端口.目前Ocelo ...

  4. 【目录】asp.net core系列篇

    随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...

  5. .Net Core 商城微服务项目系列(二):使用Ocelot + Consul构建具备服务注册和发现功能的网关

    1.服务注册 在上一篇的鉴权和登录服务中分别通过NuGet引用Consul这个包,同时新增AppBuilderExtensions类: public static class AppBuilderEx ...

  6. .net core Ocelot Consul 实现API网关 服务注册 服务发现 负载均衡

    大神张善友 分享过一篇 <.NET Core 在腾讯财付通的企业级应用开发实践>里面就是用.net core 和 Ocelot搭建的可扩展的高性能Api网关. Ocelot(http:// ...

  7. asp.net core 系列 18 web服务器实现

    一. ASP.NET Core Module 在介绍ASP.NET Core Web实现之前,先来了解下ASP.NET Core Module.该模块是插入 IIS 管道的本机 IIS 模块(本机是指 ...

  8. asp.net core 系列 16 Web主机 IWebHostBuilder

    一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...

  9. Asp.net Core 系列之--5.认证、授权与自定义权限的实现

    ChuanGoing 2019-11-24 asp.net core系列已经来到了第五篇,通过之前的基础介绍,我们了解了事件订阅/发布的eventbus整个流程,初探dapper ORM实现,并且简单 ...

  10. (8)ASP.NET Core3.1 Ocelot Consul服务注册与发现

    1.服务注册与发现(Service Discovery) ●服务注册:我们通过在每个服务实例写入注册代码,实例在启动的时候会先去注册中心(例如Consul.ZooKeeper.etcd.Eureka) ...

随机推荐

  1. 使用MVVM Toolkit简化WPF开发

    最近. NET 8 的 WPF 推出了 WPF File Dialog改进,这样无需再引用 Win32 命名空间就可以实现文件夹的选择与存储了,算是一个很方便的改进了.顺手写了一个小的 WPF 程序, ...

  2. python之字符串format()方法

    format()方法就是格式化指定的值,然后再将其插入字符串的占位符内 占位符用大括号{}来定义哈,可以使用命名索引{sws}.编号索引{0}.甚至空的占位符{}来标识占位符. 语法就是 string ...

  3. 一文搞懂C#中类成员的可访问性

    公众号「DotNet学习交流」,分享学习DotNet的点滴. 文末有总结,想快速浏览的朋友可直接看文末. 1.成员访问修饰符 在C#中类成员访问修饰符一共有5个,分别是public.private.p ...

  4. 前端解析excel表格

    需求如下: 前端拿到表格中的数据,对数据做以下判断,并将拿到的数据转换成以下json格式,传给后端. 具体实现: 下载npm包:npm install xlsx --save 在vue文件中引入依赖: ...

  5. [CF1830D] Mex Tree

    题目描述 You are given a tree with $ n $ nodes. For each node, you either color it in $ 0 $ or $ 1 $ . T ...

  6. [USACO2007OPENG] Dining G

    题目描述 Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she w ...

  7. 5分钟安装Kubernetes+带你轻松安装istio服务网格指南

    上次我跟大家简单介绍了一下Kubernetes的各个组件及其含义,本期本来计划带领大家一起学习一些常用命令,但我认为这种方式可能无法达到学习的效果.有可能你们会直接忘记,甚至可能没有兴趣去学.我也理解 ...

  8. SpringBoot-Validation优雅实现参数校验

    1.是什么? 它简化了 Java Bean Validation 的集成.Java Bean Validation 通过 JSR 380,也称为 Bean Validation 2.0,是一种标准化的 ...

  9. MybatisPlus条件查询方法全解

    1.是什么? MybatisPlus通过条件构造器可以组装复杂的查询条件,写一些复杂的SQL语句,从而简化我们的开发提升我们的开发效率 # 可以简单的理解为就是我们写SQL语句时where后面的条件 ...

  10. 时间加权平均价格算法(TWAP)和成交量平均算法(VWAP)在量化回测的应用

    为什么要引入TWAP和 VWAP? 为了评估策略的资金容量,我们对M.trade模块里买入点和卖出点这两个参数进行了更丰富的扩展,支持了策略能够按更丰富的算法交易价格(WAP)进行撮合. 如果资金是1 ...