如何在 java 中确定某个请求的优先级?
How to prioritize a certain request in java?
我觉得这是一个小众问题,所以我会尽力解释它。
简介:
我每秒发送约 500 个请求,我觉得我发送的请求越多,请求的处理速度就越慢(在某些时候它变得明显更慢)
问题: 所以问题在Java 有什么方法可以优先处理请求吗?我正在寻求的任何解决方案都是 优化此类请求的速度。因此,在发送请求之前需要花费时间的任何答案与我无关。
INFO: (我希望这足够了,如果不够请告诉我!)
- 我使用的库是 apache httpclients(但如果解决方案需要它,我可以切换)
- 我也在一个 server/pc 上对请求进行多线程处理。我希望这是有用的信息。
- CPU 使用量从 (5-15%) 变化 - 我相信这些是测量值
我正在发送 2 种类型的请求,我只需要优先处理一种类型
- HTTP GET 请求 - HTML 预期响应
- HTTP POST 请求 - JSON 预期响应 (尽管我不需要响应)
#2 是我要优先处理的请求。我很少发送这个请求,但是当我发送它时,我需要它尽可能快。
想到的解决方案:我想出的唯一解决方案是stop/end所有实时连接以执行我想要的请求,但是我认为这样做会花费相当多的时间导致解决方案成为浪费时间。
注意:你可以说我在这方面是个白痴,所以如果解决方案不存在或显而易见,我很抱歉,如果有重复的,我也很抱歉..我不能找到任何与此接近的问题。
这可能是一种解决方法,因为它必须在发送请求之前执行。考虑到您的用例(每秒 500 个请求),我的建议是首先发送最关键的请求,方法是使用 PriorityQueue
.
由于您已经对消息进行了批处理以便发送它们,这种方法将有助于根据设置的优先级对批处理的消息进行排序。
您可以先将请求包装到另一个包含 priority
字段的实体中。例如,一个 skeleton/base PriorityRequest
class:
public class PriorityRequest implements Comparable<PriorityRequest>
{
public int priority;
public PriorityRequest(int priority)
{
this.priority=priority;
}
@Override
public int compareTo(PriorityRequest request)
{
return Integer.compare(request.priority,this.priority);
}
}
并声明 children、HttpPost
和 HttpGet
:
public class PriorityHttpPost extends PriorityRequest
{
public HttpPost post;
public PriorityHttpPost(int priority, HttpPost post)
{
super(priority);
this.post=post;
}
}
public class PriorityHttpGet extends PriorityRequest
{
public HttpGet get;
public PriorityHttpGet(int priority, HttpGet get)
{
super(priority);
this.get=get;
}
}
因此,当您创建请求时,您可以将它们插入队列,以便它们自动位于其优先级的基础上:
Queue<PriorityRequest> requestQueue = new PriorityQueue<>();
/*into the batch mechanism*/
requestQueue.add(new PriorityHttpPost(6,httpPost));
//...
requestQueue.add(new PriorityHttpGet(99,httpGet));
//...
这样,您可以保证优先级较高的请求在优先级较低的请求之前离开队列,因为它们将按降序排列。
Queue- | Get (99) | --> out
| Get (9) |
| Post (6) |
| Get (3) |
| Post (1) |
Queue- | Get (9) | --> out
| Post (6) |
| Get (3) |
| Post (1) |
(...)
最后,这种方法(在某些用例中)的一些额外 特征 将包括能够定义 哪些元素先行,哪些元素先行最后一个:
requestQueue.add(new PriorityHttpPost(INTEGER.MAX_VALUE, httpPostMax));
requestQueue.add(new PriorityHttpPost(INTEGER.MAX_VALUE-1, httpPostVery));
requestQueue.add(new PriorityHttpPost(INTEGER.MIN_VALUE+1, httpPostNotVery));
requestQueue.add(new PriorityHttpPost(INTEGER.MIN_VALUE, httpPostNoOneCares));
--
完美世界,嗯,我知道..
Queue- | Post (MAX) | --> out
| Post (MAX-1) |
| ............ |
| ............ |
| Post (MIN+1) |
| Post (MIN) |
理想情况下,您永远不想在客户端上这样做。您希望在服务器上使用它,但我知道这可能不是一个选项。
(不会提到 HTTP/2
和 priority
因为我已经在评论中提到了)。
最简单的思考方式是:“我将根据一些 XXX 规则对它们进行排序”。然后你会意识到你需要一个 Queue/Deque
实现,很可能是一个线程安全的实现。您将希望某些线程将条目放入此队列中,但其他线程会删除它们。因此你需要一个线程安全的PriorityQueue
。而且,afaik,只有 blocking 这样的实现,这意味着 - 你可以无缘无故地人为地延迟非优先请求。它变得更有趣,您有 100 个 PUT 请求,只有一个具有 HIGH
优先级。您已经收到请求,但由于您无法控制线程的调度方式(插入此 queue
的线程),您的 HIGH
优先级请求放在最后。
我们所做的略有不同。我们获取所有请求并根据它们的路径将它们分派到两个不同的线程池。
.../abc -> place in queueA -> process by thread-pool-A
.../def -> place in queueB -> process by thread-pool-B
thread-pool-A
使用带 Thread.MIN_PRIORITY
的线程,而 thread-pool-B
使用 Thread.MAX_PRIORITY
。为此,您 need to read this, rather carefully。我希望我能告诉你这很顺利,或者我有实际生产的实际数字 - 但从那以后我一直渴望搬到不同的工作场所。
这只是为了让您知道还有另一种方法可以做到这一点。
我觉得这是一个小众问题,所以我会尽力解释它。
简介: 我每秒发送约 500 个请求,我觉得我发送的请求越多,请求的处理速度就越慢(在某些时候它变得明显更慢)
问题: 所以问题在Java 有什么方法可以优先处理请求吗?我正在寻求的任何解决方案都是 优化此类请求的速度。因此,在发送请求之前需要花费时间的任何答案与我无关。
INFO: (我希望这足够了,如果不够请告诉我!)
- 我使用的库是 apache httpclients(但如果解决方案需要它,我可以切换)
- 我也在一个 server/pc 上对请求进行多线程处理。我希望这是有用的信息。
- CPU 使用量从 (5-15%) 变化 - 我相信这些是测量值
我正在发送 2 种类型的请求,我只需要优先处理一种类型
- HTTP GET 请求 - HTML 预期响应
- HTTP POST 请求 - JSON 预期响应 (尽管我不需要响应)
#2 是我要优先处理的请求。我很少发送这个请求,但是当我发送它时,我需要它尽可能快。
想到的解决方案:我想出的唯一解决方案是stop/end所有实时连接以执行我想要的请求,但是我认为这样做会花费相当多的时间导致解决方案成为浪费时间。
注意:你可以说我在这方面是个白痴,所以如果解决方案不存在或显而易见,我很抱歉,如果有重复的,我也很抱歉..我不能找到任何与此接近的问题。
这可能是一种解决方法,因为它必须在发送请求之前执行。考虑到您的用例(每秒 500 个请求),我的建议是首先发送最关键的请求,方法是使用 PriorityQueue
.
由于您已经对消息进行了批处理以便发送它们,这种方法将有助于根据设置的优先级对批处理的消息进行排序。
您可以先将请求包装到另一个包含 priority
字段的实体中。例如,一个 skeleton/base PriorityRequest
class:
public class PriorityRequest implements Comparable<PriorityRequest>
{
public int priority;
public PriorityRequest(int priority)
{
this.priority=priority;
}
@Override
public int compareTo(PriorityRequest request)
{
return Integer.compare(request.priority,this.priority);
}
}
并声明 children、HttpPost
和 HttpGet
:
public class PriorityHttpPost extends PriorityRequest
{
public HttpPost post;
public PriorityHttpPost(int priority, HttpPost post)
{
super(priority);
this.post=post;
}
}
public class PriorityHttpGet extends PriorityRequest
{
public HttpGet get;
public PriorityHttpGet(int priority, HttpGet get)
{
super(priority);
this.get=get;
}
}
因此,当您创建请求时,您可以将它们插入队列,以便它们自动位于其优先级的基础上:
Queue<PriorityRequest> requestQueue = new PriorityQueue<>();
/*into the batch mechanism*/
requestQueue.add(new PriorityHttpPost(6,httpPost));
//...
requestQueue.add(new PriorityHttpGet(99,httpGet));
//...
这样,您可以保证优先级较高的请求在优先级较低的请求之前离开队列,因为它们将按降序排列。
Queue- | Get (99) | --> out
| Get (9) |
| Post (6) |
| Get (3) |
| Post (1) |
Queue- | Get (9) | --> out
| Post (6) |
| Get (3) |
| Post (1) |
(...)
最后,这种方法(在某些用例中)的一些额外 特征 将包括能够定义 哪些元素先行,哪些元素先行最后一个:
requestQueue.add(new PriorityHttpPost(INTEGER.MAX_VALUE, httpPostMax));
requestQueue.add(new PriorityHttpPost(INTEGER.MAX_VALUE-1, httpPostVery));
requestQueue.add(new PriorityHttpPost(INTEGER.MIN_VALUE+1, httpPostNotVery));
requestQueue.add(new PriorityHttpPost(INTEGER.MIN_VALUE, httpPostNoOneCares));
--
完美世界,嗯,我知道..
Queue- | Post (MAX) | --> out
| Post (MAX-1) |
| ............ |
| ............ |
| Post (MIN+1) |
| Post (MIN) |
理想情况下,您永远不想在客户端上这样做。您希望在服务器上使用它,但我知道这可能不是一个选项。
(不会提到 HTTP/2
和 priority
因为我已经在评论中提到了)。
最简单的思考方式是:“我将根据一些 XXX 规则对它们进行排序”。然后你会意识到你需要一个 Queue/Deque
实现,很可能是一个线程安全的实现。您将希望某些线程将条目放入此队列中,但其他线程会删除它们。因此你需要一个线程安全的PriorityQueue
。而且,afaik,只有 blocking 这样的实现,这意味着 - 你可以无缘无故地人为地延迟非优先请求。它变得更有趣,您有 100 个 PUT 请求,只有一个具有 HIGH
优先级。您已经收到请求,但由于您无法控制线程的调度方式(插入此 queue
的线程),您的 HIGH
优先级请求放在最后。
我们所做的略有不同。我们获取所有请求并根据它们的路径将它们分派到两个不同的线程池。
.../abc -> place in queueA -> process by thread-pool-A
.../def -> place in queueB -> process by thread-pool-B
thread-pool-A
使用带 Thread.MIN_PRIORITY
的线程,而 thread-pool-B
使用 Thread.MAX_PRIORITY
。为此,您 need to read this, rather carefully。我希望我能告诉你这很顺利,或者我有实际生产的实际数字 - 但从那以后我一直渴望搬到不同的工作场所。
这只是为了让您知道还有另一种方法可以做到这一点。