项目代码很清晰,就是项目启动时,判断配置文件是否开启定时任务,如果开启就根据启动定时任务去从数据库中提取最新的配置信息,然后更新到内部配置并生效,停止时关闭并释放定时器,然后再注册后台服务。
//注册后端服务 builder.Services.AddHostedService<DbConfigurationPoller>();现在我们启动网关项目和测试服务项目,配置网关启用定时器,代码如下。
public void ConfigureServices(IServiceCollection services) { services.AddOcelot().AddAhphOcelot(option=> { option.DbConnectionStrings = "Server=.;Database=Ctr_AuthPlatform;User ID=sa;Password=bl123456;"; option.EnableTimer = true; //启用定时任务 option.TimerDelay = 10*000;//周期10秒 }); }启动后使用网关地址访问:7777/ctr/values,可以得到正确地址。
然后我们在数据库执行网关路由修改命令,等10秒后再刷新页面,发现原来的路由失效,新的路由成功。
UPDATE AhphReRoute SET UpstreamPathTemplate=\'/cjy/values\' where ReRouteId=1看到这个结果是不是很激动,只要稍微改造下我们的网关项目就实现了网关配置信息的自动更新功能,剩下的就是根据我们项目后台管理界面配置好具体的网关信息即可。
2、接口更新的方式
对于良好的网关设计,我们应该是可以随时控制网关启用哪种配置信息,这时我们就需要把网关的更新以接口的形式对外进行暴露,然后后台管理界面在我们配置好网关相关信息后,主动发起配置更新,并记录操作日志。
我们再回顾下Ocelot源码,看是否帮我们实现了这个接口,查找法Ctrl+F搜索看有哪些地方注入了IFileConfigurationRepository这个接口,惊喜的发现有个FileConfigurationController控制器已经实现了网关配置信息预览和更新的相关方法,查看源码可以发现代码很简单,跟我们之前写的更新方式一模一样,那我们如何使用这个方法呢?
using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Ocelot.Configuration.File; using Ocelot.Configuration.Setter; namespace Ocelot.Configuration { using Repository; [Authorize] [Route("configuration")] public class FileConfigurationController : Controller { private readonly IFileConfigurationRepository _repo; private readonly IFileConfigurationSetter _setter; private readonly IServiceProvider _provider; public FileConfigurationController(IFileConfigurationRepository repo, IFileConfigurationSetter setter, IServiceProvider provider) { _repo = repo; _setter = setter; _provider = provider; } [HttpGet] public async Task<IActionResult> Get() { var response = await _repo.Get(); if(response.IsError) { return new BadRequestObjectResult(response.Errors); } return new OkObjectResult(response.Data); } [HttpPost] public async Task<IActionResult> Post([FromBody]FileConfiguration fileConfiguration) { try { var response = await _setter.Set(fileConfiguration); if (response.IsError) { return new BadRequestObjectResult(response.Errors); } return new OkObjectResult(fileConfiguration); } catch(Exception e) { return new BadRequestObjectResult($"{e.Message}:{e.StackTrace}"); } } } }从源码中可以发现控制器中增加了授权访问,防止非法请求来修改网关配置,Ocelot源码经过升级后,把不同的功能进行模块化,进一步增强项目的可配置性,减少冗余,管理源码被移到了Ocelot.Administration里,详细的源码也就5个文件组成,代码比较简单,就不单独讲解了,就是配置管理接口地址,并使用IdentityServcer4进行认证,正好也符合我们我们项目的技术路线,为了把网关配置接口和网关使用接口区分,我们需要配置不同的Scope进行区分,由于本篇使用的IdentityServer4会在后续篇幅有完整介绍,本篇就直接列出实现代码,不做详细的介绍。现在开始改造我们的网关代码,来集成后台管理接口,然后测试通过授权接口更改配置信息且立即生效。
public void ConfigureServices(IServiceCollection services) { Action<IdentityServerAuthenticationOptions> options = o => { o.Authority = "http://localhost:6611"; //IdentityServer地址 o.RequireHttpsMetadata = false; o.ApiName = "gateway_admin"; //网关管理的名称,对应的为客户端授权的scope }; services.AddOcelot().AddAhphOcelot(option => { option.DbConnectionStrings = "Server=.;Database=Ctr_AuthPlatform;User ID=sa;Password=bl123456;"; //option.EnableTimer = true;//启用定时任务 //option.TimerDelay = 10 * 000;//周期10秒 }).AddAdministration("/CtrOcelot", options); }