/// <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 } }); }); }); }
/// <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)); }