/// <summary>
        /// 解析配置
        /// </summary>
        /// <param name="configPath"></param>
        private static Service.ServiceElement ResolveServiceConfiguration(Action <GrpcOptions> grpcConfigAction = null)
        {
            var grpcOptions = new GrpcOptions();

            grpcConfigAction?.Invoke(grpcOptions);

            var sectionName = Constants.GrpcServerSectionName;
            var grpcSection = ConfigHelper.Get <GrpcServerSection>(sectionName, grpcOptions?.ConfigPath);

            if (grpcSection == null)
            {
                throw new ArgumentNullException(sectionName);
            }

            var service = grpcSection.Service;

            if (service == null)
            {
                throw new ArgumentNullException($"service");
            }

            if (string.IsNullOrEmpty(service.Name))
            {
                throw new ArgumentNullException("serviceName");
            }

            if (service.Port <= 0)
            {
                throw new ArgumentNullException("servicePort");
            }

            return(grpcSection.Service);
        }
        /// <summary>
        /// 解析配置
        /// </summary>
        /// <param name="configPath"></param>
        private static Service.ServiceElement ResolveServiceConfiguration(GrpcOptions grpcOptions = null)
        {
            var sectionName = Constants.GrpcServerSectionName;
            var grpcSection = ConfigBuilder.Build <GrpcServerSection>(sectionName, grpcOptions?.ConfigPath);

            if (grpcSection == null)
            {
                throw new ArgumentNullException(sectionName);
            }

            var service = grpcSection.Service;

            if (service == null)
            {
                throw new ArgumentNullException($"service");
            }

            if (string.IsNullOrEmpty(service.Name))
            {
                throw new ArgumentNullException("serviceName");
            }

            if (service.Port <= 0)
            {
                throw new ArgumentNullException("servicePort");
            }

            return(grpcSection.Service);
        }
        /// <summary>
        /// Grpc服务启动,注册多个服务实现
        /// </summary>
        /// <param name="services">grpc service definition</param>
        /// <param name="whenException">==null => throw</param>
        public static void Start(
            IEnumerable <ServerServiceDefinition> services,
            Action <GrpcOptions> grpcOptionBuilder = null,
            Action <Exception> whenException       = null)
        {
            try
            {
                var grpcOptions = new GrpcOptions();
                grpcOptionBuilder?.Invoke(grpcOptions);

                #region 启动服务
                var serviceElement = ResolveServiceConfiguration(grpcOptions);
                if (grpcOptions?.Tracer != null)
                {
                    grpcOptions.Tracer.ServiceName = serviceElement.Name;
                    grpcOptions.Interceptors.Add(new ServerTracerInterceptor(grpcOptions.Tracer));
                }
                server = new Server(grpcOptions.ChannelOptions)
                {
                    Ports = { new ServerPort("0.0.0.0", serviceElement.Port, ServerCredentials.Insecure) }
                };
                foreach (var service in services)
                {
                    if (grpcOptions.Interceptors?.Count > 0)
                    {
                        server.Services.Add(service.Intercept(grpcOptions.Interceptors.ToArray()));
                    }
                    else
                    {
                        server.Services.Add(service);
                    }
                }
                server.Start();
                #endregion

                #region 注册服务
                var address = ResolveConsulConfiguration(serviceElement);
                if (string.IsNullOrEmpty(address))
                {
                    return;
                }
                serverRegister = new ServerRegister(address, grpcOptions.GenServiceId);
                serverRegister.Register(serviceElement, entry => discoveryEntry = entry);
                #endregion
            }
            catch (Exception ex)
            {
                Stop();
                InvokeException(ex, whenException);
            }
        }