/// <summary> /// 清除路由,清理连接 /// </summary> /// <param name="serverName">serverName</param> /// <param name="router">router</param> public static void ClearRouter(string serverName, string router) { string path = getRouterPath(serverName) + $"/[{router}]"; logger.LogInformation($"服务退出,清理路由:{path}"); try { var existPath = currentZookeeper.existsAsync(path, false); existPath.Wait(); if (existPath.Result != null) { Delete(path); } if (currentZookeeper != null) { var rst = currentZookeeper.closeAsync(); rst.Wait(); currentZookeeper = null; } } catch (Exception e) { LogTextWriter.Write(e); // 这里吞掉算了 ,服务要退出了,不管了··· } }
/// <summary> /// 枚举转为 StatusCode /// </summary> /// <typeparam name="TEnumClass">枚举类型</typeparam> /// <param name="enumValue">枚举值</param> /// <returns>状态码</returns> public static StatusCode ToCode <TEnumClass>(this TEnumClass enumValue) where TEnumClass : struct { var cd = GetEnumCodeDescription(enumValue); var code = (int)(object)enumValue; if (cd == null) { LogTextWriter.Write($"枚举值{enumValue} 没有定义属性[CodeDescAttribute]"); // return StatusCode.ErrorCodeUndefined; return(new StatusCode(code, StatusCode.ErrorCodeUndefined.ToString())); } return(new StatusCode(code, cd.Description)); }
private static void checkTimeOut() { while (true) { try { Thread.Sleep(60 * 1000); // 每1分钟检查一次 if (dicConnections.Count < 1) { continue; } string[] keys = dicConnections.Keys.ToArray(); Random r = new Random(DateTime.Now.Millisecond); var k = keys[r.Next(0, keys.Length)]; var indxValue = dicConnections[k]; // 随机检查 var keyValuePairs = indxValue.Where(x => DateTime.Now.Subtract(x.V1).TotalMilliseconds > 2 * 60 * 1000)?.ToArray(); // 找到2分钟没有被用的连接,释放掉 if (keyValuePairs == null || keyValuePairs.Length < 1) { continue; } lock (root) { for (int i = 0; i < keyValuePairs.Length; i++) { keyValuePairs[i].V2?.Close(); indxValue.Remove(keyValuePairs[i]); keyValuePairs[i].V2 = null; } } } catch (Exception e) { LogTextWriter.Write(e); } } }
/// <summary> /// 初始化服务配置(本地super.json中必须指明读取的配置源) /// </summary> /// <returns></returns> private static void InitConfiguration() { var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); if (string.IsNullOrEmpty(env)) // 不配置就走config.json { configFile = string.Format(configFile, ""); } else { env = env.ToLower().Trim(); //switch (env) //{ // case "dev": // configFile = string.Format(configFile, ".dev"); // break; // case "test": // configFile = string.Format(configFile, ".test"); // break; // case "prod": // configFile = string.Format(configFile, ".prod"); // break; // default: // configFile = string.Format(configFile, ""); // break; //} configFile = string.Format(configFile, "." + env); } var configJson = Path.Combine(AppContext.BaseDirectory, configFile); // 在NLog配置没有初始化之前,只能靠Console输出日志 LogTextWriter.Write($"当前的环境变量是:{env},加载的指向配置文件是:{configJson}\r\n"); if (!File.Exists(configJson)) { throw new Exception($"在当前服务运行目录中找不到配置文件{configFile}"); } //配置源优先从服务本地根目录下的config.json获取, IConfiguration configSource = new ConfigurationBuilder().SetBasePath(AppContext.BaseDirectory) .AddJsonFile(configFile, optional: true, reloadOnChange: false).Build(); ServerSetting.configCenter = configSource.GetSection("ServerConfig:ConfigCenter").Get <ConfigCenter>(); //如未获取到,则配置源默认为ConfigType.Local if (ServerSetting.configCenter == null) { ServerSetting.configCenter = new ConfigCenter() { ConfigType = ConfigType.Local }; } var settingConfigBuilder = new ConfigurationBuilder(); string configPath = string.Empty; switch (ServerSetting.configCenter.ConfigType) { //配置源为ConfigType.Local时,优先读取内部config.json文件,不存在则读取上级目录Conf下的config.json case ConfigType.Local: configPath = Path.Combine(AppContext.BaseDirectory, configFile); if (File.Exists(configPath)) { settingConfigBuilder.SetBasePath(AppContext.BaseDirectory).AddJsonFile(configFile, optional: false, reloadOnChange: false); } else { var dirInfo = new DirectoryInfo(AppContext.BaseDirectory); var conf = Path.Combine(dirInfo.Parent.Parent.FullName, "conf"); bool isExist = false; if (Directory.Exists(conf)) { configPath = Path.Combine(conf, configFile); if (File.Exists(configPath)) { settingConfigBuilder.SetBasePath(conf).AddJsonFile(configFile, optional: false, reloadOnChange: false); isExist = true; } } if (!isExist) { throw new Exception($"请检查配置文件的路径是否存在{conf}/{configFile}"); } } break; case ConfigType.HttpFile: settingConfigBuilder.Sources.Add(new RemoteJsonFileConfigurationSource() { Uri = ServerSetting.configCenter.Ip, Optional = false }); configPath = ServerSetting.configCenter.Ip; break; default: throw new Exception($"The setting 'ConfigCenter.ConfigType':'{(int)ServerSetting.configCenter.ConfigType}' not support now!"); } LogTextWriter.Write($"最终的配置类型是:{ServerSetting.configCenter.ConfigType}, 最终的配置文件路径是:{configPath}\r\n"); var settingsConfig = settingConfigBuilder.Build(); //加载Nlog配置 NLog.LogManager.Configuration = new NLogLoggingConfiguration(settingsConfig.GetSection("NLog")); logger = LogFactory.CreateLogger <ServerSetting>(); //加载服务配置项 ServerSetting.config = settingsConfig.Get <Configuration>(); ServerSetting.configCenter = config.ServerConfig.ConfigCenter; if (config.ServerConfig.RpcService == null) { string msg = "请检查配置中super.json的配置是否正确,保证子节点RpcService的配置完整...."; logger.LogCritical(msg); Thread.Sleep(1000); throw new Exception(msg); } config.ConfigPath = ServerSetting.configCenter.Ip; getLocalIp(); }
/// <summary> /// 查找所有的 GrantRpcBaseServer 继承类 /// </summary> /// <returns>所有的 GrantRpcBaseServer 继承类</returns> public List <ClassInfo> GetAllInterfaceClass() { //string lang = string.Empty; //if (string.IsNullOrEmpty(lang)) //{ // lang = "zh_cn"; //} //var key = lang + "_f"; //if (sAllApiInfo.ContainsKey(key)) //{ // return sAllApiInfo[key]; //} //if (this.assembly == null) //{ // return new List<ClassInfo>(); //} // var ts = this.assembly.GetTypes(); var list = GetAllInterface(); // ts.Where(this.IsGrantRpcBaseServerChildClass).ToList(); var sum = list.Count; if (sum <= 0) { return(new List <ClassInfo>()); } var infos = new ClassInfo[sum]; Stopwatch sw = new Stopwatch(); sw.Start(); var rangesize = (int)(sum / Environment.ProcessorCount) + 1; Parallel.ForEach(Partitioner.Create(1, sum + 1, rangesize), range => { for (int i = range.Item1; i < range.Item2; i++) { var x = list[i - 1]; try { var t = this.GetInterfaceParam(x); var info = this.GetInterfaceInfo(x, t.args, ""); // var arg = new ParseTypeInfo(this.assembly, t.args); // var infoArgs = arg.Parse(); var infoArgs = new ClassInfo(this.assembly.FullName); var json = this.ToJson(t.args, false); var apiInfo = GetApiInfoByType(t.args); infoArgs.JsonDesc = json.json; infoArgs.LimitDesc = json.replaceJson; infoArgs.ApiClassInfo = apiInfo; // var rtn = new ParseTypeInfo(this.assembly, t.result); // var infoResult = rtn.Parse(); var infoResult = new ClassInfo(this.assembly.FullName); apiInfo = GetApiInfoByType(t.result); json = this.ToJson(t.result, false); infoResult.JsonDesc = json.json; infoResult.LimitDesc = json.replaceJson; infoResult.ApiClassInfo = apiInfo; info.PropertyInfo.Add(infoArgs); info.PropertyInfo.Add(infoResult); infos[i - 1] = info; } catch (Exception ex) { LogTextWriter.Write($"{x.FullName}:{ex.Message}"); var infoArgs = new ClassInfo(this.assembly.FullName); infoArgs.Name = x.Name; infoArgs.FullName = x.FullName; infoArgs.Desc = $"Parse Error:{ex.Message}"; infos[i - 1] = infoArgs; } } }); sw.Stop(); Trace.WriteLine($"Parallel.foreach {sw.ElapsedMilliseconds} ms"); return(infos.ToList()); }