一起學(xué)習(xí)Redis之在Java中使用

操作系統(tǒng):CentOS-7.8
Redis版本:6.0.5
SpringBoot 2.1.5.RELEASE
Java Version 1.8.0_231

本篇內(nèi)容主要演示在Java代碼中連接和使用Redis疟呐,對Redis不熟悉的朋友可以先看前兩篇《一起學(xué)習(xí)Redis基礎(chǔ)》《一起學(xué)習(xí)Redis高可用》,本篇涉及到的代碼完整版github地址為:https://github.com/telundusiji/dream-hammer/tree/master/module-6

一望侈、使用Redis客戶端

Jedis、Redisson和Lettuce都是比較常用的支持連接Redis的客戶端季二,所以在這里我們主要演示這三種客戶端如何連接不同的redis模式的redis

1.Jedis

Jedis特點(diǎn)

  • 比較經(jīng)典的Redis的Java客戶端撼班,對Redis的命令支持比較全面

  • 比較輕量和簡潔洋只,對其進(jìn)行改造和集成比較方便

  • 不支持異步划乖,方法調(diào)用都是同步的贬养,使用的阻塞IO

  • 客戶端實(shí)例非線程安全,多線程并發(fā)場景下琴庵,需要通過連接池來使用客戶端

  • 早期版本Spring的默認(rèn)客戶端

使用演示

  • pom依賴

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.3</version>
</dependency>

  • Jedis連接單機(jī)單實(shí)例Redis

import redis.clients.jedis.Jedis;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/17
 */
public class SingleInstanceJedis {


    private String host;
    private Integer port;
    private String password;

    /**
     * 連接單機(jī)單實(shí)例的redis
     *
     * @param host     redis主機(jī)地址
     * @param port     redis服務(wù)端口
     * @param password redis認(rèn)證密碼
     */
    public SingleInstanceJedis(String host, Integer port, String password) {
        this.host = host;
        this.port = port;
        this.password = password;
    }

    /**
     * 連接redis
     *
     * @return 一個(gè)Jedis客戶端
     */
    public Jedis connect() {
        Jedis jedis = new Jedis(host, port);
        jedis.auth(password);
        return jedis;
    }

}


  • Jedis連接哨兵模式Redis

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

import java.util.Set;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/17
 */
public class SentinelJedis {

    private JedisSentinelPool jedisSentinelPool;

    /**
     * 連接哨兵模式的redis
     *
     * @param masterName redis的master名稱
     * @param sentinels  哨兵的主機(jī)和端口信息
     * @param password   redis的認(rèn)證密碼
     */
    public SentinelJedis(String masterName, Set<String> sentinels, String password) {
        //根據(jù)redis的信息創(chuàng)建一個(gè)redis哨兵的連接池
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(10);
        config.setMaxIdle(5);
        config.setMinIdle(5);
        jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, config, password);
    }

    /**
     * 從連接池中取出一個(gè)客戶端
     *
     * @return 獲取一個(gè)Jedis客戶端
     */
    public Jedis connect() {
        return jedisSentinelPool.getResource();
    }

    /**
     * 銷毀連接池
     */
    public void close() {
        jedisSentinelPool.close();
        jedisSentinelPool.destroy();
    }
}


  • Jedis連接集群模式Redis

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.Set;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/17
 */
public class ClusterJedis {

    private Set<HostAndPort> redisNodes;
    private String password;
    private GenericObjectPoolConfig config;

    /**
     * 連接redis cluster
     *
     * @param redisNodes 集群中redis節(jié)點(diǎn)信息
     * @param password   redis 密碼
     */
    public ClusterJedis(Set<HostAndPort> redisNodes, String password) {
        this.redisNodes = redisNodes;
        this.password = password;
        config = new GenericObjectPoolConfig();
        config.setMaxTotal(10);
        config.setMaxIdle(5);
        config.setMinIdle(5);
    }

    /**
     * 連接redis cluster
     *
     * @return 一個(gè)redis cluster客戶端
     */
    public JedisCluster connect() {
        JedisCluster jedisCluster = new JedisCluster(redisNodes, 10000, 10000, 3, password, config);
        return jedisCluster;
    }

}


以上三段代碼是使用Jedis連接三種模式下Redis的簡易演示代碼误算,下面再附上測試類代碼

  • 測試類

/**
 * @author 愛做夢的錘子
 * @create 2020/7/17
 */

