API网关—Ocelot之服务发现
API网关—Ocelot之服务发现集成Consul集成nacos动态路由扩展Ocelot对注册中心的适配通过配置文件,我们可以设定路由规则模板,Ocelot网关会将接收到的符合规则的请求转发到下游服务,再从后端http service获取响应(Response)后,再返回给客户端。这样子外部应用就不需要记住每个service所在的IP和端口,而是只需要告诉网关需要消费哪个service即可。但是对
API网关—Ocelot之服务发现
通过配置文件,我们可以设定路由规则模板,Ocelot网关会将接收到的符合规则的请求转发到下游服务,再从后端http service获取响应(Response)后,再返回给客户端。这样子外部应用就不需要记住每个service所在的IP和端口,而是只需要告诉网关需要消费哪个service即可。
但是对于众多的微服务,如果我们都一一硬编码地配置其IP和Port在配置文件中,不适合微服务架构的风格,因为众多的服务地址变化会让静态配置的工作变得越来越大,而且容易出错。
Ocelot作为网关,支持的功能中包括服务发现,可以和多种服务注册中心结合,在请求转发的时候自动获取下游服务的IP和端口,减少配置的工作。其中对于Eureka和Consul,Ocelot官方已经给出了解决方案。
集成Consul
Ocelot集成Consul注册中心,需要对网关应用做一些改造。
-
安装Ocelot.Provider.Consul依赖包
Install-package Ocelot.Provider.Consul
-
设置依赖注入
public void ConfigureServices(IServiceCollection services) { services.AddOcelot(Configuration) .AddConsul(); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "OcelotGateWay", Version = "v1" }); }); }
-
修改配置信息
(1) 在之前的配置信息的基础上添加GlobalConfiguration,配置Consul相关信息"GlobalConfiguration": { "ServiceDiscoveryProvider": { "Scheme": "http", "Host": "127.0.0.1", "Port": 8500, "Type": "Consul" }
(2)修改原有的Route配置信息,去除下游服务的具体ip和端口配置,改为服务名称
"Routes": [ { "UpstreamPathTemplate": "/Customer/{url}", "UpstreamHttpMethod": [ "Get", "Post" ], "DownstreamPathTemplate": "/{url}", "DownstreamScheme": "http", "UseServiceDiscovery": true, "ServiceName": "customerService" } ]
-
启动CustomerService
可以在Consul管理页面中看到注册上来的服务
-
启动网关,通过postman进行测试
集成nacos
Ocelot官方没有提供集成nacos注册中心的支持,但是github中有一个开源库完成了Ocelot集成nacos的扩展,我们也不必重复造轮子。
扩展库github地址: https://github.com/softlgl/Ocelot.Provider.Nacos
-
安装依赖包
由于Ocelot.Provider.Nacos对nacos1.x和2.x的支持是通过nuget包的不同版本区分的,使用时请注意Ocelot.Provider.Nacos的版本,这里我使用nacos 2.x版本,所以安装1.2.2版本的包Install-package Ocelot.Provider.Nacos -v 1.2.2
-
设置依赖注入
public void ConfigureServices(IServiceCollection services) { services.AddNacosAspNet(Configuration, "nacos"); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "CustomerService", Version = "v1" }); }); }
-
修改配置文件
GlobalConfiguration节点中ServiceDiscoveryProvider改为nacos// Ocelot结合nacos注册中心 "GlobalConfiguration": { "ServiceDiscoveryProvider": { "Type": "Nacos" } }
添加nacos服务注册配置,这里和正常的nacos服务注册配置一致,实际上也是将网关作为一个服务注册到nacos中
"nacos": { "ServerAddresses": [ "http://127.0.0.1:8848" ], "DefaultTimeOut": 15000, "Namespace": "yyl", // Please set the value of Namespace ID !!!!!!!! "ListenInterval": 1000, "ServiceName": "gateway", "GroupName": "DEFAULT_GROUP", "ClusterName": "DEFAULT", "Port": 0, "Weight": 100, "RegisterEnabled": true, "InstanceEnabled": true, "Ephemeral": true, "Secure": false, "UserName": "nacos", "Password": "nacos", "ConfigUseRpc": false, "NamingUseRpc": false, "NamingLoadCacheAtStart": "", "LBStrategy": "WeightRandom" }
-
启动Customer服务和网关
可以看到Customer服务和网关都注册到nacos中
-
通过postman调用网关进行测试
动态路由
就算将Ocelot和服务注册中心结合了,可以通过服务发现自动获取下游服务的ip和端口,减少了在启动相同服务的多个实例动时的配置工作量,但是在新增或减少一个服务时还是需要修改配置文件,在routes节点中增加或减少一个配置。
当服务拆分得非常多时,将服务一一地配置到配置文件,将会是一个巨大的工程,虽然都是copy,但是会增加出错的机会,并且很难排查。
而Ocelot提供了Dynamic Routing功能,这个功能是在issue 340后增加的(见下图官方文档),目的是在使用服务发现之后,直接通过服务发现去定位从而减少配置文件中的Routes配置项。
只要请求的url地址符合既定的规则,Ocelot网关就会通过服务发现查找到对于服务的IP和地址,而Routes节点可以不做任何配置。
例如以下url:http://localhost:5001/customerService/WeatherForecast
Ocelot会将url地址中域名或者ip+端口后的第一个参数,也就是customerService作为ServiceName调用服务发现API得到IP和Port,然后加上后续的请求URL部分(/WeatherForecast)进行最终URL的访问:http://ip:port/WeatherForecast。
"Routes": [],
"GlobalConfiguration": {
"RequestIdKey": null,
"ServiceDiscoveryProvider": {
"Scheme": "http",
"Host": "127.0.0.1",
"Port": 8500,
"Type": "Consul"
}
}
postman调用测试如下:
扩展Ocelot对注册中心的适配
查看核心Ocelot.Provider.Consul的源码,可以看到Ocelot对于不同的注册中心的适配,其实就是通过一个ServiceDiscoveryFinderDelegate委托实现的,我们只要根据不同的注册中心编写ServiceDiscoveryFinderDelegate不同的实现即可
像适配nacos,只要提供自己的ServiceDiscoveryFinderDelegate,返回一个IServiceDiscoveryProvider实现类即可
IServiceDiscoveryProvider实现类中重点就是Get方法,在Get方法中通过ServiceName从注册中心中获取到可用的服务集合,而Ocelot的负载均衡机制会从中选出一个作为当前请求的url。
在使用Ocelot.Provider.Nacos的时候,GlobalConfiguration节点中的ServiceDiscoveryProvider时不需要配置注册中心地址的,但是为了使用动态路由,就必须加上Host和Port了,这里的Host和Port并没有其他作用,只是让Ocelot可以根据url解解析路由。
如下:
"GlobalConfiguration": {
"ServiceDiscoveryProvider": {
"Type": "Nacos",
"Host": "127.0.0.1",
"Port": 8000
}
}
为了集成nacos和Ocelot的动态路由功能折腾了好久,还以为动态路由功能也需要自己提供实现,查看了好久Ocelot的源码,才在DownstreamRouteFinderMiddleware中发现,查看DownstreamRouteFinderMiddleware中的IDownstreamRouteProviderFactory获取时,只有存在Host和Port的时候,才能获取到DownstreamRouteCreator,才能从url中解析出ServiceName。
微服务系列文章:
上一篇:API网关—Ocelot
下一篇:API网关—Ocelot之负载均衡
更多推荐
所有评论(0)