简体   繁体   中英

How to setup service method caching in grails

My application has a couple of services that make external calls via httpClient (GET and POST) that are unlikely to change in months, but they are slow; making my application even slower. Clarification: this is NOT about caching GORM/hibernate/queries to my db.

How can I cache these methods (persistence on disk gets bonus points...) in grails 2.1.0?

I have installed grails-cache-plugin but it doesn't seem to be working, or i configured it wrong (very hard to do since there are 2-5 lines to add only, but i've managed to do it in the past)

I also tried setting up an nginx proxy cache in front of my app, but when i submit one of my forms with slight changes, I get the first submission as result.

Any suggestions/ideas will be greatly appreciated.

EDIT : Current solution (based on Marcin's answer)

My config.groovy: (the caching part only)

//caching
grails.cache.enabled = true
grails.cache.clearAtStartup = false

grails.cache.config = {
    defaults {
        timeToIdleSeconds 3600
        timeToLiveSeconds 2629740
        maxElementsInMemory 1
        eternal false
        overflowToDisk true
        memoryStoreEvictionPolicy 'LRU'
    }

    diskStore {
        path 'cache'
    }

    cache {
        name 'scoring'
    }
    cache {
        name 'query'
    }
}

The important parts are:

  • do not clear at startup (grails.cache.clearAtStartup = false)
  • overflowToDisk=true persists all results over maxElementsInMemory
  • maxElementsInMemory=1 reduced number of elements in memory
  • 'diskStore' should be writable by the user running the app.

Grails Cache Plugin works quite well for me under Grails 2.3.11. Documentation is pretty neat, but just to show you a draft...

I use the following settings in Config.groovy :

grails.cache.enabled = true
grails.cache.clearAtStartup = true

grails.cache.config = {
    defaults {
        maxElementsInMemory 10000
        overflowToDisk false
        maxElementsOnDisk 0
        eternal true
        timeToLiveSeconds 0
    }
    cache {
        name 'somecache'
    }
}

Then, in the service I use something like:

@Cacheable(value = 'somecache', key = '#p0.id.toString().concat(#p1)')
def serviceMethod(Domain d, String s) {
    // ...
}

Notice the somecache part is reused. Also, it was important to use String as key in my case. That's why I used toString() on id .

The plugin can be also set up to use disk storage, but I don't use it.

If it doesn't help, please provide more details on your issue.

This may not help, but if you upgrade the application to Grails 2.4.x you can use the @Memoize annotation. This will automagically cache the results of each method call based upon the arguments passed into it.

In order to store this "almost static" information you could use Memcached or Redis as a cache system. (There are many others)

This two cache systems allows you to store key-value data (in your case something like this "key_GET": JSON,XML,MAP,String ).

Here is a related post: Memcached vs. Redis?

Regards.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM