예제 #1
0
        /// <summary>
        /// 使用GRpc注册Consul
        /// </summary>
        /// <param name="app">应用生成器</param>
        /// <returns>应用生成器</returns>
        public static IApplicationBuilder UseGRpcRegisterConsul(this IApplicationBuilder app)
        {
            // 获取consul配置对象
            var consulConfig = app.ApplicationServices.GetRequiredService <IOptions <ConsulOptions> >().Value;

            // 获取本服务的地址,如果不为空,则直接取。否则取配置选项里的服务地址
            if (string.IsNullOrWhiteSpace(consulConfig.ServiceAddress))
            {
                consulConfig.ServiceAddress = NetworkUtil.FilterUrl(app.ApplicationServices.GetService <IServerAddressesFeature>().Addresses.FirstOrDefault());
                if (string.IsNullOrWhiteSpace(consulConfig.ServiceAddress))
                {
                    throw new ArgumentNullException("服务地址不能为空");
                }
            }

            // 注册到Consul
            var serviceUri = new Uri(consulConfig.ServiceAddress);
            var agentCheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(consulConfig.ServiceCheck.DeregisterCriticalServiceAfter),
                Interval   = TimeSpan.FromSeconds(consulConfig.ServiceCheck.Interval),
                GRPC       = $"{serviceUri.Host}:{serviceUri.Port}",
                GRPCUseTLS = string.Compare(serviceUri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase) == 0,
                Timeout    = TimeSpan.FromSeconds(consulConfig.ServiceCheck.Timeout),
            };

            consulBuilder.AddHealthCheck(agentCheck)
            .RegisterService(consulConfig.ServiceName, serviceUri.Host, serviceUri.Port, consulConfig.Tags);

            return(app);
        }
예제 #2
0
        /// <summary>
        /// 使用哈希+IP负载均衡
        /// </summary>
        /// <param name="app">应用生成器</param>
        /// <param name="port">端口</param>
        /// <returns>应用生成器</returns>
        public static IApplicationBuilder UseHashIpPortLoadBalance(this IApplicationBuilder app, int port = 0)
        {
            if (port == 0)
            {
                var add = app.ApplicationServices.GetService <IServerAddressesFeature>().Addresses.FirstOrDefault();
                localPort = NetworkUtil.GetPortFromDomain(NetworkUtil.FilterUrl(add));
            }
            else
            {
                localPort = port;
            }

            HashIpPortLoadBalance.GetPort = () => localPort;

            return(app);
        }
        /// <summary>
        /// 创建Consul客户端注册并根据选项进行配置
        /// </summary>
        /// <param name="options">选项配置</param>
        /// <param name="getLocalServiceAddress">回调获取本地服务地址</param>
        /// <returns>Consul客户端</returns>
        public static ConsulClient CreateConsulClientRegister(ConsulOptions options, Func <string> getLocalServiceAddress = null)
        {
            if (options == null)
            {
                throw new ArgumentNullException("选项配置不能为null");
            }
            if (string.IsNullOrWhiteSpace(options.ConsulAddress))
            {
                throw new ArgumentNullException("Consul地址不能为空");
            }
            if (string.IsNullOrWhiteSpace(options.ServiceName))
            {
                throw new ArgumentNullException("服务名不能为空");
            }

            // 服务ID,如果有配置指定,则使用配置,否则由程序生成唯一
            options.ServiceId = options.ServiceId ?? $"{NetworkUtil.LocalIP}_{StringUtil.NewShortGuid()}";

            // 定义consul客户端对象
            var consulClient = new ConsulClient(clientConfig =>
            {
                clientConfig.Address    = new Uri(options.ConsulAddress);
                clientConfig.Datacenter = options.Datacenter;
            });

            // 获取本服务的地址,如果不为空,则直接取。否则取配置选项里的服务地址
            if (string.IsNullOrWhiteSpace(options.ServiceAddress) && getLocalServiceAddress != null)
            {
                options.ServiceAddress = NetworkUtil.FilterUrl(getLocalServiceAddress());
            }
            if (string.IsNullOrWhiteSpace(options.ServiceAddress))
            {
                throw new ArgumentNullException("服务地址不能为空");
            }

            var serviceUri = new Uri(options.ServiceAddress);

            // 定义一个代理服务注册对象
            var registration = new AgentServiceRegistration()
            {
                ID    = options.ServiceId,
                Tags  = options.Tags,
                Check = new AgentServiceCheck()                                                                                 // 定义健康检测对象
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(options.ServiceCheck.DeregisterCriticalServiceAfter), // 服务停止后多久注销服务
                    HTTP     = $"{serviceUri.Scheme}://{serviceUri.Host}:{serviceUri.Port}{options.ServiceCheck.HealthCheck}",  // 健康检测URL地址
                    Interval = TimeSpan.FromSeconds(options.ServiceCheck.Interval),                                             // 每隔多少时间检测
                    Timeout  = TimeSpan.FromSeconds(options.ServiceCheck.Timeout),                                              // 注册超时时间
                },
                Name    = options.ServiceName,
                Address = serviceUri.Host,
                Port    = serviceUri.Port,
            };

            // 将注册配置信息注册到consul里
            consulClient.Agent.ServiceRegister(registration).Wait();
            // 程序退出时需要反注册服务
            AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            };

            return(consulClient);
        }