1、Redis是簡介
Redis是一個開源的使用ANSI C語言編寫贞言、支持網(wǎng)絡(luò)斜棚、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫蜗字,并提供多種語言的API打肝。從2010年3月15日起脂新,Redis的開發(fā)工作由VMware主持挪捕。從2013年5月開始,Redis的開發(fā)由Pivotal贊助
工程基于基礎(chǔ)架構(gòu) Kotlin +SpringBoot + MyBatis完美搭建最簡潔最酷的前后端分離框架進行完善
2争便、Redis開發(fā)者
- redis 的作者级零,叫Salvatore Sanfilippo,來自意大利的西西里島滞乙,現(xiàn)在居住在卡塔尼亞奏纪。目前供職于Pivotal公司。他使用的網(wǎng)名是antirez斩启。
3序调、Redis安裝
- Redis安裝與其他知識點請參考幾年前我編寫文檔
Redis Detailed operating instruction.pdf
,這里不做太多的描述兔簇,主要講解在kotlin+SpringBoot然后搭建Redis與遇到的問題
4发绢、Redis應(yīng)該學(xué)習(xí)那些硬耍?
-
列舉一些常見的內(nèi)容
5、Redis有哪些命令
-
Redis常用命令
6边酒、 Redis常見應(yīng)用場景
7经柴、 Redis常見的幾種特征
- Redis的哨兵機制
- Redis的原子性
- Redis持久化有RDB與AOF方式
8、工程結(jié)構(gòu)
9墩朦、Kotlin與Redis的代碼實現(xiàn)
-
Redis 依賴的Jar配置
<!-- Spring Boot Redis 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
-
RedisProperties代碼
@Component
@Configuration
@ConfigurationProperties(prefix = "redis")
open class RedisProperties {
// Redis服務(wù)器地址
var host: String = "192.168.1.133"
// Redis服務(wù)器連接端口
var port: Int = 6739
// Redis服務(wù)器連接密碼(默認為空)
var password: String = ""
// 連接超時時間(毫秒)
var timeout: Int = 5000
// 連接超時時間(毫秒)
var database: Int = 1
// 連接池最大連接數(shù)(使用負值表示沒有限制)
var maxTotal: Int = 8
// 連接池最大阻塞等待時間(使用負值表示沒有限制)
var maxWaitMillis: Int = 1
// 連接池中的最大空閑連接
var maxIdle: Int = 8
// 連接池中的最小空閑連接
var minIdle: Int = 8
}
-
RedisTemplateDataSource代碼
/**
*參考博客: https://blog.csdn.net/New_CJ/article/details/84892543
*/
@Component
@EnableCaching // 啟動緩存
@Configuration
@EnableConfigurationProperties(RedisProperties::class)
open class RedisTemplateDataSource : CachingConfigurerSupport {
// Redis服務(wù)器地址
var host: String = "192.168.1.133"
// Redis服務(wù)器連接端口
var port: Int = 6739
// Redis服務(wù)器連接密碼(默認為空)
var password: String = ""
// 連接超時時間(毫秒)
var timeout: Int = 5000
// 連接超時時間(毫秒)
var database: Int = 1
// 連接池最大連接數(shù)(使用負值表示沒有限制)
var maxTotal: Int = 8
// 連接池最大阻塞等待時間(使用負值表示沒有限制)
var maxWaitMillis: Int = 1
// 連接池中的最大空閑連接
var maxIdle: Int = 8
// 連接池中的最小空閑連接
var minIdle: Int = 8
//解決This type has a constructor, and thus must be initialized here異常信息
constructor()
//獲取配置信息構(gòu)造方法
constructor(host:String,port:Int,password: String ,timeout: Int,database: Int,maxTotal: Int ,maxWaitMillis: Int,maxIdle: Int,minIdle: Int ){
this.host= host
this.port = port
this.password= password
this.timeout= timeout
this.database=database
this.maxTotal=maxTotal
this.maxWaitMillis=maxWaitMillis
this.maxIdle=maxIdle
this.minIdle=minIdle
}
companion object {
private val log: Logger = LoggerFactory.getLogger(RedisTemplateDataSource::class.java)
}
@Autowired lateinit var redisProperties: RedisProperties
/**
* 配置JedisPoolConfig
* @return JedisPoolConfig實體
*/
@Bean(name = arrayOf("jedisPoolConfig"))
open fun jedisPoolConfig(): JedisPoolConfig {
log.info("初始化JedisPoolConfig");
var jedisPoolConfig = JedisPoolConfig();
// 連接池最大連接數(shù)(使用負值表示沒有限制)
jedisPoolConfig.setMaxTotal(redisProperties.maxTotal);
// 連接池最大阻塞等待時間(使用負值表示沒有限制)
jedisPoolConfig.setMaxWaitMillis(redisProperties.maxWaitMillis.toLong());
// 連接池中的最大空閑連接
jedisPoolConfig.setMaxIdle(redisProperties.maxIdle);
// 連接池中的最小空閑連接
jedisPoolConfig.setMinIdle(redisProperties.minIdle);
// jedisPoolConfig.setTestOnBorrow(true);
// jedisPoolConfig.setTestOnCreate(true);
// jedisPoolConfig.setTestWhileIdle(true);
return jedisPoolConfig;
}
/**
* 實例化 RedisConnectionFactory 對象
* @param poolConfig
* @return
*/
@Bean(name = arrayOf("jedisConnectionFactory"))
open fun jedisConnectionFactory(@Qualifier(value = "jedisPoolConfig") poolConfig: JedisPoolConfig): RedisConnectionFactory {
log.info("初始化RedisConnectionFactory");
var jedisConnectionFactory = JedisConnectionFactory(poolConfig);
jedisConnectionFactory.hostName=redisProperties.host
jedisConnectionFactory.port=redisProperties.port
jedisConnectionFactory.database=redisProperties.database
return jedisConnectionFactory;
}
/**
* 實例化 RedisTemplate 對象
* @return
*/
@Bean(name = arrayOf("redisTemplateStr"))
open fun redisTemplateStr(@Qualifier(value = "jedisConnectionFactory") factory: RedisConnectionFactory): RedisTemplate<String, String> {
log.info("初始化RedisTemplate");
var redisTemplate = RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(factory);
redisTemplate.setKeySerializer(StringRedisSerializer());
redisTemplate.setHashKeySerializer(StringRedisSerializer());
redisTemplate.setHashValueSerializer(JdkSerializationRedisSerializer());
redisTemplate.setValueSerializer(JdkSerializationRedisSerializer());
redisTemplate.afterPropertiesSet();
redisTemplate.setEnableTransactionSupport(true);
return redisTemplate;
}
@Bean
override
fun cacheManager() : CacheManager{
var redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5));
return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(jedisConnectionFactory(jedisPoolConfig())))
.cacheDefaults(redisCacheConfiguration).build();
}
@Bean(value = arrayOf("redisTemplate"))
open fun redisTemplate(jedisConnectionFactory: JedisConnectionFactory): RedisTemplate<String, Any> {
//設(shè)置序列化
var jackson2JsonRedisSerializer = Jackson2JsonRedisSerializer(Object::class.java);
var om = ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
var redisTemplate = RedisTemplate<String, Any>();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
var stringSerializer = StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer); // key序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value序列化
redisTemplate.setHashKeySerializer(stringSerializer); // Hash key序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); // Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
-
RedisAutoConfiguration代碼
@EnableConfigurationProperties(RedisProperties::class)
open class RedisAutoConfiguration {
@Autowired lateinit var redisProperties: RedisProperties;
@Bean
@ConditionalOnMissingBean(RedisTemplateDataSource::class)
@ConditionalOnProperty(name = arrayOf("redis.host"))
open fun redisTemplateDataSource():RedisTemplateDataSource {
return RedisTemplateDataSource(redisProperties.host,redisProperties.port,redisProperties.password,
redisProperties.timeout,redisProperties.database,redisProperties.maxTotal,
redisProperties.maxWaitMillis,redisProperties.maxIdle,redisProperties.minIdle)
}
}
-
META-INF的spring.factories配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.flong.kotlin.core.redis.RedisAutoConfiguration
-
Controller代碼
@Autowired lateinit var stringRedisTemplate: StringRedisTemplate
//RedisTemplateK, V>這個類由于有K與V坯认,下面的做法是必須要指定Key-Value
//2 type arguments expected for class RedisTemplate
@Autowired lateinit var redisTemplate : RedisTemplate<String,Any>;
//簡單的緩存測試1
@RequestMapping("/getUserByRedis/{userId}")
fun getUserByRedis(@PathVariable("userId") userId: Long) {
var redis_key = USER_REDIS_KEY + "_" + userId;
var user = stringRedisTemplate.opsForValue().get(redis_key)
if (user == null) {
var userObj = userService.getUserId(userId)
stringRedisTemplate.opsForValue().set(redis_key, userObj.toString())
print("從DB獲取----" + JSON.toJSONString(userObj));
} else {
print("從緩存獲取----" + JSON.toJSONString(user));
}
}
//簡單的緩存測試2
@RequestMapping("/getUserByRedis1/{userId}")
fun getUserByRedis1(@PathVariable("userId") userId: Long) {
var redis_key = USER_REDIS_KEY + "_" + userId;
var user = redisTemplate.opsForValue().get(redis_key)
if (user == null) {
var userObj = userService.getUserId(userId)
redisTemplate.opsForValue().set(redis_key, userObj.toString())
print("從DB獲取----" + JSON.toJSONString(userObj));
} else {
print("從緩存獲取----" + JSON.toJSONString(user));
}
}
注意:RedisTemplateK, V>這個類由于有K與V,下面的做法是必須要指定Key-Value 2 type arguments expected for class RedisTemplate
-
運行結(jié)果
10氓涣、參考文章
11牛哺、工程架構(gòu)源代碼
12 、總結(jié)與建議
1 春哨、以上問題根據(jù)搭建 kotlin與Redis實際情況進行總結(jié)整理荆隘,除了技術(shù)問題查很多網(wǎng)上資料,通過自身進行學(xué)習(xí)之后梳理與分享赴背。
2椰拒、 在學(xué)習(xí)過程中也遇到很多困難和疑點,如有問題或誤點凰荚,望各位老司機多多指出或者提出建議燃观。本人會采納各種好建議和正確方式不斷完善現(xiàn)況,人在成長過程中的需要優(yōu)質(zhì)的養(yǎng)料便瑟。
3缆毁、 希望此文章能幫助各位老鐵們更好去了解如何在 kotlin上搭建RabbitMQ,也希望您看了此文檔或者通過找資料親身經(jīng)歷實操學(xué)習(xí)效果會更好到涂。
備注:此文章屬于本人原創(chuàng),歡迎轉(zhuǎn)載和收藏.