Asp .Net Core 系列:集成 Ocelot+Consul实现网关、服务注册、服务发现

本文主要是介绍Asp .Net Core 系列:集成 Ocelot+Consul实现网关、服务注册、服务发现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是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提供的注入方式注册consulClientservices.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 consulservices.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}
}

效果

image

image

这篇关于Asp .Net Core 系列:集成 Ocelot+Consul实现网关、服务注册、服务发现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/615713

相关文章

基于C++的UDP网络通信系统设计与实现详解

《基于C++的UDP网络通信系统设计与实现详解》在网络编程领域,UDP作为一种无连接的传输层协议,以其高效、低延迟的特性在实时性要求高的应用场景中占据重要地位,下面我们就来看看如何从零开始构建一个完整... 目录前言一、UDP服务器UdpServer.hpp1.1 基本框架设计1.2 初始化函数Init详解

Java中Map的五种遍历方式实现与对比

《Java中Map的五种遍历方式实现与对比》其实Map遍历藏着多种玩法,有的优雅简洁,有的性能拉满,今天咱们盘一盘这些进阶偏基础的遍历方式,告别重复又臃肿的代码,感兴趣的小伙伴可以了解下... 目录一、先搞懂:Map遍历的核心目标二、几种遍历方式的对比1. 传统EntrySet遍历(最通用)2. Lambd

springboot+redis实现订单过期(超时取消)功能的方法详解

《springboot+redis实现订单过期(超时取消)功能的方法详解》在SpringBoot中使用Redis实现订单过期(超时取消)功能,有多种成熟方案,本文为大家整理了几个详细方法,文中的示例代... 目录一、Redis键过期回调方案(推荐)1. 配置Redis监听器2. 监听键过期事件3. Redi

SpringBoot全局异常拦截与自定义错误页面实现过程解读

《SpringBoot全局异常拦截与自定义错误页面实现过程解读》本文介绍了SpringBoot中全局异常拦截与自定义错误页面的实现方法,包括异常的分类、SpringBoot默认异常处理机制、全局异常拦... 目录一、引言二、Spring Boot异常处理基础2.1 异常的分类2.2 Spring Boot默

基于SpringBoot实现分布式锁的三种方法

《基于SpringBoot实现分布式锁的三种方法》这篇文章主要为大家详细介绍了基于SpringBoot实现分布式锁的三种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、基于Redis原生命令实现分布式锁1. 基础版Redis分布式锁2. 可重入锁实现二、使用Redisso

SpringBoo WebFlux+MongoDB实现非阻塞API过程

《SpringBooWebFlux+MongoDB实现非阻塞API过程》本文介绍了如何使用SpringBootWebFlux和MongoDB实现非阻塞API,通过响应式编程提高系统的吞吐量和响应性能... 目录一、引言二、响应式编程基础2.1 响应式编程概念2.2 响应式编程的优势2.3 响应式编程相关技术

C#实现将XML数据自动化地写入Excel文件

《C#实现将XML数据自动化地写入Excel文件》在现代企业级应用中,数据处理与报表生成是核心环节,本文将深入探讨如何利用C#和一款优秀的库,将XML数据自动化地写入Excel文件,有需要的小伙伴可以... 目录理解XML数据结构与Excel的对应关系引入高效工具:使用Spire.XLS for .NETC

Nginx更新SSL证书的实现步骤

《Nginx更新SSL证书的实现步骤》本文主要介绍了Nginx更新SSL证书的实现步骤,包括下载新证书、备份旧证书、配置新证书、验证配置及遇到问题时的解决方法,感兴趣的了解一下... 目录1 下载最新的SSL证书文件2 备份旧的SSL证书文件3 配置新证书4 验证配置5 遇到的http://www.cppc

Nginx之https证书配置实现

《Nginx之https证书配置实现》本文主要介绍了Nginx之https证书配置的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起... 目录背景介绍为什么不能部署在 IIS 或 NAT 设备上?具体实现证书获取nginx配置扩展结果验证

SpringBoot整合 Quartz实现定时推送实战指南

《SpringBoot整合Quartz实现定时推送实战指南》文章介绍了SpringBoot中使用Quartz动态定时任务和任务持久化实现多条不确定结束时间并提前N分钟推送的方案,本文结合实例代码给大... 目录前言一、Quartz 是什么?1、核心定位:解决什么问题?2、Quartz 核心组件二、使用步骤1