什么是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. GCD Inside: GCD 宏

    1 __OBJC__ __OBJC__宏的定义在 GCD 源码中找不到,它定义在 LLVM 的源码中: // initPreprocessor.cpp static void InitializeSt ...

  2. Guess-the-Number

    第一次做压缩包逆向 了解到的用jd-gui打开 得到的简单代码可以在在线平添运行

  3. Python利用pandas进行数据合并

    当使用Python中的pandas库时,merge函数是用于合并(或连接)两个数据框(DataFrame)的重要工具.它类似于SQL中的JOIN操作,允许你根据一个或多个键(key)将两个数据框连接起 ...

  4. Linux 本地AMH 服务器管理面板实现远程访问方法

    AMH 是一款基于 Linux 系统的服务器管理面板,它提供了一系列的功能,包括网站管理.FTP 管理.数据库管理.DNS 管理.SSL 证书管理等.使用 AMH 云主机面板可以方便地管理服务器,提高 ...

  5. iOS APP包分析工具

    介绍 分享一款用于分析iOSipa包的脚本工具,使用此工具可以自动扫描发现可修复的包体积问题,同时可以生成包体积数据用于查看.这块工具我们团队内部已经使用很长一段时间,希望可以帮助到更多的开发同学更加 ...

  6. 畅捷通T+与道一云对接集成报销信息列表连通凭证创建

    畅捷通T+与道一云对接集成获取报销信息列表连通凭证创建 数据源系统:道一云 在道一云坚实的技术基础上,道一云推出全新升级的2.0产品矩阵,分别是低码平台.智能门户.场景应用.基于云原生底座,为企业提供 ...

  7. ABAP 生产订单长文本增强 <销售计划 、物料独立需求 长文本带入 计划订单-生产订单 >

    计划订单长文本带入生产订单 尝试在生产订单保存后 用 creat_text 函数 去创建长文本,发现前台不显示,查看 文本抬头底表 STXL 发现有值 ,用READ 函数 读取 能读. DATA:td ...

  8. Linux笔记03: Linux常用命令_3.4文件和目录共用命令

    3.4 目录和文件共用命令 3.4.1 rm命令 ●命令名称:rm. ●英文原意:remove files or directories. ●所在路径:/usr/bin/rm. ●执行权限:所有用户. ...

  9. Go 语言区块链测试:实践指南

    引言 Go 语言在区块链开发中的应用日益增多,凭借其简洁的语法和强大的并发支持,成为开发区块链应用的热门选择.理解和实践 Go 语言的单元测试对于保证区块链应用的质量和稳定性至关重要. Go 单元测试 ...

  10. v-for和指令

    . v-for 起遍历作用. 注意点: 1.遍历的里面第一个值是定义的元素的值,第二个值是值的名称,第三个值为下标 2.:key是v-blind:key的简写,是代码中的唯一标识,一般用id来定义 v ...