Как перехватить сервер, используемый для выполнения запроса, когда входящий трафик использует URL-адрес балансировки нагрузки? - PullRequest
0 голосов
/ 16 октября 2018

У меня есть REST-приложение Spring Boot Java со многими API, доступными для наших клиентов и пользовательского интерфейса.Мне было поручено внедрить каркас регистрации транзакций, который будет фиксировать входящие транзакции вместе с ответом, который мы отправляем.

Я работаю с Spring AOP и Around Inspect, и в настоящее время я использую объекты HttpServletRequest и HttpServletResponse для получения большого количества данных, которые мне нужны.

Из моей локальной системы у меня нет проблем с захватом используемого сервера, так как я подключаюсь к своей системе напрямую.Однако, как только я развернул свой код, я увидел, что вместо фактического имени сервера записывается URL-адрес балансировщика нагрузки.

Я также использую Eureka для обнаружения API по имени, поскольку это только одно приложение, работающее на HAProxy.

Представьте себе этот поток:

 /*
 UI -> https://my-lb-url/service-sidecar/createUser

 HAProxy directs traffic to -> my-lb-url/service-sidecar/ to one of below:
      my-server-1:12345
      my-server-2:12345
      my-server-3:12345


 Goal  : http://my-server-1:1235/createUser
 Actual: https://my-lb-url/createUser

Вот код, который я использую для получения входящего URL.

 String url = httpRequest.getRequestURL().toString();
 if(httpRequest.getQueryString() != null){
      transaction.setApi(url + "?" + httpRequest.getQueryString());
 } else {
      transaction.setApi(url);
 }

Примечание:

Я не так хорошо знаком с HAProxy / Eurkea / и т.д.как я хотел бы быть.Если что-то, изложенное выше, кажется неправильным или нет, тогда я прошу прощения.Наш системный администратор настроил их и заблокировал разработчиков.


ОБНОВЛЕНИЕ

Это новый код, который я использую для создания URL-адреса запроса, но я все еще вижу вывод тот же.

// Utility Class

public static String constructRequestURL(HttpServletRequest httpRequest) {

    StringBuilder url = new StringBuilder(httpRequest.getScheme());
    url.append("://").append(httpRequest.getServerName());

    int port = httpRequest.getServerPort();
    if(port != 80 && port != 443) {
        url.append(":").append(port);
    }
    url.append(httpRequest.getContextPath()).append(httpRequest.getServletPath());

    if(httpRequest.getPathInfo() != null) {
        url.append(httpRequest.getPathInfo());
    }
    if(httpRequest.getQueryString() != null) {
        url.append("?").append(httpRequest.getQueryString());
    }
    return url.toString();
}

// Service Class

transaction.setApi(CommonUtil.constructRequestURL(httpRequest));

1 Ответ

0 голосов
/ 18 октября 2018

Я нашел решение этой проблемы, но это не самый чистый маршрут, и я с удовольствием приму другое предложение, если это возможно.

  1. Я автоматически подключаю номер порта из моего application.yml.
  2. Я запускаю команду "hostname" на сервере Linux, на котором размещено приложение, чтобы определить сервер, выполняющий запрос.

Теперь URL-адрес, сохраненный в журналах транзакций, является точным.

-

@Autowired
private int serverPort; 

/*
 * ... 
 */

private String constructRequestURL(HttpServletRequest httpRequest) {

    StringBuilder url = new StringBuilder(httpRequest.getScheme())
            .append("://").append(findHostnameFromServer()).append(":").append(serverPort)
            .append(httpRequest.getContextPath()).append(httpRequest.getServletPath());

    if(httpRequest.getPathInfo() != null) {
        url.append(httpRequest.getPathInfo());
    }
    if(httpRequest.getQueryString() != null) {
        url.append("?").append(httpRequest.getQueryString());
    }
    return url.toString();
}

private String findHostnameFromServer(){

    String hostname = null;
    LOGGER.info("Attempting to Find Hostname from Server...");
    try {
        Process process = Runtime.getRuntime().exec(new String[]{"hostname"});
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            hostname = reader.readLine();
        }

    } catch (IOException e) {
        LOGGER.error(CommonUtil.ERROR, e);
    }
    LOGGER.info("Found Hostname: {}", hostname);
    return hostname;
}
...