介绍:

Ocelot是一个.NET API网关。该项目针对的是使用.NET运行微服务/面向服务架构的人员,他们需要一个统一的入口进入他们的系统。然而,它可以处理任何说HTTP并在ASP.NET Core支持的任何平台上运行的任何东西。

Ocelot是一组按特定顺序的中间件,Ocelot操纵HttpRequest对象进入由其配置指定的状态,直到它到达请求生成器中间件,在该中间件中创建HttpRequestMessage对象,该对象用于向下游服务发出请求。提出请求的中间件是Ocelot管道中的最后一件事。它不叫下一个中间件。来自下游服务的响应存储在每个请求作用域存储库中,并在请求返回到Ocelot管道时进行恢复。有一件中间件将HttpResponseMessage映射到HttpResponse对象上,并返回给客户端。这基本上是与其他一些功能。

Ocelot只能用于.NET Core,并且目前已经构建到netstandard2.0。所有下面 我们使用.NET Core 2.1做演示。

创建一个基本示例:

首先我们创建一个.NET Core 2.1空项目。

当然我们还是要先引用的拉, Nuget 命令行: Install-Package Ocelot

配置:添加一个json文件实现最基本的配置:

{
"ReRoutes": [],
"GlobalConfiguration": {
"BaseUrl": "urladdress"
}
}

这里最重要的是BaseUrl。Ocelot需要知道它正在运行的URL,以便执行标题查找和替换以及某些管理配置。当设置这个URL时,它应该是客户端将看到的Ocelot运行的外部URL。

然后我们将刚才的配置文件加入到ASP.NET Core Configuration:Program.cs

 public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, builder) =>
{
builder
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("ocelot.json");
})
.UseStartup<Startup>();

最后在添加服务以及设置中间件:Startup.cs

 public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot();//添加ocelot服务
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseOcelot().Wait();//设置所有的Ocelot中间件
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}

这些就是基本的所需编程代码。

配置文件的详细分析:

Ocelot的主要功能是收取HTTP请求并将它们转发到下游服务。目前以另一个http请求的形式出现。Ocelot描述了将一个请求作为ReRoute路由到另一个请求。为了在Ocelot中获得任何工作,您需要在配置中设置ReRoute。

说道这里我们补充一下刚才写的json文件的两个根节点:ReRoutes和GlobalConfiguration。

ReRoutes:是一个数组,其中的每一个元素代表了一个路由,我们可以针对每一个路由进行以上功能配置,告诉Ocelot如何处理上游请求的对象。

GlobalConfiguration:全局配置,可以适当的节约配置,比如baseurl节点,服务发现配置。

这样我们就实现了通过配置文件可以完成对Ocelot的功能配置:路由、服务聚合、服务发现、认证、鉴权、限流、熔断、缓存、Header头传递等。

配置一个示例:下面这个配置信息就是将用户的请求 /ProductService/1 转发到 localhost:8001/api/Test/1

{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/Test/{postId}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "127.0.0.1",
"Port":
}
],
"UpstreamPathTemplate": "/ProductService/{postId}",
"UpstreamHttpMethod": [ "Get", "Delete" ]
}
],
"GlobalConfiguration": {
// "BaseUrl": "http://127.0.0.1:8887/"
}
}
  • DownstreamPathTemplate:下游方位url路径
  • DownstreamScheme:下游服务http schema
  • DownstreamHostAndPorts:下游服务的地址,如果使用LoadBalancer的话这里可以填多项
  • UpstreamPathTemplate: 上游也就是用户输入的请求Url模板
  • UpstreamHttpMethod: 上游请求http方法,可使用数组:Get ,Delete等

好了这样就实现了一个基本的Ocelot网关的转发示例。

下面让我们来看一下效果吧:

首先我们运行起来webapi项目发布在8001端口。然后访问地址是:http://127.0.0.1:8001/api/Test/5

我们看到的结果是:

然后我们启动我们的网关服务;发布在端口8888下,根据以上配置我们可以看到方位地址为:http://127.0.0.1:8888/ProductService/5

然后同样的请求结果是:

这样我们就实现使用统一网关来访问不同的地址,以便我们以后实现微服务的分发部署,虽然是不是多个接口,但是我们给上游访问还是提供一个接口,我们内部实现访问该访问那个接口。

至于具体怎发布也可参考这篇文章:http://www.cnblogs.com/yanbigfeg/p/9198345.html

路由小知识:

UpstreamHost=>"UpstreamHost": "baidu.com":上游主机

