.NetCore框架Surging系列(一)介绍
.NetCore框架Surging系列(二)HTTP
.NetCore框架Surging系列(三)HTTP本地路由发现过程
.NetCore框架Surging系列(四)RPC客户端过程
.NetCore框架Surging系列(五)路由注册
路由发现
路由发现需要重点关注这么几个问题
- 为什么要做路由发现
- 如何触发路由发现
- 怎么做到路由同步
为什么要做路由发现
之前提到过,如果http请求能在当前服务找到entry
就执行本地方法,如果找不到则进行远程调用,而远程调用需要根据当前请求路由找到远程服务器,路由发现就是发现远程服务器,并建立路由管理体系
。
后面会详细介绍,如何根据请求路由找到服务器相关信息。
注:这里取名叫路由发现,不是服务发现。
/api/v1/user/get
/api/v1/user/gets
以上两个路由可能不在同一个服务(工程)当中(不支持Restful,get/gets是方法名)
如何触发路由发现
路由管理都是在类Surging.Core.Consul.ConsulServiceRouteManager
中进行的,修改路由信息都是在方法EnterRoutes里面,触发这个方法的有两个地方:
1、类初始化 (Consul中有路由信息)
2、在获取路由的时候 (Consul中不存在路由信息)
//1、类初始化
public ConsulServiceRouteManager(...) : base(stringSerializer)
{
...
EnterRoutes().Wait();
}
...
//2、在获取路由的时候
public override async Task<IEnumerable<ServiceRoute>> GetRoutesAsync()
{
await EnterRoutes();
return _routes;
}
那什么时候触发类实例化呢,实际上是在为每个接口类型创建服务实例类的时候,“DefaultBackgroundServiceEntryProvider.CreateServiceEntry”
//之前讲的创建本地的路由实例
public class DefaultBackgroundServiceEntryProvider: IBackgroundServiceEntryProvider
{
...
public BackgroundServiceEntry CreateServiceEntry(Type service)
{
...
var objInstance = _serviceProvider.GetInstances(service);
...
}
}
}
namespace Surging.Core.CPlatform.Module
{
public class EchoService : ServiceBase, IEchoService
{
//1、创建本地理由实例时创建EchoService,
//2、EchoService需要路由提供器
//3、路由提供器需要路由管理器
//4、路由管理器实例化时触发路由发现
//DefaultServiceRouteProvider : IServiceRouteProvider
//public DefaultServiceRouteProvider(...
// IServiceRouteManager serviceRouteManager
// ...
//)
//ConsulServiceRouteManager :
// ServiceRouteManagerBase :
// IServiceRouteManager
private readonly IServiceRouteProvider _serviceRouteProvider;
public EchoService(...
IServiceRouteProvider serviceRouteProvider
...
)
{
...
_serviceRouteProvider = serviceRouteProvider;
...
}
}
}
3、同步新增接口
这里注意一点,管理路由时,如果已经存在路由就返回,如果没有则重新同步路由。这里需要注意,如果路由存在就不同步了,那么其他的服务新增了接口怎么同步呢,下面是同步代码:
private async Task EnterRoutes()
{
if (_routes != null && _routes.Length > 0)
return;
...
if (_configInfo.EnableChildrenMonitor)
{
//创建子监控类
...
}
_routes = await GetRoutes(keys.Response);
}
根据掌握情况有以下几个处理方式
- 重启大法,更新服务后重启所有服务,并且服务存在依赖顺序不能乱,如果一次不行多重启几次
- 修改配置
//surgingSettings.json "Consul": { ... "EnableChildrenMonitor": true, //启用子监视器,会有一定的性能损耗 ... },
- 将路由发现改为
服务发现
怎么做到路由同步
路由发现本质上是将注册到Consul中的路由,获取到当前服务中,所有操作都在Surging.Core.Consul.ConsulServiceRouteManager
中,过程如下:
写在最后
- 路由发现是否颗粒度太细了,管理起来非常复杂,是否需要修改为服务发现呢?
- 路由不支持Restful,如果需要则尽早规划,否认很难调整过来