项目github地址:https://github.com/fotocj007/VertxWebApi

web服务器经典的mysql+redis模式,这里介绍redis的接入。

一:导入gradle

1 compile group: 'io.vertx', name: 'vertx-redis-client', version: '3.9.8'

二:添加配置文件

1 {
2 "sources": [
3 {"connectionString": "redis://:foto_CJ123@10.0.201.215:6379/0", "maxPoolSize":6},
4 {"connectionString": "redis://:foto_CJ123@10.0.201.215:6379/1", "maxPoolSize":6},
5 {"connectionString": "redis://:foto_CJ123@10.0.201.215:6379/2", "maxPoolSize":6},
6 {"connectionString": "redis://:foto_CJ123@10.0.201.215:6379/3", "maxPoolSize":6}
7 ],
8 "poolSize": 8
9 }

三:添加json文件加载 RedisConfig

 1 public class RedisConfig extends JsonObjectConfig {
2 private ArrayList<RedisOptions> sources;
3
4 private int poolSize;
5
6 public RedisConfig(Vertx vertx, String path){
7 super(vertx,path);
8 }
9
10 @Override
11 public void parse(JsonObject jsonObject) {
12 poolSize = jsonObject.getInteger("poolSize");
13 sources = new ArrayList<>();
14 JsonArray sourcesJa = jsonObject.getJsonArray("sources");
15 for (int i = 0; i < sourcesJa.size();i++) {
16 JsonObject jo = sourcesJa.getJsonObject(i);
17
18 RedisOptions redisOpt = new RedisOptions(jo);
19
20 sources.add(redisOpt);
21 }
22 }
23
24 public ArrayList<RedisOptions> getSources() {
25 return sources;
26 }
27
28 public int getPoolSize() {
29 return poolSize;
30 }
31 }

四:添加RedisPool

 1 public class ConsistentHashWithNode {
2 private static final String VIR_NODE_NAME_SEPARATOR = "@VirNode";
3
4 private static final List<String> instanceInfo = new LinkedList<>();
5
6 /**
7 * 初始化虚拟节点 key表示服务器虚拟节点的hash值,value表示服务器虚拟节点的名称
8 */
9 private static final SortedMap<Integer, String> serverHashMap = new TreeMap<>();
10 /**
11 * 设置每台服务器需要的虚拟节点
12 */
13 private static final int VIRTUAL_NODES = 1000;
14
15 /**
16 * 构建hash环
17 * @param servers
18 */
19 public ConsistentHashWithNode(List<String> servers) {
20 //首先本地缓存一份实例信息
21 instanceInfo.addAll(servers);
22 instanceInfo.forEach(instance -> {
23 for (int i = 0; i < VIRTUAL_NODES; i++) {
24 //构建虚拟节点
25 String virNodeName = instance + VIR_NODE_NAME_SEPARATOR + i;
26 serverHashMap.put(hash(virNodeName), virNodeName);
27 }
28 });
29 }
30
31 public static void addNode(String server) {
32 //首先本地缓存一份实例信息
33 instanceInfo.add(server);
34 for (int i = 0; i < VIRTUAL_NODES; i++) {
35 //构建虚拟节点
36 String virNodeName = server + VIR_NODE_NAME_SEPARATOR + i;
37 serverHashMap.put(hash(virNodeName), virNodeName);
38 }
39 }
40
41 /**
42 * 根据数据获取真实存储服务节点
43 * @param data
44 * @return
45 */
46 public static String getServer(String data) {
47 Integer firstKey;
48 SortedMap<Integer, String> subSortedMap = serverHashMap.tailMap(hash(data));
49 if (subSortedMap.isEmpty()){
50 firstKey = serverHashMap.firstKey();
51 }else{
52 firstKey = subSortedMap.firstKey();
53 }
54
55 String virNodeName = serverHashMap.get(firstKey);
56 return virNodeName.substring(0, virNodeName.indexOf(VIR_NODE_NAME_SEPARATOR));
57 }
58
59 /**
60 * FNV1_32_HASH 百度
61 * @param str
62 * @return
63 */
64 public static int hash(String str) {
65 final int p = 16777619;
66 int hash = (int)2166136261L;
67 for (int i = 0; i < str.length(); i++) {
68 hash = (hash ^ str.charAt(i)) * p;
69 }
70 hash += hash << 13;
71 hash ^= hash >> 7;
72 hash += hash << 3;
73 hash ^= hash >> 17;
74 hash += hash << 5;
75 if (hash < 0)
76 hash = Math.abs(hash);
77 return Math.abs(hash);
78 }
79 }
 1 public class RedisPool {
2 private int poolSize;
3
4 private final Vertx vertx;
5
6 private final List<RedisOptions> dataSources;
7
8 private final Map<String,List<RedisAPI>> pools;
9
10 /*************************
11 * Redis连接池参数配置和初始化
12 */
13 public RedisPool(Vertx vertx, RedisConfig redisConfig){
14 this.vertx = vertx;
15 this.poolSize = redisConfig.getPoolSize();
16 this.dataSources = redisConfig.getSources();
17 pools = new HashMap<>();
18 initPool();
19 }
20
21 private void initPool(){
22 for (RedisOptions dataSource : dataSources) {
23 String server = dataSource.getEndpoint();
24
25 List<RedisAPI> list = new ArrayList<>();
26 for (int j = 1; j <= poolSize; j++) {
27 RedisClient client = new RedisClient(vertx,dataSource);
28
29 list.add(RedisAPI.api(client));
30 }
31 pools.put(server, list);
32 ConsistentHashWithNode.addNode(server);
33 }
34 }
35
36 /*************************
37 * 根据下标获取也给链接
38 */
39 public RedisAPI getClientByIndex(int dbId){
40 RedisOptions options = dataSources.get(dbId);
41 String server = options.getEndpoint();
42 return pools.get(server).get(ThreadLocalRandom.current().nextInt(poolSize));
43 }
44
45 /*************************
46 * 根据hashKey获取一个链接
47 */
48 public RedisAPI getClient(String key){
49 String server = ConsistentHashWithNode.getServer(key);
50 return pools.get(server).get(ThreadLocalRandom.current().nextInt(poolSize));
51 }
52
53 /*************************
54 * 关闭连接
55 */
56 public void close(){
57 for(List<RedisAPI> list : pools.values()){
58 for(RedisAPI client : list){
59 client.close();
60 }
61 }
62 }
63 }

