2014-09-23 4 views
0

Использование Spring RestTemplate для вызова вызовов клиентского отдыха, можно ли дросселировать эти вызовы? . максимум 10 одновременных вызовов.Throttling RestTemplate invocations

Сам RestTemplate, похоже, не предоставляет этого, поэтому я задаюсь вопросом, что это за варианты.

Было бы лучше иметь общее решение, например. также активировать SOAP-вызовы.

ответ

0

From the docs:

Чтобы создать экземпляр RestTemplate вы можете просто позвонить по умолчанию конструктор без аргументов. Это будет использовать стандартные классы Java из пакета java.net в качестве базовой реализации для создания запросов HTTP . Это можно переопределить, указав реализацию ClientHttpRequestFactory. Spring обеспечивает реализацию HttpComponentsClientHttpRequestFactory, которая использует HTTP-адрес Apache HttpComponents для создания запросов. HttpComponentsClientHttpRequestFactory настроен с использованием экземпляра org.apache.http.client.HttpClient, который, в свою очередь, может быть сконфигурирован с информацией об учетных данных или связностью пула соединений.

Я хотел бы посмотреть в настройке RestTemplate использовать HTTP-компонентов и играть с setMaxPerRoute и setMaxTotal. Если ваш SOAP-клиент also happens to be using HTTP Components может быть способом совместного использования настроек компонентов Commons HTTP Components между ними.

Другой вариант заключается в том, чтобы свернуть самостоятельно. Вы можете создать Proxy, который использует Semaphore для блокировки, пока не будет выполнен другой запрос. Что-то вдоль этих линий (обратите внимание, что этот код полностью непроверенный и только для общения общего представления о том, как вы бы это реализовать):

public class GenericCounterProxy implements InvocationHandler 
{ 
    private final Object target; 
    private final int maxConcurrent; 
    private final Semaphore sem; 

    GenericCounterProxy(Object target, int maxConcurrent) 
    { 
     this.target = target; 
     this.maxConcurrent = maxConcurrent; 
     this.sem = new Semaphore(maxConcurrent, true); 
    } 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
     try 
     { 
      // block until acquire succeeds 
      sem.acquire() 
      method.invoke(target, args); 
     } 
     finally 
     { 
      // release the Semaphore no matter what. 
      sem.release(); 
     } 
    } 

    public static <T> T proxy(T target, int maxConcurrent) 
    { 
     InvocationHandler handler = new GenericCounterProxy(target, maxConcurrent); 
     return (T) Proxy.newProxyInstance(
      target.getClass().getClassLoader(), 
      target.getClass().getInterfaces(), 
      handler); 
    } 
} 

Если вы хотите, чтобы пойти с этим типом подхода:

  • Возможно, вам следует уточнить методы, по которым прокси-сервер приобретает Семафор, поскольку не каждый метод на целевом объекте подвергается дросселю (например, getters для настроек).
  • Вам необходимо изменить с RestTemplate на RestOperations, который является интерфейсом или изменить механизм проксирования для использования проксирования на основе классов.
+0

Thanks John. Я принимаю этот ответ, поскольку он дает мне достаточно о чем подумать и найти способ, который лучше всего подходит моей ситуации. –