.Net Core微服务入门——Ocelot API网关接入(二)

26 篇文章 1 订阅
13 篇文章 1 订阅

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": {
    //"BaseUrl": "http://localhost:5010",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}

3、修改Startup,添加consul支持

public class Startup
{
     // This method gets called by the runtime. Use this method to add services to the container.
     // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
     public void ConfigureServices(IServiceCollection services)
     {
         //添加ocelot服务
         //services.AddOcelot();
         //添加ocelot服务
         services.AddOcelot()
             .AddConsul();//添加consul支持

     }

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
         //设置Ocelot中间件
         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": {
    //"BaseUrl": "http://localhost:5010",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}

在Routes路由配置中增加了FileCacheOptions。TtlSeconds代表缓存的过期时间,Region代表缓冲区名称。

3、修改Startup,增加缓存

public void ConfigureServices(IServiceCollection services)
{
      //添加ocelot服务
      //services.AddOcelot();
      //添加ocelot服务
      services.AddOcelot()
          //添加consul支持
          .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": {
    //"BaseUrl": "http://localhost:5010",
    "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": {
    //"BaseUrl": "http://localhost:5010",
    "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)
 {
     //添加ocelot服务
     //services.AddOcelot();
     //添加ocelot服务
     services.AddOcelot()
         //添加consul支持
         .AddConsul()
         //添加缓存
         .AddCacheManager(x =>
         {
             x.WithDictionaryHandle();
         })
         //添加Polly
         .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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值