13.使用缓存

13.使用cache

为了创建高效的系统,有里会需要缓存数据。play有一个cache库,在分布式环境中使用Memcached

如果没有配置Memcached,play将使用标准的缓存来存储数据到JVM heap堆中。在JVM应用程序里缓存数据打破了play创造的“什么都不共享”的原则:你不能在多个服务器上运行同一应用程序,否则不能保证应用行为的一致性。每个应用实例将拥有不同的数据备份。

清晰理解缓存约定非常重要:当把数据放入缓存时,就不能保证数据永久存在。事实上不能这样做,缓存非常快,只在内存里存在(并没有进行持久化)。

因此使用缓存最好的用途就是数据不需要进行修改的情况

public static void allProducts() {

   List<Product> products = Cache.get("products",List.class);

    if(products ==null) {

        products =Product.findAll();

        Cache.set("products", products,"30mn");

    }

   render(products);

}

The cache API

缓存API由play.cache.Cache类提供,这个类包含了许多用于从缓存设置、替换、获取数据的方法。参考Memcached文档以了解每个方法的用法。

示例:

public static void showProduct(String id) {

    Product product= Cache.get("product_" + id, Product.class);

    if(product ==null) {

        product =Product.findById(id);

       Cache.set("product_" + id, product, "30mn");

    }

   render(product);

}

 

public static void addProduct(String name, int price) {

    Product product= new Product(name, price);

    product.save();

   showProduct(product.id);

}

 

public static void editProduct(String id, String name,int price) {

    Product product= Product.findById(id);

    product.name =name;

    product.price =price;

   Cache.set("product_" + id, product, "30mn");

   showProduct(id);

}

 

public static void deleteProduct(String id) {

    Product product= Product.findById(id);

   product.delete();

   Cache.delete("product_" + id);

    allProducts();

}

有一些方法是以safe前缀开头的方法,比如safeDelete, safeSet。而标准方法是非阻塞式的,比如:

Cache.delete("product_" + id);

delete方法将立即返回,不会一直等到缓存对象是否真的删除。因此,如果发生错误时,比如IO错误,那么要删除的对象仍旧存在。

在继续之前如果需要确定是否真的把对象删除了,就可以使用safeDelete方法:

Cache.safeDelete("product_" + id);

这个方法是阻塞式的,并且会返回一个boolean值来确定是否真的把对象删除了。因此,从缓存中删除对象的完整模式应该是这样的:

if(!Cache.safeDelete("product_" + id)) {

    throw newException("Oops, the product has not been removed from the cache");

}

...

注意:这些方法会导致调用中断,安全方法会慢慢的顺着执行下去,一般情况下,只要确实需要的时候才使用这些方法。

同时要注意,当expiration == "0s" (0秒)时, 真正的中止时间可能与缓存执行的时间不同。

不要把Session当成缓存!

如果使用框架带来的内存式的session来作缓存, 你就会发现play只允许很小的字符串数据可以存入HTTP Session,这里不应该是缓存应用程序数据的地方!

如果你已经习惯了这样做:

httpServletRequest.getSession().put("userProducts",products);

...

// 之后进行请求

products =(List<Product>)httpServletRequest.getSession().get("userProducts");

在Play里可以用其他方式实现相同效果:

Cache.set(session.getId(), products);

...

//接下来的请求为:

List<Product> products = Cache.get(session.getId(),List.class)

在这里,我们使用唯一的UUID来为每个用户在缓存里保存唯一信息。请记住,这和session对象不同,缓存并不绑定任何特定的用户!

配置mcached

如果需要允许真正的Memcached实现,就需在 memcached configuration 定义守护地址 memcached.host configuration

 

1. VL校验批量升级数量是否超过最大值 2. VL校验设备是否存在 3. VL进行权限验证 4. 校验vms中是否已经有其他的批量升级任务 5. VL透传设备查询devId 6. 设备返回devId 7. VL将devId存入本地数据库中 8. VL向VC发送查询设备升级请求 9. 进度缓存中设置进度为PROGRESS_FIRMWARE_START_DOWNLOAD 10. VC向基础云查询devId对应的hwId、oemId、currntFwVer,返回VC 11. VC调用基础云getSercureFwList 12. 基础云返回URL到VL 13. 进度缓存中设置进度为PROGRESS_FIRMWARE_DOWNLOADING 14. 在HashSet中放入URL,防止重复下载;VL根据URL到基础云中下载对应固件,将下载的固件放入数据库中,采用Map记录型号与fileId的对应关系 15. 进度缓存中设置进度为PROGRESS_FIRMWARE_DOWNLOAD_FINISH 16. VL通知设备开始下载 17. 获取主机IP以及端口,构造透传对象参数 18. VL向设备透传固件下载URL以及下载通知请求 19. VL检查给设备的固件下载url透传结果和下载固件通知返回结果,失败则返回错误 20. 进度缓存中设置进度为PROGRESS_START_DOWNLOAD 21. 创建轮询查询下载任务的状态的任务,得到结果后进行判定 22. 进度缓存中设置进度为PROGRESS_DOWNLOADING 23. 创建轮询获取下载结果的任务,解析结果,判断升级是否成功 24. 进度缓存中设置进度为PROGRESS_DOWNLOAD_PROGRESS_FINISH 25. 设备重启 26. 创建轮询获取设备固件任务,解析结果 27. 进度缓存中设置进度为PROGRESS_REBOOT_PROGRESS_FINISH 28. 清除能力集详情缓存 为上面的流程生成时序图UML
09-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值