/// <summary> /// Stops the and deregister. /// </summary> /// <param name="server">The server.</param> /// <param name="stopServer">The stop server.</param> /// <returns></returns> /// <exception cref="Exception">当前服务没有注册,或者是已经被反注册过..</exception> public static async Task <Server> StopAndDeregister(this Server server, Action <Server> stopServer = null) { if (!serviceDict.ContainsKey(server.GetHashCode())) { throw new Exception("当前服务没有注册,或者是已经被反注册过.."); } await serviceDict[server.GetHashCode()].Deregister(); serviceDict.Remove(server.GetHashCode()); InnerLogger.Log(LoggerLevel.Info, "反注册服务发现"); if (stopServer == null) { await server.KillAsync(); } else { stopServer(server); } InnerLogger.Log(LoggerLevel.Info, "grpc服务停止"); return(server); }
public async Task Invoke(MiddlewareContext context) { InnerLogger.Log(LoggerLevel.Info, $"{context.Method.FullName} :Before"); await _next(context); InnerLogger.Log(LoggerLevel.Info, $"{context.Method.FullName} :End"); }
/// <summary> /// Registers the specified agent service registration. /// </summary> /// <param name="agentServiceRegistration">The agent service registration.</param> /// <param name="config">The configuration.</param> /// <returns></returns> private static async Task Register(AgentServiceRegistration agentServiceRegistration, ConsulLocalServiceConfig config) { if (!config.ConsulIntegration) { InnerLogger.Log(LoggerLevel.Info, "ConsulIntegration=false,当前服务不集成consul环境"); return; } InnerLogger.Log(LoggerLevel.Info, "register:" + Newtonsoft.Json.JsonConvert.SerializeObject(agentServiceRegistration)); try { var client = CreateConsulClient(config.ConsulAddress); var rs = await client.Agent.ServiceRegister(agentServiceRegistration); client.Dispose(); InnerLogger.Log(LoggerLevel.Info, Newtonsoft.Json.JsonConvert.SerializeObject(rs)); } catch (Exception ex) { InnerLogger.Log(LoggerLevel.Error, $"consul Register failed {Environment.NewLine}{ex.ToString()}"); } }
public async Task Invoke(MiddlewareContext context) { System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); await _next(context); stopwatch.Stop(); InnerLogger.Log(LoggerLevel.Info, $"TimerMiddleware:{stopwatch.ElapsedMilliseconds}"); }
/// <summary> /// Starts the and register service. /// </summary> /// <param name="server">The server.</param> /// <param name="serviceConfig">The service configuration.</param> /// <returns></returns> public static async Task <Server> StartAndRegisterService(this Server server, ConsulLocalServiceConfig serviceConfig) { /* * 需要解析ServiceAddress * 支持的几种类型 * 1. 全指定 ip:port * 2. 指定Ip:0 (由grpc自动选择port) * 3. 0.0.0.0:9090 (这是自动选择当前host ip) * * 支持环境变量设置serviceaddress, consuladdresss */ if (!string.IsNullOrWhiteSpace(EnviromentParameters.ServiceAddress)) { InnerLogger.Log(LoggerLevel.Info, $"使用环境变量中配置的serviceaddress:{EnviromentParameters.ServiceAddress}"); serviceConfig.SetServiceAddress(EnviromentParameters.ServiceAddress); } if (!string.IsNullOrWhiteSpace(EnviromentParameters.ConsulAddress)) { InnerLogger.Log(LoggerLevel.Info, $"使用环境变量中的consuladdress:{EnviromentParameters.ConsulAddress}"); serviceConfig.SetConsulAddress(EnviromentParameters.ConsulAddress); } //解析ip var ipPortPair = serviceConfig.ServiceAddress.Split(':'); ipPortPair[0] = NetHelper.GetIp(ipPortPair[0]); InnerLogger.Log(LoggerLevel.Info, "选择IP:" + ipPortPair[0]); server.Ports.Add(new ServerPort(ipPortPair[0], int.Parse(ipPortPair[1]), ServerCredentials.Insecure)); server.Start(); InnerLogger.Log(LoggerLevel.Info, "grpc服务启动"); //处理端口 if (ipPortPair[1] == "0") //PickUnused { ipPortPair[1] = server.Ports.First().BoundPort.ToString(); InnerLogger.Log(LoggerLevel.Info, "自动选择port:" + ipPortPair[1]); } //重新设置ServiceAddress serviceConfig.ServiceAddress = $"{ipPortPair[0]}:{ipPortPair[1]}"; var serviceRegisterProxy = new ServiceRegister(serviceConfig); await serviceRegisterProxy.Register(); serviceDict[server.GetHashCode()] = serviceRegisterProxy; InnerLogger.Log(LoggerLevel.Info, "注册服务发现"); return(server); }
/// <summary> /// clean grpc channel resources /// </summary> public void Clean() { this._freshServiceListTimer?.Dispose(); this.ConnectedAgentServiceChannels?.ForEach(pair => { pair.Channel.ShutdownAsync().Wait(); }); this.ConsulClient?.Dispose(); InnerLogger.Log(LoggerLevel.Info, $"clean"); }
/// <summary> /// Initializes the update service list timer. /// </summary> /// <param name="consulSerivceName">Name of the consul serivce.</param> /// <param name="freshServiceListInterval">The fresh service list interval.</param> private void InitUpdateServiceListTimer(int freshServiceListInterval) { this._freshServiceListInterval = freshServiceListInterval; _freshServiceListTimer = new Timer(async obj => { await this.DownLoadServiceListAsync(); InnerLogger.Log(LoggerLevel.Debug, $"{this._freshServiceListInterval}后,继续timer"); }); _freshServiceListTimer.Change(Timeout.Infinite, Timeout.Infinite); }
private void AddGrpcChannel(string address, int port, AgentService agentService) { var newChannle = new Channel(address, port, ChannelCredentials.Insecure, ClientAgentOption?.ChannelOptions ?? new List<ChannelOption>()); var newPair = new AgentServiceChannelPair { AgentService = agentService, Channel = newChannle }; ConnectedAgentServiceChannels.Add(newPair); InnerLogger.Log(LoggerLevel.Info, $"添加新的service: {newPair.AgentService?.Service}:{newPair.AgentService?.ID} {newPair.AgentService?.Address}:{newPair.AgentService?.Port}, "); }
public async Task Invoke(MiddlewareContext context) { if (context.Options.Headers == null) { context.Options = context.Options.WithHeaders(new Metadata()); } if (!context.Options.Deadline.HasValue) { context.Options.Headers.Add(TIMEOUT_KEY, $"{_options.TimoutMilliseconds}m"); } await _next(context); InnerLogger.Log(LoggerLevel.Info, $"{context.Method.FullName} :End"); }
/// <summary> /// 取消consul服务 /// </summary> /// <param name="serviceId">注册consul服务的serviceID</param> /// <returns></returns> public async Task Deregister(string serviceId) { if (!ServiceConfig.ConsulIntegration) { return; } InnerLogger.Log(LoggerLevel.Info, "deregister timer"); consulServiceTTLRegisterTimer.Dispose(); InnerLogger.Log(LoggerLevel.Info, "Deregister:" + serviceId); var rs = await CreateConsulClient(ServiceConfig.ConsulAddress).Agent.ServiceDeregister(serviceId); InnerLogger.Log(LoggerLevel.Info, Newtonsoft.Json.JsonConvert.SerializeObject(rs)); }
private async Task RegisterTTLCheck() { var client = CreateConsulClient(ServiceConfig.ConsulAddress); var registerTtlCheckResult = await client.Agent.CheckRegister(new AgentCheckRegistration { DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1), TTL = TimeSpan.FromSeconds(ServiceConfig.TCPInterval), Status = HealthStatus.Passing, ID = ServiceConfig.GetConsulServiceId() + ":ttlcheck", ServiceID = ServiceConfig.GetConsulServiceId(), Name = "ttlcheck" }); InnerLogger.Log(LoggerLevel.Info, "RegisterTTLCheck:" + Newtonsoft.Json.JsonConvert.SerializeObject((registerTtlCheckResult))); client.Dispose(); }
/// <summary> /// init grpc channel /// </summary> private void InitGrpcChannel() { if (this.clientConfig.ConsulIntegration) { base.InitConsulClient(clientConfig.ConsulAddress); InitUpdateServiceListTimer(this.clientConfig.FreshInterval); InnerLogger.Log(LoggerLevel.Debug, $"InitUpdateServiceListTimer: {this.clientConfig.FreshInterval}ms"); } else { InnerLogger.Log(LoggerLevel.Debug, "direct connect:" + this.clientConfig.ServiceAddress); var addressList = this.clientConfig.ServiceAddress.Split(','); foreach (var address in addressList) { if (string.IsNullOrWhiteSpace(address)) continue; var hostIp = address.Split(':'); AddGrpcChannel(hostIp[0], int.Parse(hostIp[1]), new AgentService { ID = $"direct:{address}" }); } } }
private async Task DownLoadServiceListAsync() { try { this._freshServiceListTimer.Change(Timeout.Infinite, Timeout.Infinite); InnerLogger.Log(LoggerLevel.Debug, $"start DownLoadServiceList."); //当前正在使用的servicelist var currentUsageServiceChannels = this.ConnectedAgentServiceChannels.ConvertAll<AgentService>(p => p.AgentService); var newestService = new List<AgentService>(); var passOnlyService = await this.ConsulClient.Health.Service(this.clientConfig.ServiceName, "", true); passOnlyService.Response.ToList().ForEach(p => { newestService.Add(p.Service); }); if (newestService.Count == 0) { InnerLogger.Log(LoggerLevel.Info, $"找不到对应的consul服务 {this.clientConfig.ServiceName}"); return; } //检查consul服务是否有变化; var newServices = newestService.Except(currentUsageServiceChannels, new AgentServerComparer()); var abandonServices = currentUsageServiceChannels.Except(newestService, new AgentServerComparer()); if (newServices.Count() == 0 && abandonServices.Count() == 0) { InnerLogger.Log(LoggerLevel.Debug, $"consul服务没有更新.."); return; } //update consul服务 //移除已经失效的channel abandonServices.ToList().ForEach(p => { var abandonPair = this.ConnectedAgentServiceChannels.First(pair => pair.AgentService == p); this.ConnectedAgentServiceChannels.Remove(abandonPair); abandonPair.Channel.ShutdownAsync(); InnerLogger.Log(LoggerLevel.Info, $"移除失效的service: {abandonPair.AgentService.Service}:{abandonPair.AgentService.ID} {abandonPair.AgentService.Address}:{abandonPair.AgentService.Port}, "); }); //添加新的channel newServices.ToList().ForEach(p => AddGrpcChannel(p.Address, p.Port, p)); Interlocked.Exchange(ref _roundProxyIndex, 0); InnerLogger.Log(LoggerLevel.Debug, "roundProxyIndex 变更为0"); } catch (Exception ex) { InnerLogger.Log(LoggerLevel.Error, ex.ToString()); } finally { this._freshServiceListTimer.Change(this._freshServiceListInterval, Timeout.Infinite); InnerLogger.Log(LoggerLevel.Debug, $"register time, {this._freshServiceListInterval} 后继续downloadServiceList"); } }
public async Task Register() { if (!ServiceConfig.ConsulIntegration) { InnerLogger.Log(LoggerLevel.Info, "ConsulIntegration=false,当前服务不集成consul环境"); return; } var registerTimerLLtTime = (ServiceConfig.TCPInterval / 2) * 1000; if (registerTimerLLtTime <= 0) { throw new ArgumentException("TCPInterval配置错误"); } InnerLogger.Log(LoggerLevel.Info, "register: use file config"); await RegisterService(); await RegisterTTLCheck(); /* * timer本身的精度就不够 * 不能再timer里面做更多的耗时的操作 * System.Threading.Timer * Timer myTimer = new Timer(p.Display,"Processing timer event", 2000, 1000);//2秒后第一次调用,每1秒调用一次 * Timer myTimer1 = new Timer(p.Display, "Processing timer event", Timeout.Infinite, 1000);//永远不会被调用 * Timer myTimer2 = new Timer(p.Display, "Processing timer event", 2000, Timeout.Infinite);//2秒后第一次调用,之后再不调用 * * * */ consulServiceTTLRegisterTimer = new System.Timers.Timer { AutoReset = false, Interval = registerTimerLLtTime, Enabled = false }; consulServiceTTLRegisterTimer.Elapsed += async(s, r) => { try { var stopWatch = Stopwatch.StartNew(); var client = CreateConsulClient(ServiceConfig.ConsulAddress); await client.Agent.PassTTL(ServiceConfig.GetConsulServiceId() + ":ttlcheck", "timer:" + DateTime.Now); client.Dispose(); InnerLogger.Log(LoggerLevel.Debug, $"passing TTL,耗时:{stopWatch.ElapsedMilliseconds}"); } catch (Exception ex) { var content = ex.ToString(); InnerLogger.Log(LoggerLevel.Error, content); /* * passTTL会出现如下几种情况: * 1. consul服务重启中,ex会显示 connection refused by ip:port * 这种情况下,不去处理,等consul服务重启之后就好了 * 2. consul服务重启之后,会丢失之前的service,check,会有如下的错误: * Unexpected response, status code InternalServerError: CheckID "followme.srv.sms-192.168.3.10-10086-07f21040-0be9-4a73-b0a1-71755c6d6d46:ttlcheck" does not have associated TTL * 在这种情况下,需要处理,重新注册服务,check; */ if (content .Contains( $"CheckID \"{ServiceConfig.GetConsulServiceId() + ":ttlcheck"}\" does not have associated TTL") ) { InnerLogger.Log(LoggerLevel.Error, "consul PASSTTL failed:需要重新注册"); await RegisterService(); await RegisterTTLCheck(); } } finally { consulServiceTTLRegisterTimer.Enabled = true; } }; //start timer consulServiceTTLRegisterTimer.Enabled = true; }