.Net Core with 微服务 - Ocelot 网关

上一次我们通过一张架构图(.Net Core with 微服务 - 架构图)来讲述了微服务的结构,分层等内容。从现在开始我们开始慢慢搭建一个最简单的微服务架构。这次我们先用几个简单的 web api 项目以及 ocelot 网关项目来演示下网关是如何配置,如何工作的。

Ocelot 网关

Ocelot 是使用 asp.net core 开发的一个 api 网关项目。它功能丰富,集成了路由、限流、缓存、聚合等功能。它使用 .net 编写,本质上就是一堆 asp.net core 的中间件,所以它天生对 .net 友好。这些中间件拦截外部的请求,根据路由配置转发到对应的内部服务上,再把内部的返回结果对外暴露。

搭建项目结构

新建一个解决方案,新建几个项目。

  • api_gateway API网关

  • hotel_base 酒店基本信息服务

  • member_center 会员中心服务

  • ordering 订单服务

安装 Ocelot

在API网关项目上使用nuget安装Ocelot的类库。Ocelot本质上就是一堆 asp.net Core 的 middleware。所以我们需要在UseOcelot扩展方法在注册这些中间件。

Install-Package Ocelot
        public static void Main(string[] args){new WebHostBuilder().UseKestrel().UseContentRoot(Directory.GetCurrentDirectory()).ConfigureAppConfiguration((hostingContext, config) =>{config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath).AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true).AddJsonFile("routes.json").AddEnvironmentVariables();}).ConfigureServices(s => {s.AddOcelot();}).ConfigureLogging((hostingContext, logging) =>{logging.AddConsole();}).UseIISIntegration().Configure(app =>{app.UseOcelot().Wait();}).Build().Run();}}

在 main 函数内注册Ocelot的中间件,服务,使用AddJsonFile指定路由的配置文件。

路由

Ocelot最基本的功能就是反向代理。代理的配置通过一个json文件来配置。下面让我们来简单的演示下如何配置。
以下是通过网关代理访问酒店服务的酒店列表的配置示例。

 {//获取酒店列表"UpstreamPathTemplate": "/api/hotel","UpstreamHttpMethod": [ "Get" ],"DownstreamPathTemplate": "/hotel","DownstreamScheme": "http","DownstreamHostAndPorts": [{//hotel service"Host": "localhost","Port": 6003}]
}

配置主要是分为Upstream跟Downstream两部分。Upstream其实就是指代ocelot网关本身。Downstream代表真正的服务。

  • UpstreamPathTemplate 网关匹配的路径

  • UpstreamHttpMethod 网关匹配的请求方法

  • DownstreamPathTemplate 服务匹配的路径

  • DownstreamScheme 服务的Scheme,http、https

  • DownstreamHostAndPorts 服务的主机地址跟端口

上面的配置描述的意思是:把对网关的/api/hotel的GET请求转发到主机http://localhost:6003/hotel接口上。

路由参数

