1.案例背景

image.png
原有的单机 Redis 已经满足不了系统需求。这时候就需要更换为更为健壮的Redis集群服务,虽然需要修改但是不能影响目前系统的运行,还要平滑过渡过去。
随着这次的升级,可以预见的问题会有;

  1. 很多服务用到了Redis需要一起升级到集群。
  2. 需要兼容集群A和集群B,便于后续的灾备。
  3. 两套集群提供的接口和方法各有差异,需要做适配。
  4. 不能影响到目前正常运行的系统。

    2.实战代码

    接口定义

    ```java public interface CacheService {

    String get(final String key);

    void set(String key, String value);

    void set(String key, String value, long timeout, TimeUnit timeUnit);

    void del(String key);

}

  1. <a name="XD6Jd"></a>
  2. ### 接口单机版实现
  3. ```java
  4. public class CacheServiceImpl implements CacheService {
  5. private RedisUtils redisUtils = new RedisUtils();
  6. public String get(String key) {
  7. return redisUtils.get(key);
  8. }
  9. public void set(String key, String value) {
  10. redisUtils.set(key, value);
  11. }
  12. public void set(String key, String value, long timeout, TimeUnit timeUnit) {
  13. redisUtils.set(key, value, timeout, timeUnit);
  14. }
  15. public void del(String key) {
  16. redisUtils.del(key);
  17. }
  18. }

由于集群A和集群B在部分方法提供上是不同的,因此需要做一个接口适配,用于创建把不同的服务抽象为统一的接口做相同的业务

定义适配接口

public interface ICacheAdapter {

    String get(String key);

    void set(String key, String value);

    void set(String key, String value, long timeout, TimeUnit timeUnit);

    void del(String key);
}

实现集群使用服务

public class EGMCacheAdapter implements ICacheAdapter {

    private EGM egm = new EGM();

    public String get(String key) {
        return egm.gain(key);
    }

    public void set(String key, String value) {
        egm.set(key, value);
    }

    public void set(String key, String value, long timeout, TimeUnit timeUnit) {
        egm.setEx(key, value, timeout, timeUnit);
    }

    public void del(String key) {
        egm.delete(key);
    }
}
public class IIRCacheAdapter implements ICacheAdapter {

    private IIR iir = new IIR();

    public String get(String key) {
        return iir.get(key);
    }

    public void set(String key, String value) {
        iir.set(key, value);
    }

    public void set(String key, String value, long timeout, TimeUnit timeUnit) {
        iir.setExpire(key, value, timeout, timeUnit);
    }

    public void del(String key) {
        iir.del(key);
    }

}

定义抽象工厂类

public interface CacheFactory {

    CacheService singleCache();

    CacheService cluserCacheWithEGM();

    CacheService cluserCacheWithIIR();
}

public class RedisCacheFactory implements CacheFactory {

    public CacheService singleRedis(){
        return new CacheServiceImpl();
    }


    @Override
    public CacheService singleCache() {
        return new CacheServiceImpl();
    }

    @Override
    public CacheService cluserCacheWithEGM() {
        return new EGMCacheAdapter();
    }

    @Override
    public CacheService cluserCacheWithIIR() {
        return new IIRCacheAdapter();
    }
}

测试

public class ApiTest {

    @Test
    public void test_CacheService() throws Exception {
        CacheFactory redisCacheFactory = new RedisCacheFactory();

        CacheService proxy_EGM = redisCacheFactory.cluserCacheWithEGM();
        proxy_EGM.set("user_name_01", "小傅哥");
        String val01 = proxy_EGM.get("user_name_01");
        System.out.println("测试结果:" + val01);

        CacheService proxy_IIR = redisCacheFactory.cluserCacheWithIIR();
        proxy_IIR.set("user_name_01", "小傅哥");
        String val02 = proxy_IIR.get("user_name_01");
        System.out.println("测试结果:" + val02);
    }
}