ApiStationMng.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Newtonsoft.Json;
  7. using Sers.Core.Module.Api.ApiDesc;
  8. using Sers.Gover.Base.Model;
  9. using Sers.Gover.Persistence;
  10. using Sers.ServiceCenter.Entity;
  11. using Vit.Core.Module.Log;
  12. using Vit.Core.Util.ConfigurationManager;
  13. using Vit.Extensions;
  14. namespace Sers.Gover.Base
  15. {
  16. [JsonObject(MemberSerialization.OptIn)]
  17. public class ApiStationMng
  18. {
  19. [JsonProperty]
  20. ConcurrentDictionary<string, ApiStationData> apiStations;
  21. GoverApiCenterService goverManage;
  22. public ApiStationMng()
  23. {
  24. }
  25. public ApiStationMng Init(GoverApiCenterService goverManage)
  26. {
  27. this.goverManage = goverManage;
  28. if (null == apiStations)
  29. {
  30. apiStations = new ConcurrentDictionary<string, ApiStationData>();
  31. }
  32. return this;
  33. }
  34. #region 查询
  35. public IEnumerable<SsApiDesc> ApiDesc_GetAll()
  36. {
  37. var apiServices = (from apiStation in apiStations.Values
  38. from apiService in apiStation.apiServices.Values
  39. select apiService);
  40. var res = apiServices.Select((apiService)=>
  41. {
  42. var apiDesc = apiService.apiDesc.ConvertBySerialize<SsApiDesc>();
  43. apiDesc.ext = new { apiService.counter};
  44. return apiDesc;
  45. });
  46. return res;
  47. }
  48. #endregion
  49. #region ApiStation
  50. [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
  51. public List<ApiStationData> ApiStation_GetAll()
  52. {
  53. return apiStations.Values.OrderBy(m=>m.stationName).ToList();
  54. }
  55. public bool ApiStation_Pause(string stationName)
  56. {
  57. lock (this)
  58. {
  59. if (!apiStations.TryGetValue(stationName, out var apiStationData))
  60. {
  61. return false;
  62. }
  63. if (apiStationData.eStatus == EServiceStationStatus.暂停)
  64. {
  65. return true;
  66. }
  67. apiStationData.eStatus=EServiceStationStatus.暂停;
  68. foreach (var apiNode in apiStationData.apiServices.Values.SelectMany((m) => m.apiNodes))
  69. {
  70. apiNode.StopReason_Add(goverManage.apiLoadBalancingMng, "stopByApiStation");
  71. }
  72. }
  73. return true;
  74. }
  75. public bool ApiStation_Start(string stationName)
  76. {
  77. lock (this)
  78. {
  79. if (!apiStations.TryGetValue(stationName, out var apiStationData))
  80. {
  81. return false;
  82. }
  83. if (apiStationData.eStatus == EServiceStationStatus.正常)
  84. {
  85. return true;
  86. }
  87. apiStationData.eStatus = EServiceStationStatus.正常;
  88. foreach (var apiNode in apiStationData.apiServices.Values.SelectMany((m)=>m.apiNodes))
  89. {
  90. apiNode.StopReason_Remove(goverManage.apiLoadBalancingMng, "stopByApiStation");
  91. }
  92. }
  93. return true;
  94. }
  95. ApiStationData ApiStation_Get(string route)
  96. {
  97. var stationName = route.Split('/')[1];
  98. if (apiStations.TryGetValue(stationName, out var apiStationData))
  99. {
  100. return apiStationData;
  101. }
  102. return null;
  103. }
  104. public ApiStationData ApiStation_GetOrAddByName(string stationName)
  105. {
  106. return apiStations.GetOrAdd(stationName, (n) => new ApiStationData() { stationName = n });
  107. }
  108. public ApiStationData ApiStation_GetOrAddByRoute(string route)
  109. {
  110. var stationName = route.Split('/')[1];
  111. return ApiStation_GetOrAddByName(stationName);
  112. }
  113. void ApiStation_Remove(ApiStationData apiStation)
  114. {
  115. apiStations.TryRemove(apiStation.stationName,out _);
  116. }
  117. #endregion
  118. #region ApiService
  119. /// <summary>
  120. /// 移除离线的ApiService
  121. /// </summary>
  122. public void ApiService_RemoveOffline()
  123. {
  124. List<ApiStationData> changedApiStationList;
  125. lock (this)
  126. {
  127. var apiServiceItems = (from apiStation in apiStations.Values
  128. from apiService in apiStation.apiServices.Values
  129. where apiService.apiNodeCount==0
  130. select (apiStation,apiService)).ToList();
  131. foreach (var (apiStation, apiService) in apiServiceItems)
  132. {
  133. apiStation.ApiService_Remove(apiService.apiDesc.ServiceKeyGet());
  134. }
  135. changedApiStationList = apiServiceItems.Select(m => m.apiStation).Distinct().ToList();
  136. foreach (var apiStation in changedApiStationList)
  137. {
  138. if (apiStation.apiServiceCount == 0)
  139. {
  140. ApiStation_Remove(apiStation);
  141. }
  142. }
  143. }
  144. #region 持久化对应ApiStation中的所有ApiDesc(异步执行)
  145. Task.Run(() =>
  146. {
  147. try
  148. {
  149. foreach (var apiStation in changedApiStationList)
  150. {
  151. Persistence_ApiDesc.ApiDesc_SaveApiStationToJsonFile(apiStation);
  152. }
  153. }
  154. catch (Exception ex)
  155. {
  156. Logger.Error(ex);
  157. }
  158. });
  159. #endregion
  160. }
  161. #endregion
  162. #region ApiNode
  163. static bool Config_ApiRegistEvent_Print = (false != ConfigurationManager.Instance.GetByPath<bool?>("Sers.ServiceCenter.ApiRegistEvent_Print"));
  164. void ApiNode_Add(string route, ApiNode apiNode)
  165. {
  166. try
  167. {
  168. if (Config_ApiRegistEvent_Print)
  169. {
  170. Logger.Info("[ApiCenterService]Add ApiNode,serviceKey:" + apiNode.apiDesc.ServiceKeyGet());
  171. }
  172. //ApiStation 添加ApiNode
  173. var apiStation = ApiStation_GetOrAddByRoute(route);
  174. apiStation.ApiNode_Add(apiNode);
  175. if (apiStation.IsActive())
  176. {
  177. apiNode.Start(goverManage.apiLoadBalancingMng);
  178. }
  179. }
  180. catch (Exception ex)
  181. {
  182. Logger.Error(ex);
  183. }
  184. }
  185. void ApiNode_Remove(ApiNode apiNode)
  186. {
  187. var route = apiNode?.apiDesc?.route;
  188. if (string.IsNullOrWhiteSpace(route)) return;
  189. if (Config_ApiRegistEvent_Print)
  190. {
  191. Logger.Info("[ApiCenterService]Remove ApiNode,serviceKey:" + apiNode.apiDesc.ServiceKeyGet());
  192. }
  193. var apiStation = ApiStation_Get(route);
  194. if (apiStation == null) return;
  195. //ApiStation 注销ApiNode
  196. apiStation.ApiNode_Remove(apiNode);
  197. //if (apiStation.apiNodeCount == 0)
  198. //{
  199. // ApiStation_Remove(apiStation);
  200. //}
  201. //ApiLoadBalancingMng 注销ApiNode
  202. apiNode.Stop(goverManage.apiLoadBalancingMng);
  203. }
  204. #endregion
  205. #region ServiceStation
  206. #region ServiceStation_Add
  207. public void ServiceStation_Add(ServiceStation serviceStation)
  208. {
  209. //注册apiNode
  210. lock (this)
  211. {
  212. foreach (var apiNode in serviceStation.apiNodes)
  213. {
  214. var route = apiNode?.apiDesc?.route;
  215. if (string.IsNullOrWhiteSpace(route)) continue;
  216. apiNode.serviceStation = serviceStation;
  217. ApiNode_Add(route, apiNode);
  218. }
  219. }
  220. #region 持久化对应ApiStation中的所有ApiDesc(异步执行)
  221. Task.Run(() =>
  222. {
  223. try
  224. {
  225. foreach (var apiStationName in serviceStation.ApiStationNames_Get())
  226. {
  227. if (apiStations.TryGetValue(apiStationName, out var apiStation))
  228. {
  229. Persistence_ApiDesc.ApiDesc_SaveApiStationToJsonFile(apiStation);
  230. }
  231. }
  232. }
  233. catch (Exception ex)
  234. {
  235. Logger.Error(ex);
  236. }
  237. });
  238. #endregion
  239. }
  240. #endregion
  241. #region ServiceStation_Remove
  242. public void ServiceStation_Remove(ServiceStation serviceStation)
  243. {
  244. lock (this)
  245. {
  246. //注销apiNode
  247. foreach (var apiNode in serviceStation.apiNodes)
  248. {
  249. ApiNode_Remove(apiNode);
  250. }
  251. }
  252. }
  253. #endregion
  254. #region ServiceStation_Pause
  255. public void ServiceStation_Pause(ServiceStation serviceStation)
  256. {
  257. lock (this)
  258. {
  259. foreach (var apiNode in serviceStation.apiNodes)
  260. {
  261. apiNode.StopReason_Add(goverManage.apiLoadBalancingMng, "stopByServiceStation");
  262. }
  263. }
  264. }
  265. #endregion
  266. #region ServiceStation_Start
  267. public void ServiceStation_Start(ServiceStation serviceStation)
  268. {
  269. lock (this)
  270. {
  271. foreach (var apiNode in serviceStation.apiNodes)
  272. {
  273. apiNode.StopReason_Remove(goverManage.apiLoadBalancingMng, "stopByServiceStation");
  274. }
  275. }
  276. }
  277. #endregion
  278. #endregion
  279. }
  280. }