五:Redis帮助类

 1 public class RedisUtil {
2 private final Logger logger = LoggerFactory.getLogger(RedisUtil.class);
3
4 private final RedisPool redisPool;
5
6 public RedisUtil(RedisPool redisPool){
7 this.redisPool = redisPool;
8 }
9
10 /**
11 * db = 0
12 * 数据格式 key-value
13 */
14 public void setConfigValue(String rKey, String value,long ex){
15 redisPool.getClientByIndex(0).setex(rKey,String.valueOf(ex),value,res -> {
16 if(!res.succeeded()) {
17 logger.error("setConfigValue key="+rKey,res.cause());
18 }
19 });
20 }
21
22 public void getConfigValue(String rKey, Handler<AsyncResult<Response>> handler){
23 redisPool.getClientByIndex(0).get(rKey,res -> {
24 if(res.succeeded()) {
25 handler.handle(Future.succeededFuture(res.result()));
26 }else {
27 handler.handle(Future.failedFuture(res.cause()));
28 logger.error("getConfigValue key="+rKey,res.cause());
29 }
30 });
31 }
32
33 /**
34 * 分库
35 * 数据格式 key-value
36 */
37 public void setValueStrById(String passportId,String rKey, String value,long ex){
38 redisPool.getClient(passportId).setex(rKey,String.valueOf(ex),value,res -> {
39 if(!res.succeeded()) {
40 logger.error("setPlayerValue key="+rKey,res.cause());
41 }
42 });
43 }
44
45 public void getValueStrById(String passportId,String rKey,Handler<AsyncResult<Response>> handler){
46 redisPool.getClient(passportId).get(rKey,res -> {
47 if(res.succeeded()) {
48 handler.handle(Future.succeededFuture(res.result()));
49 }else {
50 handler.handle(Future.failedFuture(res.cause()));
51 logger.error("getValueStrById key="+rKey,res.cause());
52 }
53 });
54 }
55
56 }

