本文主要研究一下nacos的RaftProxy

RaftProxy

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftProxy.java

@Componentpublic class RaftProxy {    public void proxyGET(String server, String api, Map<String, String> params) throws Exception {        // do proxy        if (!server.contains(UtilsAndCommons.IP_PORT_SPLITER)) {            server = server + UtilsAndCommons.IP_PORT_SPLITER + RunningConfig.getServerPort();        }        String url = "http://" + server + RunningConfig.getContextPath() + api;        HttpClient.HttpResult result =  HttpClient.httpGet(url, null, params);        if (result.code != HttpURLConnection.HTTP_OK) {            throw new IllegalStateException("leader failed, caused by: " + result.content);        }    }    public void proxy(String server, String api, Map<String, String> params, HttpMethod method) throws Exception {        // do proxy        if (!server.contains(UtilsAndCommons.IP_PORT_SPLITER)) {            server = server + UtilsAndCommons.IP_PORT_SPLITER + RunningConfig.getServerPort();        }        String url = "http://" + server + RunningConfig.getContextPath() + api;        HttpClient.HttpResult result;        switch (method) {            case GET:                result =  HttpClient.httpGet(url, null, params);                break;            case POST:                result = HttpClient.httpPost(url, null, params);                break;            case DELETE:                result =  HttpClient.httpDelete(url, null, params);                break;            default:                throw new RuntimeException("unsupported method:" + method);        }        if (result.code != HttpURLConnection.HTTP_OK) {            throw new IllegalStateException("leader failed, caused by: " + result.content);        }    }    public void proxyPostLarge(String server, String api, String content, Map<String, String> headers) throws Exception {        // do proxy        if (!server.contains(UtilsAndCommons.IP_PORT_SPLITER)) {            server = server + UtilsAndCommons.IP_PORT_SPLITER + RunningConfig.getServerPort();        }        String url = "http://" + server + RunningConfig.getContextPath() + api;        HttpClient.HttpResult result =  HttpClient.httpPostLarge(url, headers, content);        if (result.code != HttpURLConnection.HTTP_OK) {            throw new IllegalStateException("leader failed, caused by: " + result.content);        }    }}
  • RaftProxy提供了proxyGET、proxy、proxyPostLarge三个方法,其中proxy接收了HttpMethod,可以处理GET、POST、DELETE

HttpClient

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/misc/HttpClient.java

public class HttpClient {    private static final int TIME_OUT_MILLIS = 10000;    private static final int CON_TIME_OUT_MILLIS = 5000;    private static AsyncHttpClient asyncHttpClient;    private static CloseableHttpClient postClient;    static {        AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();        builder.setMaximumConnectionsTotal(-1);        builder.setMaximumConnectionsPerHost(128);        builder.setAllowPoolingConnection(true);        builder.setFollowRedirects(false);        builder.setIdleConnectionTimeoutInMs(TIME_OUT_MILLIS);        builder.setConnectionTimeoutInMs(CON_TIME_OUT_MILLIS);        builder.setCompressionEnabled(true);        builder.setIOThreadMultiplier(1);        builder.setMaxRequestRetry(0);        builder.setUserAgent(UtilsAndCommons.SERVER_VERSION);        asyncHttpClient = new AsyncHttpClient(builder.build());        HttpClientBuilder builder2 = HttpClients.custom();        builder2.setUserAgent(UtilsAndCommons.SERVER_VERSION);        builder2.setConnectionTimeToLive(CON_TIME_OUT_MILLIS, TimeUnit.MILLISECONDS);        builder2.setMaxConnPerRoute(-1);        builder2.setMaxConnTotal(-1);        builder2.disableAutomaticRetries();        postClient = builder2.build();    }    //......    public static HttpResult httpPost(String url, List<String> headers, Map<String, String> paramValues) {        return httpPost(url, headers, paramValues, "UTF-8");    }    public static HttpResult httpPost(String url, List<String> headers, Map<String, String> paramValues, String encoding) {        try {            HttpPost httpost = new HttpPost(url);            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(5000).setConnectTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).setMaxRedirects(5).build();            httpost.setConfig(requestConfig);            List<NameValuePair> nvps = new ArrayList<NameValuePair>();            for (Map.Entry<String, String> entry : paramValues.entrySet()) {                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));            }            httpost.setEntity(new UrlEncodedFormEntity(nvps, encoding));            HttpResponse response = postClient.execute(httpost);            HttpEntity entity = response.getEntity();            String charset = encoding;            if (entity.getContentType() != null) {                HeaderElement[] headerElements = entity.getContentType().getElements();                if (headerElements != null && headerElements.length > 0 && headerElements[0] != null &&                        headerElements[0].getParameterByName("charset") != null) {                    charset = headerElements[0].getParameterByName("charset").getValue();                }            }            return new HttpResult(response.getStatusLine().getStatusCode(), IOUtils.toString(entity.getContent(), charset), Collections.<String, String>emptyMap());        } catch (Throwable e) {            return new HttpResult(500, e.toString(), Collections.<String, String>emptyMap());        }    }    public static HttpResult httpPostLarge(String url, Map<String, String> headers, String content) {        try {            HttpClientBuilder builder = HttpClients.custom();            builder.setUserAgent(UtilsAndCommons.SERVER_VERSION);            builder.setConnectionTimeToLive(500, TimeUnit.MILLISECONDS);            CloseableHttpClient httpClient = builder.build();            HttpPost httpost = new HttpPost(url);            for (Map.Entry<String, String> entry : headers.entrySet()) {                httpost.setHeader(entry.getKey(), entry.getValue());            }            httpost.setEntity(new StringEntity(content, ContentType.create("application/json", "UTF-8")));            HttpResponse response = httpClient.execute(httpost);            HttpEntity entity = response.getEntity();            HeaderElement[] headerElements = entity.getContentType().getElements();            String charset = headerElements[0].getParameterByName("charset").getValue();            return new HttpResult(response.getStatusLine().getStatusCode(),                    IOUtils.toString(entity.getContent(), charset), Collections.<String, String>emptyMap());        } catch (Exception e) {            return new HttpResult(500, e.toString(), Collections.<String, String>emptyMap());        }    }    //......}
  • httpPost的connectionRequestTimeout为5秒,connectTimeout为5秒,socketTimeout为5秒;httpPostLarge设置了500毫秒的connectionTimeToLive

小结

RaftProxy提供了proxyGET、proxy、proxyPostLarge三个方法,其中proxy接收了HttpMethod,可以处理GET、POST、DELETE

doc

  • RaftProxy