Redis with SpringBoot integration:
Step 1: Introduce it into the project
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
Copy the code
Step 2: Create the connection pool and configuration classes
RedisUtil:
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class RedisUtil { private JedisPool jedisPool; public void initPool(String host,int port ,int database){ JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(200); poolConfig.setMaxIdle(30); poolConfig.setBlockWhenExhausted(true); poolConfig.setMaxWaitMillis(10*1000); poolConfig.setTestOnBorrow(true); jedisPool=new JedisPool(poolConfig,host,port,20*1000); } public Jedis getJedis(){ Jedis jedis = jedisPool.getResource(); return jedis; }}Copy the code
RedisConfig:
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Public class RedisConfig {// Read the IP address of redis in the Configuration file, @ @ Value into assignment Value (" ${spring. Redis. Host: disabled} ") private String host; @Value("${spring.redis.port:0}") private int port; @Value("${spring.redis.database:0}") private int database; Public RedisUtil getRedisUtil(){if(host.equals("disabled")){return null; } RedisUtil redisUtil=new RedisUtil(); redisUtil.initPool(host,port,database); return redisUtil; }}Copy the code
In which project to use Redis, configure the following in application.properties:
Client login:
cd /usr/local/redis/bin
/redis-cli -h 192.168.0.100 -p 6379
192.168.0.100:6379 > ping PONG
Test it out:
@RunWith(SpringRunner.class) @SpringBootTest public class GmallManageServiceApplicationTests { @Autowired RedisUtil redisUtil; @Test public void contextLoads() { Jedis jedis = redisUtil.getJedis(); String ping = jedis.ping(); System.out.println(ping); }}Copy the code
Using r edis Business development
The first development of redis key naming specification, because redis is not as structured as the database table, all its data is indexed by key, so the readability of redis data, all rely on key.
The most commonly used method in an enterprise is object: ID :field
Such as: sku: 1314: the info
user:1092:password
Take an earlier example:
public SkuInfo getSkuInfo(String skuId){ Jedis jedis = redisUtil.getJedis(); String skuKey= RedisConst.sku_prefix+skuId+RedisConst.skuInfo_suffix; String skuInfoJson = jedis.get(skuKey); if(skuInfoJson! =null){system.err. Println (thread.currentThread ().getName()+" : hit cache "); SkuInfo skuInfo = JSON.parseObject(skuInfoJson, SkuInfo.class); jedis.close(); return skuInfo; }else{system.err.println (thread.currentThread ().getName()+" : missed cache "); System. Err. Println (Thread. CurrentThread (). The getName () + ": the query data # # # # # # # # # # # # # # # # # # # # # # #"); SkuInfo skuInfoDB = getSkuInfoDB(skuId); String skuInfoJsonStr = JSON.toJSONString(skuInfoDB); jedis.setex(skuKey,RedisConst.skuinfo_exp_sec,skuInfoJsonStr); System. Err. Println (Thread. CurrentThread (). The getName () + ": the database update is # # # # # # # # # # # # # # # # # # # #"); jedis.close(); return skuInfoDB; }}Copy the code
The above basic implementation uses the cache scheme.
Problems that may occur with high concurrency:
But there are three more problems in a high-concurrency environment.
- What if Redis is down or not connected?
- What if the Redis cache expires at peak hours, at which point requests will avalanche directly to the database?
- What happens if the user keeps querying for a piece of data that doesn’t exist, the cache doesn’t exist, the database doesn’t exist, and what happens?
public SkuInfo getSkuInfo(String skuId){ SkuInfo skuInfo = null; try { Jedis jedis = redisUtil.getJedis(); String skuInfoKey = ManageConst.SKUKEY_PREFIX + skuId + ManageConst.SKUKEY_SUFFIX; String skuInfoJson = jedis.get(skuInfoKey); If (skuInfoJson = = null | | skuInfoJson. The length () = = 0) {System. Err. Println (Thread. The currentThread (). The getName () + "cache misses!" ); String skuLockKey = ManageConst.SKUKEY_PREFIX + skuId + ManageConst.SKULOCK_SUFFIX; String lock = jedis.set(skuLockKey, "OK", "NX", "PX", ManageConst.SKULOCK_EXPIRE_PX); If ("OK".equals(lock)){system.err.println (thread.currentThread ().getName()+" Get distributed lock!" ); skuInfo = getSkuInfoFromDB(skuId); if(skuInfo==null){ jedis.setex(skuInfoKey, ManageConst.SKUKEY_TIMEOUT, "empty"); return null; } String skuInfoJsonNew = JSON.toJSONString(skuInfo); jedis.setex(skuInfoKey, ManageConst.SKUKEY_TIMEOUT, skuInfoJsonNew); jedis.close(); return skuInfo; }else{system.err.println (thread.currentThread ().getName()+" No distributed lock, start spinning!" ); Thread.sleep(1000); jedis.close(); return getSkuInfo( skuId); } } else if(skuInfoJson.equals("empty")){ return null; } else {system.err.println (thread.currentThread ().getName()+" Cache hit !!!!!!!!!!!!!!!!!!!" ); skuInfo = JSON.parseObject(skuInfoJson, SkuInfo.class); jedis.close(); return skuInfo; } }catch (JedisConnectionException e){ e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return getSkuInfoFromDB(skuId); }Copy the code
The same goes for the most recent:
Controller:
@RequestMapping("{skuId}.html")
public String item(@PathVariable("skuId") String skuId, ModelMap map, HttpServletRequest request){
SkuInfo skuInfo = skuService.item(skuId,request.getRemoteAddr());
}
Copy the code
I’m not going to write the service interface
Serviceimpl:
@override public SkuInfo item(String skuId,String IP) {system.out.println (IP +" access "+skuId+" item "); SkuInfo skuInfo = null; Jedis jedis jedis = redisutil.getJedis (); String skuInfoStr = jedis.get("sku:"+skuId+":info"); SkuInfo = json.parseObject (skuInfoStr, skuinfo.class); skuInfo = json.parseObject (skuInfoStr, skuinfo.class); If (skuInfo == null){system.out.println (IP +" found no cache "+skuId+" distributed lock "); / / get a distributed lock String OK = jedis. Set (skuId "sku:" + + ": the lock", "1", "nx", "px", 10000); If (stringutils.isblank (OK)){system.out.println (IP +" distributed lock failed, spin after 3 seconds "); Try {thread.sleep (3000); // Let it wait 3 seconds} catch (InterruptedException e) {e.printStackTrace(); } return item(skuId,ip); // spin, there is no new thread started, item(skuId, IP); }else{system.out. println(IP +" distributed lock applied successfully, access database "); SkuInfo = getSkuInfo(skuId); } system.out. println(IP +" after successful access to database, return lock, "+skuId+" item in cache "); jedis.del("sku:"+skuId+":lock"); } // Close the redis client jedis.close(); return skuInfo; }Copy the code
GetSkuInfo method:
public SkuInfo getSkuInfo(String skuId) {
SkuInfo skuInfo = new SkuInfo();
skuInfo.setId(skuId);
SkuInfo skuInfos = skuInfoMapper.selectOne(skuInfo);
SkuImage skuImage = new SkuImage();
skuImage.setSkuId(skuId);
List<SkuImage> skuImages = skuImageMapper.select(skuImage);
skuInfos.setSkuImageList(skuImages);
return skuInfos;
}
Copy the code
If for
String skuInfoStr = jedis.get(“sku:”+skuId+”:info”);
String OK = jedis.set(“sku:” + skuId + “:lock”, “1”, “nx”, “px”, 10000);
jedis.del(“sku:”+skuId+”:lock”);
You can check out the previous chapter’s blog, or check out the official website
I’m going to cut a little bit off here