- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
假设我有以下使用 @GET
方法的网络服务调用:
@GET
@Path(value = "/user/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserCache(@PathParam("id") String id, @Context HttpHeaders headers) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", id);
SqlSession session = ConnectionFactory.getSqlSessionFactory().openSession();
Cre8Mapper mapper = session.getMapper(Cre8Mapper.class);
// slow it down 5 seconds
Thread.sleep(5000);
// get data from database
User user = mapper.getUser(map);
if (user == null) {
return Response.ok().status(Status.NOT_FOUND).build();
} else {
CacheControl cc = new CacheControl();
// save data for 60 seconds
cc.setMaxAge(60);
cc.setPrivate(true);
return Response.ok(gson.toJson(user)).cacheControl(cc).status(Status.OK).build();
}
}
为了实验,我在从数据库中获取数据之前将当前线程减慢了 5 秒。
当我使用 Firefox Poster 调用我的网络服务时,在 60 秒内,第 2、3 次调用等似乎快得多,直到超过 60 秒。
但是,当我将 URI 粘贴到浏览器(Chrome)时,它似乎每次都慢了 5 秒。我真的很困惑缓存实际上是如何用这种技术完成的。这是我的问题:
max-age
并决定何时获取数据? 在本教程中 JAX-RS caching tutorial :缓存实际上是如何工作的?第一行总是从数据库中获取数据:
Book myBook = getBookFromDB(id);
那么它是如何被认为是缓存的呢?除非代码不按上/下顺序执行。
@Path("/book/{id}")
@GET
public Response getBook(@PathParam("id") long id, @Context Request request) {
Book myBook = getBookFromDB(id);
CacheControl cc = new CacheControl();
cc.setMaxAge(86400);
EntityTag etag = new EntityTag(Integer.toString(myBook.hashCode()));
ResponseBuilder builder = request.evaluatePreconditions(etag);
// cached resource did change -> serve updated content
if (builder == null){
builder = Response.ok(myBook);
builder.tag(etag);
}
builder.cacheControl(cc);
return builder.build();
}
最佳答案
从你的问题中我看到你混合了客户端缓存(http)和服务器端缓存(数据库)。我认为这的根本原因是您首先在 firefox 和 chrome 中观察到的不同行为我会尝试清除它
When I call my web service using Firefox Poster, within 60 seconds it seemed much faster on the 2nd, 3rd calls and so forth, until it passed 60 seconds. However, when I paste the URI to a browser (Chrome), it seemed to slow down 5s everytime.
示例:
@Path("/book")
public Response getBook() throws InterruptedException {
String book = " Sample Text Book";
TimeUnit.SECONDS.sleep(5); // thanks @fge
final CacheControl cacheControl = new CacheControl();
cacheControl.setMaxAge((int) TimeUnit.MINUTES.toSeconds(1));
return Response.ok(book).cacheControl(cacheControl).build();
}
我已经启动并运行了一个 Restful 网络服务,它的 url 是
http://localhost:8780/caching-1.0/api/cache/book - GET
火狐:
当我第一次访问 url 时,浏览器向服务器发送请求并得到带有缓存控制 header 的响应。
60 秒内的第二个请求(使用 Enter):这次 firefox 没有去服务器获取响应,而是从缓存中加载数据
60 秒后的第三个请求(使用 Enter):
这次 firefox 向服务器发出请求并得到响应。
第四个请求使用刷新(F5 或 ctrl F5):
如果我在前一个请求的 60 秒内刷新页面(而不是按回车键),firefox 不会从缓存中加载数据,而是向服务器发出请求并在请求中使用特殊 header
Chrome :
第二个请求在 60 秒内(使用 Enter):这次 chrome 再次向服务器发送请求而不是从缓存中加载数据,并且在请求中添加了 header cache-control = "max-age=0"
聚合结果:
由于 chrome 对输入点击的响应不同,您在 firefox 和 chrome 中看到了不同的行为,这与 jax-rs 或您的 http 响应无关。总而言之,客户端(firefox/chrome/safari/opera)会在缓存控制中缓存指定时间段的数据,客户端不会向服务器发出新请求,除非时间到期或我们强制刷新。
我希望这能澄清您的问题 1、2、3。
4.In this tutorial JAX-RS caching tutorial: How does caching actually work? The first line always fetch the data from the database:
Book myBook = getBookFromDB(id);
So how it is considered cached? Unless the code doesn't execute in top/down order.
您提到的示例不是在谈论最小化数据库调用,而是在谈论通过网络节省带宽,客户端已经有数据并与服务器检查(重新验证)是否更新数据,如果没有数据更新您正在发送实际实体的响应。
关于java - 缓存在 JAX-RS 中是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17481839/
我在Windows 10中使用一些简单的Powershell代码遇到了这个奇怪的问题,我认为这可能是我做错了,但我不是Powershell的天才。 我有这个: $ix = [System.Net.Dn
var urlsearch = "http://192.168.10.113:8080/collective-intellegence/StoreClicks?userid=" + userId +
我有一个非常奇怪的问题,过去两天一直让我抓狂。 我有一个我试图控制的串行设备(LS 100 光度计)。使用设置了正确参数的终端(白蚁),我可以发送命令(“MES”),然后是定界符(CR LF),然后我
我目前正试图让无需注册的 COM 使用 Excel 作为客户端,使用 .NET dll 作为服务器。目前,我只是试图让概念验证工作,但遇到了麻烦。 显然,当我使用 Excel 时,我不能简单地使用与可
我开发了简单的 REST API - https://github.com/pavelpetrcz/MandaysFigu - 我的问题是在本地主机上,WildFly 16 服务器的应用程序运行正常。
我遇到了奇怪的情况 - 从 Django shell 创建一些 Mongoengine 对象是成功的,但是从 Django View 创建相同的对象看起来成功,但 MongoDB 中没有出现任何数据。
我是 flask 的新手,只编写了一个相当简单的网络应用程序——没有数据库,只是一个航类搜索 API 的前端。一切正常,但为了提高我的技能,我正在尝试使用应用程序工厂和蓝图重构我的代码。让它与 pus
我的谷歌分析 JavaScript 事件在开发者控制台中运行得很好。 但是当从外部 js 文件包含在页面上时,它们根本不起作用。由于某种原因。 例如; 下面的内容将在包含在控制台中时运行。但当包含在单
这是一本名为“Node.js 8 the Right Way”的书中的任务。你可以在下面看到它: 这是我的解决方案: 'use strict'; const zmq = require('zeromq
我正在阅读文本行,并创建其独特单词的列表(在将它们小写之后)。我可以使它与 flatMap 一起工作,但不能使它与 map 的“子”流一起工作。 flatMap 看起来更简洁和“更好”,但为什么 di
我正在编写一些 PowerShell 脚本来进行一些构建自动化。我发现 here echo $? 根据前面的语句返回真或假。我刚刚发现 echo 是 Write-Output 的别名。 写主机 $?
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我将一个工作 View Controller 类从另一个项目复制到一个新项目中。我无法在新项目中加载 View 。在旧项目中我使用了presentModalViewController。在新版本中,我
我对 javascript 很陌生,所以很难看出我哪里出错了。由于某种原因,我的功能无法正常工作。任何帮助,将不胜感激。我尝试在外部 js 文件、头部/主体中使用它们,但似乎没有任何效果。错误要么出在
我正在尝试学习Flutter中的复选框。 问题是,当我想在Scaffold(body :)中使用复选框时,它正在工作。但我想在不同的地方使用它,例如ListView中的项目。 return Cente
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我有一个组合框,其中包含一个项目,比如“a”。我想调用该组合框的 Action 监听器,仅在手动选择项目“a”完成时才调用。我也尝试过 ItemStateChanged,但它的工作原理与 Action
你能看一下照片吗?现在,一步前我执行了 this.interrupt()。您可以看到 this.isInterrupted() 为 false。我仔细观察——“这个”没有改变。它具有相同的 ID (1
我们当前使用的是 sleuth 2.2.3.RELEASE,我们看不到在 http header 中传递的 userId 字段没有传播。下面是我们的代码。 BaggageField REQUEST_I
我正在尝试在我的网站上设置一个联系表单,当有人点击发送时,就会运行一个作业,并在该作业中向所有管理员用户发送通知。不过,我在失败的工作表中不断收到此错误: Illuminate\Database\El
我是一名优秀的程序员,十分优秀!