简介

    
   
   
   
   
   
   

         本文我们介绍ocelot使用consul实现服务发现。

         我将使用ocelot的13.5.2版本向您展示此功能。

step1

         启动consul

         在本次演示,我将使用docker运行consul的实例。(你也可以自己安装consul,不需要docker)

   docker run -p 8500:8500 consul

   启动后,我们会看到下面的结果。

step2

         新建一个在consul注册了的api服务。

         为了演示,我将创建两个web api项目,它们端口不一样但服务名一样。

    编写控制器的代码如下:

[route("api/[controller]")]  
[apicontroller]  
public class valuescontroller : controllerbase  
{  
    // get api/values  
    [httpget]  
    public actionresult<ienumerable<string>> get()  
    {  
        var port = request.host.port;  
  
        return new string[] { "value1", "value2", port.value.tostring() };  
    }  
}  

  接下来将它注册到consul,下面的代码,打个样。

public static class appextensions  
{             
    public static iservicecollection addconsulconfig(this iservicecollection services, iconfiguration configuration)  
    {  
        services.addsingleton<iconsulclient, consulclient>(p => new consulclient(consulconfig =>  
        {  
            var address = configuration.getvalue<string>("consul:host");  
            consulconfig.address = new uri(address);  
        }));  
        return services;  
    }  
  
    public static iapplicationbuilder useconsul(this iapplicationbuilder app)  
    {  
        var consulclient = app.applicationservices.getrequiredservice<iconsulclient>();  
        var logger = app.applicationservices.getrequiredservice<iloggerfactory>().createlogger("appextensions");  
        var lifetime = app.applicationservices.getrequiredservice<iapplicationlifetime>();  
  
        if (!(app.properties["server.features"] is featurecollection features)) return app;  
  
        var addresses = features.get<iserveraddressesfeature>();  
        var address = addresses.addresses.first();  
  
        console.writeline($"address={address}");  
  
        var uri = new uri(address);  
        var registration = new agentserviceregistration()  
        {  
            id = $"myservice-{uri.port}",  
            // servie name  
            name = "myservice",  
            address = $"{uri.host}",  
            port = uri.port  
        };  
  
        logger.loginformation("registering with consul");  
        consulclient.agent.servicederegister(registration.id).configureawait(true);  
        consulclient.agent.serviceregister(registration).configureawait(true);  
  
        lifetime.applicationstopping.register(() =>  
        {  
            logger.loginformation("unregistering from consul");  
            consulclient.agent.servicederegister(registration.id).configureawait(true);  
        });  
  
        return app;  
    }  
}  

  我们还得修改startup.cs以便可注册。

public class startup  
{  
    public startup(iconfiguration configuration)  
    {  
        configuration = configuration;  
    }  
  
    public iconfiguration configuration { get; }  
  
    public void configureservices(iservicecollection services)  
    {  
        services.addconsulconfig(configuration);  
        services.addmvc().setcompatibilityversion(compatibilityversion.version_2_2);  
    }  
  
    public void configure(iapplicationbuilder app, ihostingenvironment env)  
    {  
        if (env.isdevelopment())  
        {  
            app.usedeveloperexceptionpage();  
        }  
  
        app.useconsul();  
  
        app.usemvc();  
    }  
}  

  当我们启动我们的项目,会在consul发现名为myservices的实例,它包括两个节点。

 

  为了看看新服务的具体细节,点开myservice,我们会看到两个节点的具体信息。

  接下来创建apigateway

step3

         通过.net core cli 添加下面的包

dotnet add package ocelot --version 13.5.2  
dotnet add package ocelot.provider.consul --version 13.5.2 

 

   新建ocelot.json,内容如下。

{  
    "reroutes": [  
      {  
        "useservicediscovery": true,   
        "downstreampathtemplate": "/{url}",   
        "downstreamscheme": "http",  
        "servicename": "myservice",   
        "loadbalanceroptions": {   
          "type": "roundrobin"  
        },  
        "upstreampathtemplate": "/{url}",   
        "upstreamhttpmethod": [ "get" ],   
        "reroutescasesensitive": false   
      }  
    ],  
    "globalconfiguration": {   
      "servicediscoveryprovider": {   
        "host": "localhost",  
        "port": 8500,  
        "type":"pollconsul",  
        "pollinginterval": 100  
      }  
    }  
}  

  使用服务发现我们在globalconfiguration中添加servicediscoveryprovider节点。

名称

描述

host

表明consul的主机

port

指明consul的端口

 type

1. consul, 意味每次请求ocelot会从consul获得服务信息。

2. pollconsul, 意味着ocelot将向consul推荐最新的服务信息

 pollinginterval

 告诉ocelot多长时间调用consul来更改服务配置

  在这里,reroute依然很重要。因为它告诉ocelot,当发出请求时我们希望使用的服务名称和负载均衡器。 如果未指定负载均衡器,则ocelot将不会对请求进行负载均衡。

  设置此选项后,ocelot将从服务中查找下游主机和端口,发现提供程序,并查找任何可用服务的负载均衡请求。

  最后,我们需要在program.cs 中配置ocelot。

public class program  
{  
    public static void main(string[] args)  
    {  
        createwebhostbuilder(args).build().run();  
    }  
  
    public static iwebhostbuilder createwebhostbuilder(string[] args) =>  
        webhost.createdefaultbuilder(args)  
         .useurls("http://*:9000")  
         .configureappconfiguration((hostingcontext, config) =>  
         {  
            config  
                .setbasepath(hostingcontext.hostingenvironment.contentrootpath)  
                .addjsonfile("ocelot.json")  
                .addenvironmentvariables();  
         })  
        .configureservices(services =>  
        {  
            services.addocelot()  
                .addconsul();  
        })  
        .configure(app =>  
        {  
            app.useocelot().wait();  
        });  
}  

  启动apigateway,访问http://localhost:9000/api/values.

  看一下打印的日志。请求的详细信息都在控制台显示。

 

  源码在此

  网盘链接:https://pan.baidu.com/s/17sqfgcyx8yehrl_lwkaula
  提取码:p3d0

总结

         在这篇文章中我们学习了ocelot使用consul实现服务发现简单的例子。完结!!!!