net.wicp.tams.common.grpc.ribbon.RibbonClient Maven / Gradle / Ivy
package net.wicp.tams.common.grpc.ribbon;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.apache.commons.collections.CollectionUtils;
import com.netflix.appinfo.MyDataCenterInstanceConfig;
import com.netflix.client.ClientFactory;
import com.netflix.config.ConfigurationManager;
import com.netflix.discovery.CacheRefreshedEvent;
import com.netflix.discovery.DefaultEurekaClientConfig;
import com.netflix.discovery.DiscoveryManager;
import com.netflix.discovery.StatusChangeEvent;
import com.netflix.discovery.shared.transport.jersey.Jersey1DiscoveryClientOptionalArgs;
import com.netflix.eventbus.impl.EventBusImpl;
import com.netflix.eventbus.spi.EventBus;
import com.netflix.eventbus.spi.InvalidSubscriberException;
import com.netflix.eventbus.spi.Subscribe;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.Conf;
import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.IOUtil;
import net.wicp.tams.common.grpc.ribbon.event.ICacheRefreshedCallback;
import net.wicp.tams.common.grpc.ribbon.event.IStatusChangeCallback;
@SuppressWarnings("deprecation")
@Slf4j
public class RibbonClient {
private static RibbonClient inst = new RibbonClient();
private final EventBus eventBus;
private final RoundRobinRule chooseRule = new RoundRobinRule();
private RibbonClient() {
Properties ribbonProp = Conf.getPreToProp("common.grpc.ribbon.default", true);
ConfigurationManager.loadProperties(ribbonProp);
Jersey1DiscoveryClientOptionalArgs optionalArgs = new Jersey1DiscoveryClientOptionalArgs();
eventBus = new EventBusImpl();
optionalArgs.setEventBus(eventBus);
try {
DiscoveryManager.getInstance().initComponent(new MyDataCenterInstanceConfig(),
new DefaultEurekaClientConfig(), optionalArgs);
log.info("ribbon初始化完成");
} catch (Exception e) {
log.error("初始化ribbon客户端出错", e);
}
}
public static RibbonClient getInst() {
return inst;
}
@SuppressWarnings("rawtypes")
public DynamicServerListLoadBalancer getLb(String clientName) {
// ClientFactory.getNamedLoadBalancer会缓存结果, 所以不用担心它每次都会向eureka发起查询
DynamicServerListLoadBalancer lb2 = (DynamicServerListLoadBalancer) ClientFactory
.getNamedLoadBalancer(clientName);
return lb2;
}
public DiscoveryEnabledServer getServerOne(String clientName) {
Server selected = chooseRule.choose(getLb(clientName), null);
if (null == selected) {
log.error("服务{}没有可用地址", clientName);
return null;
} else {
return (DiscoveryEnabledServer) selected;
}
}
public List getServerAvailable(String clientName) {
List serverList = getLb(clientName).getReachableServers();
if (CollectionUtils.isEmpty(serverList)) {
log.error("服务{}没有可用地址", clientName);
return Collections.emptyList();
}
return serverList;
}
public void addClient(String path) {
Properties properties = IOUtil.fileToProperties(path);
addClient(properties);
}
public void addClient(Properties props) {
ConfigurationManager.loadProperties(props);
for (Object key : props.keySet()) {
String keystr = String.valueOf(key);
if (keystr.endsWith(".ribbon.DeploymentContextBasedVipAddresses")) {
hasClient.add(keystr.replace(keystr, ".ribbon.DeploymentContextBasedVipAddresses"));
break;
}
}
}
private List hasClient = new ArrayList<>();
public void addClientByAppName(String appName) {
if (hasClient.contains(appName)) {
return;
}
Properties props = new Properties();
props.put(String.format("%s.ribbon.DeploymentContextBasedVipAddresses", appName), "S3");
props.put(String.format("%s.ribbon.NIWSServerListClassName", appName),
"com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList");
props.put(String.format("%s.ribbon.ServerListRefreshInterval", appName), "60000");
props.put(String.format("%s.ribbon.DeploymentContextBasedVipAddresses", appName), appName);
addClient(props);
hasClient.add(appName);
}
private Object eventFreshListener = null;
public Result regFreshEvent(ICacheRefreshedCallback callback) {
if (eventFreshListener != null) {
eventBus.unregisterSubscriber(eventFreshListener);
}
eventFreshListener = new Object() {
@Subscribe
public void consume(CacheRefreshedEvent event) {
callback.callback(event);
}
};
try {
eventBus.registerSubscriber(eventFreshListener);
return Result.getSuc();
} catch (InvalidSubscriberException e) {
log.error("注册刷新事件失败");
return Result.getError("注册刷新事件失败,原因:" + e.getMessage());
}
}
private Object eventStatusChangeListener = null;
public Result regStatusChangeEvent(IStatusChangeCallback callback) {
if (eventStatusChangeListener != null) {
eventBus.unregisterSubscriber(eventStatusChangeListener);
}
eventStatusChangeListener = new Object() {
@Subscribe
public void consume(StatusChangeEvent event) {
callback.callback(event);
}
};
try {
eventBus.registerSubscriber(eventStatusChangeListener);
return Result.getSuc();
} catch (InvalidSubscriberException e) {
log.error("注册刷新事件失败");
return Result.getError("注册刷新事件失败,原因:" + e.getMessage());
}
}
}