1. 程式人生 > 其它 >SpringCloud Ribbon(三)之IPing機制

SpringCloud Ribbon(三)之IPing機制

技術標籤:Spring Cloud

一、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;
    }

}