java缓存案例,Java項目中使用Redis緩存案例

緩存的目的是為了提高系統的性能,緩存中的數據主要有兩種:

1.熱點數據。我們將經常訪問到的數據放在緩存中,降低數據庫I/O,同時因為緩存的數據的高速查詢,加快整個系統的響應速度,也在一定程度上提高並發量。

2.查詢耗時的數據。如果有一些數據查詢十分耗時,那么每次請求這些數據時,都去數據庫查詢的話,會使得系統響應速度特別低,數據庫cpu 100%。將這些數據放緩存,會極大提高系統響應速度,但同時數據實時性較差。

最近工作中有碰到需要使用緩存的情況,場景如下:app端看板統計數據匯總,在打開app時加載看板數據,匯總數據來源於不同的庫,各個數據的生成接口已經寫好,只需要去調用接口整合數據返回即可。

具體我們來看看是怎么實現的吧。

第一步,取mysql中查詢各個接口的信息:

getPanelInfo.java

1 /*service代碼略*/

2 List panels = panelService.getAllPanels(); //得到接口的名稱,接口的url

第二步,根據拿到的信息生成請求參數:

getPanelInfo.java

1 WrapResponseModel resonseModel = newWrapResponseModel();2 Map headers = new HashMap<>();3 headers.put("username", username);4 headers.put("token",token);5 List content = new ArrayList();6 for(PanelDto panelDto:panel){7 //發送http請求

8 content.add(HttpRequestUtils.get(panelDto.getUrl(), headers));9 }10 //返回格式

11 responseModel.setCode(SUCCESS_CODE);12 responseModel.setData(content);

第三步,發送http請求調用接口:

HttpRequestUtils.java

1 public static String get(String url, Mapheaders) {2 RequestConfig config =RequestConfig.custom().setConnectTimeout(TIME_OUT).setConnectionRequestTimeout(TIME_OUT).setSocketTimeout(TIME_OUT).build();3 String ret = null;4 //創建HttpClient對象

5 CloseableHttpClient closeHttpClient =HttpClients.createDefault();6 CloseableHttpResponse httpResponse = null;7 //發送get請求

8 HttpGet httpGet = newHttpGet(url);9 try{10 //add header

11 if(Objects.nonNull(headers)) {12 Set keys =headers.keySet();13 for (Iterator i =keys.iterator(); i.hasNext(); ) {14 String key =i.next();15 httpGet.addHeader(key, headers.get(key));16 }17 }18

19 httpGet.setConfig(config);20 //執行Get請求 得到Response對象

21 httpResponse =closeHttpClient.execute(httpGet);22 //httpResponse.getStatusLine() 響應頭信息

23 int httpResponseCode =httpResponse.getStatusLine().getStatusCode();24

25 if (200 !=httpResponseCode) {26 logger.error("http返回值異常, httpResponseCode = " +httpResponseCode);27 }28

29 //返回對象

30 HttpEntity httpEntity =httpResponse.getEntity();31 ret = EntityUtils.toString(httpEntity, "UTF-8");32 } catch(UnsupportedEncodingException e) {33 logger.error(e.getMessage(), e);34 } catch(ClientProtocolException e) {35 logger.error(e.getMessage(), e);36 } catch(IOException e) {37 //logger.error(e.getMessage(), e);

38 } finally{39 if (httpResponse != null) {40 try{41 httpResponse.close();42 } catch(IOException e) {43 logger.error(e.getMessage(), e);44 }45 }46 if (closeHttpClient != null) {47 try{48 closeHttpClient.close();49 } catch(IOException e) {50 logger.error(e.getMessage(), e);51 }52 }53 }54 returnret;55 }

第四步,查詢數據set進redis,之后返回查詢的數據:

getPanelInfo.java

1 if (!Objects.equals(redisCache, "false")) {

2 //redisttl過期時間3 redisProxyHandler.set(redisKey, JSON.toJSONString(responseModel), REDIS_TTL);4 logger.error("set succeed!!!!!!!!!!!!!!!!");5 }

redisHandler.java

1 public void set(String key, String value, intseconds) {2 redisCacheProvider.set(key, value, seconds);3 }

redisProvider.java

1 @Autowired2 privateJedisPool jedisPool;3

4 publicJedis getJedis() {5 Jedis jedis = this.jedisPool.getResource();6 //使用index為2的database

7 jedis.select(2);8 returnjedis;9 }10

11 public void set(String key, String value, intseconds) {12 Jedis jedis = null;13 try{14 jedis =getJedis();15 jedis.setex(key, seconds, value);16 Long exp =jedis.ttl(key);17 if (exp < 0) {18 throw new RuntimeException("data time out!");19 }20 } catch(Throwable e) {21 logger.error(e.getMessage(), e);22 throw newTokenException(e.getMessage());23 } finally{24 if(jedis != null){jedis.close;}25 }26 }

第五步,請求接口的時候,先請求redis緩存,如果命中則返回命中數據,否則,將執行上面的發送http請求在拼湊數據返回的代碼:

getPanelInfo.java

1 String panelInfo =redisProxyHandler.get(redisKey);2 Long expire =redisProxyHandler.getExpire(redisKey);3 //命中才返回,否則會去發http請求

4 if (Objects.nonNull(panelInfo) && (expire > 0) && expire

redisHandler.java

1 publicString get(String key)2 returnredisCacheProvider.get(key);3 }

redisProvider.java

1 publicString get(String key) {2 String value = null;3 Jedis jedis = null;4 try{5 jedis =getJedis();6 value =jedis.get(key);7 } catch(Throwable e) {8 logger.error(e.getMessage(), e);9 throw newTokenException(e.getMessage());10 } finally{11 if(jedis != null){12 jedis.close();13 }14 }15 returnvalue;16 }

redis相關配置文件如下

applicationContext.xml

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

redis.properties

1 # 控制一個pool可分配多少個jedis實例2 redis.pool.maxTotal=10003 # 控制一個pool最多有多少個狀態為idle(空閑)的jedis實例4 redis.pool.maxIdle=2005 # 表示當borrow一個jedis實例時,最大的等待時間,如果超過等待時間,則直接拋出JedisConnectionException6 redis.pool.maxWaitMillis=20007 #在borrow一個jedis實例時,是否提前進行validate操作;如果為true,則得到的jedis實例均是可用的8 redis.pool.testOnBorrow=true9 # redis 單機10 # 單機 host11 jedis.host=127.0.0.112 # 單機 port13 jedis.port=6379

看了上面的代碼,我們知道一般的緩存是怎么使用的,在這個案例中,每個redisKey是根據請求的用戶名拼接特定的字符串生成的,每個請求用戶對應的key只在redis中保存一定的時間,過了指定的過期時間REDIS_TTL,數據將會被清除掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值