Esempio n. 1
0
        private void UpdateConfigServices()
        {
            lock (this)
            {
                string url = AssembleMetaServiceUrl();

                Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest request = new Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest(url);
                int       maxRetries = 5;
                Exception exception  = null;

                for (int i = 0; i < maxRetries; i++)
                {
                    try
                    {
                        HttpResponse <IList <ServiceDTO> > response = m_httpUtil.DoGet <IList <ServiceDTO> >(request);
                        IList <ServiceDTO> services = response.Body;
                        if (services == null || services.Count == 0)
                        {
                            continue;
                        }
                        m_configServices.WriteFullFence(services);
                        return;
                    }
                    catch (Exception ex)
                    {
                        logger.Warn(ex);
                        exception = ex;
                    }

                    Thread.Sleep(1000); //sleep 1 second
                }

                throw new ApolloConfigException(string.Format("Get config services failed from {0}", url), exception);
            }
        }
        private ApolloConfig LoadApolloConfig()
        {
            string    appId      = m_configUtil.AppId;
            string    cluster    = m_configUtil.Cluster;
            string    dataCenter = m_configUtil.DataCenter;
            int       maxRetries = 2;
            Exception exception  = null;

            IList <ServiceDTO> configServices = ConfigServices;
            string             url            = null;

            for (int i = 0; i < maxRetries; i++)
            {
                IList <ServiceDTO> randomConfigServices = new List <ServiceDTO>(configServices);
                randomConfigServices.Shuffle();
                //Access the server which notifies the client first
                if (m_longPollServiceDto.ReadFullFence() != null)
                {
                    randomConfigServices.Insert(0, m_longPollServiceDto.AtomicExchange(null));
                }

                foreach (ServiceDTO configService in randomConfigServices)
                {
                    url = AssembleQueryConfigUrl(configService.HomepageUrl, appId, cluster, m_namespace, dataCenter, m_remoteMessages.ReadFullFence(), m_configCache.ReadFullFence());

                    logger.Debug(string.Format("Loading config from {0}", url));
                    Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest request = new Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest(url);

                    try
                    {
                        HttpResponse <ApolloConfig> response = m_httpUtil.DoGet <ApolloConfig>(request);

                        if (response.StatusCode == 304)
                        {
                            logger.Debug("Config server responds with 304 HTTP status code.");
                            return(m_configCache.ReadFullFence());
                        }

                        ApolloConfig result = response.Body;

                        logger.Debug(
                            string.Format("Loaded config for {0}: {1}", m_namespace, result));

                        return(result);
                    }
                    catch (ApolloConfigStatusCodeException ex)
                    {
                        ApolloConfigStatusCodeException statusCodeException = ex;
                        //config not found
                        if (ex.StatusCode == 404)
                        {
                            string message = string.Format("Could not find config for namespace - appId: {0}, cluster: {1}, namespace: {2}, please check whether the configs are released in Apollo!", appId, cluster, m_namespace);
                            statusCodeException = new ApolloConfigStatusCodeException(ex.StatusCode, message);
                        }
                        logger.Warn(statusCodeException);
                        exception = statusCodeException;
                    }
                    catch (Exception ex)
                    {
                        logger.Warn(ex);
                        exception = ex;
                    }
                }

                Thread.Sleep(1000); //sleep 1 second
            }
            string fallbackMessage = string.Format("Load Apollo Config failed - appId: {0}, cluster: {1}, namespace: {2}, url: {3}", appId, cluster, m_namespace, url);

            throw new ApolloConfigException(fallbackMessage, exception);
        }
        private void DoLongPollingRefresh(string appId, string cluster, string dataCenter)
        {
            Random     random         = new Random();
            ServiceDTO lastServiceDto = null;

            while (!m_longPollingStopped.ReadFullFence())
            {
                int    sleepTime = 50; //default 50 ms
                string url       = null;
                try
                {
                    if (lastServiceDto == null)
                    {
                        IList <ServiceDTO> configServices = ConfigServices;
                        lastServiceDto = configServices[random.Next(configServices.Count)];
                    }

                    url = AssembleLongPollRefreshUrl(lastServiceDto.HomepageUrl, appId, cluster, dataCenter);

                    logger.Debug(
                        string.Format("Long polling from {0}", url));
                    Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest request = new Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest(url);
                    //longer timeout - 10 minutes
                    request.Timeout = 600000;

                    HttpResponse <IList <ApolloConfigNotification> > response = m_httpUtil.DoGet <IList <ApolloConfigNotification> >(request);

                    logger.Debug(
                        string.Format("Long polling response: {0}, url: {1}", response.StatusCode, url));
                    if (response.StatusCode == 200 && response.Body != null)
                    {
                        UpdateNotifications(response.Body);
                        UpdateRemoteNotifications(response.Body);
                        Notify(lastServiceDto, response.Body);
                        m_longPollSuccessSchedulePolicyInMS.Success();
                    }
                    else
                    {
                        sleepTime = m_longPollSuccessSchedulePolicyInMS.Fail();
                    }

                    //try to load balance
                    if (response.StatusCode == 304 && random.NextDouble() >= 0.5)
                    {
                        lastServiceDto = null;
                    }

                    m_longPollFailSchedulePolicyInSecond.Success();
                }
                catch (Exception ex)
                {
                    lastServiceDto = null;

                    int sleepTimeInSecond = m_longPollFailSchedulePolicyInSecond.Fail();
                    logger.Warn(
                        string.Format("Long polling failed, will retry in {0} seconds. appId: {1}, cluster: {2}, namespace: {3}, long polling url: {4}, reason: {5}",
                                      sleepTimeInSecond, appId, cluster, AssembleNamespaces(), url, ExceptionUtil.GetDetailMessage(ex)));

                    sleepTime = sleepTimeInSecond * 1000;
                }
                finally
                {
                    Thread.Sleep(sleepTime);
                }
            }
        }