软件篇-分布式文件系统(over) - docker方式安装和Java客户端

分布式文件系统

1.简介

通过先前的例子我们发现普通的方式安装及其麻烦,假如我们需要搭建集群,那更加麻烦。所以在安装软件时并不推荐使用常规的方式去安装,而是推荐使用基于Docker方式去安装

2.镜像选择

要想基于Dokcer的方式去安装,那么我们就需要选择合适的镜像。为了更好的安装,我更换了一台计算机,其IP地址为172.16.0.4并安装了docker,搭建了私服。如果不知道安装,可以参考《Docker 使用系列》

  • 搜索镜像

    docker search fastdfs
    
    image-20200430133125682.png

    发现虽然镜像有很多,但是并没有官方所提供的。同时其他的镜像我们也不清楚别人构建的过程。因此我们可以自己制作一个镜像。

3. 制作镜像

3.1 镜像文件解释

我们可以从github来拉取一个制作镜像的Dockerfile.

  • 地址

    https://github.com/gzlj/fastdfs

  • 目录结构

    image-20200430133432204.png
  • 关于文件解释

    image-20200430133731835.png

    所需的软件

  • Dockerfile解释

    #基础镜像
    FROM centos:7
    #作者信息
    MAINTAINER liujun "1747441374@qq.com"
    
    #安装所需的依赖
    RUN yum install -y zlib zlib-devel pcre pcre-devel gcc gcc-c++ openssl openssl-devel libevent libevent-devel perl unzip
    
    #安装 libfastcommon
    #将libfastcommon-1.0.35.zip 复制到 /usr/local/src/ 
    ADD libfastcommon-1.0.35.zip /usr/local/src/
    # 进入到 /usr/local/src 并解压,同时还编译和运行
    RUN cd /usr/local/src \
        && unzip /usr/local/src/libfastcommon-1.0.35.zip \
        && cd libfastcommon-1.0.35 \
        && ./make.sh \
        && ./make.sh install
    
    #安装 fastdfs
    # 将fastdfs-5.11.zip 复制到 /usr/local/src/下
    ADD fastdfs-5.11.zip /usr/local/src/
    # 解压
    RUN cd /usr/local/src/ && unzip fastdfs-5.11.zip
    # 编译安装,同时将配置复制到 /etc/fdfs下
    RUN cd /usr/local/src/fastdfs-5.11 \
    && ./make.sh \
    && ./make.sh install \
    && cp conf/*.conf /etc/fdfs \
    && cd /etc/fdfs/ \
    && rm -rf *.sample
    
    #安装nginx
    #将fastdfs-nginx-module_v1.16.tar.gz 复制 /usr/local/src/
    ADD fastdfs-nginx-module_v1.16.tar.gz /usr/local/src/
    #ADD fastdfs-nginx-module-1.20.zip /usr/local/src/
    #run cd /usr/local/src/ && unzip fastdfs-nginx-module-1.20.zip && ln -s fastdfs-nginx-module-1.20 fastdfs-nginx-module
    
    #将nginx-1.7.8.tar.gz 复制 /usr/local/src/
    ADD nginx-1.7.8.tar.gz /usr/local/src/
    # 添加模块,编译安装nginx
    RUN cd /usr/local/src/ \
        && cd nginx-1.7.8 \
        && ./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/fastdfs-nginx-module/src \
        && make \
        && make install \
        && cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
    # 复制 nginx.conf 到 /usr/local/nginx/conf/
    ADD nginx.conf /usr/local/nginx/conf/
    
    #创建 storage和tracker 存储日志和数据目录
    RUN mkdir -p /export/fastdfs/{storage,tracker}
    # 将脚本复制到 /usr/local/src/
    ADD tracker.sh /usr/local/src/
    ADD storage.sh /usr/local/src/
    
  • nginx.conf解释

    #user  nobody;
    worker_processes  1;
    
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    
    #pid        logs/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
        #access_log  logs/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  65;
    
        #gzip  on;
    
        server {
            # 默认监听 8080,这个在创建容器时可以更换
            listen       8080;
            # 监听域名为本机
            server_name  localhost;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            # 如果发送的请求中,包含group 交给ngx_fastdfs_module 处理
            location ~/group[1-9]/M00 {
                root /export/fastdfs/storage/data;
                ngx_fastdfs_module;
            }
    
            #error_page  404              /404.html;
    
            # redirect server error pages to the static page /50x.html
            #
            # 错误页面
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    
            # proxy the PHP scripts to Apache listening on 127.0.0.1:80
            #
            #location ~ \.php$ {
            #    proxy_pass   http://127.0.0.1;
            #}
    
            # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            #
            #location ~ \.php$ {
            #    root           html;
            #    fastcgi_pass   127.0.0.1:9000;
            #    fastcgi_index  index.php;
            #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            #    include        fastcgi_params;
            #}
    
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            #location ~ /\.ht {
            #    deny  all;
            #}
        }
    
    
        # another virtual host using mix of IP-, name-, and port-based configuration
        #
        #server {
        #    listen       8000;
        #    listen       somename:8080;
        #    server_name  somename  alias  another.alias;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
    
    
        # HTTPS server
        #
        #server {
        #    listen       443 ssl;
        #    server_name  localhost;
    
        #    ssl_certificate      cert.pem;
        #    ssl_certificate_key  cert.key;
    
        #    ssl_session_cache    shared:SSL:1m;
        #    ssl_session_timeout  5m;
    
        #    ssl_ciphers  HIGH:!aNULL:!MD5;
        #    ssl_prefer_server_ciphers  on;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
    
    }
    
    
  • tracker.sh解释

    #!/bin/sh
    if [ ! -f /initialized ]; then {
    touch /initialized
    #TRACKER_PORT 创建容器时需要手动指,如果采用默认的话,可以把这行删掉
    sed -i "s#\(port\).*#\1=$TRACKER_PORT#" /etc/fdfs/tracker.conf
    #TRACKER_BASE_PATH 创建容器时需要手动指定
    sed -i "s#\(base_path\).*#\1=$TRACKER_BASE_PATH#" /etc/fdfs/tracker.conf
    }
    fi
    # 重启 tracker
    /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
    # 展示日志
    tail -f /export/fastdfs/tracker/logs/trackerd.log
    
  • storage.sh 解释

    #!/bin/sh
    if [ ! -f /initialized ]; then {
      touch /initialized
      # STORAGE_PORT 创建容器时需要手动指定,如果采用默认的话,可以把这行删掉
      sed -i "s#\(port\).*#\1=$STORAGE_PORT#" /etc/fdfs/storage.conf
      
      # GROUP_NAME 创建容器时需要手动指定组名,如果采用默认的话,可以把这行删掉
      sed -i "s#\(group_name\).*#\1=$GROUP_NAME#" /etc/fdfs/storage.conf
      
      # STORAGE_BASE_PATH 创建容器时需要手动指定存储日志和数据的目录
      sed -i "s#\(base_path\).*#\1=$STORAGE_BASE_PATH#" /etc/fdfs/storage.conf
      
      # STORAGE_BASE_PATH 创建容器时需要手动指定文件上传的存储目录
      sed -i "s#\(store_path0\).*#\1=$STORAGE_PATH0#" /etc/fdfs/storage.conf
    
      # 创建容器时手动指定tracker_server
      sed -i "s#\(tracker_server\).*##" /etc/fdfs/storage.conf
      
      #HTTP_SERVER_PORT 创建容器时手动指定
      sed -i "s#\(http.server_port\).*#\1=$HTTP_SERVER_PORT#" /etc/fdfs/storage.conf
      
      # STORAGE_BASE_PATH 创建容器时 指定 STORAGE_BASE_PATH 的值是mod_fastdfs.conf存储日志和数据的目录
      sed -i "s#\(base_path\).*#\1=$STORAGE_BASE_PATH#" /etc/fdfs/mod_fastdfs.conf
      
      # STORAGE_PATH0 创建容器时 指定 STORAGE_PATH0文件上传的存储路径
      sed -i "s#\(store_path0\).*#\1=$STORAGE_PATH0#" /etc/fdfs/mod_fastdfs.conf
      
      #  STORAGE_PORT 手动指定端口,想要默认可以直接删掉
      sed -i "s#\(storage_server_port\).*#\1=$STORAGE_PORT#" /etc/fdfs/mod_fastdfs.conf
    
      # 设置 mod_fastdfs 的 tracker_server
      sed -i "s#\(tracker_server\).*##" /etc/fdfs/mod_fastdfs.conf
      
      # GROUP_NAME 设置组名
      sed -i "s#\(group_name\).*#\1=$GROUP_NAME#" /etc/fdfs/mod_fastdfs.conf
      
      # GROUP_COUNT 设置组的数量
      sed -i "s#\(group_count\).*#\1=$GROUP_COUNT#" /etc/fdfs/mod_fastdfs.conf
    
      # 设置 HTTP_SERVER_PORT 端口
      sed -i "s#\(http.server_port\).*#\1=$HTTP_SERVER_PORT#" /etc/fdfs/mod_fastdfs.conf
      
      #设置组名
      sed -i "s#\(url_have_group_name\).*#\1=true#" /etc/fdfs/mod_fastdfs.conf
      
      # 这个非常重要,将HTTP_SERVER_PORT 的值设置为Nginx的监听端口
      sed -i "s#listen       8080#listen       $HTTP_SERVER_PORT#g" /usr/local/nginx/conf/nginx.conf
      for i in $( echo $TRACKER_SERVER | awk -v FS="," '{for(i=1;i<=NF;i++)print $i}'  );do echo "tracker_server=$i" >> /etc/fdfs/storage.conf;done
      for i in $( echo $TRACKER_SERVER | awk -v FS="," '{for(i=1;i<=NF;i++)print $i}'  );do echo "tracker_server=$i" >> /etc/fdfs/mod_fastdfs.conf;done
    
      #add groups 添加组
      i=1
      while(( $i<=$GROUP_COUNT ))
      do
      # 设置组信息
      echo "[group$i]" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组名
      echo "group_name=group$i" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组的端口
      echo "storage_server_port=$STORAGE_PORT" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组的存储路径数量
      echo "store_path_count=1" >> /etc/fdfs/mod_fastdfs.conf
      
      # 设置组的文件存储路径
      echo "store_path0=$STORAGE_PATH0" >> /etc/fdfs/mod_fastdfs.conf
      let "i++"
      done
    }
    fi
    
    cd /etc/fdfs
    touch mime.types
    /usr/local/nginx/sbin/nginx -t
    /usr/local/nginx/sbin/nginx
    
    # 启动storage 
    /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
    
    #展示日志
    tail -f /export/fastdfs/storage/logs/storaged.log
    

3.2 镜像制作

  • 根据上述中的 liujun 给我们提供的制作镜像的文件下载下来,并上传到 计算机上

    image-20200430140508262.png
  • 下载 unzip 并解压

    image-20200430140538812.png
  • 进入解压好的目录下,进行构建

    docker build -t 宿主机Ip:私服端口/fastdfs:5.11 .
    这个格式的镜像可以直接推送到私服,不用起别名
    
    image-20200430142223145.png
    image-20200430142726739.png

镜像构建成功

  • 上传到私服

    docker push 172.16.0.47:5000/fastdfs:5.11
    

    成功后访问私服:

    image-20200430142921025.png

    上传成功。

3.3 创建容器

这里我们创建一个tracker容器和一个storage容器,当然可以创建集群,无非是多创建几个容器。

但是我们在一台宿主机搭建集群意义也不大,如果多台机器的话,都是重复工作。如果有实际需求可以自己动手搭建。可以参考上述文件中的READ ME.md

3.3.1 创建并运行容器

  • 创建并运行容器(tracker)

    docker run -di --name=fdfs_tracker -v /var/fdfs/tracker:/export/fastdfs/tracker  --net=host -e TRACKER_BASE_PATH=/export/fastdfs/tracker  -e TRACKER_PORT=22123 172.16.0.47:5000/fastdfs:5.11 sh /usr/local/src/tracker.sh
    

    -v /var/fdfs/tracker 将track容器存储数据的目录映射到宿主机上

    --net=host 网络模式,映射容器上所有端口

    -e TRACKER_BASE_PATH=/export/fastdfs/tracker 设置tracker容器内存储日志和数据的目录,不要改

    -e TRACKER_PORT=22123 设置track的端口

    sh /usr/local/src/tracker.sh 执行容器里面的脚本

    image-20200430150103063.png
  • 创建并运行容器(storage)

    docker run -di --name=fdfs_storage -v /var/fastdfs/storage:/export/fastdfs/storage --net=host -e STORAGE_PORT=23001 -e STORAGE_BASE_PATH=/export/fastdfs/storage -e STORAGE_PATH0=/export/fastdfs/storage -e TRACKER_SERVER=172.16.0.47:22123 -e GROUP_COUNT=1 -e HTTP_SERVER_PORT=8081  -e GROUP_NAME=group1 172.16.0.47:5000/fastdfs:5.11  sh /usr/local/src/storage.sh
    

    -v /var/fdfs/tracker 将track容器存储数据的目录映射到宿主机上

    --net=host 网络模式,映射容器上所有端口

    -e STORAGE_PORT=23001 设置storage的端口

    -e STORAGE_BASE_PATH=/export/fastdfs/storage 设置 storage容器内存储日志和数据的位置,不要改

    -e STORAGE_PATH0 =/export/fastdfs/storage 设置文件上传的存储路径

    -e TRACKER_SERVER=172.16.0.47:22123 设置tracker_server设置地址

    -e GROUP_COUNT=1 设置组的数量为1

    -e HTTP_SERVER_POR=8081 设置storage的http端口和nginx的监听端口

    -e GROUP_NAME=group1 设置组名

    sh /usr/local/src/storage.sh 执行storage脚本

3.3.2 测试

进入storage容器中,测试是否与tracker进行了连接

docker exec -it fdfs_storage  /bin/bash
image-20200430151716789.png

测试命令

 /usr/bin/fdfs_monitor /etc/fdfs/storage.conf 
image-20200430151824548.png

连接成功。

通过浏览器访问,也可以看到nginx

image-20200430151922551.png

4.Java客户端连接

4.1 简介

FastDFS的作者余庆先生也给我们提供一个java客户端用来连接 FastDFS,但是已经很久不维护了。但是在GitHub上有一款开源的FastDFS客户端。 这个客户端得到了在原来余庆先生提供的客户端基础上进行大量的重构

配置及其简单,支持连接池,支持自动生成缩略图,同时还支持SpringBoot 2.x

地址:https://github.com/tobato/FastDFS_Client

image-20200430152747762.png

4.2 编码

4.2.1 上传普通文件

  • 创建SpringBoot项目并导入依赖(springboot 版本:2.1.13.RELEASE)

    image-20200430153304493.png
<dependency>
     <groupId>com.github.tobato</groupId>
      <artifactId>fastdfs-client</artifactId>
      <version>1.27.2</version>
</dependency>
  • 修改application.yml文件,增加配置

    image-20200430153404158.png
    fdfs:
      connect-timeout: 600
      so-timeout: 1501
      tracker-list: # tracker地址
        - 172.16.0.47:22123
    
  • 增加配置类

    package com.wangzh.fastdfs.config;
    
    import com.github.tobato.fastdfs.FdfsClientConfig;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableMBeanExport;
    import org.springframework.context.annotation.Import;
    import org.springframework.jmx.support.RegistrationPolicy;
    
    @Configuration
    @Import(FdfsClientConfig.class)
    // 解决jmx重复注册问题
    @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
    public class FastDFSClientConfig {
    }
    
    
  • 测试上传普通文件

    package com.wangzh.fastdfs;
    
    import com.github.tobato.fastdfs.domain.fdfs.StorePath;
    import com.github.tobato.fastdfs.service.FastFileStorageClient;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class FastdfsApplicationTests {
    
        /**
         *
         *  注入上传的客户端对象
         */
        @Autowired
        private FastFileStorageClient storageClient;
    
    
    
        @Test
        public void upload() throws FileNotFoundException {
            File file = new File("C:\\Users\\wangzh\\Desktop\\html.pdf");
            /*
             *  第一个参数 为组名,不写 默认group1
             *  第二个参数为文件流
             *  第三个参数为上传文件的大小
             *  第四个参数为 文件后缀名
             * */
            StorePath storePath = storageClient.uploadFile("group1", new FileInputStream(file), file.length(), "pdf");
    
            /*
             * 打印文件名Id 包含组名
             *  执行后的结果为: group1/M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
             *   group1  组名 
             *     M00 代表设置的  storage_path0
                 00/00 存储的具体磁盘目录
             *    rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
             */
            System.out.println(storePath.getFullPath());
    
            /*
            *   打印文件名,不包含组名
            *     执行后的结果为:     M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
            * */
            System.out.println(storePath.getPath());
    
    
        }
    
    
    }
    
    

    访问:

    http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qgcOAbO_rAAi5YaAFEK0182.pdf
    
    image-20200430155108327.png

    文件上传成功。

