Esempio n. 1
0
        /// <summary>
        /// 根据服务名返回IP地址
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="flowControlCfgKey"></param>
        /// <param name="clientIp"></param>
        /// <returns></returns>
        public async Task <IPEndPoint> GetFlowControlEndPointByServicePath(string serviceName, ServiceConfigureInfo configure, IPEndPoint clientIp)
        {
            //根据服务返回健康地址
            var healthNode = await _registerCenter.GetServieByName(serviceName);

            if (healthNode != null && healthNode.Any())
            {
                if (configure != null)
                {
                    //更新健康节点和缓存同步
                    configure.ReflushConfigureEndPoint(healthNode);
                    //若配置流控,则进行熔断和限流检测
                    var point = await _breaker.CheckCircuitByEndPoint(configure, clientIp);

                    if (point != null)
                    {
                        //将有效地址的熔断数据清空
                        configure.CleanBreakTimes();
                        return(point);
                    }
                }
                else
                {
                    //如果当前服务并未配置流控,则直接负载均衡返回节点
                    return(_endPointConfigure.GetServieByLoadBalane(healthNode, clientIp, LoadBalanceType.IPHash));
                }
            }
            else
            {
                //删除所有地址并同步
                if (configure != null)
                {
                    configure.RemoveAllNode();
                }
                _logger.LogError($"没有找到健康的服务节点:{serviceName}");
            }
            return(null);
        }
Esempio n. 2
0
        /// <summary>
        /// 检查服务断路状态
        /// </summary>
        /// <param name="pathName"></param>
        /// <param name="serviceInfo"></param>
        /// <param name="addr"></param>
        /// <returns></returns>
        public async Task <IPEndPoint> CheckCircuitByEndPoint(ServiceConfigureInfo configure, IPEndPoint clientEndPoint)
        {
            //根据配置抛弃断路状态地址
            var useAddr = configure.GetEndPoints().Where(x => x.BreakerTime == null || (x.BreakerTime != null && x.BreakerTime.Value.AddSeconds(configure.DefBreakerRetryTimeSec) <= DateTime.Now)).ToList();

            //若全部熔断
            if (!useAddr.Any())
            {
                _logger.LogError("服务被熔断,无法提供服务");
                return(null);
            }
            else
            {
                //负载均衡有效地址
                var addr = _endPointConfigure.GetServieByLoadBalane(useAddr, clientEndPoint, LoadBalanceType.IPHash, configure);
                //初始化令牌桶并判断是否限流
                _tokenBucket.InitTokenBucket(configure.DefCapacity, configure.DefRateLimit);
                if (await _tokenBucket.Grant(configure))
                {
                    return(addr);
                }
                return(null);
            }
        }