如何防止客户端 REST API 使用 Jersey 调用 block/prioritize 某些 API 调用
How to prevent client REST API Call block/prioritize certain API calls with Jersey
我目前正在制作一个应用程序,该应用程序将从 api 中获取信息并对其进行分析并将其存储在我的后端 mongodb 中。我使用 java servlet 作为服务器,使用 jersey 作为调用 api 的客户端。我 运行 遇到一个问题,如果有人告诉我的 servlet 告诉 jersey 客户端在 rapid 连续中多次调用 api,网站就会冻结,因为它需要 ~只需一次查询即可在 20 秒内获取所有内容。现在一次自发地有 5 个查询,完成所有操作需要大约 100 秒。
注意:我并没有使用从 api 获得的所有数据并立即将其提供给用户。我只从 1 个调用中提供用户数据,而其他 300 个调用是将他们的所有数据放入我的数据库中。
tl;博士:
用户点击按钮 -> 球衣进行 400 api 次调用 -> 球衣从 1 次调用中向用户提供数据,然后在后台处理其他 399 次(需要 20 秒) -> 在 20 秒内,其他人点击按钮 ->在前一个人的 399 次调用完成之前,他不会从该 1 次调用中获取数据。
我能否以某种方式使 399 调用在后台进行,以便第二个用户的第一个 api 调用(它给他们一些东西看)可以继续并在 399 之前执行?异步会工作吗?
顺便说一句,这是我的球衣 api 调用代码:
构造函数:
public APICaller(){
client = Client.create();
sync = RateLimiter.getInstance();
}
调用函数:
public String call(String url){
try {
WebResource webResource = client
.resource(url);
ClientResponse response = webResource.accept("application/json")
.get(ClientResponse.class);
if (response.getStatus() != 200) {
/*throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus() + " header : " + response.getHeaders());*/
System.out.println("Failed : HTTP error code : "
+ response.getStatus() + " header : " + response.getHeaders());
if(response.getStatus() == 404)
return "404";
if(response.getStatus() == 429)
return "429";
if(response.getStatus() == 503)
return "503";
}
String output = response.getEntity(String.class);
return output;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
PS:如果我的代码看起来很糟糕,我很抱歉,但我仍在学习如何使用 Jersey。如果代码应该以任何方式改进,请告诉我。谢谢。
您可以实现一个队列系统,将每个请求按顺序排列,然后在请求完成时将其弹出。如果优先级较高,您可以在处理过程中将项目添加到前面。
所以
队列(先进先出)
[]:
呼叫 1:[1a,1b,1c,1d]
人口:1a ... 1b ...
调用 2:[1c,1d] <--- 单击按钮 在第一个调用中碰撞
变成
[2a,1c,1d,2b,2c,2d]
人口:2a ... 1c ... 1d ... ... 2d
您可以通过将它们放入数组本身来获得第一个调用,因此 call1[1a,1b,1c,1d] 和 call2[2a,2b,2c,3d] 然后 call1[1] => 1a
我不知道如何在 java 中执行此操作,但在 JS 中我必须检查每个方法的响应何时完成,因为它完成调用以检查队列中是否有任何要保留的内容迭代它。也许 while 循环可以做到这一点。这将允许循环继续,直到所有后续调用完成。
我目前正在制作一个应用程序,该应用程序将从 api 中获取信息并对其进行分析并将其存储在我的后端 mongodb 中。我使用 java servlet 作为服务器,使用 jersey 作为调用 api 的客户端。我 运行 遇到一个问题,如果有人告诉我的 servlet 告诉 jersey 客户端在 rapid 连续中多次调用 api,网站就会冻结,因为它需要 ~只需一次查询即可在 20 秒内获取所有内容。现在一次自发地有 5 个查询,完成所有操作需要大约 100 秒。
注意:我并没有使用从 api 获得的所有数据并立即将其提供给用户。我只从 1 个调用中提供用户数据,而其他 300 个调用是将他们的所有数据放入我的数据库中。
tl;博士: 用户点击按钮 -> 球衣进行 400 api 次调用 -> 球衣从 1 次调用中向用户提供数据,然后在后台处理其他 399 次(需要 20 秒) -> 在 20 秒内,其他人点击按钮 ->在前一个人的 399 次调用完成之前,他不会从该 1 次调用中获取数据。
我能否以某种方式使 399 调用在后台进行,以便第二个用户的第一个 api 调用(它给他们一些东西看)可以继续并在 399 之前执行?异步会工作吗?
顺便说一句,这是我的球衣 api 调用代码: 构造函数:
public APICaller(){
client = Client.create();
sync = RateLimiter.getInstance();
}
调用函数:
public String call(String url){
try {
WebResource webResource = client
.resource(url);
ClientResponse response = webResource.accept("application/json")
.get(ClientResponse.class);
if (response.getStatus() != 200) {
/*throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus() + " header : " + response.getHeaders());*/
System.out.println("Failed : HTTP error code : "
+ response.getStatus() + " header : " + response.getHeaders());
if(response.getStatus() == 404)
return "404";
if(response.getStatus() == 429)
return "429";
if(response.getStatus() == 503)
return "503";
}
String output = response.getEntity(String.class);
return output;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
PS:如果我的代码看起来很糟糕,我很抱歉,但我仍在学习如何使用 Jersey。如果代码应该以任何方式改进,请告诉我。谢谢。
您可以实现一个队列系统,将每个请求按顺序排列,然后在请求完成时将其弹出。如果优先级较高,您可以在处理过程中将项目添加到前面。
所以
队列(先进先出) []:
呼叫 1:[1a,1b,1c,1d]
人口:1a ... 1b ...
调用 2:[1c,1d] <--- 单击按钮 在第一个调用中碰撞
变成
[2a,1c,1d,2b,2c,2d]
人口:2a ... 1c ... 1d ... ... 2d
您可以通过将它们放入数组本身来获得第一个调用,因此 call1[1a,1b,1c,1d] 和 call2[2a,2b,2c,3d] 然后 call1[1] => 1a
我不知道如何在 java 中执行此操作,但在 JS 中我必须检查每个方法的响应何时完成,因为它完成调用以检查队列中是否有任何要保留的内容迭代它。也许 while 循环可以做到这一点。这将允许循环继续,直到所有后续调用完成。