当传入流量使用负载均衡器 URL 时,如何捕获用于满足请求的服务器?



我有一个Spring Boot Java REST应用程序,其中有许多API公开给我们的客户端和UI。我的任务是实现一个事务日志记录框架,该框架将捕获传入的事务以及我们发送的响应。

我可以使用Spring AOP和Around检查,我目前正在利用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. 我正在从我的应用程序.yml自动连接端口号。
  2. 我在托管应用程序的 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;
}

最新更新