Пример #1
0
        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>
        /// 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);
        }
Пример #3
0
        /// <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()}");
            }
        }
Пример #4
0
        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);
        }
Пример #6
0
        /// <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");
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        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}, ");
        }
Пример #9
0
        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");
        }
Пример #10
0
        /// <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));
        }
Пример #11
0
        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();
        }
Пример #12
0
 public async Task Invoke(MiddlewareContext context)
 {
     var _retryAsync = Policy
                       .Handle <Exception>()
                       .RetryAsync(_options.RetryTimes, async(exception, retryCount) =>
     {
         await InnerLogger.LogAsync(LoggerLevel.Error, $"-------第{retryCount}次重试!exception:{exception.Message}");
     });
     // todo:这里设置没有用,还不知道原因;
     var _timeoutAsync = Policy
                         .TimeoutAsync(TimeSpan.FromMilliseconds(_options.TimoutMilliseconds), async(ct, ts, tk, exception) =>
     {
         await InnerLogger.LogAsync(LoggerLevel.Error, $"---------超时.");
     });
     await Policy.WrapAsync(_retryAsync, _timeoutAsync).ExecuteAsync(async() =>
     {
         await _next(context);
     });
 }
Пример #13
0
        /// <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}" });
                }
            }
        }
Пример #14
0
        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");
            }
        }
Пример #15
0
        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;
        }