好记性不如烂笔头。

Ocelot + Consul 微服务网关的实现

关于Consul的使用,查看 Consul服务注册与发现

一、实现手动配置Consul中的服务发现

Program.cs中的代码,其中使用Consul服务发现,需要添加对Ocelot.Provider.Consul的支持,在Nuget上可找到Ocelot.Provider.Consul包

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;
using System.IO;

namespace OcelotTest
{
    public class Program
    {
        public static void Main(string[] args)
        {
            new WebHostBuilder()
                .UseUrls("http://*:99")
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config
                        .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                        .AddJsonFile("appsettings.json", true, true)
                        .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
                        .AddJsonFile("ocelot.json", false,true)//引入ocelot配置文件
                        .AddEnvironmentVariables();
                })
                .ConfigureServices(s =>
                {
                    s.AddOcelot() //注册对ocelot的支持
.AddConsul();//注册对Consul的支持 }) .ConfigureLogging((hostingContext, logging) => { //add your logging }) .UseIISIntegration() .Configure(app => {
//配置使用Ocelot app.UseOcelot().Wait(); }) .Build() .Run(); } } }

ocelot.json中的代码,负载均衡支持3种算法 LeastConnection(最小连接数),RoundRobin(轮询),CookieStickySessions(基于会话的负载,可以理解为,基于同一会话的请求,会被分发到同一台服务器上),以下代码中,使用了RoundRobin 轮询进行负载。

 {
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{url}",
      "UpstreamPathTemplate": "/api/{url}",
      "ServiceName": "s1"
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": null,
    "ServiceDiscoveryProvider": {
      "Host": "10.1.1.29",
      "Port": 8500,
      "Type": "Consul"
    },
    "UseServiceDiscovery": false,
    "DownstreamScheme": "http",
    "UpstreamHttpMethod": [ "Get", "Post" ],
    "LoadBalancerOptions": {
      "Type": "RoundRobin"
    }
  }
}

以下Consul中的信息截图,注册了一个服务,服务名称s1

打开浏览器,输入网址,接着刷新几次,可以看到输出不同的端口

二、以上是手动配置Consul中的服务发现的结果,接下来配置自动服务发现

ocelot.json配置看起来像这样,其中ReRoutes为空,在手动配置服务与自动服务发现中,2个配置不能共存,所以ReRoutes要设置为空数组或者不设置些参数。

{
  "ReRoutes": [],
  "GlobalConfiguration": {
    "BaseUrl": null,
    "ServiceDiscoveryProvider": {
      "Host": "10.1.1.29",
      "Port": 8500,
      "Type": "Consul"
    },
    "UseServiceDiscovery": false,
    "DownstreamScheme": "http",
    "UpstreamHttpMethod": [ "Get", "Post" ],
    "LoadBalancerOptions": {
      "Type": "RoundRobin"
    }
  }
}

在s1服务的基础上,复制并注册了一个s2服务,看下图

访问动态路由服务时,需要加服务名称前缀,如/s1/api/health,s1即服务名称,访问s2的路径则是/s2/api/health,下图是s1,s2的访问结果