六:初始化,修改Config

 1 public class Configure {
2 private static final Configure ourInstance = new Configure();
3
4 public static Configure getInstance() {
5 return ourInstance;
6 }
7
8 protected Vertx vertx;
9
10 public MysqlConfig mysqlConfig;
11 private MySQLUtil mySQLPool;
12 public DaoManager daoManager;
13
14 private RedisConfig redisConfig;
15 private RedisPool redisPool;
16 public RedisUtil redisUtil;
17
18 public void init(Vertx vertx){
19 this.vertx = vertx;
20
21 initHandler();
22
23 loadConfig();
24
25 initDb();
26 initRedis();
27 }
28
29 private void initHandler(){
30 HandlerManager.getInstance().addHandler(new DemoHandler());
31 }
32
33 /**
34 * 加载db和Redis配置文件
35 */
36 protected void loadConfig(){
37 mysqlConfig = new MysqlConfig(vertx, "res/mysql.json");
38 redisConfig = new RedisConfig(vertx, "res/redis.json");
39 }
40
41 protected void initDb(){
42 List<JsonObject> list = new ArrayList<>();
43 for(int i = 0; i< mysqlConfig.configs.size();i++){
44 list.add(mysqlConfig.configs.getJsonObject(i));
45 }
46 mySQLPool = new MySQLUtil(vertx,2,list);
47
48 daoManager = new DaoManager(mysqlConfig,mySQLPool);
49 }
50
51 /**
52 * 初始化Redis
53 */
54 protected void initRedis(){
55 redisPool = new RedisPool(vertx,redisConfig);
56 redisUtil = new RedisUtil(redisPool);
57 }
58 }

七:测试一下,修改DemoHandler

    PlayerInfo info = new PlayerInfo();
info.setUserName("kkkkkdd");
info.setAge(100); // PlayerDao client = Configure.getInstance().daoManager.getPlayerDao();
// client.saveBaseEntity(info,res -> {
//
// }); String key = "demo_test_key";
Configure.getInstance().redisUtil.setConfigValue(key, JsonObject.mapFrom(info).toString(),300); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} Configure.getInstance().redisUtil.getConfigValue(key,res -> {
System.out.println(res.result().toString()); PlayerInfo rInfo = new JsonObject(res.result().toString()).mapTo(PlayerInfo.class);
System.out.println(rInfo.getUserName());
});

发起请求:

项目结构:

