zoukankan      html  css  js  c++  java
  • Servlet 3.0笔记之Redis操作示范Retwis JAVA版

    最近学习Redis,一个目前风头正劲的KEY-VALUE NOSQL,支持LIST、SET、MAP等格式存储,某些操作竟然是原子级别,比如incr命令,相当惊艳。官方提供的一个Retwis(simple clone of Twitter)示范,证明了完全可以使用redis替代SQL数据库存储数据,真是一大开创性创新,挑战人们的传统思维模式,为之惊叹!

    不过那是一个PHP版本,我下载到本地PHP但无法部署成功;还好有一个Retwis-RB示范,还提供一个在线版,试用之后,再下载源代码,RUBY + Sinatra MVC结构,看的流口水,代码那般简洁。

    为体验Redis,同时也为对比Ruby代码,因此诞生了Retwis-JAVA,Retwis-RB的山寨版,因此其逻辑和HTML资源一致,再次表示对原作者Dan Lucraft的感谢。

    Retwis-JAVA,基于Servlet 3.0 + UrlRewrite + Freemarker + Jedis。示范运行在Tomcat 7中,redis为最新的2.22版本,jedis为redis的java客户端操作框架。在Servlet 3.0规范中,对Url映射处理依然没有进步,因此只能使用UrlRewrite框架让部分url看起来友好一些。另外,项目没有使用IOC容器框架,没有使用MVC框架,代码量稍微多些,代码相对耦合一些。若使用Struts2 + Spring 代码量会少一些。

    对涉及到的redis存储结构,大致如下:


    涉及到的两个对象很简单:


    序列化后以二进制数据保存到redis中:

        private byte[] object2Bytes(V value) {
            
    if (value == null)
                
    return null;

            ByteArrayOutputStream arrayOutputStream 
    = new ByteArrayOutputStream();
            ObjectOutputStream outputStream;
            
    try {
                outputStream 
    = new ObjectOutputStream(arrayOutputStream);

                outputStream.writeObject(value);
            } 
    catch (IOException e) {
                e.printStackTrace();
            } 
    finally {
                
    try {
                    arrayOutputStream.close();
                } 
    catch (IOException e) {
                    e.printStackTrace();
                }
            }

            
    return arrayOutputStream.toByteArray();
        }


        
    public void save(String key, V value) {
            jedis.set(getKey(key), object2Bytes(value));
        }

    获取用户的timeline时,redis的LRANGE命令提供对list类型数据提供分页操作:

        private List<Status> timeline(String targetId, int page) {
            
    if (page < 1)
                page 
    = 1;

            
    int startIndex = (page - 1* 10;
            
    int endIndex = page * 10;

            List
    <String> idList = super.jedis
                    .lrange(targetId, startIndex, endIndex);

            
    if (idList.isEmpty())
                
    return new ArrayList<Status>(0);

            List
    <Status> statusList = new ArrayList<Status>(idList.size());
            
    for (String id : idList) {
                Status status 
    = load(Long.valueOf(id));

                
    if (status == null)
                    
    continue;

                status.setUser(userService.load(status.getUid()));

                statusList.add(status);
            }

            
    return statusList;
        }

    很显然,LRANGE取出了Status对象的ID,然后我们需要再次根据ID获取对应的Status对象二进制数据,然后反序列化:

        public Status load(long id) {
            
    return super.get(getFormatId(id));
        }

        
    private String getFormatId(long id) {
            
    return String.format(STATUS_ID_FORMAT, id);
        }

        
    private static final String STATUS_ID_FORMAT = "status:id:%d";

        
    public V get(String key) {
            
    return byte2Object(jedis.get(getKey(key)));
        }

        @SuppressWarnings(
    "unchecked")
        
    private V byte2Object(byte[] bytes) {
            
    if (bytes == null || bytes.length == 0)
                
    return null;

            
    try {
                ObjectInputStream inputStream;
                inputStream 
    = new ObjectInputStream(new ByteArrayInputStream(bytes));
                Object obj 
    = inputStream.readObject();

                
    return (V) obj;
            } 
    catch (IOException e) {
                e.printStackTrace();
            } 
    catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            
    return null;
        }

    以上使用JDK内置的序列化支持;更多序列化,可参考hessian、google protobuf等序列化框架,后者提供业界更为成熟的跨平台、更为高效的序列化方案。更多代码请参见附件。

    一些总结和思考:

    1. 不仅仅是缓存,替代SQL数据库已完全成为可能,更高效,更经济;虽然只是打开了一扇小的窗户,但说不准以后人们会把大门打开。
    2. 实际环境中,可能最佳方式为SQL + NOSQL配合使用,互相弥补不足;还好,redis指令不算多,可速查,简单易记。
    3. JAVA和RUBY代码相比,有些重

    另:

    在线版,请参考 http://retwisrb.danlucraft.com/。那个谁谁,要运行范例,保证redis运行才行。

    Retwis-JAVA下载

    参考资料:

    Writing a simple Twitter clone with PHP and Redis

    https://github.com/xetorthio/jedis

    http://redis.io/commands

  • 相关阅读:
    Jmeter之http性能测试实战 非GUI模式压测 NON-GUI模式 结果解析TPS——干货(十一)
    UI Recorder 自动化测试 回归原理(九)
    UI Recorder 自动化测试 录制原理(八)
    UI Recorder 自动化测试 整体架构(七)
    UI Recorder 自动化测试 配置项(六)
    UI Recorder 自动化测试 工具栏使用(五)
    UI Recorder 自动化测试 回归测试(四)
    UI Recorder 自动化测试 录制(三)
    UI Recorder 自动化测试工具安装问题疑难杂症解决(二)
    UI Recorder 自动化测试安装教程(一)
  • 原文地址:https://www.cnblogs.com/ooooo/p/2239413.html
Copyright © 2011-2022 走看看