Example #1
0
        /// <summary>
        /// 初始化
        /// </summary>
        internal Endpoint(Configuration configuration)
        {
            this.Configuration = configuration;

            if (this.Configuration.ID == null)
            {
                this.Configuration.Identity(new Identity()
                {
                    Source = System.Environment.MachineName,
                    //TODO:修改为外部指定
                    AuthKey = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(System.Environment.MachineName, "MD5")
                });
            }

            this._localTable     = new List <ServiceConfig>();
            this._clientTable    = new List <ServiceConfig>();
            this._associateTable = new ServiceConfigTable();
        }
Example #2
0
        //刷新容器
        private void RefreshContainer(ServiceConfigTable associateTable)
        {
            //排除从关联节点获取到的本地服务
            associateTable.Services = (associateTable ?? new ServiceConfigTable()).Services.Where(o =>
                                                                                                  //由于存在多地址情况 只判断Name+AssemblyName是否相同即可,避免本地暴露的服务被指向其他地址
                                                                                                  !this._localTable.Exists(p => p.Name.Equals(o.Name) && p.AssemblyName.Equals(o.AssemblyName))).ToArray();

            //卸载原有而新服务表中不存在的远程服务
            this._container.ClearRemoteServices(this.FilterANotInB(this._associateTable, associateTable));

            //替换关联节点服务表 先于容器注册前替换避免此时的调用拿到组件而没有服务信息
            this._associateTable = associateTable;
            //清空配置表
            this.ClearServiceTable();

            //注册原来没有而新服务表中存在的远程服务
            //this._container.RegisterRemoteServices(this.FilterANotInB(associateTable, this._associateTable));
            //重新注册避免外部原因导致的远程组件移除
            this._container.RegisterRemoteServices(associateTable.Services.Select(o => o.Type).ToArray());
        }
Example #3
0
        //准备服务表
        private void PrepareServiceTable(ServiceConfigTable table, List <ServiceConfig> configs)
        {
            //填充services用于负载均衡支持
            configs.ForEach(o =>
            {
                //保留configs属性为了短期兼容原不支持多地址的设计
                table.AddServiceConfig(o);

                var service = table.Services
                              .ToList()
                              .FirstOrDefault(p =>
                                              p.Name.Equals(o.Name) && p.AssemblyName.Equals(o.AssemblyName));

                if (service == null)
                {
                    service = new ServiceInfo(o.Name, o.AssemblyName);
                    table.AddServiceInfo(service);
                }

                service.LoadBalancingAlgorithm = o.LoadBalancingAlgorithm;
                service.AddServiceConfig(o);
            });
        }
Example #4
0
 //清空服务表
 private void ClearServiceTable()
 {
     lock (_serviceTableLock)
         this._serviceTable = null;
     this._log.Debug("由于服务发生变更,服务配置表被清空");
 }
Example #5
0
 private Type[] FilterANotInB(ServiceConfigTable a, ServiceConfigTable b)
 {
     return(a.Services
            .Where(o => b.Services.FirstOrDefault(p => p.Type == o.Type) == null)
            .Select(o => o.Type).ToArray());
 }
Example #6
0
        /// <summary>
        /// 尝试刷新关联节点配置,返回是否需要刷新服务表
        /// </summary>
        /// <returns>是否需要刷新服务表_serviceTable</returns>
        private bool RefreshAssociate()
        {
            if (this.AssociateUri == null)
            {
                return(false);
            }

            //以下代码段均在线程安全前提下

            #region 检查关联节点是否可连接
            Exception ex;
            if (!this._remoteHandle.TryConnect(this.AssociateUri, null, out ex))
            {
                //仅移除来自关联节点的服务配置
                this._associateTable.Services.ToList().ForEach(o =>
                                                               o.Configs = o.Configs.Where(p => !p.HostUri.Equals(this.AssociateUri)).ToArray());
                //仅移除没有可用服务配置的服务
                this._container.ClearRemoteServices(this._associateTable.Services
                                                    .Where(o => o.Configs.Length == 0)
                                                    .Select(o => o.Type)
                                                    .ToArray());
                //关联节点不存在后保留原始配置可以进行正常调用
                this._log.Warn("连接关联节点时发生异常,来自该节点内的远程服务已被卸载,其余服务保留", ex);
                return(true);
            }
            #endregion

            #region 检查版本
            try
            {
                if (this._associateTable.Version.Equals(this._remoteHandle.GetVersion(this.AssociateUri)))
                {
                    return(false);
                }
            }
            catch (Exception e)
            {
                this._log.Warn("检查关联节点服务表版本时发生异常", e);
                return(false);
            }
            #endregion

            #region 重新向本地容器注册关联节点的远程服务并清空配置表
            try
            {
                var configs = this._remoteHandle.GetServiceConfigs(this.AssociateUri);
                //重试一次,防止意外情况造成的空列表
                if (configs == null || configs.Services.Length == 0)
                {
                    configs = this._remoteHandle.GetServiceConfigs(this.AssociateUri);
                }
                if (configs == null || configs.Services.Length == 0)
                {
                    this._log.InfoFormat("从关联节点获取到空列表");
                }
                //包含刷新容器和配置表逻辑
                this.RefreshContainer(configs ?? new ServiceConfigTable());
            }
            catch (Exception e)
            {
                this._log.Warn("刷新关联服务节点时发生异常", e);

                if (this._associateTable == null)
                {
                    this._associateTable = new ServiceConfigTable();
                }
            }
            #endregion

            #region 重新将本地服务注册至关联节点
            try
            {
                if (this._localTable.Count > 0)
                {
                    this._remoteHandle.Register(this.AssociateUri, this._localTable.ToArray());
                    this._log.Debug("将本地服务重新注册至关联节点");
                }
            }
            catch (Exception e)
            {
                this._log.Warn("将本地服务重新注册至关联节点时发生异常", e);
            }
            #endregion

            return(false);
        }