.net core 微服务之Api网关(Api Gateway)

原文:.net core 微服务之Api网关(Api Gateway)

微服务网关目录

      • 1、 微服务引子
      • 2、使用Nginx作为api网关
      • 3、自创api网关(重复轮子)
        • 3.1、构建初始化
        • 3.2、构建中间件
      • 4、结语
  • 引用链接

1、 微服务引子

首先恭喜你,进入微服务的开发世界。微服务属于架构演进中的一种阶段,其特点是根据业务模块水平划分服务种类,每个服务可以独立部署并互相隔离,并对外提供轻量的Api调用,服务具有高可用特性。

微服务应遵循的设计原则:

  • 单一职责原则: 每个微服务只需要实现自己的业务逻辑
  • 服务自治原则: 每个微服务都是独立的,不依赖其他模块
  • 轻量级通信原则:一般采用Http + Json方式
  • 接口明确原则:接口尽量做的更通用,更灵活,从而尽量避免接口参数的来回修改。

我从2017年12月开始接触微服务概念,并开始着手构建公司的微服务平台,系统架构采用 .net core webapi方式组织,随着微服务的增多,越来越需要一个统一入口管理这些微服务。

2、使用Nginx作为api网关

Nginx是由IgorSysoev为俄罗斯访问量第二的Rambler.ru站点开发的,一个高性能的HTTP和反向代理服务器。2012年,Nginx荣获年度云计算开发奖,并成长为世界第二大Web服务器。全世界流量最高的前1000名网站中,超过25%都使用Nginx来处理海量的互联网请求。

Nginx很牛掰,业界公认的首选,选择它作为api网关,可以说不用开发介入,只需要运维的同学好好规划配置即可。

网关配置规划如下:

/api/ServiceA —> ServiceA

/api/ServiceB —> ServiceB

/api/ServiceC —> ServiceC

外部统一的访问入口是Nginx,然后根据服务名称路由到不同的微服务站点。

api网关的路由难题解决了,其他熔断,灰度发布,线上测试,日志拦截等功能nginx做起来相对比较吃力,不过对于中小型平台已经够用了。

3、自创api网关(重复轮子)

半年后,换了家公司,公司微服务平台搭建采用Thrift RPC作为各个微服务的通讯协议,由于当时的无知(Socket协议已被Nginx支持),所以决定写个Api代理类,没敢叫Api网关,是因为实现的功能仅限于路由!

仅仅是路由,当然是祭出 .net core Web应用。

3.1、构建初始化

MVC框架包就别包含了,轻量的性能才能好!

Main函数初始化线程池大小

			//初始化线程池最小大小 为 300
           ThreadPool.GetMinThreads(out var wt, out var ct);
           if (wt < 300 || ct < 300)
           {
               ThreadPool.SetMinThreads(Math.Max(wt, 300), Math.Max(ct, 300));
           }

**注意:**线程池不是越大越好,最佳选择约等于 cpu内核的2倍,有个公式参考:

多说一句吧,思考下:

为什么Nginx只用4个线程发挥出的性能就大大超越了100个进程的Apache HTTPD?回想一下计算机科学的基础知识,答案其实是很明显的。

我要支持跨域访问:

public void ConfigureServices(IServiceCollection services)
{
      services.AddCors(options =>
      {
          options.AddPolicy("AllowAll", p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());
      });
  }

配置下使用中间件

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
       {
           app.UseCors("AllowAll");
           app.UseMiddleware<ProxyMiddleware>();
           // app.UseMvc();
       }

3.2、构建中间件

