/// <summary>
        /// Soa服务自注册
        /// </summary>
        /// <param name="serviceId"></param>
        /// <param name="instanceId"></param>
        private void RegisterService(string serviceId, string instanceId)
        {
            logger.Info($"Soa self registration : {serviceId}-{instanceId}");

            if (string.IsNullOrEmpty(instanceId))
            {
                logger.Warn("Instance id is empty, soa self registration will be ignored");
                return;
            }

            var result = client.Call <SoaRegisterRequestType, SoaResponseType>
                             (DynamicConfigFactory.GetInstance("global.properties").GetStringProperty("SoaCenter"),
                             "soa", "register", new SoaRegisterRequestType()
            {
                ServiceId  = serviceId,
                InstanceId = instanceId
            });

            var resp = result.Result;

            if (resp.Header.ResponseCode != (int)ErrorCode.Success)
            {
                throw new SoaServiceException(ErrorCode.SoaRegistionFailed,
                                              $"Soa self registion failure, error code : {resp.Header.ResponseCode}, reason : {resp.Header.ResponseCode}");
            }
        }
        private void Listen(string app)
        {
            var config = DynamicConfigFactory.GetInstance($"{app}.status.properties");

            // 应用程序状态发生变化后,对应的Soa服务可用实例的清单也会发生变化
            config.RegisterListener(() =>
            {
                // 获取需要更新的服务清单
                var services = QueryServiceByAppId(app);

                // 获取AppInfo
                var appInfo = ResourceClient.AppInfoQuery(app);

                // 更新Soa在配置中心的可用实例列表
                services.ForEach(p =>
                {
                    var addressList = GetAvailableInstances(appInfo, config, p);
                    var address     = addressList == null ? string.Empty : string.Join(";", addressList);

                    logger.Info($"Update soa instances list : {address}");
                    // 更新配置中心的Soa对应的实例的清单
                    // 为了提高性能,如果Soa注册中心的服务采用集群的环境,那么需要一个Controller来控制和分配每一个实例支持不同的app
                    Modifier.Update($"soa.{p.ServiceId}.properties", new List <ModifiedPropertyInfo>()
                    {
                        new ModifiedPropertyInfo()
                        {
                            Key   = "ServerList",
                            Value = address
                        }
                    });
                });
            });
        }
Beispiel #3
0
        /// <summary>
        /// Soa自动寻址
        /// </summary>
        /// <typeparam name="Req"></typeparam>
        /// <typeparam name="Resp"></typeparam>
        /// <param name="serviceId"></param>
        /// <param name="operationName"></param>
        /// <param name="timeoutInMs"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task <Resp> Call <Req, Resp>(string serviceId, string operationName, Req request, int timeoutInMs = DEFAULT_TIMEOUT_IN_MS)
        {
            var provider = DynamicConfigFactory.GetInstance($"soa.{serviceId}.properties");
            var address  = provider.GetStringProperty("ServerList");

            if (string.IsNullOrEmpty(address))
            {
                throw new SoaClientException(ErrorCode.AppResourceUnavilable, "There's no effective instances available");
            }

            var addressList = address.Split(';');

            // TODO, 这里需要优化为Soa负载均衡策略
            var val = (new Random()).Next(addressList.Length - 1);

            return(await Call <Req, Resp>(addressList[val], serviceId, operationName, request, timeoutInMs));
        }