Net Core微服务入门——Ocelot API网关接入(二)
我们先接入Consul,实现服务发现
服务发现
1、引入 Ocelot.Provider.Consul 包
2、修改ocelot.json,接入consul(ServiceDiscoveryProvider)
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/api/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"ServiceName": "MyApi",
"LoadBalancerOptions": {
"Type": "RoundRobin"
}
}
],
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "localhost",
"Port": 8500,
"Type": "Consul"
}
}
}
3、修改Startup,添加consul支持
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot()
.AddConsul();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseOcelot().Wait();
}
}
启动运行,方法网关api接口,正常
服务治理
其实服务治理没有一个非常明确的定义。它的作用简单来说,就是帮助我们更好的管理服务,提升服务的可用性。
负载均衡,缓存,限流,熔断,链路追踪 等等。。。都属于常用的服务治理手段。服务发现也可以算是服务治理。
我们一个个试试
缓存
引入Ocelot.Cache.CacheManager包:
2、修改ocelot.json
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/api/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"ServiceName": "MyApi",
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"FileCacheOptions": {
"TtlSeconds": 5,
"Region": "regionname"
}
}
],
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "localhost",
"Port": 8500,
"Type": "Consul"
}
}
}
在Routes路由配置中增加了FileCacheOptions。TtlSeconds代表缓存的过期时间,Region代表缓冲区名称。
3、修改Startup,增加缓存
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot()
.AddConsul()
.AddCacheManager(x =>
{
x.WithDictionaryHandle();
});
}
限流
限流就是限制客户端一定时间内的请求次数。
1、修改ocelot.json,增加限流配置
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/api/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"ServiceName": "MyApi",
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"FileCacheOptions": {
"TtlSeconds": 5,
"Region": "regionname"
},
"RateLimitOptions": {
"ClientWhitelist": [ "SuperClient" ],
"EnableRateLimiting": true,
"Period": "5s",
"PeriodTimespan": 2,
"Limit": 2
}
}
],
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "localhost",
"Port": 8500,
"Type": "Consul"
},
"RateLimitOptions": {
"DisableRateLimitHeaders": false,
"QuotaExceededMessage": "too many requests...",
"HttpStatusCode": 999,
"ClientIdHeader": "Test"
}
}
}
在Routes路由配置中增加了RateLimitOptions。
ClientWhitelist代表客户端白名单,在白名单中的客户端可以不受限流的影响;
EnableRateLimiting代表是否限流;
Period代表限流的单位时间,例如1s,5m,1h,1d等;
PeriodTimespan代表客户端达到请求上限多少秒后可以重试;
Limit代表客户端在定义的时间内可以发出的最大请求数。
在GlobalConfiguration配置中也增加了RateLimitOptions。
DisableRateLimitHeaders代表是否禁用X-Rate-Limit和Retry-After标头(请求达到上限时response header中的限制数和多少秒后能重试);
QuotaExceededMessage:代表请求达到上限时返回给客户端的消息;
HttpStatusCode:代表请求达到上限时返回给客户端的HTTP状态代码。
ClientIdHeader可以允许自定义用于标识客户端的标头。默认情况下为“ ClientId”。
最重要的就是Period,PeriodTimespan,Limit这几个配置。
重新启动api,网关。
访问正常,多刷新几次,出现如下情况:
触发了限流机制。
超时/熔断
超时,就是网关请求服务时可容忍的最长响应时间。
熔断的意思就是当请求某个服务的异常次数达到一定量时,那么网关在一定时间内就不再对这个服务发起请求了,直接熔断。
1、引入 Ocelot.Provider.Polly包
2、修改ocelot.json,增加QoSOptions:
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"UpstreamPathTemplate": "/api/{url}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"ServiceName": "MyApi",
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"FileCacheOptions": {
"TtlSeconds": 5,
"Region": "regionname"
},
"RateLimitOptions": {
"ClientWhitelist": [ "SuperClient" ],
"EnableRateLimiting": true,
"Period": "5s",
"PeriodTimespan": 2,
"Limit": 2
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 10000,
"TimeoutValue": 5000
}
}
],
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "localhost",
"Port": 8500,
"Type": "Consul"
},
"RateLimitOptions": {
"DisableRateLimitHeaders": false,
"QuotaExceededMessage": "too many requests...",
"HttpStatusCode": 999,
"ClientIdHeader": "Test"
}
}
}
ExceptionsAllowedBeforeBreaking代表发生错误的次数
DurationOfBreak代表熔断时间
TimeoutValue代表超时时间。
以上的配置意思就是当服务发生3次错误时,那么就熔断10秒,期间客户端的请求直接返回错误,10秒之后恢复。
3、修改Startup,添加 AddPolly
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot()
.AddConsul()
.AddCacheManager(x =>
{
x.WithDictionaryHandle();
})
.AddPolly();
}
启动,运行,正常
熔断具体就不测试了,有兴趣的可以自行测试
Docker运行
发布,上传到私有仓,在31客户端上执行命令
docker run -d -p 5010:80 --name ocelot1 192.168.8.25:5000/ocelotapigateway
运行成功,但打开 http://192.168.8.31:5010/api/product/getall 无法访问 。
查看日志:
无法识别的主机:consul31-client
找不到192.168.8.31这台主机,连不上api
经过调查,发现:
consul client 和 myapi部署在同一台服务器上。consul client 的节点node= consul31-client,同一台服务器,ocelot通过consul的节点node访问api时,是把节点当做ip访问的(这里有点奇怪!)。
重新部署创建consult client,把node 节点直接改成ip
docker run -d --restart=always -p 8500:8500 --name consul31-client --net=host -e CONSUL_BIND_INTERFACE=ens33 consul agent -node=192.168.8.31 -client=0.0.0.0 -bind=192.168.8.31 -retry-join=192.168.8.25:8301 -retry-join=192.168.8.27:8301 -retry-join=192.168.8.28:8301
重新运行,打开 http://192.168.8.31:5010/api/product/getall,顺利获取到数据
随后,将consul换成了服务器
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "192.168.8.25",
"Port": 8500,
"Type": "Consul"
},
重新发布,顺利启动,访问正常
然后,然后,我又作死的把 192.168.8.25 上的consul停掉了,重新访问ocelot网关 api,发现不通,挂了。
那么问题来了:
我有3台服务器,搭建了consul集群,而 ServiceDiscoveryProvider 又没法配置多个Consul服务,一旦consul服务挂了,ocelot还是无法正常访问api。这consul集群不上白搭建了,没什么用!
那怎么办呢?
搭建多个ocelot网关,每个网关对应不同的consul。
这个发方法貌似可行,但是consul相关配置是在ocelot.json中配置的,我们docker发布后,可不方便修改。总不能发布几个ocelot网关服务,就发布几个镜像吧,这太费人了!
那怎么办呢?
下一章,我们将演示,Ocelot和Consul集群高可用,来解决这个问题:
https://blog.csdn.net/weixin_41003771/article/details/119221476
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)