Envoy实现.NET架构的网关(一)静态配置与文件动态配置
什么是Gateway
在微服務(wù)體系結(jié)構(gòu)中,如果每個(gè)微服務(wù)通常都會公開一組精細(xì)終結(jié)點(diǎn),這種情況可能會有以下問題
如果沒有 API 網(wǎng)關(guān)模式,客戶端應(yīng)用將與內(nèi)部微服務(wù)相耦合。
在客戶端應(yīng)用中,單個(gè)頁面/屏幕可能需要多次調(diào)用多個(gè)服務(wù)。?
如果沒有網(wǎng)關(guān),所有微服務(wù)必定會暴露在“外部世界”中。
每個(gè)公開發(fā)布的微服務(wù)都必須處理授權(quán)和 SSL 等問題。
而Gateway可以為微服務(wù)組提供單一入口點(diǎn),API 網(wǎng)關(guān)位于客戶端應(yīng)用和微服務(wù)之間。它充當(dāng)反向代理,將請求從客戶端路由到服務(wù)。它還可以提供其他跨領(lǐng)域功能,例如身份驗(yàn)證、SSL 終止和緩存。
什么是Envoy
Envoy 是專為大型現(xiàn)代 SOA(面向服務(wù)架構(gòu))架構(gòu)設(shè)計(jì)的 L7 代理和通信總線,它有以下優(yōu)勢
C++11編寫,原生代碼高性能
L3/L4 filter架構(gòu),例如TCP代理
HTTP L7 filter架構(gòu),緩存,限速,路由/轉(zhuǎn)發(fā)
頂級HTTP2與GRPC支持
服務(wù)發(fā)現(xiàn)與動態(tài)配置
健康檢查
高級負(fù)載均衡
我們可以借助Envoy實(shí)現(xiàn)API Gateway。Envoy通過yaml配置文件來組織網(wǎng)關(guān)的信息。下面來說說Envoy中的核心概念
.NET網(wǎng)關(guān)與Gateway實(shí)戰(zhàn)-Envoy與kong課程希望大家支持??https://ke.qq.com/course/4033027?tuin=1271860f
Listener
一個(gè)命名的網(wǎng)絡(luò)地址,可以被下游客戶端連接,它的配置樣式如下:
static_resources:listeners:- name: listener_0address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 10000此配置說明Envoy監(jiān)聽在10000端口,下游客戶端可以通過此端口與Envoy交互
L3/L4過濾器Filter
L3/L4過濾器Filter可以幫我們實(shí)現(xiàn)如:HTTP連接管理,限速,TCP代理等功能,它的配置樣式如下:
filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerscheme_header_transformation:scheme_to_overwrite: httpstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: local_servicedomains: ["*"]routes:- match:prefix: "/"route:host_rewrite_literal: 192.168.43.94cluster: service_envoyproxy_iohttp_filters:- name: envoy.filters.http.router此配置說明通過HttpConnectionManager這個(gè)過濾器來接受HTTP請求,并將請求通過router過濾器的配置轉(zhuǎn)發(fā)到service_envoyproxy_io這個(gè)上游集群
Upstream Cluster
Envoy 的集群管理器管理所有配置的上游集群,用來真正處理Envoy接受的請求,其配置樣式如下:
clusters:- name: service_envoyproxy_ioconnect_timeout: 30stype: strict_dnsdns_lookup_family: V4_ONLYlb_policy: ROUND_ROBINload_assignment:cluster_name: service_envoyproxy_ioendpoints:- lb_endpoints:- endpoint:address:socket_address:address: 192.168.43.94port_value: 5000此配置說明Envoy會將請求轉(zhuǎn)發(fā)到192.168.43.94:5000這個(gè)地址。
調(diào)用邏輯我們總結(jié)如下,Listener接受請求,將請求交給過濾器,過濾器處理完后,根據(jù)路由規(guī)則將請求轉(zhuǎn)發(fā)給上游集群,上游集群中的endpoint會真正處理請求。
運(yùn)行Envoy
我們通過docker運(yùn)行一個(gè)默認(rèn)Envoy容器
docker run --rm -it -p 9901:9901 -p 10000:10000 envoyproxy/envoy-dev訪問http://localhost:10000/,發(fā)現(xiàn)其跳轉(zhuǎn)到Envoy官網(wǎng)
?
?我們進(jìn)入容器查看其配置,發(fā)現(xiàn)其最終會將請求轉(zhuǎn)發(fā)到www.envoyproxy.io
cat /etc/envoy/envoy.yaml- lb_endpoints:- endpoint:address:socket_address:address: www.envoyproxy.ioport_value: 443靜態(tài)文件配置
我們現(xiàn)在通過Envoy來實(shí)現(xiàn)我們自己的網(wǎng)關(guān)。靜態(tài)文件配置是我們把配置信息提前配置好,Envoy啟動后不可修改配置內(nèi)容
準(zhǔn)備服務(wù)
我們準(zhǔn)備兩個(gè).NET WebAPI,server1與server2,其中分別創(chuàng)建NameController,并新建Get方法
Server1
[HttpGet]public string Get(){_logger.LogInformation("call server1");var req = Request;return "server1";}Server2
[HttpGet]public string Get(){_logger.LogInformation("call server2");var req = Request;return "server2";}并將server1的啟動端口指定為5000,將server2的啟動端口指定為5001
Server1
webBuilder.UseUrls("http://*:5555").UseStartup<Startup>();Server2
webBuilder.UseUrls("http://*:5001/").UseStartup<Startup>();我們啟動Server1與Server2
準(zhǔn)備Envoy配置
我們將上節(jié)課的默認(rèn)Envoy配置文件從容器中取出,并作修改如下
admin:address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 9901 static_resources:listeners:- name: listener_0address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 10000filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerscheme_header_transformation:scheme_to_overwrite: httpstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: local_servicedomains: ["*"]routes:- match:prefix: "/"route:host_rewrite_literal: 192.168.43.94cluster: service_envoyproxy_iohttp_filters:- name: envoy.filters.http.routerclusters:- name: service_envoyproxy_ioconnect_timeout: 30stype: static# Comment out the following line to test on v6 networksdns_lookup_family: V4_ONLYlb_policy: ROUND_ROBINload_assignment:cluster_name: service_envoyproxy_ioendpoints:- lb_endpoints:- endpoint:address:socket_address:address: 192.168.43.94port_value: 5000- endpoint:address:socket_address:address: 192.168.43.94port_value: 5001我們啟動Envoy,驗(yàn)證配置是否正確
docker run --rm -it -p 9901:9901 -p 10000:10000 -v D:/gateway/envoy/config/static/envoy.yaml:/etc/envoy/envoy.yaml -v D:/gateway/envoy/logs:/logs envoyproxy/envoy-dev -c /etc/envoy/envoy.yaml --log-path logs/custom.log調(diào)用api,發(fā)現(xiàn)其實(shí)現(xiàn)了負(fù)載
http://localhost:10000/Name動態(tài)文件配置
動態(tài)文件可以幫助我們實(shí)現(xiàn)當(dāng)文件發(fā)生更改時(shí),Envoy 將自動更新其配置。
修改靜態(tài)文件,將其中的cluster提取到cds.yaml文件中
resources: - "@type": type.googleapis.com/envoy.config.cluster.v3.Clustername: example_proxy_clustertype: STRICT_DNStyped_extension_protocol_options:envoy.extensions.upstreams.http.v3.HttpProtocolOptions:"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptionsexplicit_http_config:http_protocol_options: {}load_assignment:cluster_name: example_proxy_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: 192.168.43.94port_value: 5000將listener提取到lds.yaml文件中
resources: - "@type": type.googleapis.com/envoy.config.listener.v3.Listenername: listener_0address:socket_address:address: 0.0.0.0port_value: 10000filter_chains:- filters:- name: envoy.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: ingress_httphttp_filters:- name: envoy.filters.http.routerroute_config:name: local_routevirtual_hosts:- name: local_servicedomains:- "*"routes:- match:prefix: "/envoyapi/"route:prefix_rewrite: "/"host_rewrite_literal: 192.168.43.94cluster: example_proxy_cluster修改envoy.yaml讓其引用lds.yaml與cds.yaml文件
admin:address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 9902 node:cluster: test-clusterid: test-id dynamic_resources:cds_config:path: /etc/envoy/cds.yamllds_config:path: /etc/envoy/lds.yaml啟動Envoy
docker run --rm -it -p 9902:9902 -p 10000:10000 -v D:/gateway/envoy/config/dynamic/:/etc/envoy/ -v D:/gateway/envoy/logs:/logs envoyproxy/envoy-dev -c /etc/envoy/envoy.yaml --log-path logs/custom.log調(diào)用api,發(fā)現(xiàn)調(diào)用成功
http://localhost:10000/envoyapi/Name修改動態(tài)文件配置
修改cds.yaml,將endpoint端口設(shè)置為5001
resources: - "@type": type.googleapis.com/envoy.config.cluster.v3.Clustername: example_proxy_clustertype: STRICT_DNStyped_extension_protocol_options:envoy.extensions.upstreams.http.v3.HttpProtocolOptions:"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptionsexplicit_http_config:http_protocol_options: {}load_assignment:cluster_name: example_proxy_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: 192.168.43.94port_value: 5001進(jìn)入容器內(nèi)部強(qiáng)制更新文件
# cd /etc/envoy # mv cds.yaml tmp # mv tmp cds.yaml調(diào)用api,發(fā)現(xiàn)在不重啟Envoy的情況下,實(shí)現(xiàn)了配置信息的動態(tài)更新
至此,我們已經(jīng)通過Envoy的靜態(tài)配置與文件動態(tài)配置實(shí)現(xiàn)了一個(gè)網(wǎng)關(guān)來代理我們的.NET程序
相關(guān)文章:
Dapr實(shí)戰(zhàn)(一) 基礎(chǔ)概念與環(huán)境搭建
Dapr + .NET Core實(shí)戰(zhàn)(二) 服務(wù)調(diào)用
Dapr + .NET Core實(shí)戰(zhàn)(三)狀態(tài)管理
Dapr + .NET 實(shí)戰(zhàn)(四)發(fā)布和訂閱
Dapr + .NET 實(shí)戰(zhàn)(五)Actor
Dapr + .NET 實(shí)戰(zhàn)(六)綁定
Dapr + .NET 實(shí)戰(zhàn)(七)Secrets
Dapr + .NET 實(shí)戰(zhàn)(八)服務(wù)監(jiān)測
Dapr + .NET 實(shí)戰(zhàn)(九)本地調(diào)試
Dapr + .NET 實(shí)戰(zhàn)(十-終篇)K8S運(yùn)行Dapr
Dapr + .NET實(shí)戰(zhàn)(十一)單機(jī)Dapr集群負(fù)載均衡
Dapr + .NET 實(shí)戰(zhàn)(十二)服務(wù)調(diào)用之GRPC
Dapr + .NET 實(shí)戰(zhàn)(十三)跨語言開發(fā)
為什么 Dapr 如此令人興奮
總結(jié)
以上是生活随笔為你收集整理的Envoy实现.NET架构的网关(一)静态配置与文件动态配置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用LightBDD轻松实现行为驱动开发
- 下一篇: 浅谈.Net异步编程的前世今生----E