4.2.2 上传图片

上传图片并自动创建缩略图

  • 增加缩略图配置

    image-20200430155651106.png
    fdfs:
      connect-timeout: 600
      so-timeout: 1501
      tracker-list: # tracker地址
        - 172.16.0.47:22123
      thumb-image:
        width: 70
        height: 70
    
  • 编码

    package com.wangzh.fastdfs;
    
    import com.github.tobato.fastdfs.domain.fdfs.StorePath;
    import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig;
    import com.github.tobato.fastdfs.service.FastFileStorageClient;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class FastdfsApplicationTests {
    
        /**
         *
         *  注入上传的客户端对象
         */
        @Autowired
        private FastFileStorageClient storageClient;
    
    
        /**
         * 注入缩略图配置对象
         */
        @Autowired
       private ThumbImageConfig thumbImageConfig;
    
        @Test
        public void testUpload() throws FileNotFoundException {
            File file = new File("D:\\1_soft\\1.jpg");
            StorePath storePath = storageClient.uploadImageAndCrtThumbImage(new FileInputStream(file), file.length(), "jpg", null);
            System.out.println("带分组路径:" + storePath.getFullPath());
            System.out.println("不带分组路径:" + storePath.getPath());
            System.out.println("获取缩略图路径:" + thumbImageConfig.getThumbImagePath(storePath.getPath()));
    
        }
    
    
    
    }
    
    

    结果:

    带分组路径:group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg
    不带分组路径:M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg
    获取缩略图路径:M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269_70x70.jpg
    

    我们通过浏览器访问一下:

    http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269_70x70.jpg
    
    image-20200430160108928.png
    http://172.16.0.47:8081/group1/M00/00/00/rBAAL16qhXaAbzbAACXrwCHvecY269.jpg
    
    image-20200430160208936.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,784评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,745评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,702评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,229评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,245评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,376评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,798评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,471评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,655评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,485评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,535评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,235评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,793评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,863评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,096评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,654评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,233评论 2 341

推荐阅读更多精彩内容