dotnetCore微服务API网关-Ocelot学习笔记(一、API网关介绍及Ocelot介绍和配置)
零、为啥写这个
说实话工作用了两年多的微服务了,自己却连工作所用的微服务API网关都没有深入的了解和学习过,只存在于会改会写的阶段,一直觉得特别惭愧,所以自己一直想深入的了解和学习一下,然后近期不是工作不是很忙,就想着研究一下,结果去找网上的文档和博客,这里容我骂句脏话(此处并不针对谁,不服你憋着),找了十篇,结果八篇内容都差不多,全都是把官方文档的架构图拿来翻译一下,然后就是按照官方示例贴代码,让人整个看下来还是一脸懵逼,不懂还是不懂,而且找来找去就那么几篇,也不知道是这网关没人用,还是说DotNet生态不好。没办法,只能自己扒拉源码,然后把自己的理解写下来,希望对其他人也能有一些帮助。当然,要是没帮助那算了。我也不是大佬,只能理解到这种程度,或许以后有新的理解了我会把这篇文档重新写一遍,大家共同学习进步吧。
一、关于什么是API网关
API网关通常是指。。。我特么也不知道怎么讲(lll¬ω¬),通俗点大白话讲,网关在我眼里其实就是某个微服务系统的统一入口,所有对该系统的请求访问都需要通过网关转发,从而不需要分别去请求那些各个独立的服务,而且网关还支持协议转换,外部客户端可以使用Http进行请求,到了网关内部可以转换为RPC去请求具体的服务接口。
要是还不理解的话,给你个场景,自己体会,你有一个非常喜欢的人,然后终于某天你鼓起勇气想当面对她表白,于是你买了一束花准备送给她,当你骑着你心爱的小摩托兴奋无比的到了姑娘家小区门口的时候,突然发现小区西门立着一位带着红箍老大爷拦住了你的脚步,大爷看到你问:“小伙子找谁啊,要干啥 ”。然后你跟大爷说:“我要去找几号楼几号楼的XX,我是她朋友,来找她送点东西”,然后大爷掏出一个神奇的小本本让你把身份证及电话号码登记,然后扫码量体温,等你做好以后,大爷拿起门岗的电话,拨通她们家的电话,此时电话一直没人接,然后大爷告诉你,家没人,你改天再来吧!然后无情地把你赶走,但是你不死心,你又去到了小区的北门,结果发现北门锁了!倔强的你又无奈的去了小区的东门,这次经过一系列的登记和沟通后,东门的大爷说,因为疫情原因我不能让你进去,不过你可以把东西给我我给你转送过去,然后你把鲜花交给大爷,大爷骑着小电电去帮你送,一会大爷回来了,带回来一封信,你拆看信上写着你是个好人!但我们不合适,然后你还不死心,天天去送,天天得到的都是同一封信,最后那姑娘直接把信放在了大爷那,你一去大爷直接从抽屉里拿出了信。
综上所述,我们来梳理下:
首先我们把小区看成是一个微服务的系统,小区内的每栋楼都一>个独立的服务。而门户就可以看成服务的接口。
而此时,我们的小区大爷就可以看作是这个系统的网关
通过上面我们知道网关可以做到:
0、入口统一:网关不在乎你从什么地方来,你是手机客户端也好,PC客户端或者网页客户端也罢,统统都要走网关。
1、超时断开:当你请求长时间没有回应的时候,网关会断开请求
2、路由转发:网关要知道你访问的系统内部地址是哪里(路由地址Route)后并帮你进行转发,把请求转发到具体的服务接口上
3、请求方式限制:要知道你的目的是干什么(POST/GET/等..)
4、认证鉴权:登记身份(认证、鉴权)
5、负载均衡:就算一个门锁了(网关服务坏掉了),也有其他门(网关)可以处理,不会出现一个网关坏掉整个系统瘫痪的情况出现。
6、协议转换:当你骑着心爱的小摩托(Http请求)来的时候,网关转发的时候可能转换成另一种请求协议,如:GRPC或其他RPC协议(Ocelot好像只支持Http,很尴尬)
7、缓存机制:当你请求频繁并且获取的数据都是一样的时候,其实可以把数据放到网关层面缓存起来,这样可以减少系统的压力
网关还可以做的事情
1、服务降级:当你请求某项资源用时较长或者高峰时,网关会将你的请求降级到你早前设置好的降级策略中,保证接口返回可用的部分数据或者资源。
2、削峰/限流:当你的请求过多的时候,容易对服务器造成非常大压力,比如秒杀或者某些需要抢购的活动时,这个时候我们就需要把请求进行削峰/限流,提示用户排队等候。(讲到这里,我想到我之前面试一家公司的时候,面试我的那位大哥问了我很经典的搭建秒杀服务的问题,问我如何保证系统稳定和库存,当时对网关不甚了解,虽然讲到降级削峰,也是在接口级别做的,后来面试结束后我很不要脸的问了一下大哥如何处理秒杀的情况,这位大哥给我说了一句:“能在前面做的事情,你为啥非要放在后端做?你这不是给服务器增加压力嘛,削峰和限流是没错,但是我们可以在网关级别进行削峰和限流,甚至一些不重要的数据也可以缓存在网关级别。自此我就记住了网关的这两个功能。直到现在这位大哥还在我微信列表里面,本来想着遇到问题的时候请教一番,但是自始至终不敢打搅人家 -_-b”)
3、网关熔断:当网关检测到某个请求经常超时的时候,就会直接把请求熔断掉。
二、OcelotAPI网关介绍及配置方法:
接下来是官方文档原话:
Ocelot is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system.
In particular I want easy integration with IdentityServer reference and bearer tokens.
Ocelot is a bunch of middlewares in a specific order.
Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features.
翻译(大概就这意思,我当初上学的时候去参加四级考试,并且写满了卷子,却得了0分!!所以别指望我的英语水平。):
Ocelot的目标用户是,使用.Net开发的微服务/面向服务的体系结构所需要的一个统一入口站点
我特别希望能够轻松地对IdentityServer进行引用和承载令牌集成。
Ocelot 是一群(一堆?)由特性顺序组成的中间件。
Ocelot操纵HttpRequest对象进入到一个请求构建器中并设置为由其所配置的状态,在那里他创建了一个HttpRequestMessage对象,该对象用于向下游服务发出请求,发出请求的的这个中间件是Ocelot请求管道中最后一个中间件,他并不没有下一个中间件可以调用,但是会有一个中间件将HttpResponseMessage映射给HttpResponse对象,用以返回给客户端。这就是他的基本特性了。
使用方法:
在使用之前,首先要了解网关项目所需的结构和文件。
0、网关项目需要使用Asp.Net Core项目,也就是我们说的Web项目(控制台也行,只不过我嫌麻烦)
1、网关的路由规则均有ocelot.json结构的json文件进行控制,这点跟平常项目的appsettings.json用法一样,
并且支持中间添加环境变量如:ocelot.Debug.json,来区分不同环境变量下的网关项目规则。
接下来开始一步步操作:
1、创建一个ASP.Net Core项目,我这里选择的是一个空项目,这里就不放图了,然后选择SDK,
我用的是3.1的,Net5也行,主要是我还没了解完5,项目创建完以后,使用Nuget包,引用官方的包,命令就不敲了,自己去搜吧。包名:Ocelot。
2、开始配置启动类吧(Program):
因为在Ocelot中路由规则等也是通过配置文件所配置的,所以配置方法和appsettings.json的方法一样,直接通过ConfigureAppConfiguration方法来将配置添加到主机的全局配置中。就像图上写的一样,手动指定Json文件,只要确保Json文件存在就可以了。而第二种就简单多了,直接使用Iconfiguraton拓展方法,调用AddOcelot(this IConfigurationBuilder builder,IWebHostEnvironment env)方法,这样的话Ocelot会在内部先查找“ocelot.json” 和“ocelot.global.json” 文件,然后查找根据环境变量匹配出对应环境变量的文件名,最后通过读取文件等一系列操作,将各个不同文件的规则全部合并到一个文件里面去。emmmm...不得不说,这个操作特别骚。(下图是源码)
不过这里要说一下,在16.0.1这个版本的时候,AddOcelotBaseUrl()这个方法已经被标记过时了。此时支持的是在Json文件里面去设置基本URL:Please set BaseUrl in ocelot.json GlobalConfiguration.BaseUrl
在上面配置文件配置之后,我们还需要在主机的Config里面去添加一下中间件管道,此时我们的网关算是集成成功了!不过你以为这就完了?图样!我们还没有去配置规则
三、OcelotAPI网关路由规则文件:
如上所说,我们网关路由规则,使用的是Ocelot.json文件进行配置,那么这个规则都可以配置什么呢?他又是如何进行控制的呢?看下图:
这是官方文档提供的配置示例,第一张图呢,是整个Json的结构,第一个字段呢,就是我们需要配置的路由规则,这是个数组类型,为的就是让我们配置多个服务的路由规则
具体字段后面单开篇幅介绍好了。现在只介绍一下这些个字段,然后我们就会有一个问题,这些个字段是怎么去控制程序执行的呢?
在源码中我们看一下注册服务时候调用的AddOcelot()函数可以看出,他在方法里先是获取了项目的全局配置,然后实例化了一个OcelotBuilder类,并将配置传了进去,当我点击去看之后,我惊呆了,我特么第一次见这么长的构造函数,不过不要紧,下面全是依赖注入的东西,我们先放一边,直接看上面那一段的操作。通过注册TOptions配置实例绑定的方法,Ocelot将配置文件绑定到了一个FileConfiguration类中,点开这个类你会发现,这里面则全都是我们Json文件配置的东西,而通过配置的绑定,我们所指定的规则,则全都会赋值到这个类里面,并且在下面使之通过依赖注入注入到根容器中,以待使用的时候可以控制。
四、结束语:
时间不早了,媳妇催我睡觉了,剩下的下章在讲。拜拜各位。早睡早起身体好