springboot中集成memcached
阿新 • • 發佈:2018-12-20
nec @service 客戶端連接 fix 二進制 github use 算法 @override
前言
Memcached 是一個高性能的分布式內存對象緩存系統,其存儲性能在某些方面不比redis,甚至在文本類型數據的存儲上性能略優於redis,本文將介紹如何在springboot中集成memcached
準備工作
首先我們需要一款客戶端連接對象,類似於我們在使用redis時使用的jedis , 目前memcached主流的客戶端是Xmemcached,如果使用的是maven構建項目,則引入對應的依賴
<!--引入memcached--> <dependency> <groupId>com.googlecode.xmemcached</groupId> <artifactId>xmemcached</artifactId> <version>2.4.5</version> </dependency>
配置
memcached在yml(properties)文件的相關配置
# memcached配置 memcached: server: 1.1.1.1:3333 2.2.2.2:4444 #memcached服務器集群(格式為host:port,多個服務器之間用空格隔開) opTimeout: 3000 #接口操作的默認超時時間,可以被接口覆蓋 poolSize: 10 #池子大小 failureMode: false #是否開啟失敗模式,默認為false enabled: true # 是否使用memcached緩存
將memcached的配置由bean來管理,方便我們調用
1 package com.me.config.properties; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 6 /** 7 * @author : wang zns 8 * @date : 2018-12-19 9 */ 10 @Component 11 @ConfigurationProperties(prefix = "memcached")12 public class MemcachedProperties { 13 14 /** 15 * 服務器 16 */ 17 private String server; 18 19 /** 20 * 操作超時時間,可以被API覆蓋 21 */ 22 private Integer opTimeout; 23 /** 24 * 連接池大小 25 */ 26 private Integer poolSize; 27 28 /** 29 * 是否開啟失敗模式 30 */ 31 private boolean failureMode; 32 33 /** 34 * 是否使用memcached緩存 35 */ 36 private boolean enabled; 37 38 39 40 public String getServer() { 41 return server; 42 } 43 44 public void setServer(String server) { 45 this.server = server; 46 } 47 48 public Integer getOpTimeout() { 49 return opTimeout; 50 } 51 52 public void setOpTimeout(Integer opTimeout) { 53 this.opTimeout = opTimeout; 54 } 55 56 public Integer getPoolSize() { 57 return poolSize; 58 } 59 60 public void setPoolSize(Integer poolSize) { 61 this.poolSize = poolSize; 62 } 63 64 public boolean isFailureMode() { 65 return failureMode; 66 } 67 68 public void setFailureMode(boolean failureMode) { 69 this.failureMode = failureMode; 70 } 71 72 public boolean isEnabled() { 73 return enabled; 74 } 75 76 public void setEnabled(boolean enabled) { 77 this.enabled = enabled; 78 } 79 }
memcached配置類(創建memcached客戶端對象,並註入spring容器中)
1 package com.me.config; 2 3 import cn.stylefeng.guns.config.properties.MemcachedProperties; 4 import lombok.extern.slf4j.Slf4j; 5 import net.rubyeye.xmemcached.MemcachedClient; 6 import net.rubyeye.xmemcached.MemcachedClientBuilder; 7 import net.rubyeye.xmemcached.XMemcachedClientBuilder; 8 import net.rubyeye.xmemcached.command.BinaryCommandFactory; 9 import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator; 10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Qualifier; 12 import org.springframework.context.annotation.Bean; 13 import org.springframework.context.annotation.Configuration; 14 15 /** 16 * @author : wang zns 17 * @date : 2018-12-19 18 */ 19 @Configuration 20 @Slf4j 21 public class MemcachedConfig { 22 23 @Autowired 24 private MemcachedProperties memcachedProperties; 25 26 27 28 @Bean(name = "memcachedClientBuilder") 29 public MemcachedClientBuilder getBuilder() { 30 MemcachedClientBuilder memcachedClientBuilder = new XMemcachedClientBuilder(memcachedProperties.getServer()); 31 32 // 內部采用一致性哈希算法 33 memcachedClientBuilder.setSessionLocator(new KetamaMemcachedSessionLocator()); 34 // 操作的超時時間 35 memcachedClientBuilder.setOpTimeout(memcachedProperties.getOpTimeout()); 36 // 采用二進制傳輸協議(默認為文本協議) 37 memcachedClientBuilder.setCommandFactory(new BinaryCommandFactory()); 38 // 設置連接池的大小 39 memcachedClientBuilder.setConnectionPoolSize(memcachedProperties.getPoolSize()); 40 // 是否開起失敗模式 41 memcachedClientBuilder.setFailureMode(memcachedProperties.isFailureMode()); 42 return memcachedClientBuilder; 43 } 44 45 /** 46 * 由Builder創建memcachedClient對象,並註入spring容器中 47 * @param memcachedClientBuilder 48 * @return 49 */ 50 @Bean(name = "memcachedClient") 51 public MemcachedClient getClient(@Qualifier("memcachedClientBuilder") MemcachedClientBuilder memcachedClientBuilder) { 52 MemcachedClient client = null; 53 try { 54 client = memcachedClientBuilder.build(); 55 } catch(Exception e) { 56 log.info("exception happens when bulid memcached client{}",e.toString()); 57 } 58 return client; 59 } 60 61 62 63 }
使用
有了client對象之後,我們可以像直接操作服務端那樣進行對應的操作,下面用一個小案例進行演示
service
1 package cn.stylefeng.guns.modular.housemanage.cache; 2 3 import cn.stylefeng.guns.modular.system.model.TblHouse; 4 5 /** 6 * 房屋管理緩存 業務層 7 * @author : wang zns 8 * @date : 2018-12-19 9 */ 10 public interface HouseManageCacheService { 11 12 /** 13 * 添加 14 * @param tblHouse 15 */ 16 void add(TblHouse tblHouse); 17 18 /** 19 * 根據主鍵刪除 20 * @param tblHouseId 21 */ 22 void delete(Integer tblHouseId); 23 24 }View Code
serviceImpl
1 package cn.stylefeng.guns.modular.housemanage.cache; 2 3 import cn.stylefeng.guns.modular.housemanage.service.ITblHouseService; 4 import cn.stylefeng.guns.modular.system.model.TblHouse; 5 import com.alibaba.fastjson.JSON; 6 import lombok.extern.slf4j.Slf4j; 7 import net.rubyeye.xmemcached.MemcachedClient; 8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.stereotype.Service; 10 11 /** 12 * @author : wang zns 13 * @date : 2018-12-19 14 */ 15 @Service 16 @Slf4j 17 public class HouseManageCacheServiceImpl implements HouseManageCacheService{ 18 19 @Autowired 20 private MemcachedClient memcachedClient; 21 @Autowired 22 private ITblHouseService iTblHouseService; 23 24 @Override 25 public void add(TblHouse tblHouse) { 26 // 先入庫,入庫成功則入緩存 27 boolean isSuccess = iTblHouseService.insert(tblHouse); 28 if (isSuccess) { 29 try { 30 String houseJsonStr = JSON.toJSONString(tblHouse); 31 memcachedClient.set(String.valueOf(tblHouse.getId()),0,houseJsonStr); 32 } catch (Exception e) { 33 log.info("exception happens when add House:{}",e.toString()); 34 throw new RuntimeException(e.getMessage()); 35 } 36 } 37 } 38 39 @Override 40 public void delete(Integer tblHouseId) { 41 // 先刪除數據庫內容,成功則清空緩存 42 boolean isSuccess = iTblHouseService.deleteById(tblHouseId); 43 if (isSuccess) { 44 try { 45 memcachedClient.delete(String.valueOf(tblHouseId)); 46 } catch (Exception e) { 47 log.info("exception happens when delete House:{}",e.toString()); 48 throw new RuntimeException(e.getMessage()); 49 } 50 } 51 } 52 53 }View Code
controller
1 /** 2 * 新增房屋管理 3 */ 4 @RequestMapping(value = "/add") 5 @ResponseBody 6 public Object add(@Valid TblHouse tblHouse, BindingResult bindingResult) { 7 if(bindingResult.hasErrors()){ 8 throw new ServiceException(BizExceptionEnum.REQUEST_NULL); 9 } 10 // 如果確定要使用緩存 11 if (memcachedProperties.isEnabled()) { 12 houseManageCacheService.add(tblHouse); 13 } else { 14 tblHouseService.insert(tblHouse); 15 } 16 return SUCCESS_TIP; 17 } 18 19 /** 20 * 刪除房屋管理 21 */ 22 @RequestMapping(value = "/delete") 23 @ResponseBody 24 public Object delete(@RequestParam Integer tblHouseId) { 25 if (memcachedProperties.isEnabled()) { 26 houseManageCacheService.delete(tblHouseId); 27 } else { 28 tblHouseService.deleteById(tblHouseId); 29 } 30 return SUCCESS_TIP; 31 }View Code
運行結果:
提交之後,去緩存服務器上查看
至此,springboot中集成memcached就完成了
寫在最後
springboot集成memcached非常簡單,核心步驟就是添加依賴、創建client對象並註入spring容器、然後就是用client對象進行各種操作。
client的接口當然有非常多,xmemcached對接口進行了封裝。
最後附上xmemcached官網的地址,裏面的文檔很詳細 https://github.com/killme2008/xmemcached/wiki
springboot中集成memcached