此功能允许您基于上游主机进行ReRoutes。这通过查看客户端使用的主机头来工作,然后将其用作我们用来识别ReRoute的信息的一部分。这样就是显示了只有在主机头值为baidu.com时才会匹配。

Priority=> "Priority": 0:优先级

此功能设置访问路由的优先级,假设在同一个路由下有多个路由,会根据优先级匹配优先级最高的,0是最低的。

Dynamic Routing:动态路由

这个主要是为了服务发现而实现的,在这种模式下,Ocelot将使用上游路径的第一个分段来查找服务发现提供商的下游服务。官网给出的大概配置效果:

{
"ReRoutes": [],
"Aggregates": [],
"GlobalConfiguration": {
"RequestIdKey": null,
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": ,
"Type": null,
"Token": null,
"ConfigurationKey": null
},
"RateLimitOptions": {
"ClientIdHeader": "ClientId",
"QuotaExceededMessage": null,
"RateLimitCounterPrefix": "ocelot",
"DisableRateLimitHeaders": false,
"HttpStatusCode":
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": ,
"DurationOfBreak": ,
"TimeoutValue":
},
"BaseUrl": null,
"LoadBalancerOptions": {
"Type": "LeastConnection",
"Key": null,
"Expiry":
},
"DownstreamScheme": "http",
"HttpHandlerOptions": {
"AllowAutoRedirect": false,
"UseCookieContainer": false,
"UseTracing": false
}
}
}

Ocelot实现多个端口的轮询:

以上实现的这个有什么用啊,单独发布了接口,然后使用另外一个接口去复制他吗?别急,这只是其中的一个基本使用,现在我们有了基本步骤,我们改一改,实现webapi发布两个接口,8001,8002.然后还使用网关地址访问,可以循环的访问到8001端口和8002端口。

说起来简单,做起来也简单,我们只需要在我们上面的配置上修改一下即可:

{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/Test/{postId}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "127.0.0.1",
"Port":
},
{
"Host": "127.0.0.1",
"Port":
}
],
"UpstreamPathTemplate": "/ProductService/{postId}",
"UpstreamHttpMethod": [ "Get" ],
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
}
],
"GlobalConfiguration": {
// "BaseUrl": "http://127.0.0.1:8887/"
}
}

启动两个端口:

重复请求网关两次结果:

Ocelot+ Consul:

实现目标:启动服务发现然后模拟集群发布功能,实现发布端口8001,8002后,启动服务发现,然后配置Ocelot网关。实现访问统一接口可以轮询访问8001,8002,8001,8002,...这样。然后可以在添加8003,继续规则。

实现以上目标我们不需要该我们的示例代码,只需要修改配置json文件即可:

{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/Test/{postId}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/Product123Service/{postId}",
"UpstreamHttpMethod": [ "Get" ],
"ServiceName": "ProductService",
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"UseServiceDiscovery": true
}
],
"GlobalConfiguration": {
// "BaseUrl": "http://127.0.0.1:8887/"
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": ,
"Type": "PollConsul",
"PollingInterval":
}
}
}

这个就是我们的服务功能:

Ocelot允许您指定服务发现提供程序,并使用它来查找Ocelot正在将请求转发给下游服务的主机和端口。目前,这仅在GlobalConfiguration部分中受支持,这意味着将为所有的ReRoute使用相同的服务发现提供程序,以便在ReRoute级别指定ServiceName。

  • ServiceName:consul的服务名称
  • LoadBalancerOptions:使用的算法,目前有两种RoundRobin(轮询方式)和LeastConnection(最小连接)
  • UseServiceDiscovery:是否启用服务发现功能 true:为启动
  • ServiceDiscoveryProvider:配置服务发现的一些配置
  • Host:主机地址
  • Port:端口
  • PollingInterval:轮询的间隔时间,以毫秒为单位。并告诉Ocelot多久可以向Consul调用服务配置的更改

想要了解更多可以访问Ocelot官网:http://ocelot.readthedocs.io/en/latest/features/servicediscovery.html

系列目录:

微服务系列文章主要介绍微服务所使用到的一些技术和一些技术示例:

