前言
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)