由于希望使用Wcf作为公司内的通讯框架,因此基于Wcf进行了一些扩展,主要的目的有以下几个方面:
1) 希望减少客户端调用的复杂度,调用方式简化为WcfServiceLocator.Create<ITestService>().Add(1,2)。不需要考虑:endpoint配置,信道创建,信道出问题等等问题。
2) 希望减少服务端配置的复杂度,没有配置文件(或者说配置文件不需要更改),所有和服务相关的元数据处于数据库中,这样客户端也没有配置。
3) 有后台来管理所有元数据的配置,并且可以在配置更改的时候通知相关的客户端来重新建立信道,通知相关的服务端来重启服务。
4) 进行简单的路由功能,比如优先考虑IPC/TCP的信道而不是HTTP的信道,引用了高版本服务契约的客户端优先访问高版本服务契约的服务端。也就是说,在生产环境中,如果契约不兼容,可以再开一组高版本的服务端集群,客户端一个一个更新契约,一个一个引入高版本的服务端,等更新全部完成之后再撤去老版本的服务端。
5) 我非常重视横切关注点,希望整个框架在下面几个维度建立日志:
A)调用信息,客户端调用远程方法结束后记录,服务端完成远程方法执行后记录,可以记录调用的方法名、服务名、所需时间、两端版本、两端机器名等信息
B)启动信息,客户端第一次建立信道工厂的时候记录,服务端第一次启动服务的时候记录
C)消息信息,客户端收到和发送的消息,服务端收到和发送的消息
D)异常信息,服务端产生的异常,客户端收到的经过包装的异常
6) 这些大量的日志的记录策略本身是在数据库中配置的,日志记录到存储中,使用Mongodb的Nosql技术
总之,一句话,服务的消费者和提供者只需要考虑怎么去写服务,其它的配置/部署/横切等等基础工作全都不需要考虑,配置集中对于部署有好处,各种具有独立开关的日志对于故障排查有好处。
整体结构如下:
1) ConfigCenter是一个网站,有两个作用,一提供了配置的后台,二是实现了IWcfConfigService,暴露出去,提供服务:
public interface IWcfConfigService
{
[OperationContract]
WcfService GetWcfService(string serviceType, string serviceContractVersion, string machineName); // 服务端的配置
[OperationContract]
WcfClientEndpoint GetWcfClientEndpoint(string serviceContractType, string serviceContractVersion, string machineName); //客户端的端点
[OperationContract]
ClientLogConfig GetClientLogConfig(string serviceContractType); //客户端的横切配置
[OperationContract]
ServerLogConfig GetServerLogConfig(string serviceContractType, string machineName); //服务端的横切配置
}
配置信息保存在MSSQL中,后台提供配置。此外,在修改了配置之后,向Redis发布消息,所有客户端和服务端会订阅这些消息。实现配置更改的发布订阅。
2) LogService也是一个网站,同样是实现各种日志的查看,以及提供IWcfLogService的实现:
public interface IWcfLogService
{
[OperationContract]
string Health(); //心跳,不可用的时候切换为本地日志服务
[OperationContract(Name = "LogList", IsOneWay = true)]
void Log(List<AbstractLogInfo> logInfo);
[OperationContract(Name = "LogOne", IsOneWay = true)]
void Log(AbstractLogInfo logInfo);
}
收集到日志之后通过队列,写入Mongodb,后台提供查看。
3) WcfExtension是框架主体,主要分为四个部分:
A) Client是所有和客户端信道、代理、行为相关的东西,实现调用的代理以及日志的收集
B) Server是所有和服务端相关的东西,包括服务的IOC、各种日志收集、异常处理、服务行为等
C) Log包括IWcfLogService服务契约以及、数据契约和数据的收集模块
D) Config包括IWcfConfigService服务契约、相关的数据契约(也包括框架本身的配置)
4)Clients.Console是控制台方式的客户端,生产环境很可能是网站。引用WcfExtension框架和业务服务契约。
5)Hosts.Console是控制台方式的服务端,生产环境很可能是网站或Windows服务。引用WcfExtension框架、业务服务契约和实现。
6)WcfExtension.Services.Interface是业务契约,被客户端和服务端引用。
7)WcfExtension.Services.Implementation是业务实现,只被服务端引用。
此文只是介绍一下基本的架构,后续的文章会介绍一些实现以及提供源代码。