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());
});
发起请求:
项目结构: