/** * WS * Dianping.com Inc. * Copyright (c) 2003-2013 All Rights Reserved. */ package com.dianping.pigeon.remoting.invoker.listener; import com.dianping.pigeon.config.ConfigManager; import com.dianping.pigeon.config.ConfigManagerLoader; import com.dianping.pigeon.domain.HostInfo; import com.dianping.pigeon.log.LoggerLoader; import com.dianping.pigeon.registry.RegistryManager; import com.dianping.pigeon.remoting.ServiceFactory; import com.dianping.pigeon.remoting.invoker.Client; import com.dianping.pigeon.remoting.invoker.ClientManager; import com.dianping.pigeon.remoting.invoker.config.InvokerConfig; import org.apache.commons.lang.StringUtils; import com.dianping.pigeon.log.Logger; import org.springframework.util.CollectionUtils; import java.util.List; import java.util.Map; import java.util.Set; public class ProviderAvailableListener implements Runnable { private static final Logger logger = LoggerLoader.getLogger(ProviderAvailableListener.class); private Map<String, List<Client>> workingClients; private static ConfigManager configManager = ConfigManagerLoader.getConfigManager(); private static final String KEY_INTERVAL = "pigeon.providerlistener.interval"; private static final String KEY_AVAILABLE_LEAST = "pigeon.providerlistener.availableleast"; public ProviderAvailableListener() { configManager.getLongValue(KEY_INTERVAL, 3000); configManager.getIntValue(KEY_AVAILABLE_LEAST, 1); } private int getAvailableClients(List<Client> clientList) { int available = 0; if (CollectionUtils.isEmpty(clientList)) { available = 0; } else { for (Client client : clientList) { int w = RegistryManager.getInstance().getServiceWeight(client.getAddress()); if (w > 0 && !client.isClosed() && client.isActive()) { available += w; } } } return available; } public void run() { long sleepTime = configManager.getLongValue(KEY_INTERVAL, 3000); int checkCount = 0; while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(sleepTime); try { checkReferencedServices(); } catch (Throwable e) { logger.info("check referenced services failed:", e); } Set<InvokerConfig<?>> services = ServiceFactory.getAllServiceInvokers().keySet(); long now = System.nanoTime(); for (InvokerConfig<?> invokerConfig : services) { String url = invokerConfig.getUrl(); String vip = invokerConfig.getVip(); if (StringUtils.isNotBlank(vip) && vip.startsWith("console:")) { continue; } int available = getAvailableClients(this.getWorkingClients().get(url)); if (available < configManager.getIntValue(KEY_AVAILABLE_LEAST, 1)) { logger.info("check provider available for service:" + url); String error = null; try { ClientManager.getInstance().registerClients(invokerConfig); } catch (Throwable e) { error = e.getMessage(); } if (error != null) { logger.warn("[provider-available] failed to get providers, caused by:" + error); } } } sleepTime = configManager.getLongValue(KEY_INTERVAL, 3000) - ((System.nanoTime() - now) / 1000000); // close register thread pool /* * if (++checkCount > 0) { * ClientManager.getInstance().closeRegisterThreadPool(); } */ } catch (Throwable e) { logger.info("[provider-available] task failed:", e); } finally { if (sleepTime < 1000) { sleepTime = 1000; } } } } private void checkReferencedServices() { Map<String, Set<HostInfo>> serviceAddresses = RegistryManager.getInstance().getAllReferencedServiceAddresses(); for (String key : serviceAddresses.keySet()) { Set<HostInfo> hosts = serviceAddresses.get(key); if (hosts != null) { for (HostInfo host : hosts) { if (host.getApp() == null) { String app = RegistryManager.getInstance().getReferencedApp(host.getConnect()); logger.info("set " + host.getConnect() + "'s app to " + app); host.setApp(app); RegistryManager.getInstance().setReferencedApp(host.getConnect(), app); } if (host.getVersion() == null) { String version = RegistryManager.getInstance().getReferencedVersion(host.getConnect()); logger.info("set " + host.getConnect() + "'s version to " + version); host.setVersion(version); RegistryManager.getInstance().setReferencedVersion(host.getConnect(), version); } } } } } public Map<String, List<Client>> getWorkingClients() { return workingClients; } public void setWorkingClients(Map<String, List<Client>> workingClients) { this.workingClients = workingClients; } }