Giả sử tôi có cuộc gọi dịch vụ web sau đây sử dụng phương pháp @GET
:Bộ nhớ đệm hoạt động như thế nào trong JAX-RS?
@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();
}
}
Để thử nghiệm, tôi làm chậm xử lí hiện tại 5 giây trước khi lấy dữ liệu từ cơ sở dữ liệu của tôi.
Khi tôi gọi dịch vụ web của mình bằng cách sử dụng Firefox Poster, trong vòng 60 giây, nó có vẻ nhanh hơn nhiều vào các cuộc gọi thứ 2, thứ 3 và tiếp tục, cho đến khi nó vượt quá 60 giây.
Tuy nhiên, khi tôi dán URI vào trình duyệt (Chrome), nó dường như làm chậm 5 lần mỗi lần. Và tôi thực sự bối rối về cách bộ nhớ đệm thực sự được thực hiện với kỹ thuật này. Dưới đây là câu hỏi của tôi:
- POSTER có thực sự xem tiêu đề
max-age
và quyết định khi nào cần tìm nạp dữ liệu? - Ở phía máy khách (web, android ....), khi truy cập dịch vụ web của tôi, tôi có cần kiểm tra tiêu đề và sau đó thực hiện lưu vào bộ nhớ cache theo cách thủ công hoặc trình duyệt đã lưu trữ dữ liệu ?
- Có cách nào để tránh tìm nạp dữ liệu từ cơ sở dữ liệu mỗi lần không? Tôi đoán tôi sẽ phải lưu trữ dữ liệu của tôi trong bộ nhớ bằng cách nào đó, nhưng nó có khả năng có thể hết bộ nhớ?
Trong hướng dẫn này JAX-RS caching tutorial: Bộ nhớ đệm thực sự hoạt động như thế nào? Dòng đầu tiên luôn tìm nạp dữ liệu từ cơ sở dữ liệu:
Đặt myBook = getBookFromDB (id);
Vậy làm cách nào để được lưu trong bộ nhớ cache? Trừ khi mã không thực thi theo thứ tự trên/xuống.
@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();
}
Lưu ý phụ, không trả lời câu hỏi: thay vì '86400', bạn có thể sử dụng' TimeUnit.DAYS.toSeconds (1) '. Dễ dàng hơn nhiều trên mắt và không cần nỗ lực giải mã;) – fge
@fge: Cảm ơn;) – Chan
Tương tự, bạn có thể sử dụng 'TimeUnit.SECONDS.sleep (5)', theo cách – fge