【微服务No.4】 API网关组件Ocelot+Consul的更多相关文章

  1. spring cloud+dotnet core搭建微服务架构:Api网关(三)

    前言 国庆假期,一直没有时间更新. 根据群里面的同学的提问,强烈推荐大家先熟悉下spring cloud.文章下面有纯洁大神的spring cloud系列. 上一章最后说了,因为服务是不对外暴露的,所 ...

  2. Chris Richardson微服务翻译:构建微服务之使用API网关

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关(本文) 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...

  3. spring cloud+.net core搭建微服务架构:Api网关(三)

    前言 国庆假期,一直没有时间更新. 根据群里面的同学的提问,强烈推荐大家先熟悉下spring cloud.文章下面有纯洁大神的spring cloud系列. 上一章最后说了,因为服务是不对外暴露的,所 ...

  4. Spring Cloud 微服务三: API网关Spring cloud gateway

    前言:前面介绍了一款API网关组件zuul,不过发现spring cloud自己开发了一个新网关gateway,貌似要取代zuul,spring官网上也已经没有zuul的组件了(虽然在仓库中可以更新到 ...

  5. 谈谈微服务中的 API 网关(API Gateway)

    前言 又是很久没写博客了,最近一段时间换了新工作,比较忙,所以没有抽出来太多的时间写给关注我的粉丝写一些干货了,就有人问我怎么最近没有更新博客了,在这里给大家抱歉. 那么,在本篇文章中,我们就一起来探 ...

  6. 微服务中的 API 网关(API Gateway)

    API 网关(API Gateway)提供高性能.高可用的 API 托管服务,帮助用户对外开放其部署在 ECS.容器服务等云产品上的应用,提供完整的 API 发布.管理.维护生命周期管理.用户只需进行 ...

  7. .NET微服务架构及API网关

    一.MSA简介 1.1.MSA是什么 微服务架构MSA是Microservice Architecture的简称,它是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相通讯.互相配合, ...

  8. 微服务架构中API网关的角色

    [上海尚学堂的话]:本文主要讲述了Mashape的首席技术执行官Palladino对API网关的详细介绍,以及API网关在微服务中所起的作用,同时介绍了Mashape的一款开源API网关Kong. A ...

  9. Spring Cloud 微服务二:API网关spring cloud zuul

    前言:本章将继续上一章Spring Cloud微服务,本章主要内容是API 网关,相关代码将延续上一章,如需了解请参考:Spring Cloud 微服务一:Consul注册中心 Spring clou ...

随机推荐

  1. [ 10.05 ]CF每日一题系列—— 962B贪心和思维?

    Description: 非 * 号的地方可以放A或B,不能AA或BB,一共有a个A,b个B,问你最多放几个 Solution: 1.模拟一下,找连续空位长度,如果长度为奇数,则我可以有一个位置放任意 ...

  2. 清除Linux日志文件命令

    find /opt/tomcat/logs/catalina_* -mtime +9 -exec rm -rf {} \;

  3. 软件测试-chapter2-homework2

    程序一 1.the fault:for循环中i>0应改为i>=0 for (int i=x.length-1; i >= 0; i--) 2. (Reachability可达性,是f ...

  4. pycharm断点应用

    1.在需要打断点行处,单击鼠标左键打断点 2.调试程序开始,在第一个断点之前停止 3.跳过第一个断点进入到下一个断点

  5. C/C++ 多线程机制

    一.C/C++多线程操作说明 C/C++多线程基本操作如下: 1. 线程的建立结束 2. 线程的互斥和同步 3. 使用信号量控制线程 4. 线程的基本属性配置 在C/C++代码编写时,使用多线程机制, ...

  6. Android 代码混淆配置总结

    一.前言 为何需要混淆呢?简单的说,就是将原本正常的项目文件,对其类,方法,字段,重新命名,a,b,c,d,e,f…之类的字母,达到混淆代码的目的,这样反编译出来,结构乱糟糟的,看了也头大. 另外说明 ...

  7. Javascript高级编程学习笔记(82)—— 富文本操作(2)

    操作富文本 与富文本编辑器的交互的主要方式就是使用 document.execCommand() 方法 该方法可以对文档执行自定义命令,并且可以应用大多数格式 该方法接收三个参数: 要执行命令的名称 ...

  8. 使用githubpages主题NexT的语法

    使用githubpages主题NexT的语法 NexT 前言 不知道为啥?网站总是不出现? 添加「标签」页面 title: 标签测试文章 tags: - Testing - Another Tag - ...

  9. editormd实现文章详情页面预览

    继之前博客写了editmd.js(国内开源的一款前端Markdown框架)实现的写文章功能之后,本博客介绍使用editormd实现文章预览功能,之前博客链接:https://blog.csdn.net ...

  10. ubuntu下opencv的版本切换及遇到的问题解决

    默认使用opencv 3.2的时候,使用SVM的时候,系统报错如下: error: ‘class MySVM’ has no member named ‘decision_func’ 解决方法:要把系 ...