/* * Copyright 2009-2016 Weibo, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.weibo.api.motan.transport.support; import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import com.weibo.api.motan.common.MotanConstants; import com.weibo.api.motan.common.URLParamType; import com.weibo.api.motan.core.extension.ExtensionLoader; import com.weibo.api.motan.exception.MotanFrameworkException; import com.weibo.api.motan.rpc.URL; import com.weibo.api.motan.transport.Client; import com.weibo.api.motan.transport.Endpoint; import com.weibo.api.motan.transport.EndpointManager; import com.weibo.api.motan.transport.HeartbeatFactory; import com.weibo.api.motan.util.LoggerUtil; /** * @author maijunsheng * @version 创建时间:2013-6-14 * */ public class HeartbeatClientEndpointManager implements EndpointManager { private ConcurrentMap<Client, HeartbeatFactory> endpoints = new ConcurrentHashMap<Client, HeartbeatFactory>(); // 一般这个类创建的实例会比较少,如果共享的话,容易“被影响”,如果某个任务阻塞了 private ScheduledExecutorService executorService = null; @Override public void init() { executorService = Executors.newScheduledThreadPool(1); executorService.scheduleWithFixedDelay(new Runnable() { @Override public void run() { for (Map.Entry<Client, HeartbeatFactory> entry : endpoints.entrySet()) { Client endpoint = entry.getKey(); try { // 如果节点是存活状态,那么没必要走心跳 if (endpoint.isAvailable()) { continue; } HeartbeatFactory factory = entry.getValue(); endpoint.heartbeat(factory.createRequest()); } catch (Exception e) { LoggerUtil.error("HeartbeatEndpointManager send heartbeat Error: url=" + endpoint.getUrl().getUri(), e); } } } }, MotanConstants.HEARTBEAT_PERIOD, MotanConstants.HEARTBEAT_PERIOD, TimeUnit.MILLISECONDS); } @Override public void destroy() { executorService.shutdownNow(); } @Override public void addEndpoint(Endpoint endpoint) { if (!(endpoint instanceof Client)) { throw new MotanFrameworkException("HeartbeatClientEndpointManager addEndpoint Error: class not support " + endpoint.getClass()); } Client client = (Client) endpoint; URL url = endpoint.getUrl(); String heartbeatFactoryName = url.getParameter(URLParamType.heartbeatFactory.getName(), URLParamType.heartbeatFactory.getValue()); HeartbeatFactory heartbeatFactory = ExtensionLoader.getExtensionLoader(HeartbeatFactory.class).getExtension(heartbeatFactoryName); if (heartbeatFactory == null) { throw new MotanFrameworkException("HeartbeatFactory not exist: " + heartbeatFactoryName); } endpoints.put(client, heartbeatFactory); } @Override public void removeEndpoint(Endpoint endpoint) { endpoints.remove(endpoint); } public Set<Client> getClients() { return Collections.unmodifiableSet(endpoints.keySet()); } }