zoukankan      html  css  js  c++  java
  • 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());
            });

    发起请求:

     

    项目结构:

  • 相关阅读:
    ASCII码对照表
    有种美叫做放弃
    OCX和DLL的区别
    江湖经验:喝酒的学问技巧
    TC2.0实现多文件编译
    希尔排序
    CalcOpticalFlowPyrLK的使用(转)
    简单选择排序的实现
    VS2008中解决方案窗口的问题
    用友T3用友通行政单位没有损益类科目,如何做期间损益结转?
  • 原文地址:https://www.cnblogs.com/cj8988/p/15040013.html
Copyright © 2011-2022 走看看