public class JedisTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(JedisTest.class);
    private static final String TEST_KEY = "jedis";
    private static final String TEST_VALUE = "dream-hammer";

    @Test
    public void singleInstance() {
        SingleInstanceJedis singleInstanceJedis = new SingleInstanceJedis("192.168.56.90", 6379, "123456");
        Jedis jedis = singleInstanceJedis.connect();
        jedis.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("jedis單機(jī)單實(shí)例:{}", jedis.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE, jedis.get(TEST_KEY));
    }

    @Test
    public void sentinel() {
        Set<String> sentinels = new HashSet<>();
        sentinels.add("192.168.56.91:26379");
        sentinels.add("192.168.56.92:26379");
        sentinels.add("192.168.56.93:26379");
        SentinelJedis sentinelJedis = new SentinelJedis("redis-master", sentinels, "123456");
        Jedis jedis = sentinelJedis.connect();
        jedis.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("jedis哨兵模式:{}", jedis.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE, jedis.get(TEST_KEY));
    }

    @Test
    public void cluster() {
        Set<HostAndPort> redisNodes = new HashSet<>();
        redisNodes.add(new HostAndPort("192.168.56.81",6379));
        redisNodes.add(new HostAndPort("192.168.56.82",6379));
        redisNodes.add(new HostAndPort("192.168.56.83",6379));
        redisNodes.add(new HostAndPort("192.168.56.84",6379));
        redisNodes.add(new HostAndPort("192.168.56.85",6379));
        redisNodes.add(new HostAndPort("192.168.56.86",6379));
        ClusterJedis clusterJedis = new ClusterJedis(redisNodes, "123456");
        JedisCluster jedisCluster = clusterJedis.connect();
        jedisCluster.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("jedis集群模式:{}", jedisCluster.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE, jedisCluster.get(TEST_KEY));
    }
}


2.Redisson

Redisson特點(diǎn)

  • 基于Netty實(shí)現(xiàn),使用非阻塞IO迷殿,支持異步儿礼,性能高

  • API是線程安全的,可以操作單個(gè)Redisson連接來完成多種操作

  • 實(shí)現(xiàn)多種分布式和可擴(kuò)展的Java數(shù)據(jù)結(jié)構(gòu)庆寺,例如蚊夫,分布式鎖,分布式集合懦尝,可通過Redis支持延遲隊(duì)列

  • Redisson注重分布式和鎖的相關(guān)功能知纷,所以在基礎(chǔ)功能上較為簡單,不支持Redis的原生命令操作陵霉,比如不支持字符串操作等

使用演示

  • pom依賴

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.5</version>
</dependency>

  • redisson連接單機(jī)單實(shí)例Redis

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/17
 */
public class SingleInstanceRedisson {

    private Config config;

    /**
     * 連接單機(jī)單實(shí)例的redis
     *
     * @param host     redis主機(jī)地址
     * @param port     redis 端口
     * @param password redis密碼
     */
    public SingleInstanceRedisson(String host, Integer port, String password) {
        config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + host + ":" + port)
                .setPassword(password);

    }

    /**
     * 連接redis
     *
     * @return 一個(gè)RedissonClient客戶端
     */
    public RedissonClient connect() {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }
}


  • redisson連接哨兵模式Redis

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/17
 */
public class SentinelRedisson {

    private Config config;

    /**
     * 連接哨兵模式redis
     *
     * @param masterName redis的master名稱
     * @param sentinels  哨兵的連接信息 redis://sentinelHost:sentinelPort
     * @param password   redis密碼
     */
    public SentinelRedisson(String masterName, String[] sentinels, String password) {
        config = new Config();
        config.useSentinelServers()
                .setMasterName(masterName)
                .addSentinelAddress(sentinels)
                .setPassword(password);

    }

    /**
     * 連接redis
     *
     * @return 一個(gè)RedissonClient客戶端
     */
    public RedissonClient connect() {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

}


  • redisson連接集群模式Redis

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/17
 */
public class ClusterRedisson {

    private Config config;

    /**
     * 連接cluster模式的redis
     *
     * @param redisNodes redis集群中節(jié)點(diǎn)信息 redis://nodeHost:nodePort
     * @param password   redis密碼
     */
    public ClusterRedisson(String[] redisNodes, String password) {
        config = new Config();
        config.useClusterServers()
                .addNodeAddress(redisNodes)
                .setPassword(password);

    }

    /**
     * 連接redis
     *
     * @return 一個(gè)RedissonClient客戶端
     */
    public RedissonClient connect() {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

}


以上三段代碼是使用Redisson連接三種模式下Redis的簡易演示代碼琅轧,下面再附上測試類代碼

  • 測試類

/**
 * @author 愛做夢的錘子
 * @create 2020/7/20
 */
public class RedissonTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(RedissonTest.class);
    private static final String TEST_KEY = "redisson";
    private static final long TEST_VALUE = 100L;

    @Test
    public void singleInstance() {
        SingleInstanceRedisson singleInstanceRedisson = new SingleInstanceRedisson("192.168.56.90", 6379, "123456");
        RedissonClient redissonClient = singleInstanceRedisson.connect();
        RAtomicLong atomicLong = redissonClient.getAtomicLong(TEST_KEY);
        atomicLong.set(TEST_VALUE);
        LOGGER.info("redisson單機(jī)單實(shí)例:{}", redissonClient.getAtomicLong(TEST_KEY).get());
        Assert.assertEquals(TEST_VALUE, redissonClient.getAtomicLong(TEST_KEY).get());
    }

    @Test
    public void sentinel() {
        String[] sentinels = new String[]{"redis://192.168.56.91:26379", "redis://192.168.56.92:26379", "redis://192.168.56.93:26379"};
        SentinelRedisson sentinelRedisson = new SentinelRedisson("redis-master", sentinels, "123456");
        RedissonClient redissonClient = sentinelRedisson.connect();
        RAtomicLong atomicLong = redissonClient.getAtomicLong(TEST_KEY);
        atomicLong.set(TEST_VALUE);
        LOGGER.info("redisson哨兵模式:{}", redissonClient.getAtomicLong(TEST_KEY).get());
        Assert.assertEquals(TEST_VALUE, redissonClient.getAtomicLong(TEST_KEY).get());
    }

    @Test
    public void cluster() {
        String[] redisNodes = new String[]{
                "redis://192.168.56.81:6379",
                "redis://192.168.56.82:6379",
                "redis://192.168.56.83:6379",
                "redis://192.168.56.84:6379",
                "redis://192.168.56.85:6379",
                "redis://192.168.56.86:6379"
        };
        ClusterRedisson clusterRedisson = new ClusterRedisson(redisNodes, "123456");
        RedissonClient redissonClient = clusterRedisson.connect();
        RAtomicLong atomicLong = redissonClient.getAtomicLong(TEST_KEY);
        atomicLong.set(TEST_VALUE);
        LOGGER.info("redisson集群模式:{}", redissonClient.getAtomicLong(TEST_KEY).get());
        Assert.assertEquals(TEST_VALUE, redissonClient.getAtomicLong(TEST_KEY).get());
    }
}


3.Lettuce

Lettuce特點(diǎn)

  • Redis高級客戶端,線程安全的踊挠,單個(gè)Lettuce連接可以在多個(gè)線程中操作

  • 基于Netty實(shí)現(xiàn)乍桂,使用非阻塞IO,支持異步

  • 對Redis基礎(chǔ)操作支持全面效床,相對Jedis來說更加高效睹酌,不要考慮太多線程安全問題

  • 相對Redisson來說分布式鎖和分布式數(shù)據(jù)結(jié)構(gòu)等都需要自行實(shí)現(xiàn)

  • Spring現(xiàn)有版本的默認(rèn)redis客戶端

使用演示

  • pom依賴

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.1.6.RELEASE</version>
</dependency>

  • lettuce連接單機(jī)單實(shí)例Redis

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/20
 */
public class SingleInstanceLettuce {

    private RedisURI redisURI;

    /**
     * 使用Lettuce連接單機(jī)單實(shí)例的redis
     * @param host redis的主機(jī)地址
     * @param port redis的端口號
     * @param password redis的密碼
     */
    public SingleInstanceLettuce(String host, Integer port, String password) {
        redisURI = RedisURI.builder()
                .withHost(host)
                .withPort(port)
                .withPassword(password)
                .build();
    }

    /**
     * 連接redis獲取一個(gè)連接
     * @return 一個(gè)redis連接
     */
    public StatefulRedisConnection<String, String> connect() {
        RedisClient redisClient = RedisClient.create(redisURI);
        StatefulRedisConnection<String, String> connect = redisClient.connect();
        return connect;
    }
}


  • lettuce連接哨兵模式redis

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.codec.Utf8StringCodec;
import io.lettuce.core.masterslave.MasterSlave;
import io.lettuce.core.masterslave.StatefulRedisMasterSlaveConnection;

import java.util.List;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/20
 */
public class SentinelLettuce {
    private List<RedisURI> redisURIList;

    /**
     * 連接哨兵模式的redis
     * @param redisURIList 哨兵模式redis下的哨兵的信息,建議使用RedisURI.builder.sentinel填寫哨兵信息來進(jìn)行構(gòu)造
     */
    public SentinelLettuce(List<RedisURI> redisURIList) {
        this.redisURIList = redisURIList;
    }

    /**
     * 連接redis獲取一個(gè)連接
     * @return 一個(gè)redis的連接
     */
    public StatefulRedisMasterSlaveConnection<String, String> connect() {
        RedisClient redisClient = RedisClient.create();
        StatefulRedisMasterSlaveConnection<String, String> connect = MasterSlave.connect(redisClient, new Utf8StringCodec(), redisURIList);
        return connect;
    }
}


  • lettuce連接集群模式Redis

import io.lettuce.core.RedisURI;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;

import java.util.List;

/**
 * @author 愛做夢的錘子
 * @create 2020/7/20
 */
public class ClusterLettuce {

    private List<RedisURI> redisURIList;

    /**
     * 使用Lettuce連接集群模式redis
     * @param redisURIList 集群中redis節(jié)點(diǎn)的信息剩檀,建議使用RedisURI.builder來進(jìn)行構(gòu)造
     */
    public ClusterLettuce(List<RedisURI> redisURIList) {
        this.redisURIList = redisURIList;
    }

    /**
     * 連接redis獲取一個(gè)連接
     * @return 一個(gè)redis的連接
     */
    public StatefulRedisClusterConnection<String, String> connect() {
        RedisClusterClient redisClusterClient = RedisClusterClient.create(redisURIList);
        StatefulRedisClusterConnection<String, String> connect = redisClusterClient.connect();
        return connect;
    }


}

以上三段代碼是使用Lettuce連接三種模式下Redis的簡易演示代碼憋沿,下面再附上測試類代碼

  • 測試類

/**
 * @author 愛做夢的錘子
 * @create 2020/7/20
 */
public class LettuceTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(LettuceTest.class);
    private static final String TEST_KEY = "lettuce";
    private static final String TEST_VALUE = "dream-hammer";

    @Test
    public void SingleInstance(){
        SingleInstanceLettuce singleInstanceLettuce = new SingleInstanceLettuce("192.168.56.90", 6379, "123456");
        StatefulRedisConnection<String, String> connection = singleInstanceLettuce.connect();
        RedisCommands<String, String> commands = connection.sync();
        commands.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("lettuce單機(jī)單實(shí)例:{}",commands.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE,commands.get(TEST_KEY));
    }

    @Test
    public void sentinel(){
        List<RedisURI> redisURIList = new ArrayList<>();
        redisURIList.add(RedisURI.builder().withSentinelMasterId("redis-master").withSentinel("192.168.56.91",26379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withSentinelMasterId("redis-master").withSentinel("192.168.56.92",26379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withSentinelMasterId("redis-master").withSentinel("192.168.56.93",26379).withPassword("123456").build());
        SentinelLettuce sentinelLettuce = new SentinelLettuce(redisURIList);
        StatefulRedisMasterSlaveConnection<String, String> connection = sentinelLettuce.connect();
        RedisCommands<String, String> commands = connection.sync();
        commands.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("lettuce哨兵模式:{}",commands.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE,commands.get(TEST_KEY));
    }

    @Test
    public void cluster(){
        List<RedisURI> redisURIList = new ArrayList<>();
        redisURIList.add(RedisURI.builder().withHost("192.168.56.81").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.82").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.83").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.84").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.85").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.86").withPort(6379).withPassword("123456").build());
        ClusterLettuce clusterLettuce = new ClusterLettuce(redisURIList);
        StatefulRedisClusterConnection<String, String> connection = clusterLettuce.connect();
        RedisAdvancedClusterCommands<String, String> commands = connection.sync();
        commands.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("lettuce集群模式:{}",commands.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE,commands.get(TEST_KEY));
    }

}


二、在SpringBoot中使用Redis

在上一部分我們演示了直接使用不同的redis客戶端連接Redis沪猴,并進(jìn)行簡單操作卤妒,在這一部分,我們將演示一下字币,在SpringBoot如何連接三種模式的redis

  • pom依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

  • 在application.yml文件中配置redis連接信息

# 連接單機(jī)單實(shí)例版的redis配置
spring:
  redis:
    host: 192.168.56.90
    port: 6379
    password: 123456
    database: 0

# 連接哨兵模式的redis配置
spring:
  redis:
    sentinel:
      master: redis-master
      nodes: 192.168.56.91:26379,192.168.56.92:26379,192.168.56.92:26379
    password: 123456
   
# 連接集群模式redis配置
spring:
  redis:
    cluster:
      nodes: 192.168.56.81:6379,192.168.56.82:6379,192.168.56.83:6379,192.168.56.84:6379,192.168.56.85:6379,192.168.56.86:6379
    password: 123456

  • 使用演示代碼

/**
 * @author 愛做夢的錘子
 * @create 2020/7/20
 */
@Service("redisSpring")
public class RedisSpring {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public Object redisTemplateOperate(Object key, Object value) {
        redisTemplate.opsForValue().set(key, value);
        return redisTemplate.opsForValue().get(key);
    }

    public String stringRedisTemplateOperate(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
        return stringRedisTemplate.opsForValue().get(key);
    }

}

  • 測試該功能的代碼

/**
 * @author 愛做夢的錘子
 * @create 2020/7/20
 */
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
@EnableAutoConfiguration
public class SpringTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringTest.class);

    @Autowired
    private RedisSpring redisSpring;

    private static final String TEST_KEY = "spring";
    private static final String TEST_VALUE = "dream-hammer";

    @Test
    public void test() {
        Object value = redisSpring.redisTemplateOperate(TEST_KEY, TEST_VALUE);
        LOGGER.info("redisTemplate:{}",value);
        Assert.assertEquals(value,TEST_VALUE);
        String s = redisSpring.stringRedisTemplateOperate(TEST_KEY, TEST_VALUE);
        LOGGER.info("stringRedisTemplate:{}",s);
        Assert.assertEquals(TEST_VALUE,s);
    }

}

總結(jié)

在本篇中主要是代碼演示则披,演示三種客戶端連接三種模式下的redis的方式,可以幫助大家快速學(xué)習(xí)和使用redis洗出。由于本篇代碼比較多士复,所以代碼錘子也傳到了github地址為:https://github.com/telundusiji/dream-hammer/tree/master/module-6

個(gè)人公眾號【愛做夢的錘子】,全網(wǎng)同id,個(gè)站 http://te-amo.site阱洪,歡迎關(guān)注便贵,里面會分享更多有用知識

覺得不錯就點(diǎn)個(gè)贊叭QAQ

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市冗荸,隨后出現(xiàn)的幾起案子承璃,更是在濱河造成了極大的恐慌,老刑警劉巖蚌本,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盔粹,死亡現(xiàn)場離奇詭異,居然都是意外死亡程癌,警方通過查閱死者的電腦和手機(jī)舷嗡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嵌莉,“玉大人进萄,你說我怎么就攤上這事∪袂停” “怎么了中鼠?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沿癞。 經(jīng)常有香客問我兜蠕,道長,這世上最難降的妖魔是什么抛寝? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮曙旭,結(jié)果婚禮上盗舰,老公的妹妹穿的比我還像新娘。我一直安慰自己桂躏,他們只是感情好钻趋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剂习,像睡著了一般蛮位。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鳞绕,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天失仁,我揣著相機(jī)與錄音,去河邊找鬼们何。 笑死萄焦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拂封,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼茬射,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冒签?” 一聲冷哼從身側(cè)響起在抛,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萧恕,沒想到半個(gè)月后刚梭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡廊鸥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年望浩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惰说。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡磨德,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吆视,到底是詐尸還是另有隱情典挑,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布啦吧,位于F島的核電站您觉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏授滓。R本人自食惡果不足惜琳水,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望般堆。 院中可真熱鬧在孝,春花似錦、人聲如沸淮摔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽和橙。三九已至仔燕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間魔招,已是汗流浹背晰搀。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留办斑,地道東北人厕隧。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吁讨。 傳聞我的和親對象是個(gè)殘疾皇子髓迎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348