第五节:基于Ocelot网关简介、路由功能、集成Consul使用
一. 基礎(chǔ)說(shuō)明
1. API網(wǎng)關(guān)剖析
(1).什么是Api
API是Application Programming Interface縮寫,翻譯成中文就是應(yīng)用程序接口。在實(shí)際微服務(wù)中可以理解一個(gè)個(gè)功能方法。就比如你一個(gè)商品服務(wù)的微服務(wù), 可以對(duì)外提供 API 接口為,獲取商品目錄、獲取商品詳情等。
(2).什么是網(wǎng)關(guān)(Gateway)
它是一個(gè)服務(wù)器,用來(lái)轉(zhuǎn)發(fā)其他服務(wù)器通信數(shù)據(jù)的, 它接收從客戶端發(fā)送來(lái)的請(qǐng)求時(shí),它就像自己擁有資源的源服務(wù)器一樣對(duì)請(qǐng)求進(jìn)行處理。
(3).什么是Api網(wǎng)關(guān)
通俗的來(lái)說(shuō)就是用來(lái)限制客戶端訪問(wèn)服務(wù)端api一道門檻。
2. 微服務(wù)架構(gòu)中為什么要用網(wǎng)關(guān)?
(1).在這之前,我們的技術(shù)棧中只引入了Consul,客戶端訪問(wèn)Consul拿到對(duì)應(yīng)的IP+Port,最終還是要訪問(wèn)業(yè)務(wù)服務(wù)器的,但很多情況我們并不想讓業(yè)務(wù)服務(wù)器直接對(duì)外開(kāi)放,所以這個(gè)時(shí)候就需要引入網(wǎng)關(guān)進(jìn)行轉(zhuǎn)發(fā)了.
(2).現(xiàn)在的微服務(wù)還沒(méi)有加權(quán)限校驗(yàn),如果將權(quán)限校驗(yàn)加個(gè)每個(gè)微服務(wù)的業(yè)務(wù)服務(wù)器上,開(kāi)發(fā)量很大,這個(gè)時(shí)候引入網(wǎng)關(guān),可以在網(wǎng)關(guān)層校驗(yàn).
(3).沒(méi)有網(wǎng)關(guān),很難做限流,而且各個(gè)業(yè)務(wù)的負(fù)責(zé)人員不能獨(dú)立負(fù)責(zé)自己的服務(wù)器器。
3. 網(wǎng)關(guān)都有哪些作用?
路由、負(fù)載均衡、限流、認(rèn)證、授權(quán)、鏈路監(jiān)控、熔斷降級(jí)、Service Fabric
4. Ocelot相關(guān)信息
(1).依賴程序集:通過(guò)Nuget安裝 【Ocelot 15.0.6】
GitHub地址:https://github.com/ThreeMammals/Ocelot
(2).參考文檔:
官網(wǎng):https://ocelot.readthedocs.io/en/latest/
ocelot 中文文檔:https://blog.csdn.net/sD7O95O/article/details/79623654
資料:http://www.csharpkit.com/apigateway.html
中文文檔:http://www.jessetalk.cn/2018/03/19/net-core-apigateway-ocelot-docs/
(3).其他網(wǎng)關(guān)框架:
A. Netflix Zuul +java實(shí)現(xiàn)
B. Kong nginx +lua腳本實(shí)現(xiàn)
C. Tyk go語(yǔ)言開(kāi)發(fā),收費(fèi)版本
D. Ocelot aspnetcore開(kāi)發(fā)的
5. Ocelot的原理
Ocelot是一堆的asp.net core middleware組成的一個(gè)管道。當(dāng)它拿到請(qǐng)求之后會(huì)用一個(gè)request builder來(lái)構(gòu)造一個(gè)HttpRequestMessage發(fā)到下游的真實(shí)服務(wù)器,等下游的服務(wù)返回response之后再由一個(gè)middleware將它返回的HttpResponseMessage映射到HttpResponse上。
(1).上游是什么:Ocelot自身就是上游(Upstream)
(2).下游是什么:Ocelot轉(zhuǎn)發(fā)給的(業(yè)務(wù))服務(wù)器就是下游(Downstream)
二. 路由功能
1.路由的含義
Ocelot(即上游)按照匹配規(guī)則接收客戶端發(fā)送的請(qǐng)求 → 將客戶端請(qǐng)求轉(zhuǎn)換成業(yè)務(wù)服務(wù)器(即下游)的地址 → 調(diào)用下游服務(wù),返回結(jié)果 → Ocelot再將下游服務(wù)的結(jié)果返回給客戶端.
2. 參數(shù)介紹
- Downstream 下游服務(wù)配置
- UpStream 上游服務(wù)配置
- Aggregates 服務(wù)聚合配置
- ServiceName, LoadBalancer, UseServiceDiscovery 配置服務(wù)發(fā)現(xiàn)
- AuthenticationOptions 配置服務(wù)認(rèn)證
- RouteClaimsRequirement 配置Claims鑒權(quán)
- RateLimitOptions 限流配置
- FileCacheOptions 緩存配置
- QosOptions 服務(wù)質(zhì)量與熔斷
- DownstreamHeaderTransform 頭信息轉(zhuǎn)發(fā)
3. 路由直接轉(zhuǎn)發(fā)指定的地址
(1).業(yè)務(wù)場(chǎng)景:
客戶端訪問(wèn)網(wǎng)關(guān) → 網(wǎng)關(guān)把請(qǐng)求直接轉(zhuǎn)發(fā)給"指定ip+端口"業(yè)務(wù)服務(wù)器 (該場(chǎng)景網(wǎng)關(guān)本身不配置Consul,直接轉(zhuǎn)發(fā))
(2).業(yè)務(wù)編寫與測(cè)試:
A. 新建網(wǎng)關(guān)項(xiàng)目OcelotGateWay,通過(guò)Nuget安裝【Ocelot 15.0.7】程序集
B. 新建一個(gè)OcelotConfig.json的配置文件,屬性改為"始終復(fù)制",用于存放Ocelot的配置。
代碼如下:
{
"ReRoutes": [
{
//轉(zhuǎn)發(fā)下游(業(yè)務(wù)服務(wù)器)的匹配規(guī)則
"DownstreamPathTemplate": "/api/{url}",
//下游請(qǐng)求類型
"DownstreamScheme": "http",
//下游的ip和端口,和上面的DownstreamPathTemplate匹配起來(lái)
"DownstreamHostAndPorts": [
{
"Host": "127.0.0.1",
"Port": 7001
}
],
//上游(即Ocelot)接收規(guī)則
"UpstreamPathTemplate": "/GoodsService/{url}",
//上游接收請(qǐng)求類型
"UpstreamHttpMethod": [ "Get", "Post" ]
},
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "127.0.0.1",
"Port": 7004
}
],
"UpstreamPathTemplate": "/OrderService/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ]
}
]
}
剖析上述xml:
- DownstreamPathTemplate:下游路徑模板
- DownstreamScheme:下游服務(wù)http schema
- DownstreamHostAndPorts:下游服務(wù)的地址,如果使用LoadBalancer的話這里可以填多項(xiàng)
- UpstreamPathTemplate: 上游也就是用戶輸入的請(qǐng)求Url模板,會(huì)將這個(gè)請(qǐng)求轉(zhuǎn)發(fā)給下游,如上代碼,客戶端請(qǐng)求 :網(wǎng)關(guān)ip+端口/GoodsService/{url},會(huì)轉(zhuǎn)發(fā)給下游:127.0.0.1:7001/api/{url}
- UpstreamHttpMethod: 上游請(qǐng)求http方法,可使用數(shù)組
C. 在Program中通過(guò)AddJsonFile將上述json文件加載進(jìn)來(lái).
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
//配置相關(guān)
.ConfigureAppConfiguration((hostingContext, config) =>
{
//1. 加載json文件 (配置后面兩個(gè)參數(shù)為true,當(dāng)配置文件發(fā)生變化的時(shí)候,會(huì)自動(dòng)更新加載,而不必重啟整個(gè)項(xiàng)目)
config.AddJsonFile("OcelotConfig.json", optional: true, reloadOnChange: true);
})
.ConfigureWebHostDefaults(webBuilder =>
{
//添加命令行支持(寫在上面的Main里也可以)
var config = new ConfigurationBuilder().AddCommandLine(args).Build();
webBuilder.UseStartup<Startup>();
});
D. 在Startup中進(jìn)行注冊(cè)和使用,services.AddOcelot(); app.UseOcelot().Wait();
public void ConfigureServices(IServiceCollection services)
{
//1.注冊(cè)O(shè)celot
var ocelot = services.AddOcelot();
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//1.使用Ocelot
app.UseOcelot().Wait(); //這里不寫異步用法了
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
E. 啟動(dòng)項(xiàng)目,7001端口啟動(dòng)GoodsService、7004端口啟動(dòng)OrderService、7020端口啟動(dòng)OcelotGateWay,指令如下:
【dotnet GoodsService.dll --urls="http://*:7001" --ip="127.0.0.1" --port=7001】 業(yè)務(wù)服務(wù)器地址
【dotnet OrderService.dll --urls="http://*:7004" --ip="127.0.0.1" --port=7004】 業(yè)務(wù)服務(wù)器地址
【dotnet OcelotGateWay.dll --urls="http://*:7020" --ip="127.0.0.1" --port=7020】 網(wǎng)關(guān)地址
F. PostMan測(cè)試
(1). Get測(cè)試: http://127.0.0.1:7020/GoodsService/Catalog/GetGoodById1?id=123,會(huì)將請(qǐng)求地址轉(zhuǎn)發(fā)給http://127.0.0.1:7001/api/Catalog/GetGoodById1?id=123 ,請(qǐng)求成功。
(2). Post請(qǐng)求:http://127.0.0.1:7020/OrderService/Buy/pOrder1,會(huì)將請(qǐng)求地址轉(zhuǎn)發(fā)給http://127.0.0.1:7004/api/Buy/pOrder1,請(qǐng)求成功。
三. 集成Consul
與Consul結(jié)合實(shí)現(xiàn)業(yè)務(wù)服務(wù)器的負(fù)載均衡(推薦用法)
1.業(yè)務(wù)背景
上述通過(guò) Ocelot直接轉(zhuǎn)發(fā)給指定的 ip+端口,只是為了演示,實(shí)際場(chǎng)景中,比如OrderService這個(gè)業(yè)務(wù)服務(wù)器,會(huì)部署在多臺(tái)服務(wù)器上進(jìn)行分?jǐn)傉?qǐng)求壓力,當(dāng)然我可以利用Ocelot自身實(shí)現(xiàn)負(fù)載均衡,但不推薦,原因有二: ① Ocelot本身的負(fù)載均衡機(jī)制不完善 ② 每次增加或減少業(yè)務(wù)服務(wù)器,都需要改網(wǎng)關(guān)的配置文件,耦合性很強(qiáng)。
解決方案:Ocelot與Consul結(jié)合,客戶端訪問(wèn)網(wǎng)關(guān)→網(wǎng)關(guān)通過(guò)ServiceName去Consul中找一個(gè)地址進(jìn)行匹配訪問(wèn)(Ocelot提供了多種算法去Consul中找地址)
2.業(yè)務(wù)編寫與測(cè)試
A. 通過(guò)Nuget安裝【Ocelot 15.0.7】程序集 和 【Ocelot.Provider.Consul 15.0.7】程序集
B. 新建一個(gè)OcelotConfig.json的配置文件,屬性改為"始終復(fù)制",用于存放Ocelot的配置.
配置分享:
//模式三:將Ocelot與consul結(jié)合處理,在consul中已經(jīng)注冊(cè)業(yè)務(wù)服務(wù)器地址,在Ocelot端不需要再注冊(cè)了(推薦用法)
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"ServiceName": "GoodsService", //Consul中的服務(wù)名稱
"LoadBalancerOptions": {
"Type": "RoundRobin" //輪詢算法:依次調(diào)用在consul中注冊(cè)的服務(wù)器
},
"UseServiceDiscovery": true, //啟用服務(wù)發(fā)現(xiàn)(可以省略,因?yàn)闀?huì)默認(rèn)賦值)
"UpstreamPathTemplate": "/GoodsService/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ]
},
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"ServiceName": "OrderService",
"LoadBalancerOptions": {
"Type": "LeastConnection" //最小連接數(shù)算法
},
"UseServiceDiscovery": true,
"UpstreamPathTemplate": "/OrderService/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ]
}
],
//下面是配置Consul的地址和端口
"GlobalConfiguration": {
//對(duì)應(yīng)Consul的ip和Port(可以省略,因?yàn)闀?huì)默認(rèn)賦值)
"ServiceDiscoveryProvider": {
"Host": "127.0.0.1",
"Port": 8500
}
}
}
剖析配置:
LoadBalancer將決定負(fù)載均衡的算法
- LeastConnection – 將請(qǐng)求發(fā)往最空閑的那個(gè)服務(wù)器
- RoundRobin – 輪流發(fā)送
- NoLoadBalance – 總是發(fā)往第一個(gè)請(qǐng)求或者是服務(wù)發(fā)現(xiàn)
ServiceName(對(duì)應(yīng)服務(wù)名), UseServiceDiscovery 啟用注冊(cè)發(fā)現(xiàn)(可省略),ServiceDiscoveryProvider 配置Consul的ip和端口。
C. 在Program中通過(guò)AddJsonFile將上述json文件加載進(jìn)來(lái). (代碼同上)
D. 在Startup中進(jìn)行注冊(cè)和使用,services.AddOcelot().AddConsul(); app.UseOcelot().Wait();
代碼分享:
public void ConfigureServices(IServiceCollection services)
{
//1.注冊(cè)O(shè)celot和Consul
services.AddOcelot().AddConsul();
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//1.使用Ocelot
app.UseOcelot().Wait(); //這里不寫異步用法了
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
E. 啟動(dòng)項(xiàng)目
7001,7002,7003 端口啟動(dòng)GoodsService、7004,7005,7006端口啟動(dòng)OrderService、7020端口啟動(dòng)OcelotGateWay
【dotnet GoodsService.dll --urls="http://*:7001" --ip="127.0.0.1" --port=7001】 業(yè)務(wù)服務(wù)器1地址
【dotnet GoodsService.dll --urls="http://*:7001" --ip="127.0.0.1" --port=7001】 業(yè)務(wù)服務(wù)器1地址
【dotnet GoodsService.dll --urls="http://*:7001" --ip="127.0.0.1" --port=7001】 業(yè)務(wù)服務(wù)器1地址
【dotnet OrderService.dll --urls="http://*:7004" --ip="127.0.0.1" --port=7004】 業(yè)務(wù)服務(wù)器2地址
【dotnet OrderService.dll --urls="http://*:7004" --ip="127.0.0.1" --port=7004】 業(yè)務(wù)服務(wù)器2地址
【dotnet OrderService.dll --urls="http://*:7004" --ip="127.0.0.1" --port=7004】 業(yè)務(wù)服務(wù)器2地址
【dotnet OcelotGateWay.dll --urls="http://*:7020" --ip="127.0.0.1" --port=7020】 網(wǎng)關(guān)地址
F. PostMan測(cè)試:
(1).Get測(cè)試: http://127.0.0.1:7020/GoodsService/Catalog/GetGoodById1?id=123, 會(huì)按照輪詢算法依次轉(zhuǎn)發(fā)給 :http://127.0.0.1:7001/api/Catalog/GetGoodById1?id=123,http://127.0.0.1:7001/api/Catalog/GetGoodById1?id=123,http://127.0.0.1:7001/api/Catalog/GetGoodById1?id=123,請(qǐng)求成功。
(2).Post請(qǐng)求:http://127.0.0.1:7020/OrderService/Buy/pOrder1 ,會(huì)根據(jù)最小連接數(shù)算法,轉(zhuǎn)發(fā)給7004 7005 7006連接數(shù)最小的業(yè)務(wù)服務(wù)器。
測(cè)試結(jié)果同上述路由轉(zhuǎn)發(fā)的圖
!
作者 : Yaopengfei(姚鵬飛)
博客地址 : http://www.cnblogs.com/yaopengfei/
聲明1 : 如有錯(cuò)誤,歡迎討論,請(qǐng)勿謾罵^_^。
聲明2 : 原創(chuàng)博客請(qǐng)?jiān)谵D(zhuǎn)載時(shí)保留原文鏈接或在文章開(kāi)頭加上本人博客地址,否則保留追究法律責(zé)任的權(quán)利。
總結(jié)
以上是生活随笔為你收集整理的第五节:基于Ocelot网关简介、路由功能、集成Consul使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: codevs1219 骑士遍历(棋盘DP
- 下一篇: 已退出手机市场的LG发布安卓平板:骁龙6