HTTP-ответ кэша в сервисе Spring MVC Rest - PullRequest
6 голосов
/ 25 февраля 2011

У меня есть служба отдыха MVC, которая возвращает данные в XML.Я хотел бы кэшировать этот ответ XML.Как мне этого добиться?Возможно ли это сделать с помощью mvc: interceptors?

Ответы [ 6 ]

5 голосов
/ 25 февраля 2011

Вы могли бы сделать эту работу, но я думаю, что есть лучшие решения.

Во-первых, если вы хотите использовать перехватчики Spring MVC, вы будете использовать метод postHandle для хранения чего-либо в вашем кеше и preHandleпроверить кеш и возможную обходную обработку.Вопрос в том, что вы храните в кеше.Вам нужно будет хранить полный ответ.Это означает, что вам нужно будет легко получить полный ответ от вашего ModelAndView в postHandle.Это может или не может быть легко, в зависимости от того, как вы делаете вещи.

Скорее всего, вам лучше использовать другой механизм кэширования все вместе.Я рекомендую кэшировать на уровне веб-сервера.Это особенно верно, если вы хотите кешировать на уровне перехватчика, так как он находится «рядом» с веб-сервером, и я не вижу никакой выгоды в повторном изобретении колеса там.Apache имеет кеш-модуль.Как и nginx.Лак тоже очень классный.

Я должен также упомянуть, что вы не должны кэшировать, пока не определите, что вам нужно (не преждевременно оптимизируйте).Это пустая трата вашего времени и усилий.Во-вторых, когда вы определили, что у вас есть проблемы с производительностью, которые необходимо устранить (и кэширование - это правильное решение), вам следует кэшировать правильные данные в нужном месте.

Теперь, скажем, выопределили, что у вас есть проблемы с производительностью и что-то вроде кэширования является хорошим решением.Следующее, что нужно определить - это то, что можно кэшировать.Если для каждого URL вы возвращаете одни и те же данные, то лучшим вариантом будет кэширование на уровне веб-сервера (Apache, nginx, Varnish и т. Д.).

Часто бывает, что два клиентапопадет на один и тот же URL и получит разные данные.Это легче всего увидеть на таком сайте, как Facebook.Когда я вхожу, я вижу другие данные, чем видит мой друг.В этом случае вы не сможете кэшировать на уровне веб-сервера.Вам нужно будет кешировать внутри вашего приложения.Обычно это означает кэширование на уровне базы данных.

4 голосов
/ 19 июля 2016

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

Попробуйте использовать некоторые стратегии кэширования, связанные с HTTP.

Вы можете добавить один из HTTP-заголовков к вашим запросам

#cache expires in 3600 seconds
cache-control: private, max-age=3600

#hash of your content
ETag: "e6811cdbcedf972c5e8105a89f637d39-gzip"

# redirect caching to any HTTP header  
vary: User-Agent

Подробное описание методов кэширования

Весенний пример

@RequestMapping (value = "/resource/1.pdf", produces = "application/octet-stream")
public ResponseEntity<InputStreamResource> getAttachement (@RequestParam (value = "id") Long fileId) 
{
    InputStreamResource isr = new InputStreamResource(javaInputStream);
    HttpHeaders headers = new HttpHeaders();
    //other headers
    headers.setCacheControl("private, max-age=3600");
    return new ResponseEntity<>(irs, headers, HttpStatus.OK);

}
4 голосов
/ 13 сентября 2011

Я не мог не согласиться с частью оптимизации решения.

Веб-запросы по своей сути медленные, поскольку вы загружаете данные из удаленного местоположения, возможно, в нескольких тысячах миль.Каждый вызов должен иметь полное время приема-передачи TCP как минимум для самих пакетов, возможно, для connect и fin для каждого запроса, который для connect является синхронным обменом из трех пакетов перед началом передачи данных.

USзадержка от берега к побережью составляет около 50 мс в хороший день, поэтому каждое соединение подвергается штрафу в 150 мс, который для большинства реализаций приходится на каждый запрос.

Кэширование ответа на стороне клиента полностью устраняет эту задержкуи если у службы есть правильные заголовки в их ответе, это тривиально.Если этого не произойдет, вам придется определить политику кэширования, которая по большей части не особенно сложна.Большинство вызовов API выполняются в режиме реального времени или нет.

По моему мнению, кэширование ответов REST - это не преждевременная оптимизация, это здравый смысл.

3 голосов
/ 01 апреля 2013

Я использую это, и это работает с удивительной скоростью.Действительно простой в использовании spring + ehcache:

1) Контроллер:

    @Cacheable("my.json")
    @RequestMapping("/rest/list.json")
    public ResponseEntity list(@RequestParam(value = "page", defaultValue = "0", required = false)
                               int pageNum,
                               @RequestParam(value = "search", required = false)
                               String search) throws IOException {
    ...
    }

2) В ehcache.xml примерно так:

 <cache name="my.json" maxElementsInMemory="10000" eternal="true" overflowToDisk="false"/>

3) Настроить пружину,Я использую стиль весны javaconf:

@Configuration
@EnableCaching
public class ApplicationConfiguration {


    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() throws MalformedURLException {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        return ehCacheManagerFactoryBean;
    }

    @Bean
    @Autowired
    public EhCacheCacheManager cacheManager(EhCacheManagerFactoryBean ehcache) {
        EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
        ehCacheCacheManager.setCacheManager(ehcache.getObject());
        return ehCacheCacheManager;
    }
}
0 голосов
/ 05 июля 2012

Начиная с Spring 3.1, вы можете использовать аннотацию @ Cachable . Также имеется поддержка условного кэширования и некоторых родственных аннотаций, таких как @ CachePut , @ CacheEvict и @ Caching для более детального управления.

Spring в настоящее время поддерживает два разных менеджера кэша , один из которых поддерживается ConcurrentHashMap, а другой - Ehcache .

Наконец, не забудьте прочитать подробности о том, как включить аннотации.

0 голосов
/ 25 февраля 2011

На уровне приложения я бы использовал простой кэш Java как EHCache.EHCache довольно легко интегрировать с методами в bean-компонентах Spring.Вы можете аннотировать ваши методы обслуживания как @Cacheable, и все готово.Проверьте это на EHCache Spring Annotations .

На уровне HTTP Spring MVC предоставляет полезный ETag фильтр .Но я думаю, что было бы лучше, если бы вы могли настраивать этот тип кэширования на уровне сервера больше, чем на уровне приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...