一、IPing机制
IPing是一个主动探测服务节点存活的机制,通过判断服务节点的当前状态,设置节点的可用状态。只有当节点为可用时候才会作为负载均衡器的选取节点。
IPing有以下几种模式:
- DummyPing:默认返回true,即认为所有节点都可用,这也是单独使用Ribbon时的默认模式
- NIWSDiscoveryPing:借助Eureka服务发现机制获取节点状态。节点状态是UP,则认为是可用状态
- PingUrl:主动向服务节点发起一次http调用,对方有响应则认为节点是可用状态
- NoOpPing:返回true
- PingConstant:返回设置的常量值
二、IPing配置
(1)application.yaml配置
#单个服务设置
[service-name]:
ribbon:
NFLoadBalancerPingClassName: com.netflix.loadbalancer.DummyPing
(2)代码配置
public class MicroRibbonConfig {
@Bean
public IPing microIPing(){
return new DummyPing();
}
}
@RibbonClient(name = "micro-service", configuration = MicroRibbonConfig.class)
public class RibbonClientConfig {
}
三、IPing模式实现
(1)DummyPing
public class DummyPing extends AbstractLoadBalancerPing {
public DummyPing() {
}
public boolean isAlive(Server server) {
return true;
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
public abstract class AbstractLoadBalancerPing implements IPing, IClientConfigAware{
AbstractLoadBalancer lb;
@Override
public boolean isAlive(Server server) {
return true;
}
public void setLoadBalancer(AbstractLoadBalancer lb){
this.lb = lb;
}
public AbstractLoadBalancer getLoadBalancer(){
return lb;
}
}
(2)PingUrl
public class PingUrl implements IPing {
private static final Logger LOGGER = LoggerFactory.getLogger(PingUrl.class);
String pingAppendString = "";
boolean isSecure = false;
String expectedContent = null;
/*
*
* Send one ping only.
*
* Well, send what you need to determine whether or not the
* server is still alive. Should return within a "reasonable"
* time.
*/
public PingUrl() {
}
public PingUrl(boolean isSecure, String pingAppendString) {
this.isSecure = isSecure;
this.pingAppendString = (pingAppendString != null) ? pingAppendString : "";
}
public void setPingAppendString(String pingAppendString) {
this.pingAppendString = (pingAppendString != null) ? pingAppendString : "";
}
public String getPingAppendString() {
return pingAppendString;
}
public boolean isSecure() {
return isSecure;
}
/**
* Should the Secure protocol be used to Ping
* @param isSecure
*/
public void setSecure(boolean isSecure) {
this.isSecure = isSecure;
}
public String getExpectedContent() {
return expectedContent;
}
/**
* Is there a particular content you are hoping to see?
* If so -set this here.
* for e.g. the WCS server sets the content body to be 'true'
* Please be advised that this content should match the actual
* content exactly for this to work. Else yo may get false status.
* @param expectedContent
*/
public void setExpectedContent(String expectedContent) {
this.expectedContent = expectedContent;
}
public boolean isAlive(Server server) {
String urlStr = "";
if (isSecure){
urlStr = "https://";
}else{
urlStr = "http://";
}
urlStr += server.getId();
urlStr += getPingAppendString();
boolean isAlive = false;
HttpClient httpClient = new DefaultHttpClient();
HttpUriRequest getRequest = new HttpGet(urlStr);
String content=null;
try {
HttpResponse response = httpClient.execute(getRequest);
content = EntityUtils.toString(response.getEntity());
isAlive = (response.getStatusLine().getStatusCode() == 200);
if (getExpectedContent()!=null){
LOGGER.debug("content:" + content);
if (content == null){
isAlive = false;
}else{
if (content.equals(getExpectedContent())){
isAlive = true;
}else{
isAlive = false;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
// Release the connection.
getRequest.abort();
}
return isAlive;
}
public static void main(String[] args){
PingUrl p = new PingUrl(false,"/cs/hostRunning");
p.setExpectedContent("true");
Server s = new Server("ec2-75-101-231-85.compute-1.amazonaws.com", 7101);
boolean isAlive = p.isAlive(s);
System.out.println("isAlive:" + isAlive);
}
}
(3)PingConstant
public class PingConstant implements IPing {
boolean constant = true;
public void setConstant(String constantStr) {
constant = (constantStr != null) && (constantStr.toLowerCase().equals("true"));
}
public void setConstant(boolean constant) {
this.constant = constant;
}
public boolean getConstant() {
return constant;
}
public boolean isAlive(Server server) {
return constant;
}
}
(4)NoOpPing
public class NoOpPing implements IPing {
@Override
public boolean isAlive(Server server) {
return true;
}
}