搭建微服务注册中心和API网关(Consul+Ocelot)

前言

Ocelot是一个基于.net core的开源webapi 服务网关项目,目前已经支持了IdentityServer认证。根据 作者介绍,Ocelot本质上是一堆中间件的集合,当HttpRequest请求到达后由一堆中间件进行处理,处理完毕,请求根据配置转发给下游服务。然后接受下游服务的返回信息在转发给客户端。

Consul是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。它具有很多优点。包括:基于 raft 协议,比较简洁; 支持健康检查, ACL自身的访问权限控制,同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN(广域网) 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows。

这是一个搭建过程的记录,我尽量详细的描述这个过程。先说一下项目整体结构如下图:

项目介绍:

1、OcelotApiGateway是api网关项目。test1和test1.fuben、test2是API项目

2、test1和test1.fuben相互做“负载”功能的测试。

3、test2配合test1、test1.fuben做请求转发测试。

我们要把test1、test1.fuben、test2三个项目的ip和port注册到consul节点的services下,然后让OcelotApiGateway项目去发现这些在consul中的服务地址。最后我们通过配置Ocelot的json文件,实现“访问OcelotApiGateway项目时候,转发请求,负债均衡”到对应的test1和test1.fuben、test2中。

 

第一步:准备环境

.netcore3.0,consul_1.62_win64,ocelot最新版。

 

第二步:启动consul

在consul.exe所在的目录下启动cmd,执行以下命令:

consul agent -server  -dev -node=MyNode1

命令含义:在数据中心中启动一个server节点,开发模式,节点名称叫做MyNode1.执行后显示如下内容

此时,表示启动consul单节点模式成功,consul的ip为127.0.0.1,prot为8500.然后可以登录到consul的管理界面进行查看:http://localhost:8500/ui,如图:

第三步:创建3个API项目

咱们以test1为示例(其他两个项目复制这个项目就行了,毕竟只是测试),创建一个.netCore API项目,在nuget中安装Consul包

1、先在test1中写下本服务的“健康检查接口”:

    [Route("[controller]/[action]")]
    [ApiController]
    public class HealthController : ControllerBase
    {
        [HttpGet]
        public IActionResult Check() => Ok("ok");
    }

这个接口是供consul(定时)调用的,用来检查这个服务是否还活着,进而consul就可以确定本服务的运行状况。

2、写一个随便写一个接口。我们一会用来测试

3、启动服务的时候,在Startup的Configure函数最后添加代码,表示当项目启动的时候就“注册服务”

            //注册服务
            string Address = "localhost";//服务ip地址
            int Port = 10577;//服务端口
            using (var client = new ConsulClient())
            {
                var result =  client.Agent.ServiceRegister(new AgentServiceRegistration()
                {
                    ID = "ServerName_" + Guid.NewGuid(),//服务编号保证不重复
                    Name = "ServerTest1",//服务的名称 集群使用consul
                    Address = Address,//服务ip地址
                    Port = Port,//服务端口
                    Check = new AgentServiceCheck //健康检查
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后反注册
                        Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔,或者称为心跳间隔(定时检查服务是否健康)
                        HTTP = "http://" + Address + ":" + Port + "/health/check",//健康检查地址
                        Timeout = TimeSpan.FromSeconds(5)//服务的注册时间
                    }
                });
            }

4、本项目在复制两份,一份命名test2、一份命名test1.fuben。首先,三个项目简单修改一下上面的代码,把adress和prot换成自己的ip和port。然后单独把test2注册的服务名字修改为Servertest2.全部修改完成后,目的就是test1/test1.fuben注册到consul节点的ServerTest1下面,这样就可以做负载了),test2单独注册到consul节点的ServerTest2下面。

 

第四步:创建API网关项目

1、先创建一个空的web项目,在nuget中安装Ocelot包和Ocelot.provider.consul包。

2、在创建一个名为ocelot.json的配置文件(json格式)。稍后再介绍这个文件如何添加配置。

{
  "ReRoutes": [
    //Api网关请求转发后,对test1和test1.fuben做负载
    {
      "DownstreamPathTemplate": "/{url}",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/api/{url}", //上游地址,表示如果配到地址为/api/{url}格式的请求,就转发到/url
      "UpstreamHttpMethod": [ "Get" ],
      "UseServiceDiscovery": true, //使用服务发现功能
      "ServiceName": "ServerTest", //注册的服务名
      "LoadBalancerOptions": {
        "Type": "RoundRobin" //负载方式
      }
    },
    //api网关对请求进行转发,test2网站
    {
      "DownstreamPathTemplate": "/weatherforecast", //下游地址
      "DownstreamScheme": "http", //请求协议
      "UpstreamPathTemplate": "/tianqi/", //上游地址,表示如果配到地址为/tianqi的请求,就转发到/weatherforecast
      "UpstreamHttpMethod": [ "Get" ], //请求method
      "UseServiceDiscovery": true, //使用服务发现���能
      "ServiceName": "ServerTest2" //注册的服务名
    }
  ],
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul",
      "PollingInterval": 100
    }
  }
}

这个json文件,分为两大块,GlobalConfiguration节点是全局配置,里面包含consul的地址信息。ReRoutes里面配置的是请求转发信息。描述如下:

a、如果请求地址符合/api/{url}格式,则读取Consul里面ServerTest1服务中注册的地址,然后进行转发请求,如果Consul里面ServerTest1服务中注册的地址有多份,那么,就进行负载请求。

b、如果请求地址符合/tianqi格式,则读取Consul里面ServerTest2服务中注册的地址,然后从Consul里面ServerTest2服务中读取地址,转发到该地址的/weatherforecast上。

3、打开program.cs,把ocelot.json添加到“启动加载”中,并且配置一下网关项目访问的地址(也可以在启动文件中配置)

        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args)
        {
            return WebHost.CreateDefaultBuilder(args)
                            .UseStartup<Startup>()
                            .UseUrls("http://localhost:8230")
                            .ConfigureAppConfiguration((hostingContext, builder) =>
                            {
                                builder.AddJsonFile("Ocelot.json", false, true);
                            })
                            .Build();
        }

4、修改satrtup文件,把Ocelot中间件添加到管道中:

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddControllers();
            services.AddOcelot().AddConsul();//注册对Ocelot和Consul的支持;
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseOcelot().Wait();//
        }

 

此时配置部分就可以了。运行项目(api网关项目一定要最后运行,因为只有其他项目先注册地址,他才能发现并读取地址)。全部运行后,访问consul的管理界面,就可以看到如下的内容,表示注册成功!

此时证明注册服务成功,我们也可以在点点别的,看看健康检查啥的,有没有问题,等等。然后我们就可以通过网关的“地址+端口”,根据Ocelot.json配置的路由规则进行访问了。

比如:http://localhost:8230/api/health/check   根据匹配规则,他会根据ServerTest1中注册的地址进行请求转发、并且对test1、test1.fuben进行负债均衡。

比如:http://localhost:8230/tianqi    根据匹配规则,会直接进入ServerTest2中注册地址,转发到/weatherForecast上面,来请求test2项目。

 

最后

这里就结束了,Ocelot.Json还有各种各样的花式配置,自己百度吧,很简单的。项目源码地址:Ocelot_Consul_Test.rar (11.24 mb)

添加评论

Loading