Vertx 接入Redis (八)的更多相关文章

  1. python框架之Django(16)-接入Redis

    准备 安装Redis 参考 Ubuntu 中 Redis 的安装与使用. 在python中使用Redis 参考 python 中使用 Redis . 安装依赖包 在 Django 中接入 Redis ...

  2. Android支付接入(八):Amazon亚马逊支付

    下面跟大家一起走一遍Amazon亚马逊的支付,亚马逊目前刚把业务拓展到大陆市场,但这并不代表Amazon支付不成熟,恰恰相反,Amazon的支付流程,支付结果获取及测试另人称赞,支付流程.测试流程简洁 ...

  3. 高可用Redis(八):Redis主从复制

    1.Redis复制的原理和优化 1.1 Redis单机的问题 1.1.1 机器故障 在一台服务器上部署一个Redis节点,如果机器发生主板损坏,硬盘损坏等问题,不能在短时间修复完成,就不能处理Redi ...

  4. Redis(八):spring data redis 理解

    前言 Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案.我们(官方)提供了一个 "template" ,这是一个高级 ...

  5. Redis——SpringBoot项目使用Lettuce和Jedis接入Redis集群

    Jedis连接Redis: 非线程安全 如果是多线程环境下共用一个Jedis连接池,会产生线程安全问题,可以通过创建多个Jedis实例来解决,但是创建许多socket会影响性能,因此好一点的方法是使用 ...

  6. 《闲扯Redis八》Redis字典的哈希表执行Rehash过程分析

    一.前言 随着操作的不断执行, 哈希表保存的键值对会逐渐地增多或者减少, 为了让哈希表的负载因子(load factor)维持在一个合理的范围之内, 当哈希表保存的键值对数量太多或者太少时, 程序需要 ...

  7. redis支持远程接入的安全防护问题

    如果我们没有启用保护模式,支持远程接入,启用默认端口6379,而且是用root用户启动的,那么基本上redis就是在裸奔了,人家分分钟搞你没商量. 我们模拟一下,现在机器A(ip假设为10.100.1 ...

  8. Redis集群最佳实践

    今天我们来聊一聊Redis集群.先看看集群的特点,我对它的理解是要需要同时满足高可用性以及可扩展性,即任何时候对外的接口都要是基本可用的并具备一定的灾备能力,同时节点的数量能够根据业务量级的大小动态的 ...

  9. thinkphp5使用redis实现秒杀商品活动

    如题,废话少说贴码为上↓ // 初始化redis数据列表 模拟库存50,redis搭建在centos中已开启 public function redisinit(){ $store=50; // 库存 ...

  10. 高可用Redis(九):Redis Sentinel

    1.主从复制高可用的问题 主从复制高可用的作用 1.为master提供备份,当master宕机时,slave有完整的备份数据 2.对master实现分流,实现读写分离 但是主从架构有一个问题 1.如果 ...

随机推荐

  1. JDK8-时间格式化类-时区类-工具类--java进阶day07

    1.时间格式化类:DateTimeFormatter 1.创建方式 使用DateTimeFormatter调用ofPattern方法即可 . 2.格式化方法 创建好DateTimeFormatter对 ...

  2. RESTful的连接时间超时时间设定

    dsResrful的连接方式时,如何设定timeout呢? DSRestConnection.HTTP.ConnectTimeout := 5000; 就这么简单.因为封装的indy的TidHTTP. ...

  3. gRPC+Proto 实现键盘记录器 —— 深度实战解析

    在当今的分布式系统开发领域,RPC(Remote Procedure Call,远程过程调用) 技术犹如一颗璀璨的明星,凭借其强大的透明性和卓越的高性能,在微服务架构中占据着举足轻重的地位.本文将全方 ...

  4. 字符串处理,push pop路径,组合命令,for

    字符串处理字符串截取.命令嵌套命令格式:%变量名:~ m,n%,其中,m表示开始位置(默认开头),n表示从m位置开始向后截取的字符个数(默认到结尾),若n为负数则表示向前截取个数,作用:将命令中的某段 ...

  5. 初学嵌入式是弄linux还是单片机?

    作为一个从机械转行到嵌入式的工程师,我深刻理解初学者面临的困惑.嵌入式领域分支众多,初期选择Linux还是单片机确实是个让人纠结的问题.我当年就在这个问题上纠结了好久,走了不少弯路. 其实,我之所以能 ...

  6. 基于transformer的机器翻译:手把手教你实现

    目录 前言 transformer模型的搭建 Input embedding Encoder Decoder output transformer构建 data数据集处理 train config 参 ...

  7. 使用java代码获取JVM信息

    转载请注明出处: 最近在环境中定位服务问题,由于服务使用的docker部署的,且使用的docker镜像,在启动之后,容器内没有jdk相关的工具[jstat.jmap等等]:于是采用 在项目中使用jav ...

  8. Asp.net core 少走弯路系列教程(一)了解 W3C

    前言 新人学习成本很高,网络上太多的名词和框架,全部学习会浪费大量的时间和精力. 新手缺乏学习内容的辨别能力,本系列文章为新手过滤掉不适合的学习内容(比如多线程等等),让新手少走弯路直通罗马. 作者认 ...

  9. 【代码】Python3|用Python PIL压缩图片至指定大小,并且不自动旋转

    代码主体是GPT帮我写的,我觉得这个功能非常实用. 解决自动旋转问题参考:一行代码解决PIL/OpenCV读取图片出现自动旋转的问题,增加一行代码image = ImageOps.exif_trans ...

  10. Python中strftime()与strptime()的行为与datetime的时间格式码

    前言 datetime在python中的作用不可小视,它可以与string进行相互转化,比如 import datetime # 将输出当前时间的'日/月/年' datetime.datetime.n ...