Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0b01361

Browse files
committed
add lettuce sync client code readme in lettuce sample
1 parent 00d5513 commit 0b01361

File tree

2 files changed

+223
-0
lines changed

2 files changed

+223
-0
lines changed

‎springboot-lettuce-sample/README.md‎

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,225 @@ B~~~~~B~~~~~B~~~~~B~~~~~~~~~~~B |
264264

265265
LFU把原先的key对象内部的24位时钟分为了两个部分,前16位还代表时钟,后8位代表一个计数器。
266266
使用LFU淘汰时,会根据计数器中key使用的频率精准的淘汰最少使用频率的key。
267+
268+
269+
------------
270+
271+
272+
### SpringBoot集成Lettuce框架-实现Redis调用实战
273+
Lettuce是一个高性能基于Java编程的Redis驱动框架,底层集成了Project Reactor提供了天然的反应式编程,通信框架集成了Netty使用非阻塞IO,支持异步与响应式连接。
274+
275+
##### 1、添加Lettuce和apache pool依赖
276+
<dependency>
277+
<groupId>org.projectlombok</groupId>
278+
<artifactId>lombok</artifactId>
279+
<version>1.18.10</version>
280+
</dependency>
281+
282+
<dependency>
283+
<groupId>org.apache.commons</groupId>
284+
<artifactId>commons-pool2</artifactId>
285+
<version>2.9.0</version>
286+
</dependency>
287+
288+
##### 2、准备Lettuce连接配置
289+
```java
290+
#Redis服务器地址
291+
spring.redis.host=10.211.55.6
292+
#Redis服务端口
293+
spring.redis.port=6379
294+
#Redis密码
295+
spring.redis.password=
296+
#是否需要SSL
297+
spring.redis.ssl=false
298+
#Redis默认库,一共015
299+
spring.redis.database=0
300+
301+
#设置可分配的最大Redis实例数量
302+
spring.redis.pool.maxTotal=20
303+
#设置最多空闲的Redis实例数量
304+
spring.redis.pool.maxIdle=5
305+
#归还Redis实例时,检查有消息,如果失败,则销毁实例
306+
spring.redis.pool.testOnReturn=true
307+
#当Redis实例处于空闲状态时检查有效性,默认flase
308+
spring.redis.pool.testWhileIdle=true
309+
```
310+
311+
##### 3、Lettuce连接Bean配置LettuceClientConfig
312+
```java
313+
//如果标注了@Configuration,则通过SpringBoot自动扫描注解自动加载,否则需要在入口类中通过@Import手动加载
314+
@Configuration
315+
public class LettuceClientConfig {
316+
317+
//Redis服务器地址
318+
@Value("${spring.redis.host}")
319+
private String host;
320+
321+
//Redis服务端口
322+
@Value("${spring.redis.port}")
323+
private Integer port;
324+
325+
//Redis密码
326+
@Value("${spring.redis.password}")
327+
private String password;
328+
329+
//是否需要SSL
330+
@Value("${spring.redis.ssl}")
331+
private Boolean ssl;
332+
333+
//Redis默认库,一共0〜15
334+
@Value("${spring.redis.database}")
335+
private Integer database;
336+
337+
338+
//Lettuce连接配置(Redis单机版实例)
339+
@Bean(name = "redisClient")
340+
public RedisClient redisClient() {
341+
RedisURI uri = RedisURI.Builder.redis(this.host, this.port)
342+
.withDatabase(this.database)
343+
.build();
344+
return RedisClient.create(uri);
345+
}
346+
347+
}
348+
```
349+
350+
##### 4、配置Lettuce连接池LettucePoolConfig
351+
```java
352+
@Component
353+
public class LettucePoolConfig {
354+
355+
@Resource
356+
RedisClient redisClient;
357+
358+
//设置可分配的最大Redis实例数量
359+
@Value("${spring.redis.pool.maxTotal}")
360+
private Integer maxTotal;
361+
362+
//设置最多空闲的Redis实例数量
363+
@Value("${spring.redis.pool.maxIdle}")
364+
private Integer maxIdle;
365+
366+
//归还Redis实例时,检查有消息,如果失败,则销毁实例
367+
@Value("${spring.redis.pool.testOnReturn}")
368+
private Boolean testOnReturn;
369+
370+
//当Redis实例处于空闲壮体啊时检查有效性,默认flase
371+
@Value("${spring.redis.pool.testWhileIdle}")
372+
private Boolean testWhileIdle;
373+
374+
//Apache-Common-Pool是一个对象池,用于缓存Redis连接,
375+
//因为Letture本身基于Netty的异步驱动,但基于Servlet模型的同步访问时,连接池是必要的
376+
//连接池可以很好的复用连接,减少重复的IO消耗与RedisURI创建实例的性能消耗
377+
@Getter
378+
GenericObjectPool<StatefulRedisConnection<String, String>> redisConnectionPool;
379+
380+
//Servlet初始化时先初始化Lettuce连接池
381+
@PostConstruct
382+
private void init() {
383+
GenericObjectPoolConfig<StatefulRedisConnection<String, String>> redisPoolConfig
384+
= new GenericObjectPoolConfig<>();
385+
redisPoolConfig.setMaxIdle(this.maxIdle);
386+
redisPoolConfig.setMinIdle(0);
387+
redisPoolConfig.setMaxTotal(this.maxTotal);
388+
redisPoolConfig.setTestOnReturn(this.testOnReturn);
389+
redisPoolConfig.setTestWhileIdle(this.testWhileIdle);
390+
redisPoolConfig.setMaxWaitMillis(1000);
391+
this.redisConnectionPool =
392+
ConnectionPoolSupport.createGenericObjectPool(() -> redisClient.connect(), redisPoolConfig);
393+
}
394+
395+
//Servlet销毁时先销毁Lettuce连接池
396+
@PreDestroy
397+
private void destroy() {
398+
redisConnectionPool.close();
399+
redisClient.shutdown();
400+
}
401+
}
402+
```
403+
404+
##### 5、为了简化Redis指令的操作,便于传入回调函数,这里编写一个抽象的方法
405+
```java
406+
@FunctionalInterface
407+
public interface SyncCommandCallback<T> {
408+
409+
//抽象方法,为了简化代码,便于传入回调函数
410+
T doInConnection(RedisCommands<String, String> commands);
411+
}
412+
413+
```
414+
415+
##### 6、编写Lettuce工具类,使用同步的方式获取Redis连接,并分装Redis的get和set操作指令
416+
```java
417+
@Component
418+
@Slf4j
419+
public class LettuceUtil {
420+
421+
@Autowired
422+
LettucePoolConfig lettucePoolConfig;
423+
424+
//编写executeSync方法,在方法中,获取Redis连接,利用Callback操作Redis,最后释放连接,并返回结果
425+
//这里使用的同步的方式执行cmd指令
426+
public <T> T executeSync(SyncCommandCallback<T> callback) {
427+
//这里利用try的语法糖,执行完,自动给释放连接
428+
try (StatefulRedisConnection<String, String> connection = lettucePoolConfig.getRedisConnectionPool().borrowObject()) {
429+
//开启自动提交,如果false,命令会被缓冲,调用flushCommand()方法发出
430+
connection.setAutoFlushCommands(true);
431+
//设置为同步模式
432+
RedisCommands<String, String> commands = connection.sync();
433+
//执行传入的实现类
434+
return callback.doInConnection(commands);
435+
} catch (Exception e) {
436+
log.error(e.getMessage());
437+
throw new RuntimeException(e);
438+
}
439+
}
440+
441+
//分装一个set方法
442+
public String set(final String key, final String val) {
443+
return executeSync(commands -> commands.set(key, val));
444+
}
445+
446+
//分装一个get方法
447+
public String get(final String key) {
448+
return executeSync(commands -> commands.get(key));
449+
}
450+
}
451+
452+
```
453+
454+
##### 7、采用Spring的Servlet进行使用与测试
455+
@RestController
456+
@RequestMapping("/lettuce")
457+
public class LettuceController {
458+
459+
//加载Lettuce工具类
460+
@Autowired
461+
LettuceUtil lettuceUtil;
462+
463+
/**
464+
* 使用Lettuce工具类,调用Redis的Set指令
465+
* http://127.0.0.1:8080/lettuce/set?key=name&val=ipipman
466+
*
467+
* @param key
468+
* @param val
469+
* @return
470+
*/
471+
@GetMapping("/set")
472+
public Object setItem(@RequestParam(name = "key", required = true) String key,
473+
@RequestParam(name = "val", required = true) String val) {
474+
return lettuceUtil.set(key, val);
475+
}
476+
477+
/**
478+
* 使用Lettuce工具类,调用Redis的Get指令
479+
* http://127.0.0.1:8080/lettuce/get?key=name
480+
*
481+
* @param key
482+
* @return
483+
*/
484+
@GetMapping("/get")
485+
public Object getItem(@RequestParam(name = "key", required = true) String key) {
486+
return lettuceUtil.get(key);
487+
}
488+
}

‎springboot-lettuce-sample/src/main/java/com/ipman/springboot/lettuce/sample/utils/LettuceUtil.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ public String get(final String key) {
4949
return executeSync(commands -> commands.get(key));
5050
}
5151
}
52+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /