Docker下Jedis體驗

jedis是redis的java版本的客戶端實現,本文經過一些web請求&響應的實例展現了jedis的基本用法;java

開始編碼前咱們先把環境準備好,總共兩個server,對應兩個docker容器:git

  1. redis,採用redis的3.2.8版本,本次實戰用的是redis單機;
  2. tomcat,採用7.0.77-jre8版本,因爲要支持在線部署,因此tomcat鏡像對官方鏡像作了少許定製,詳情請參照《實戰docker,編寫Dockerfile定製tomcat鏡像,實現web應用在線部署》,這裏能夠不用本身動手作,在hub.docker.com下載bolingcavalry/online_deploy_tomcat:0.0.1鏡像便可,爲了支持在線部署,請在本地maven環境的settings.xml中的servers節點內增長一個server節點,內容以下:
<server>
       <id>tomcat7</id>
       <username>bolingcavalry</username>
       <password>bolingcavalrypswd</password>
     </server>

以上只是對環境作個介紹,不須要本身動手去挨個構建,經過一個docker-compose.yml便可搭建成功,docker-compose.yml文件內容以下:程序員

version: '2'
services:
  redis001: 
    image: daocloud.io/library/redis:3.2.8
    restart: always
  tomcat001: 
    image: bolingcavalry/online_deploy_tomcat:0.0.1
    links: 
      - redis001:redishost
    ports: 
      - "8080:8080"
    environment:
      TOMCAT_SERVER_ID: tomcat_server_001
    restart: always

打開控制檯,在docker-compose.yml文件所在目錄下執行如下命令:github

docker-compose up -d

執行完畢後環境就搭建成功了,在瀏覽器輸入"localhost:8080"能夠看到熟悉的tomcat首頁:web

[外鏈圖片轉存中...(img-dXCPA2Gd-1568682376493)]redis

環境OK了,能夠開始編碼了,源代碼的git地址是git@github.com:zq2599/blog_demos.git,裏面有多個工程,本篇用到的工程是redisdemo,以下圖紅框所示:spring

這裏寫圖片描述

這是個maven工程,首先看下maven依賴,pom中的依賴除了jedis,還要加上spring,jstl,common等經常使用庫,以下:docker

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <!-- 表示開發的時候引入,發佈的時候不會加載此包 -->
            <scope>test</scope>
        </dependency>
        <!-- spring核心包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- 導入java ee jar 包 -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <!-- JSTL標籤類 -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- 映入JSON -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <!-- 上傳組件包 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>

        <!-- redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

而後是web.xml中的配置,包括spring mvc配置和擴展配置文件(spring-extends.xml):shell

<!-- Spring的配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-extends.xml</param-value>
    </context-param>

    <!-- 編碼過濾器 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- Spring監聽器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 防止Spring內存溢出監聽器 -->
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>

    <!-- Spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

接下來就是java編碼了,因爲web請求是多線程併發進行的,多個線程會同時使用redis服務,因此咱們使用jedis的鏈接池JedisPool來爲併發請求同時提供jedis服務的實例;api

鏈接池一個就夠了,因此這裏建立了一個單例的類RedisPool,它的功能以下:

實例化一個Jedis資源池對象,也就是JedisPool;
爲業務線程提供獲取Jedis和歸還Jedis的服務;

接下來咱們看一下RedisPool的關鍵代碼,包括實例化,JedisPool建立,獲取Jedis,歸還Jedis四個部分:

RedisPool的實例化:

public static RedisPool getInstance(){
        if(null==instance) {
            synchronized (RedisPool.class){
                if(null==instance){
                    instance = new RedisPool();
                }
            }
        }

        return instance;
    }

下面時資源池的初始化代碼,注意紅框部分的ADDR參數是redis服務器的ip,本例中要鏈接的是docker 容器,因此ADDR的值用的是"redishost",這個和tomcat容器啓動時的link參數中的redis容器的別名一致:

這裏寫圖片描述

下面是getJedis方法,從資源池取出一個Jedis實例給業務線程,因爲jedisPool.getResource方法是線程安全的,因此getJedis()能夠被多個線程同時調用,不用鎖操做:

public Jedis getJedis(){
        try {
            if(null!=jedisPool){
                Jedis jedis = jedisPool.getResource();
                return jedis;
            }else{
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

下面是業務線程用完Jedis實例後,歸還給資源池時調用的方法,注意,本次使用的jedis是2.9.0版本,因此繼續使用jedisPool.returnResource,jedis3.0版本以後就要用新的方法來歸還到資源池了:

public void returnResource(final Jedis jedis){
        if(jedis!=null){
            //jedis.close()取代jedisPool.returnResource(jedis)方法將3.0版本開始
            jedisPool.returnResource(jedis);
        }
    }

寫完了RedisPool,就解決了Jedis的來源問題,接下來咱們看下如何使用Jedis:

本文只是入門學習,因此只展現了部分Jedis服務,經過RedisService接口對外提供,API以下:

/**
     * string操做,常規設置key-value
     * @param key
     * @param value
     */
    void strSet(String key, String value);

    /**
     * string操做,常規經過key獲取value
     * @param key
     * @return
     */
    String setGet(String key);

    /**
     * list操做,尾部追加數據
     * @param key
     * @param value
     */
    void listAppend(String key, String value);

    /**
     * list操做,獲取說有數據
     */
    List<String> listGetAll(String key);

    /**
     * 指定鍵值在redis中是否存在
     * @param key
     * @return
     */
    boolean exists(String key);

具體的實如今RedisServiceImpl中,咱們挑幾個看看:

@Override
    public void strSet(String key, String value) {
        Jedis jedis = borrowJedis();

        if(null!=jedis){
            jedis.set(key, value);
        }

        returnJedis(jedis);
    }

    @Override
    public String setGet(String key) {
        Jedis jedis = borrowJedis();

        if(null!=jedis){
            String value = jedis.get(key);
            returnJedis(jedis);
            return value;
        }

        return null;
    }

    @Override
    public void listAppend(String key, String value) {
        Jedis jedis = borrowJedis();

        if(null!=jedis){
            jedis.rpush(key, value);
            returnJedis(jedis);
        }
    }

    @Override
    public List<String> listGetAll(String key) {
        List<String> list = null;

        Jedis jedis = borrowJedis();

        if(null!=jedis){
            list = jedis.lrange(key, 0, -1);
            returnJedis(jedis);
        }

        return null==list ? new ArrayList() : list;
    }

能夠發現,Jedis提供的api與redis客戶端上的命令是很像的,例如jedis.get,jedis.lrange等等,基本上會操做命令行就能找到對應的api了。

再看看上次的對RedisService的調用場景,本例中用的是spring mvc,因此咱們先看下RedisController:

下面四個方法表明了四個url入口:

@RequestMapping("/simpleset")
    public String simpleset(HttpServletRequest request, Model model) {
        addCommon(model);
        return "simple_set";
    }

    @RequestMapping("/simpleget")
    public String simpleget(HttpServletRequest request, Model model) {
        addCommon(model);
        return "simple_get";
    }

    @RequestMapping("/listappend")
    public String listappend(HttpServletRequest request, Model model) {
        addCommon(model);
        return "list_append";
    }

    @RequestMapping("/listgetall")
    public String listgetall(HttpServletRequest request, Model model) {
        addCommon(model);
        return "list_get_all";
    }

以第一個simpleset爲例,在瀏覽器中輸入http://localhost:8080/redisdemo/simpleset,對應的simpleset方法會被調用,打開simple_get.jsp,以下圖:

這裏寫圖片描述

輸入了key,value,點擊提交後,因爲form中指定了提交地址是strget,因此RedisController的get方法會被調用:

@RequestMapping("/strget")
    public String get(HttpServletRequest request, Model model) {
        String key = request.getParameter("key");

        String rlt;

        //判斷key在redis中是否存在
        if(redisService.exists(key)){
            rlt = "simple_get_success";
            String value = redisService.setGet(key);

            model.addAttribute("value", value);
        }else{
            rlt = "check";
            model.addAttribute("exists", "不存在");
        }

        model.addAttribute("key", key);

        addCommon(model);
        return rlt;
    }

key若是存在,就取出數據,並跳轉到simple_get_success.jsp頁面,不然跳轉到check.jsp頁面,分別展現不一樣的內容。

以上就是jedis基本用法的簡介,詳情請見redisdemo源碼。

另外,部署工程的時候,請使用命令mvn clean package -U -Dmaven.test.skip=true tomcat7:redeploy,就能將工程編譯打包部署到tomcat上去。

歡迎關注個人公衆號:程序員欣宸

在這裏插入圖片描述

相關文章
相關標籤/搜索