Vertx 接入Redis (八)

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

 

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

一:导入gradle

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

 

二:添加配置文件

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 }
View Code

 

三:添加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 }
View Code

 

四:添加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 }
View Code
 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 }
View Code

 

五: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 }
View Code

 

六:初始化,修改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 }
View Code

 

七:测试一下,修改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());
        });

发起请求:

 

 

 

 

项目结构:

 

posted @ 2021-07-21 16:13  Joy_CShow  阅读(940)  评论(0编辑  收藏  举报