使用Ocelot构建GateWay
添加Nuget包:Ocelot
添加配置文件Ocelot.json 具体配置可以看另一篇 Ocelot配置
Json配置文件主要包含两个根节点:
ReRoutes:路由重定向配置 都是数组结构 可以配置多个
GlobalConfigrations:全局配置
ReRoutes 主要包含了上下游的路径、方式、限流、负载等设置
我们先配置一个最简单的设置:
这里我做了一个负载,把api部署了2份做了一个简单的分布式,当我访问test的时候会被转发到20001或者 20002上
{ "ReRoutes": [ { "DownstreamPathTemplate": "/api/values/getuser", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 20001 }, { "Host": "localhost", "Port": 20002 } ], "UpstreamPathTemplate": "/test", "UpstreamHttpMethod": [ "Get" ], "LoadBalancer": "LeastConnection", "ServiceName": "userservices", "UseServiceDiscovery": true } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:20000", "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 8500 } } }
这里我结合了Consul来实现,关于Consul的使用可以看官方文档:
需要下载consul.exe程序并将其启动起来 这是一个服务发现健康检查的组件 如果没有添加系统path设置就直接进入consul.exe目录启动起来
httpServer的默认地址是8500,访问下会进入consul的ui
访问 :http://localhost:20000/test
访问:http://localhost:20001/api/values/getuser
得到一样的结果,这里已经被转发了,因为我们配置负载均衡及健康监测
从而保证了在服务器宕机后或者在高QPS下的正常访问
在APIGateWay网关里添加对Ocelot的设置
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, builder) => { builder .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath) .AddJsonFile("Ocelot.json"); }) .UseStartup<Startup>() .UseUrls("http://localhost:20000") .Build();
添加相关服务注册及configure
services.AddOcelot();
app.UseOcelot().Wait();
网关配置好后,需要对业务接口服务实现健康检查,设置好先关的参数处理consul的频率
DeregisterCriticalServiceAfter 失败多久后注销服务的
Interval 检查发送的评率
HTTP 检查的地址
applicationLifetime.ApplicationStarted.Register(() => { //自动获取当前接口服务地址 var features = app.Properties["server.Features"] as FeatureCollection; var addessess = features.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url)); foreach (var address in addessess) { var httpcheck = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(userappsetting.Value.DeregisterCriticalServiceAfter), Interval = TimeSpan.FromSeconds(userappsetting.Value.Interval), HTTP = new Uri(address, "/api/Check").OriginalString, }; //这里可以注入配置 var agentReg = new AgentServiceRegistration() { ID = $"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}", Check = httpcheck, Name = userappsetting.Value.ServiceName, Address = address.Host, Port = address.Port }; client.Agent.ServiceRegister(agentReg).ConfigureAwait(false); } }); applicationLifetime.ApplicationStopped.Register(() => { var features = app.Properties["server.Features"] as FeatureCollection; var addessess = features.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url)); foreach (var address in addessess) { client.Agent.ServiceDeregister($"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}").GetAwaiter().GetResult(); } });
注:上述代码注册指适用于 Hosting方式 ,如果你用的IIS做寄宿,
var addessess = features.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url));
获取到的地址不是你期待的地址,它是本地 127.0.0.1:随机端口 ,会导致健康检查服务注册了之后无法进行健康检查
可以配置下不同的启动方式来设置
applicationLifetime.ApplicationStarted.Register(() => { if (userappsetting.Value.IsIISHost) { #region IIS 寄宿方式 var httpcheck = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(userappsetting.Value.DeregisterCriticalServiceAfter), Interval = TimeSpan.FromSeconds(userappsetting.Value.Interval), HTTP = new Uri(new Uri(userappsetting.Value.CurrentIISUrl), userappsetting.Value.MatchPath).OriginalString }; //这里可以注入配置 var agentReg = new AgentServiceRegistration() { ID = $"{userappsetting.Value.ServiceName}_{userappsetting.Value.CurrentIISUrl}_{userappsetting.Value.CurrentIISPort}", Check = httpcheck, Name = userappsetting.Value.ServiceName, Address = userappsetting.Value.CurrentIISUrl, Port = userappsetting.Value.CurrentIISPort }; client.Agent.ServiceRegister(agentReg).ConfigureAwait(false); #endregion } else { #region 服务注册健康检查 Hosting寄宿 var addessess = app.ServerFeatures.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url)); foreach (var address in addessess) { var httpcheck = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(userappsetting.Value.DeregisterCriticalServiceAfter), Interval = TimeSpan.FromSeconds(userappsetting.Value.Interval), HTTP = new Uri(address, userappsetting.Value.MatchPath).OriginalString }; //这里可以注入配置 var agentReg = new AgentServiceRegistration() { ID = $"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}", Check = httpcheck, Name = userappsetting.Value.ServiceName, Address = address.Host, Port = address.Port }; client.Agent.ServiceRegister(agentReg).ConfigureAwait(false); } #endregion } }); applicationLifetime.ApplicationStopped.Register(() => { if (userappsetting.Value.IsIISHost) { client.Agent.ServiceDeregister($"{userappsetting.Value.ServiceName}_{userappsetting.Value.CurrentIISUrl}_{userappsetting.Value.CurrentIISPort}").GetAwaiter().GetResult(); } else { var addessess = app.ServerFeatures.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url)); foreach (var address in addessess) { client.Agent.ServiceDeregister($"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}").GetAwaiter().GetResult(); } } }); return applicationLifetime;
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/liyouming欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接。