zoukankan      html  css  js  c++  java
  • 关于Ocelot和Consul 实现GateWay(网关) 服务注册 负载均衡

    Ocelot   路由  请求聚合  服务发现 认证  鉴权 限流熔断 内置负载均衡器

    Consul   自动服务发现    健康检查 

    通过Ocelot搭建API网关   服务注册   负载均衡

    1.创建三个空API项目  Api.Gateway(Ocelot网关服务器)      Api.ServiceA(资源服务器A)     Api.ServiceB(资源服务器B)   

    2.Api.Gateway项目中  添加Ocelot包   添加Ocelot.Json配置文件  Ocelot服务器端口配成5000

    {
      "ReRoutes": [
        {
          //暴露出去的地址
          "UpstreamPathTemplate": "/api/{controller}",
          "UpstreamHttpMethod": [ "Get" ],
          //转发到下面这个地址
          "DownstreamPathTemplate": "/api/{controller}",
          "DownstreamScheme": "http",
          //资源服务器列表
          "DownstreamHostAndPorts": [
            {
              "host": "localhost",
              "port": 5011
            },
            {
              "host": "localhost",
              "port": 5012
            }
          ],
          //决定负载均衡的算法
          "LoadBalancerOptions": {
            "Type": "LeastConnection"
          }
        }
      ],
      //对外暴露的访问地址  也就是Ocelot所在的服务器地址
      "GlobalConfiguration": {
        "BaseUrl": "http://localhost:5000"
      }
    }
    LeastConnection – 将请求发往最空闲的那个服务器
    RoundRobin – 轮流发送
    NoLoadBalance – 总是发往第一个请求或者是服务发现

    3.项目启动读取Ocelot配置

            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration((hostingContext, builder) => {
                        builder
                        .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                        .AddJsonFile("Ocelot.json");
                    })
                    .UseStartup<Startup>();
        }

    把Ocelot注册到DI容器

    services.AddOcelot();

    管道中开启Ocelot

    app.UseOcelot().Wait();

    4.配置资源服务器 在Ocelot中配置好了  把对应的/api/{controller}地址会进行转发

        [Route("apiservice/[controller]")]
        [ApiController]
        public class ValuesController : ControllerBase
        {
            // GET api/values
            [HttpGet]
            public string Get()
            {
                return "这是A资源服务器API";
            }

    5.通过localhost:5000/api/value访问    实现了负载均衡       测试的时候修改了端口或者其他的  最要先把iis对应端口进程关闭  不然可能没有更新过来     

     这种做法  如果其中一台服务器挂了   Ocelot没办法知道  还是会转发接口过去   如果新增服务器    就需要修改配置文件    可以通过Ocelot+Consul实现自动服务发现和服务健康监测

     *********************************************************************

     Ocelot+Consul实现服务发现和健康监测

    下载了consul后   就是一个exe文件  通过cmd进入目录      consul agent --dev运行    consul默认ui地址 http://localhost:8500

    API项目配置consul   项目启动后 自动被consul发现

    1.添加consul Nuget包    启动consul服务    

    2.在管道中配置

            public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                //注册项目启动的方法
                lifetime.ApplicationStarted.Register(OnStart);
                //注册项目关闭的方法
                lifetime.ApplicationStarted.Register(OnStopped);
                app.UseMvc();
            }
            private void OnStart()
            {
                var client = new ConsulClient();
                //健康检查
                var httpCheck = new AgentServiceCheck()
                {
                    //服务出错一分钟后 会自动移除
                    DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
                    //每10秒发送一次请求到 下面的这个地址 这个地址就是当前API资源的地址
                    Interval = TimeSpan.FromSeconds(10),
                    HTTP = $"http://localhost:5011/HealthCheck"
                };
    
                var agentReg = new AgentServiceRegistration()
                {
                    //这台资源服务的唯一ID
                    ID = "JcbServiceA",
                    Check = httpCheck,
                    Address = "localhost",
                    Name = "servicename",
                    Port = 5011
                };
                client.Agent.ServiceRegister(agentReg).ConfigureAwait(false);
            }
            //关闭的时候在consul中移除
            private void OnStopped()
            {
                var client = new ConsulClient();
                //根据ID在consul中移除当前服务
                client.Agent.ServiceDeregister("JcbServiceA");
            }

    3.启动项目后  进入consul发现 当前项目已经被consul发现   这样就实现了服务的自动发现  

    4.然后在把Consul结合到Ocelot中   在Ocelot中安装Ocelot.Provider.Consul  包

    在管道中把Consul注册到DI容器

                services.AddOcelot().AddConsul();

    修改Ocelot.Json配置文件

    {
      "ReRoutes": [
        {
          //暴露出去的地址
          "UpstreamPathTemplate": "/api/{controller}",
          "UpstreamHttpMethod": [ "Get" ],
          //转发到下面这个地址
          "DownstreamPathTemplate": "/api/{controller}",
          "DownstreamScheme": "http",
          //资源服务器列表
          //"DownstreamHostAndPorts": [
          //  {
          //    "host": "localhost",
          //    "port": 5011
          //  },
          //  {
          //    "host": "localhost",
          //    "port": 5012
          //  }
          //],
          //决定负载均衡的算法
          "LoadBalancerOptions": {
            "Type": "LeastConnection"
          },
          "ServiceName": "servicename", //服务注册标识, 这个需要和资源API注册的名称相同
          "UseServiceDiscovery": true //启用服务发现
          //"ReRoutesCaseSensitive": false
        }
      ],
      //对外暴露的访问地址  也就是Ocelot所在的服务器地址
      "GlobalConfiguration": {
        "BaseUrl": "http://localhost:5000",
        "ServiceDiscoveryProvider": {
          "Host": "localhost", // Consul Service IP
          "Port": 8500, // Consul Service Port
          //"Type": "PollConsul",
          //"PollingInterval": 100 //健康检查时间端
        }
      }
    }

    5.这样就实现了动态的服务注册    

    如果其中一台服务挂了    一分钟后还是连接不上   consul会自动移除这台服务  并且不会再将请求转发到这台服务上     这时候就可以动态的实现服务的新增

    注意:在这里通过Consul发现服务的时候   

    当资源API只有一台   启用和关闭当前资源API   Consul都能正常检查到      

    当资源API有两台的时候  关闭其中一台资源API是正常的        然后在关闭另外一台 Consul的控制台已经检测到这台API连接失败了  但是Localhost:8500界面上显示还是正常的(并且这台关闭的API会一直显示正常)   不清楚为什么

    ************************

    Ocelot +IdentityServer4     在网关实现统一身份验证  

    1.在Ocelot项目中添加  IdentityServer4.AccessTokenValidation  包

    DI容器添加身份验证    这里的authenticationProviderKey 要和Ocelot.Json中的authenticationProviderKey 相同

            public void ConfigureServices(IServiceCollection services)
            {
            
                var authenticationProviderKey = "finbook";
    
                services.AddAuthentication()
                    .AddIdentityServerAuthentication(authenticationProviderKey, options =>
                    {
                        options.Authority = "http://localhost:3000";
                        options.ApiName = "gateway_api";
                        options.SupportedTokens = SupportedTokens.Both;
                        options.ApiSecret = "secret";
                        options.RequireHttpsMetadata = false;
                    });
                services.AddOcelot().AddConsul();
                //services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    
            }

    2.修改Ocelot.Json配置文件

          "AuthenticationOptions": {
            //这个名称要和Startup中配置的权限key相同
            "AuthenticationProviderKey": "finbook",
            //允许访问的资源API   在IdentityServer中配置
            "AllowedScopes": [ "gateway_api" ]
          }

    https://www.cnblogs.com/weiBlog/p/9833807.html

  • 相关阅读:
    设计模式单例模式的实现方式
    Springboot,SSM框架比较,区别
    多线程系列之自己实现一个 lock 锁
    springBoot 自动配置原理自己新建一个 starter
    Hashmap 实现方式 jdk1.7 和 1.8区别
    给WPF中的DataGrid控件添加右键菜单(ContextMenu),以便用户可以显示或者隐藏DataGrid中的列,并且下次运行时依然保持上次关闭时的列的布局
    WPF XAML页面 无智能感知
    【读书笔记】排列研究排列中的代数组合学
    使用Mathematica做序列的DTFT的几个例子
    BGF bivariate generating function 双变量生成函数
  • 原文地址:https://www.cnblogs.com/jiangchengbiao/p/10567575.html
Copyright © 2011-2022 走看看