Skip to content

Commit

Permalink
[apache#4678] optimized sc/kie/config-center isolation address check …
Browse files Browse the repository at this point in the history
…logic (apache#4680)
chengyouling authored Jan 18, 2025
1 parent f3616b7 commit 2ec1cc0
Showing 11 changed files with 106 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@
import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.apache.servicecomb.http.client.common.HttpUtils;
import org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@@ -49,6 +50,8 @@ public class ConfigCenterClient implements ConfigCenterOperation {

public static final String DARK_LAUNCH = "darklaunch@";

private static final String ADDRESS_CHECK_PATH = "/v3/default/configuration/health?mode=readiness";

private final HttpTransport httpTransport;

private final ConfigCenterAddressManager addressManager;
@@ -133,25 +136,8 @@ public QueryConfigurationsResponse queryConfigurations(QueryConfigurationsReques
}

@Override
public void checkAddressAvailable(QueryConfigurationsRequest request, String address) {
String dimensionsInfo = buildDimensionsInfo(request, true);
try {
String uri = address + "/configuration/items?dimensionsInfo="
+ HttpUtils.encodeURLParam(dimensionsInfo) + "&revision=" + request.getRevision();

Map<String, String> headers = new HashMap<>();
headers.put("x-environment", request.getEnvironment());
HttpRequest httpRequest = new HttpRequest(uri, headers, null,
HttpRequest.GET);

HttpResponse httpResponse = httpTransport.doRequest(httpRequest);
if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED
|| httpResponse.getStatusCode() == HttpStatus.SC_OK) {
addressManager.recoverIsolatedAddress(address);
}
} catch (Exception e) {
LOGGER.error("check config center isolation address {} available error!", address);
}
public void checkAddressAvailable(String address) {
ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH);
}

private String buildDimensionsInfo(QueryConfigurationsRequest request, boolean withVersion) {
Original file line number Diff line number Diff line change
@@ -105,7 +105,7 @@ public void run() {
return;
}
for (String address : isolationAddresses) {
configCenterClient.checkAddressAvailable(queryConfigurationsRequest, address);
configCenterClient.checkAddressAvailable(address);
}
}
}
Original file line number Diff line number Diff line change
@@ -34,8 +34,7 @@ public interface ConfigCenterOperation {
/**
* Check config center isolation address available
*
* @param request queryConfigurationsRequest
* @param address isolation address
*/
void checkAddressAvailable(QueryConfigurationsRequest request, String address);
void checkAddressAvailable(String address);
}
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@

import com.google.common.eventbus.EventBus;

import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
@@ -45,6 +44,7 @@
import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.apache.servicecomb.http.client.common.HttpUtils;
import org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
@@ -54,6 +54,8 @@ public class KieClient implements KieConfigOperation {

private static final Logger LOGGER = LoggerFactory.getLogger(KieClient.class);

private static final String ADDRESS_CHECK_PATH = "/v1/health";

protected HttpTransport httpTransport;

protected String revision = "0";
@@ -115,18 +117,8 @@ public ConfigurationsResponse queryConfigurations(ConfigurationsRequest request,
}

@Override
public void checkAddressAvailable(ConfigurationsRequest request, String address) {
String url = buildUrl(request, address);
HttpRequest httpRequest = new HttpRequest(url, null, null, HttpRequest.GET);
try {
HttpResponse httpResponse = httpTransport.doRequest(httpRequest);
if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED
|| httpResponse.getStatusCode() == HttpStatus.SC_OK) {
addressManager.recoverIsolatedAddress(address);
}
} catch (IOException e) {
LOGGER.error("check kie config isolation address {} available error!", address);
}
public void checkAddressAvailable(String address) {
ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH);
}

private String buildUrl(ConfigurationsRequest request, String currentAddress) {
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ protected void initTaskPool(String taskName) {
public void startConfigKieManager() {
this.configurationsRequests.forEach((t) ->
this.startTask(new PollConfigurationTask(0, t)));
schedulerCheckAddressAvailable("kie-addr-check", new CheckKieAddressTask(configurationsRequests.get(0)),
schedulerCheckAddressAvailable("kie-addr-check", new CheckKieAddressTask(),
kieConfiguration.getRefreshIntervalInMillis());
}

@@ -164,20 +164,14 @@ public void execute() {
}

class CheckKieAddressTask implements Runnable {
ConfigurationsRequest configurationsRequest;

public CheckKieAddressTask(ConfigurationsRequest configurationsRequest) {
this.configurationsRequest = configurationsRequest;
}

@Override
public void run() {
List<String> isolationAddresses = kieAddressManager.getIsolationAddresses();
if (isolationAddresses.isEmpty()) {
return;
}
for (String address : isolationAddresses) {
configKieClient.checkAddressAvailable(this.configurationsRequest, address);
configKieClient.checkAddressAvailable(address);
}
}
}
Original file line number Diff line number Diff line change
@@ -35,8 +35,7 @@ public interface KieConfigOperation {
/**
* Check kie isolation address available
*
* @param configurationsRequest configurationsRequest
* @param address isolation address
*/
void checkAddressAvailable(ConfigurationsRequest configurationsRequest, String address);
void checkAddressAvailable(String address);
}
Original file line number Diff line number Diff line change
@@ -194,8 +194,8 @@ private List<String> getZoneOrRegionAddress() {
return results;
}

public void recoverIsolatedAddress(String address) {
recordSuccessState(address);
public void recordSuccessState(String address) {
resetFailureStatus(address);
if (addressAutoRefreshed) {
if (isolationZoneAddress.remove(address)) {
LOGGER.warn("restore same region address [{}]", address);
@@ -217,7 +217,7 @@ public void recoverIsolatedAddress(String address) {
}
}

public void recordSuccessState(String address) {
public void resetFailureStatus(String address) {
addressFailureStatus.put(address, 0);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.servicecomb.http.client.utils;

import org.apache.http.HttpStatus;
import org.apache.servicecomb.http.client.common.AbstractAddressManager;
import org.apache.servicecomb.http.client.common.HttpRequest;
import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;

public class ServiceCombServiceAvailableUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCombServiceAvailableUtils.class);

public static void checkAddressAvailable(AbstractAddressManager addressManager, String address,
HttpTransport httpTransport, String path) {
String formatUrl = addressManager.formatUrl(path, true, address);
HttpRequest httpRequest = new HttpRequest(formatUrl, null, null, HttpRequest.GET);
try {
HttpResponse response = httpTransport.doRequest(httpRequest);
if (response.getStatusCode() == HttpStatus.SC_OK) {
addressManager.recordSuccessState(address);
return;
}

// old server does not provide the check api, using TCP checks whether the server is ready.
if (response.getStatusCode() == HttpStatus.SC_NOT_FOUND && telnetCheckAddress(address)) {
LOGGER.warn("[{}] path does not provide, tcp check address ready!", path);
addressManager.recordSuccessState(address);
}
} catch (IOException e) {
LOGGER.error("check isolation address [{}] available error!", address);
}
}

private static boolean telnetCheckAddress(String address) {
URI ipPort = parseIpPortFromURI(address);
if (ipPort == null) {
return false;
}
try (Socket s = new Socket()) {
s.connect(new InetSocketAddress(ipPort.getHost(), ipPort.getPort()), 3000);
return true;
} catch (IOException e) {
LOGGER.warn("ping endpoint {} failed, It will be quarantined again.", address);
}
return false;
}

private static URI parseIpPortFromURI(String address) {
try {
return new URI(address);
} catch (URISyntaxException e) {
LOGGER.error("build uri error with address [{}].", address);
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -101,7 +101,7 @@ public void recordStateTest() throws ExecutionException {
Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address());

// test fail 2 times ,it will not be isolated
addressManager.recordSuccessState(address);
addressManager.resetFailureStatus(address);
Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address());

// test recodeStatus times
@@ -115,7 +115,7 @@ public void recordStateTest() throws ExecutionException {
Assertions.assertEquals("http://127.0.0.4:30100", addressManager.address());

// test restore isolation
addressManager.recoverIsolatedAddress("http://127.0.0.3:30100");
addressManager.recordSuccessState("http://127.0.0.3:30100");
Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address());
Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address());
}
Original file line number Diff line number Diff line change
@@ -562,7 +562,7 @@ public void checkIsolationAddressAvailable() {
return;
}
for (String address : isolationAddresses) {
httpClient.checkAddressAvailable("/registry/microservices", null, null, address);
httpClient.checkAddressAvailable(address);
}
}
}
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
import org.apache.servicecomb.http.client.common.HttpRequest;
import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@@ -32,6 +33,8 @@ public class ServiceCenterRawClient {

private static final String HEADER_TENANT_NAME = "x-domain-name";

private static final String ADDRESS_CHECK_PATH = "/v4/default/registry/health/readiness";

private final String tenantName;

private final HttpTransport httpTransport;
@@ -93,16 +96,8 @@ private HttpResponse doHttpRequest(String url, boolean absoluteUrl, Map<String,
}
}

public void checkAddressAvailable(String url, Map<String, String> headers, String content,
String address) {
String formatUrl = addressManager.formatUrl(url, false, address);
HttpRequest httpRequest = buildHttpRequest(formatUrl, headers, content, HttpRequest.GET);
try {
httpTransport.doRequest(httpRequest);
addressManager.recoverIsolatedAddress(address);
} catch (IOException e) {
LOGGER.error("check service center isolation address {} available error!", address);
}
public void checkAddressAvailable(String address) {
ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH);
}

private HttpRequest buildHttpRequest(String url, Map<String, String> headers, String content, String method) {

0 comments on commit 2ec1cc0

Please sign in to comment.