Ocelot的path模板可以使用{param}模式来匹配参数,然后传递到下游服务器上。

    {//获取单个酒店"UpstreamPathTemplate": "/api/hotel/{hotel_id}","UpstreamHttpMethod": [ "Get" ],"DownstreamPathTemplate": "/hotel/{hotel_id}","DownstreamScheme": "http","DownstreamHostAndPorts": [{//hotel service"Host": "localhost","Port": 6003}],"Key": "hotel_base_info",}

使用{hotel_id}匹配hotelId参数。

    {//获取酒店房间列表"UpstreamPathTemplate": "/api/hotel_rooms/{hotel_id}","UpstreamHttpMethod": [ "Get" ],"DownstreamPathTemplate": "/room/hotel_rooms/{hotel_id}","DownstreamScheme": "http","DownstreamHostAndPorts": [{//hotel service"Host": "localhost","Port": 6003}],"Key": "hotel_rooms"}

使用{hotel_id}匹配hotelId参数。

    {//获取查询订单"UpstreamPathTemplate": "/api/order/query?day={day}","UpstreamHttpMethod": [ "Get" ],"DownstreamPathTemplate": "/order/get_orders?day={day}","DownstreamScheme": "http","DownstreamHostAndPorts": [{//order service"Host": "localhost","Port": 6001}]}

在QueryString上使用{day}匹配参数。

限流

Ocelot支持对请求的限流操作。

 "RateLimitOptions": {"EnableRateLimiting": true,"Period": "1s","PeriodTimespan": 1,"Limit": 1}

在路由配置节点添加RateLimitOptions节点。

  • EnableRateLimiting = true 开启限流

  • Period = 1s 限流的时间区间为1s

  • PeriodTimespan = 1 限流后重置时间

  • Limit = 1 限制请求的数量

上面的配置的意思是1秒内限制一次请求,1秒后重置这个限制。

缓存

Ocelot可以对请求的响应值提供缓存服务。

//缓存5s"FileCacheOptions": { "TtlSeconds": 5 }

在路由配置节点上配置FileCacheOptions字段,TtlSeconds代表需要缓存的时间,单位是秒。

聚合

上一回我们讲微服务架构的时候说到“聚合服务层”,我们说这一层的主要功能是对请求进行聚合适配跟裁剪。其实ocelot已经提供了简单的api聚合功能。如果聚合的需求比较简单,那么可以使用ocelot直接实现。

简单聚合

简单聚合可以通过配置把几个请求的聚合成一个请求,一次性返回几个请求的响应。响应通过json格式被包装返回。

  "Aggregates": [{//聚合 查询酒店信息跟酒店房间列表"RouteKeys": ["hotel_base_info","hotel_rooms"],"UpstreamPathTemplate": "/api/hotel_detail/{hotel_id}"},]

RouteKeys 代表需要聚合的请求的键值。

使用代码聚合

上面我们直接通过配置实现了api之间聚合请求。这种聚合比较简单,会把聚合的几个请求的响应值原封不动的返回回来。有的时候我们需要对返回值做一些转换或者裁剪,比如同一个api我们对移动端的响应可能需要裁剪掉部分字段。这种需求在ocelot内我们可以使用代码来完成。
这里不太推荐这种聚合方式,这会造成网关跟下游服务的强耦合关系。

这里我们演示下如何把获取酒店信息跟酒店房间列表的返回值进行裁剪,并返回一个新的响应。

    public class HotelDetailInfoForMobileAggregator : IDefinedAggregator{public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses){dynamic hotelInfo = new ExpandoObject();List<dynamic> rooms = new List<dynamic>();foreach (var context in responses){if ((context.Items["DownstreamRoute"] as dynamic).Key == "hotel_base_info"){var respContent = await context.Items.DownstreamResponse().Content.ReadAsStringAsync();hotelInfo = JsonConvert.DeserializeObject<dynamic>(respContent);}if ((context.Items["DownstreamRoute"] as dynamic).Key == "hotel_rooms"){var respContent = await context.Items.DownstreamResponse().Content.ReadAsStringAsync();rooms = JsonConvert.DeserializeObject<List<dynamic>>(respContent);}}dynamic newResponse = new ExpandoObject();newResponse.hotel = new { hotelInfo.id,hotelInfo.name};newResponse.rooms = rooms.Select(x => new { x.id,x.no});var stringContent = new StringContent(JsonConvert.SerializeObject(newResponse));return new DownstreamResponse(stringContent, System.Net.HttpStatusCode.OK, responses.SelectMany(x => x.Items.DownstreamResponse().Headers).ToList(),"OK");}}

每一个聚合都需要继承IDefinedAggregator这个接口然后实现Aggregate方法。在这个方法内对每个请求的响应值进行裁剪,然后重新组合。

    {//聚合 查询酒店信息跟酒店房间列表 移动端 裁剪"RouteKeys": ["hotel_base_info","hotel_rooms"],"UpstreamPathTemplate": "/api/m/hotel_detail/{hotel_id}","Aggregator": "HotelDetailInfoForMobileAggregator"}

在配置文件的Aggregates内添加一个配置节点在“Aggregator”字段上指定Aggregator的类名。

  .ConfigureServices(s => {s.AddOcelot().AddTransientDefinedAggregator<HotelDetailInfoForMobileAggregator>();})

同时在ConfigureServices方法内配置HotelDetailInfoForMobileAggregator的依赖注入。

总结

本次我们通过几个最简单的web api项目,演示了如何使用 ocelot 网关进行反向代理,限流,聚合等常用功能。可以看到 ocelot 的配置使用还是比较简单的。因为是 .net 代码编写,所以对.net 开发者比较友好,我们可以直接使用 .net 代码来编写一些功能,比如直接使用代码来聚合请求的结果。

相关文章

  • .Net Core with 微服务 - 架构图

  • .NET Core with 微服务 - 什么是微服务

演示代码

https://github.com/kklldog/myhotel_microservice

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/301823.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

60 Minutes专访李开复:泛人工智能可能永远实现不了

全世界只有3.14 % 的人关注了数据与算法之美尽管你听说过人工智能&#xff0c;但机器仍然无法像人类一样思考&#xff0c;但在过去的几年里&#xff0c;它们已经具备了学习的能力。突然之间&#xff0c;我们的设备睁开了眼睛和竖起了耳朵&#xff0c;汽车开始无人行驶。今天&am…

API之子窗口创建 (转)

子窗口的创建非常非常重要 步骤&#xff1a;1、新建窗口类&#xff0c;在窗口类中指名对应的自定义的窗口过程。窗口类类名要唯一&#xff0c;它 是各窗口类相互区别的标识。注意&#xff0c;类名或为静态变量&#xff0c;或为全局变量&#xff0c;因为程 序随时都用他们。…

java 支付宝 退款_Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝支付)

最近一直在接触第三方,刚接入完支付宝的API做一下总结,个人能力薄弱有不对的地方望指教. 做的是一个小型电商项目,所以会接入第三方的支付和登入功能, 第一次接入第三方撸了很多官方文档.然后创建应用选择需要接入的功能,有些应用是需要签约的签约就好了审核蛮快的.以上应用申…

DB排行榜更新,.NET Core+MySQL成主流!

上图是DB-Engines数据库流行度最新排行榜&#xff0c;Oracle、MySQL、SQLServer虽几经下滑&#xff0c;然而还是遥遥领先的前三名。后起之秀PostgreSQL和MongoDB持续增长&#xff0c;然而在体量上还相差甚远&#xff0c;可以预见这些年&#xff0c;三大关系型数据库的主流地位是…

史上最惨锦鲤即将来袭!奖品堪比5年高考3年模拟!

全世界只有3.14 % 的人关注了数据与算法之美在锦鲤盛行的2018年我们超级数学建模也跟风来了一个“史上最惨锦鲤”活动为什么叫史上最惨锦鲤呢因为平常看一本数学书就已经头疼了何况我们奖品还是100本数学书试问除了学霸还有谁能承受这种殊荣巧的是最后的得主还真是一个学霸那就…

人工智能读心术

全世界只有3.14 % 的人关注了数据与算法之美对于许多无法发出声音的人来说&#xff0c;他们想说的话会通过某种信号隐藏在大脑中。人类无法直接破译这些信号。但是&#xff0c;最近有三个研究小组在“破译”这种大脑语言密码上取得了一定进展。Science杂志最新报道了哥伦比亚大…

今日港股期货(港股期货今日交易动向)

港股期货收涨0.6% 首次突破31000点 今日港股期货大涨&#xff0c;形势一时看好。其中&#xff0c;恒生指数期货一度突破31000点关口&#xff0c;创出历史新高。分析人士表示&#xff0c;市场情绪积极&#xff0c;投资者对于全球经济复苏前景和中国经济增长的预期不断提高&…

春节特惠活动┃一张纸一幅图,竟然提高了10倍的学习和工作效率!?

▲数据汪特别推荐点击上图进入玩酷屋人类大脑的容量远远超出一般人的想象&#xff0c;时到21世纪的今天&#xff0c;我们对大脑的运用远远不够。大脑机能的使用率基于我们的思维模式&#xff0c;而思维导图正是开发大脑中最有效的利器&#xff01;之前小木给大家推荐了一套基于…

java class文件 代码_java_基础——用代码编译.java文件+加载class文件

java_基础——用代码编译.java文件加载class文件java_基础——用代码编译.java文件加载class文件【简单编译的流程】package com.zjm.www.test;import java.io.IOException;import javax.tools.JavaCompiler;import javax.tools.JavaCompiler.CompilationTask;import javax.too…

WPF 记一个Popup踩坑记录

看名字就知道&#xff0c;它是一个弹出控件&#xff0c;顾名思义&#xff0c;我们可以用它来实现类似Combobox那种&#xff0c;点击后弹出下面选项列表的操作。记录&#xff1a;需求&#xff1a;有一个文本框 &#xff0c;鼠标点击后&#xff0c;弹出一个Popup。我编写了以下xa…

通过电话号码获取姓名 (+86或者飞信)

2019独角兽企业重金招聘Python工程师标准>>> /** * 通过电话号码获取姓名 (86或者飞信) */ /* public String getContactName(String phoneNum) { String contactName "";// 处理电话号码格式问题 if (phoneNum.length() > 11) {ContentResolver cr …

春节特惠活动┃强烈推荐!孩子的科普从这套全球畅销250万册的最酷科学书起步...

▲数据汪特别推荐点击上图进入玩酷屋在马斯的学生时代的记忆中&#xff0c;数学定义定理、化学方程式、物理公式……这些科学知识点总是冷冰冰的&#xff0c;枯燥、深奥也总是科学的代名词。如今教育局明确规定科学课是小学必修课&#xff0c;孩子也逐步接受科学知识的熏陶。但…

删除未使用的引用 | Visual Studio 2019(16.10)新功能试用

当解决方案很小时&#xff0c;我们清楚地知道解决方案中使用了哪些项目引用和NuGet包&#xff0c;要想清理它们很容易。而对于大型的解决方案&#xff0c;有哪些包在使用中&#xff0c;开发人员很难找到它们&#xff0c;或者找起来可能很耗时。Visual Studio 2019(16.10)添加了…

女生转行IT与男生有什么不一样?

全世界只有3.14 % 的人关注了数据与算法之美在我的后台咨询者当中&#xff0c;女生向我咨询最多的问题就是&#xff1a;女生转行IT有什么困难&#xff1f;是不是很多IT企业都不要女生啊&#xff1f;女生的逻辑不如男生&#xff0c;是不是学不好编程&#xff1f;等等。1以上的所…

Blazor 基础入门

Blazor 基础知识IntroBlazor 是微软在 .NET 里推出的一个 WEB 客户端 UI 交互的框架&#xff0c;使用 Blazor 你可以代替 JavaScript 来实现自己的页面交互逻辑&#xff0c;可以很大程度上进行 C# 代码的复用&#xff0c;Blazor 对于 .NET 开发人员来说是一个不错的选择。托管模…

java 列表展开方式_android列表控件实现展开、收缩功能

最近在做一个Rss阅读器&#xff0c;我看了一看别人做的阅读器中的lisView可以伸缩&#xff0c;展开&#xff0c;我就在网上搜索了一下。果然让我找到&#xff0c;下面就我找到的一个小例子&#xff0c;给大家分享一下。ActivityMain .javapackage com.android;import android.a…

每个人都应该学习编程,因为它会教你如何思考

▲数据汪特别推荐点击上图进入玩酷屋扎克伯格11岁开始学习编程&#xff0c;创办Facebook&#xff1b;比尔盖茨13岁学习编程&#xff0c;创办微软……乔布斯说&#xff1a;“每一个人都应该学习电脑编程&#xff0c;因为它会教你如何思考。"现在在北京上海&#xff0c;顶级…

.NET Core HttpClient请求异常思考

【导读】上一篇我们讨论了针对项目上异常信息的具体分析而给出对应解决方案&#xff0c;本篇仅是我个人对相关异常信息了解过后的进一步学习和思考&#xff0c;希望对后续遇到此异常信息的同学们给予思路扩展下面我们结合如下两个异常信息进行大致排查分析&#xff0c;到底什么…

程序员编程10大原则,请牢牢记住!

全世界只有3.14 % 的人关注了数据与算法之美1、想清楚&#xff0c;再动手写代码刚入行的新手&#xff0c;为了展示自己的能力&#xff0c;拿到需求迫不及待地就开始上手写代码&#xff0c;大忌&#xff01;2、不交流&#xff0c;就会头破血流不爱说话和沟通&#xff0c;需求都理…

技术分享|基于SQL Server Change Tracking实现宽表的增量更新

源宝导读&#xff1a;在企业建设信息化的过程中&#xff0c;客户通常会使用一些数仓工具来构建数据资产&#xff0c;随着用户的要求越来越高&#xff0c;传统的ETL技术已经无法满足客户的实时性诉求&#xff0c;本文将分享“天际-数据平台”如何基于SQL Server来实现数仓数据的…