書く時間:2019年12月1日
春ブーツ:2.1、JDK 1.8、IDE:のIntelliJ IDEA
1.説明
リアクティブプログラミング動作Redis
、Lettuce
サポートするReactive
モード。
春データRedisのメインのサポート:
ReactiveRedisConnection
ReactiveRedisConnectionFactory
ReactiveRedisTemplate
opsForXxx()
:コンセプト反応性のプログラミングは、を参照してください
第三十ピアン:SpringBoot原子炉は、反応性のプログラミングが導入
SpringBoot原子炉の反応プログラミング本物1:30 Yipianを。
2.ドッカー開始のRedis
履歴の表示Redisのプロセスに始めます
% docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8eb8d32453bb redis "docker-entrypoint.s…" 2 months ago Up 19 minutes 0.0.0.0:6379->6379/tcp redis
スタートRedisのプロセス
% docker start redis
redis
Redisのクライアントは現在空で、すべてのキーを見始めます。
% docker exec -it redis redis-cli
127.0.0.1:6379> keys *
(empty list or set)
:詳細な説明を参照することができ
最初Niansan記事:のSpringBootドッカーエントリ
Redisのドッカーエントリ:第三十二章を
3.プロジェクト設立
参考チュートリアル[SpringBoot 2.1 |ファースト:SpringBootプロジェクトの建設]ディレクトリに、rpcclientのと呼ばれる新しい春のブートプロジェクトを作成するには、src/main/java/resources
コンフィギュレーション・ファイルを見つけるために、application.properties
名前を変更し、application.yml
。
バージョン2.1.10が選ぶ春ブーツ>はロンボク。チェックツール開発者に依存
SQL>データ春JDBC、H2データベース
のNoSQL>反応性春データのRedisを
4. application.ymlプロフィール
spring:
redis:
host: "localhost"
テーブルと初期化データ・データベースの構築
ではapplication.yml
、同じディレクトリ、ファイルを作成しますschema.sql
drop table t_coffee if exists;
create table t_coffee (
id bigint auto_increment,
create_time timestamp,
update_time timestamp,
name varchar(255),
price bigint,
primary key (id)
);
ではapplication.yml
、同じディレクトリ、ファイルを作成しますdata.sql
insert into t_coffee (name, price, create_time, update_time) values ('espresso', 2000, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('latte', 2500, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('capuccino', 2500, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('mocha', 3000, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('macchiato', 3000, now(), now());
モデルの作成6
com.zgpeace.reactive.Coffee
package com.zgpeace.reactive;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Coffee {
private Long id;
private String name;
private Long price;
}
7.コントローラ
package com.zgpeace.reactive;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
import org.springframework.data.redis.core.ReactiveHashOperations;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@SpringBootApplication
@Slf4j
public class ReactiveApplication implements ApplicationRunner {
private static final String KEY = "COFFEE_MENU";
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private ReactiveStringRedisTemplate redisTemplate;
public static void main(String[] args) {
SpringApplication.run(ReactiveApplication.class, args);
}
@Bean
ReactiveStringRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) {
return new ReactiveStringRedisTemplate(factory);
}
@Override
public void run(ApplicationArguments args) throws Exception {
ReactiveHashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
CountDownLatch cdl = new CountDownLatch(1);
List<Coffee> list = jdbcTemplate.query(
"select * from t_coffee", (rs, i) ->
Coffee.builder()
.id(rs.getLong("id"))
.name(rs.getString("name"))
.price(rs.getLong("price"))
.build()
);
Flux.fromIterable(list)
.publishOn(Schedulers.single())
.doOnComplete(() -> log.info("list ok"))
.flatMap(c -> {
log.info("try to put {},{}", c.getName(), c.getPrice());
return hashOps.put(KEY, c.getName(), c.getPrice().toString());
})
.doOnComplete(() -> log.info("set ok"))
.concatWith(redisTemplate.expire(KEY, Duration.ofMinutes(1)))
.doOnComplete(() -> log.info("expire ok"))
.onErrorResume(e -> {
log.error("exception {}", e.getMessage());
return Mono.just(false);
})
.subscribe(b -> log.info("Boolean: {}", b),
e -> log.error("Exception {}", e.getMessage()),
() -> cdl.countDown());
log.info("Waiting");
cdl.await();
}
}
解像度:
jdbcTemplate.query
クエリデータベース内のデータ、およびリストに組み立てFlux.fromIterable(list)
リストをトラバースpublishOn(Schedulers.single())
シングルスレッドでPublisher
実行flatMap
堆積物の配列redis
concatWith(redisTemplate.expire(KEY, Duration.ofMinutes(1)))
Redisのデータセットの有効期限は1分です。CountDownLatch
一つだけのスレッドタスキングが可能、同期ロックを通します。
次のように結果を出力
Bootstrapping Spring Data repositories in DEFAULT mode.
[ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 1ms. Found 0 repository interfaces.
[ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
[ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
[ main] c.zgpeace.reactive.ReactiveApplication : Started ReactiveApplication in 1.279 seconds (JVM running for 1.779)
[ main] c.zgpeace.reactive.ReactiveApplication : Waiting
[ single-1] c.zgpeace.reactive.ReactiveApplication : try to put espresso,2000
[ single-1] io.lettuce.core.EpollProvider : Starting without optional epoll library
[ single-1] io.lettuce.core.KqueueProvider : Starting without optional kqueue library
[ single-1] c.zgpeace.reactive.ReactiveApplication : try to put latte,2500
[ single-1] c.zgpeace.reactive.ReactiveApplication : try to put capuccino,2500
[ single-1] c.zgpeace.reactive.ReactiveApplication : try to put mocha,3000
[ single-1] c.zgpeace.reactive.ReactiveApplication : try to put macchiato,3000
[ single-1] c.zgpeace.reactive.ReactiveApplication : list ok
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : Boolean: true
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : Boolean: true
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : Boolean: true
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : Boolean: true
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : Boolean: true
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : set ok
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : Boolean: true
[ioEventLoop-4-1] c.zgpeace.reactive.ReactiveApplication : expire ok
[ Thread-5] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
[ Thread-5] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Redisのデータを確認してください8。
ターミナルで表示Redisのデータ
127.0.0.1:6379> keys *
1) "COFFEE_MENU"
127.0.0.1:6379> hgetall COFFEE_MENU
1) "espresso"
2) "2000"
3) "latte"
4) "2500"
5) "capuccino"
6) "2500"
7) "mocha"
8) "3000"
9) "macchiato"
10) "3000"
9.ダウンロード
https://github.com/zgpeace/Spring-Boot2.1/tree/master/reactor/ReactiveRedisDemo
10.参考文献
https://github.com/geektime-geekbang/geektime-spring-family