路由转发,一个中间件即可搞定。

    public class ProxyMiddleware
   {
       private readonly RequestDelegate m_Next;

       public ProxyMiddleware(RequestDelegate next)
       {
           this.m_Next = next;
       }

       public Task Invoke(HttpContext context)
       {
           if (context.Request.Method?.ToUpper() == "GET")
           {
               var path = context.Request.Path.HasValue ? context.Request.Path.ToString().ToLower() : string.Empty;
               if (string.IsNullOrEmpty(path) || path.Equals("/") || path.Equals("/api") || path.Equals("/api/"))
               {
                   return this.SendConstRespond(context);
               }
               //增加一个代理网关接口,返回微服务列表
               else if (path.EndsWith("/getallservices"))
               {
                   return this.SendServiceListRespond(context);
               }

               return this.SendStringRespond(context);
           }

           if (context.Request.ContentType == null || context.Request.ContentType.IndexOf("application/json") < 0)
           {
               context.Response.StatusCode = 403;
               context.Response.ContentType += "application/json;charset=utf-8;";
               return context.Response.WriteAsync("Please set ContentType=application/json");
           }

           return this.SendStringRespond(context);
       }

       private Task SendStringRespond(HttpContext context)
       {
           context.Response.StatusCode = 200;
           context.Response.ContentType += "application/json;charset=utf-8;";

           Task task = new Task(() =>
           {
               if (ServerSetting.Config.QuantumConfig.RpcService.ServerType==ServerType.HttpWebApi)
               {
                  string constResp = QuantumHttpProxy.SendHttp(context);
                   using (var strStream = new StreamWriter(context.Response.Body))
                   {
                       strStream.Write(constResp);
                       strStream.Flush();
                   }
               }
               else
               {
                   QuantumHttpProxy.Send(context);
               }
           });
           task.Start();

           return task;
       }

       private Task SendConstRespond(HttpContext context)
       {
           context.Response.StatusCode = 200;
           context.Response.ContentType += "application/json;charset=utf-8;";

           Task task = new Task(() =>
           {
               var constResp = new
               {
                   rid = string.Empty,
                   c = 200,
                   msg = "Access api gateway success!"
               };
               using (var strStream = new StreamWriter(context.Response.Body))
               {
                   strStream.Write(JsonConvert.SerializeObject(constResp));
                   strStream.Flush();
               }
           });
           task.Start();
           return task;
       }
       private Task SendServiceListRespond(HttpContext context)
       {
           context.Response.StatusCode = 200;
           context.Response.ContentType += "application/json;charset=utf-8;";

           Task task = new Task(() =>
           {
               var svrs = ServerSetting.Config?.HttpProxy?.Items?.Select(x => x.Name)?.ToList() ?? new List<string>();
               var constResp = new
               {
                   rid = Guid.NewGuid().ToString("N"),
                   c = 200,
                   v = svrs,
               };
               using (var strStream = new StreamWriter(context.Response.Body))
               {
                   strStream.Write(JsonConvert.SerializeObject(constResp));
                   strStream.Flush();
               }
           });
           task.Start();
           return task;
       }
   }

上面的代码里 有 QuantumHttpProxy,是我们封装的rpc调用,因此各位同学要用此类,请自行修改之。

4、结语

没有重试,熔断也没有降级,是否很low?

这就是实际实践的力量,不必耗费太多精力在一些非关键点上!

好吧,我承认我研究了 **polly**类库,重试,熔断,降级都准备好了,你就起航吧~~~

另外:造轮子只适合特定场景,小投入就可以完成的某些特定功能,比如上面的路由功能!如果你是云服务,可以重点考虑下 阿里API网关,亚马逊api网关!

引用链接

  1. 口袋代码仓库
  2. 在线计算器
  3. 本节源码:github

原文地址:https://www.cnblogs.com/lonelyxmas/p/10286315.html

时间: 2024-08-09 01:22:11

.net core 微服务之Api网关(Api Gateway)的相关文章

.NET Core微服务二:Ocelot API网关

.NET Core微服务一:Consul服务中心 .NET Core微服务二:Ocelot API网关 .NET Core微服务三:polly熔断与降级 本文的项目代码,在文章结尾处可以下载. 本文使用的环境:Windows10 64位 + VS 2019 + .NET Core 2.1 + Ocelot 8.0.8 Ocelot 相关地址: https://github.com/ThreeMammals/Ocelot https://ocelot.readthedocs.io/en/lates

.NET Core微服务之基于Ocelot实现API网关服务(续)

一.负载均衡与请求缓存 1.1 负载均衡 为了验证负载均衡,这里我们配置了两个Consul Client节点,其中ClientService分别部署于这两个节点内(192.168.80.70与192.168.80.71). 为了更好的展示API Repsonse来自哪个节点,我们更改一下返回值: [Route("api/[controller]")] public class ValuesController : Controller { // GET api/values [Http

.NET Core微服务之基于Consul实现服务治理

一.Consul基础介绍 Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,比如 Airbnb的SmartStack等相比,Consul的方案更"一站式",内置了服务注册与发现框 架.分布一致性协议实现.健康检查.Key/Value存储.多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等),使用起来也较 为简单. Consul用Golang实现,因此具有天然可移植性(支持Linux.windows和Ma

.NET Core微服务之路:目录

微服务架构,对于从事JAVA架构的童鞋来说,早已不是什么新鲜的事儿,他们有鼎鼎大名的Spring Cloud这样的全家桶框架支撑,包含微服务核心组件如 1. Eureka:实现服务注册与发现. 2. Zuul:实现统一API网关. 3. Hystrix:实现熔断保护与可视化监控. 4. Config:实现统一管理配置. (还有更多组件,欢迎补充) 都是我们NET程序员梦寐以求的福音,而.NET Core发展至今,也专门是为微服务提供的框架平台,只是目前处于各路神仙各显神通的阶段,没有一个统一的框

.net core 微服务之日志落盘设计

原文:.net core 微服务之日志落盘设计 目录 1.设计目标 2.日志流程 3.串联请求事务 3.1 请求ID 3.2 处理服务器.服务 3.3 处理接口名 3.4 日志的发生时间 3.5 接口返回状态码 4.记录结构 5.RabbitMq队列 6.落盘 7.性能优化 8.简单统计 引用链接 1.设计目标 对各个微服务的访问进行请求追踪,注重排查开发.线上问题 消息队列发送.多服务落盘,事后分析 日志分析 性能优化 2.日志流程 前端Api网关MQXX微服务api请求1条代理层访问时间日志

.NET Core微服务系列基础文章

今年从原来的Team里面被抽出来加入了新的Team,开始做Java微服务的开发工作,接触了Spring Boot, Spring Cloud等技术栈,对微服务这种架构有了一个感性的认识.虽然只做了两个月的开发工作,但是对微服务架构的兴趣却没有结束,又因为自己的.NET背景(虽然对.NET的生态有点恨铁不成钢),想要探索一下在.NET平台下的微服务架构的可行性,也准备一些材料作为分享的素材. 幸运的是,在.NET Core首届在线峰会上,看到了很多前辈的分享,也增强了自己要摸索和实践.NET Co

ASP.NET Core微服务框架Ocelot+Consul+IdentityServer4实战演练

一.背景介绍 API网关的流行源于最近几年移动应用与企业间接口对接的兴起,使得原来单一的PC客户端,变化到PC客户端.各种浏览器.手机移动端及智能终端等.同时系统之间大部分都不是单独运行,经常会涉及与其他系统对接.共享数据的需求.随着微服务架构概念的提出,API网关成为了微服务架构的一个标配组件.随着业务快速发展,面向手机移动应用业务越来越多,为了减少客户端与服务的耦合,节约后端微服务的开发成本,建立一个高性能.高可用.减少上线风险的API网关成为一个迫切的需求. 1).目前面临现状:假设你正好

[译]API网关(API Gateway)

This a translation of an article ( http://microservices.io/patterns/apigateway.html) originally written and copyrighted by Chris Richardson ( http://twitter.com/crichardson). 模式:API网关 背景 我们假设你使用微服务模式创建一个在线商店,并正在实现商品详情页面.你需要开发多个版本的商品详情用户界面: 用于桌面和手机浏览器

AspNetCore微服务下的网关-Kong(一)

Kong是Mashape开源的高性能高可用API网关和API服务管理层.它基于OpenResty,进行API管理,并提供了插件实现API的AOP.Kong在Mashape 管理了超过15,000 个API,为200,000开发者提供了每月数十亿的请求支持.本文将从架构.API管理.插件三个层面介绍Kong. 架构 按照康威定律,我们系统架构会拆的很散,系统由一堆服务组成,如下图所示: 库存服务.优惠券服务.价格服务时之前都会做一些特殊处理,如限流.黑白名单,日志.请求统计.而这些处理几乎是所有服