文档章节

基于GridFS+NGinx构建分布式文件系统 之实战(三)

一枚Sir
 一枚Sir
发布于 2014/06/20 15:21
字数 2722
阅读 4937
收藏 10

基于GridFS构建分布式文件系统 
首先看看什么是GridFS: 
GridFS is a mechanism for storing large binary files in MongoDB. There are several
reasons why you might consider using GridFS for file storage:
• Using GridFS can simplify your stack. If you’re already using MongoDB, GridFS
obviates the need for a separate file storage architecture.
• GridFS will leverage any existing replication or autosharding that you’ve set up for
MongoDB, so getting failover and scale-out for file storage is easy.
• GridFS can alleviate some of the issues that certain filesystems can exhibit when
being used to store user uploads. For example, GridFS does not have issues with
storing large numbers of files in the same directory.
• You can get great disk locality with GridFS, because MongoDB allocates data files
in 2GB chunks.
 
上面这段话摘自《MongoDB权威指南》 
到现在为止你大概知道GridFS能为我们做点什么了,简单点就是可以帮我们存储文件。那么如何将文件存储到GridFS中呢? 
你确保已经安装了MongoDB,如何安装配置请参考《MongoDB权威指南》APPENDIX A 部分,这里就不多说了。 
下面以java为例子,看看如何实现。下载mongo-java-driver驱动包。 

File uploadfile = new File("C://Users/bdjb0201/Desktop/default.jpg"); //待上传的文件
  DB db = mongoTemplate.getDb();//获得db
  GridFS gridFS = new GridFS(db, "FSimgs");
  GridFSInputFile file;
  try {
   file = gridFS.createFile(uploadfile);
   file.setFilename(uploadfile.getName());
   file.save();//保存
   //下面用来查询
   List<GridFSDBFile> list = gridFS.find(uploadfile.getName());
   for (GridFSDBFile gridFSDBFile : list) {
    System.out.println(gridFSDBFile.getUploadDate());//输出上传时间
   }
  } catch (IOException e) {
   e.printStackTrace();
  }

    
上面的短短几行代码就实现了文件的上传,以及查看功能。 
看起来很方便,但是在大多数的应用中,应用服务器只负责处理动态请求,静态资源一般由专门的web服务器去处理(apache、nginx等)。 

那么很多情况就像下面图中描述的一样:

    

现在应用服务器将文件写入到MongoDB中已经完成,接下来就是如何让web服务器(图中NG)可以直接访问那个被存入GridFS的文件就可以 了。在github上有个项目nginx-gridfs就是干这个事情的,项目首页(https://github.com/mdirolf /nginx-gridfs),上面详细讲解了如何安装配置nginx-gridfs。

下面是我的安装笔记:

//确保你已经安装了mongodb和git工具  

 // 下载nginx-gridfs

    cd/opt
    git clonegit://github.com/mdirolf/nginx-gridfs.git
    cdnginx-gridfs
    gitsubmodule init
    gitsubmodule update

 //安装 nginx
    tar -zxvfnginx-xxx.tar.gz
    cdnginx-xxx
    ./configure--add-module=/opt/nginx-gridfs/
     make

     make install

     注【/opt/nginx-gridfs/ 为nginx-gridfs下载目录】

//配置nginx

    在nginx.conf中server加入:
       location /gridfs/ {
          gridfs my_app field=filename type=string;
       }

    注【my_app 为mongodb存储文件的数据库名字】

    //启用nginx 
//打开浏览器输入要访问的图片:http://192.168.1.109:28118/gridfs/6b6e567cjw1dmea3323e1j.jpg。 你看到了之前上传的文件

 

***************************一下是下载jar包的实战**********************

 

Mongodb GridFS图片文件存储解决方案

    之前解决方案是接收图片数据后,将图片直接存储到盘阵,然后通过Apache做服务器,将图片信息存储到数据库,并且存储一个Apache的访问路径。

    目前需要后台服务存储图片,将图片存储到MongoDB集群中,然后通过Nginx中的nginx-gridfs模块进行访问,在浏览器中通过url访问,效果与Apache访问本地文件一样。

一、安装MongoDB(参照:Linux 安装mongoDB 2.2.7http://my.oschina.net/MrMichael/blog/266501

二、安装nginx-gridfs 

    (1)下载nginx-gridfs插件

      网上有传出使用git安装此插件的,这个比较麻烦,我在文章的附件中留了下载包。本人测试可用。

      下载后还要下载mongo的c语言驱动包,这个也可以在附件中下载。

      下载完成后进行解压:tar -zxf nginx-gridfs.tar.gz

                                         tar -zxf mongo-c-driver-0.94.2.tar.gz

[root@bdjb-0197 opt]# tar -zxf nginx-gridfs.tar.gz 
[root@bdjb-0197 opt]# tar -zxf mongo-c-driver-0.94.2.tar.gz

    解压完成后将驱动包内容全部拷贝到nginx-gridfs目录下的mongo-c-driver目录中:

 [root@bdjb-0197 opt]# mv mongo-c-driver-0.94.2/*  nginx-gridfs/mongo-c-driver/

     如果有提示已经存在src目录,没有关系,忽略。然后就是下载Nginx,编译安装的过程了。

mv:是否覆盖"nginx-gridfs/mongo-c-driver/src"? y
mv: 无法将"mongo-c-driver-0.94.2/src" 移动至"nginx-gridfs/mongo-c-driver/src": 目录非空

 三、安装NGinx

    有人说:“Nginx版本太高对支持nginx-gridfs模块不是很成功,使用的Nginx1.7弄了一天都出不来图片。换成1.0.1就好了。”但是我用的是1.5.1是可以的。

    下载:nginx-1.5.1.tar.gz  和  pcre-8.32.tar.gz

     1 . 安装 pcre 让nginx支持rewrite

            pcre-8.32.tar.gz上传到/opt 目录下面

            1) 解压 pcre

   tar -zxf pcre-8.32.tar.gz//解压 pcre 后 /opt下面会有 pcre-8.32 文件夹

             2)配置pcre

 cd /opt/pcre-8.32

             3)make

./configure

#./configure
#make

            命令后屏幕会生成一堆文件,不用去管它

             4)安装

              在linux 中输入

 make install

        2.安装 nginx

             nginx-1.5.1.tar.gz上传到/opt 目录下面

             1) 解压 nginx

               tar zxvf    nginx-1.5.1.tar.gz  解压 nginx 后 /opt 下面会有nginx-1.5.1 文件夹

              2 配置nginx

               cd   nginx-1.5.1

> ./configure --prefix=/usr/local/nginx --with-openssl=/usr/include/openssl --with-http_stub_status_module --add-module=/opt/nginx-gridfs

    ./configure --prefix=/usr/local/nginx --with-http_stub_status_module

              3)make

                在linux 中输入 make 命令后屏幕会生成一堆文件,不用去管它

             4)安装 make install

               在linux 中输入 make install

             5) 检查是否安装成功

        >cd  /usr/local/nginx/sbin
        >./nginx -t

                 可能出错:sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

解决方法(直接运行):
32位系统 [root@sever lib]# ln -s /usr/local/lib/libpcre.so.1 /lib
64位系统 [root@sever lib]# ln -s /usr/local/lib/libpcre.so.1 /lib64
 
然后执行ps -ef | grep nginx 查看nginx进程确认是否真的已经启动了,在进程列表里会有最起码两个, worker(nginx工作进程)和master(nginx主进程)
 
root 4349 1 0 02:24 ? 00:00:00 nginx: master process sbin/nginx -c conf/nginx.conf
nginx 4350 4349 0 02:24 ? 00:00:00 nginx: worker process 
root 4356 28335 0 02:30 pts/1 00:00:00 grep nginx
NGINX 就 OK了

  

       6)启动nginx 

          cd  /usr/local/nginx/sbin 目录下面 输入

./nginx   //启动 nginx

       7 )检查是否启动成功

          ie 浏览器中输入 http://192.168.15.132

     

         出现nginx 欢迎界面说明启动成功

说明:nginx 默认配置端口是80.配置文件主要是conf 文件夹中的nginx.conf  文件

        8)停止nginx

               pkill -9 nginx

 

四、配置GridFS+NGinx

        

配置mogon-gridfs地址:

      在vim /usr/local/nginx/conf/nginx.conf配置文件中,增加下面的内容:

        location /pics/ {
                gridfs rms
                field=filename
                type=string;
                mongo 127.0.0.1:27017;
        }

      

     gridfs:nginx识别插件的名字

     rms:数据库名称

     [root_collection]: 选择collection,如root_collection=blog, mongod就会去找blog.files与blog.chunks两个块,默认是fs

     [field]:查询字段,保证mongdb里有这个字段名,支持_id, filename, 可省略, 默认是_id

     [type]:解释field的数据类型,支持objectid, int, string, 可省略, 默认是int

     [user]:用户名, 可省略

     [pass]:密码, 可省略    

     mongo:mongodb url mongo名称 地址:端口

具体shell如:

        #access_log  logs/host.access.log  main;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /pics/ {
                gridfs rms
                field=filename
                type=string;
                mongo 127.0.0.1:27017;
        }
        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html

      启动:/usr/local/nginx/sbin/nginx

      查看日志:tail -f /usr/local/nginx/logs/error.log

四、测试开发

      测试例子使用java开发,代码在附件中

    (1)图片写入

     全部的例子在附件中,GridFSTest.rar,例子还需要mongodb的驱动jar包mongo-java-driver-2.9.3.jar 。

                try {
   Mongo mongo = new Mongo("192.168.100.52", 27017);// 创建连接
   DB db = mongo.getDB("pics"); // 选择数据库
   byte[] files = createImage(800, 600, "800 X 600"); // 创建图片
   save(files, "test3.jpg", db); // 存储图片
  } catch (Exception e) {
   e.printStackTrace();
  }

(2)文件获取

        通过代码获取图片就不写了。只写如何在程序中传递文件路径,然后在前端展示。

       存储图片信息时,可以加上ip地址:http://192.168.1.237/pics/default.jpg ,然后前端应用通过给定的URL地址就可以获取图片内容了。

       在浏览器中输入地址可以获得相同的效果。

 

 

    *********************************************NGinx启动、停止***************************************

启动操作:

    命令:

 nginx -c /usr/nginx/conf/nginx.conf

    -c参数指定了要加载的nginx配置文件路径。

停止操作:

    停止操作是通过向nginx进程发送信号(什么是信号请参阅linux文章)来进行的

    步骤1:查询nginx主进程号

 ps -ef | grep nginx

        在进程列表里面找master进程,它的编号就是主进程号了。

    步骤2:发送信号

        从容停止Nginx:

 kill -QUIT 主进程号

        快速停止Nginx:

 kill -TERM 主进程号

         强制停止Nginx:

 pkill -9 nginx

 

另外,若在nginx.conf配置了pid文件存放路径则该文件存放的就是Nginx主进程号,如果没指定则放在nginx的logs目录下。有了pid文件,我们就不用先查询Nginx的主进程号,而直接向Nginx发送信号了,命令如下:

 kill -信号类型 '/usr/nginx/logs/nginx.pid'

 平滑重启

        如果更改了配置就要重启Nginx,要先关闭Nginx再打开?不是的,可以向Nginx发送信号,平滑重启。

平滑重启命令:

 kill -HUP 住进称号或进程号文件路径

 

        注意,修改了配置文件后最好先检查一下修改过的配置文件是否正确,以免重启后Nginx出现错误影响服务器稳定运行。判断Nginx配置是否正确命令如下:

 nginx -t -c /usr/nginx/conf/nginx.conf

         平滑升级

如果服务器正在运行的Nginx要进行升级、添加或删除模块时,我们需要停掉服务器并做相应修改,这样服务器就要在一段时间内停止服务,Nginx可以在不停机的情况下进行各种升级动作而不影响服务器运行。

        步骤1:

如果升级Nginx程序,先用新程序替换旧程序文件,编译安装的话新程序直接编译到Nginx安装目录中。

        步骤2:执行命令

 kill -USR2 旧版程序的主进程号或进程文件名

此时旧的Nginx主进程将会把自己的进程文件改名为.oldbin,然后执行新版Nginx。新旧Nginx会同市运行,共同处理请求。

这时要逐步停止旧版Nginx,输入命令:

 kill -WINCH 旧版主进程号

慢慢旧的工作进程就都会随着任务执行完毕而退出,新版的Nginx的工作进程会逐渐取代旧版工作进程。

 

此时,我们可以决定使用新版还是恢复到旧版。

不重载配置启动新/旧工作进程

kill -HUP 旧/新版主进程号

从容关闭旧/新进程

kill -QUIT 旧/新主进程号

如果此时报错,提示还有进程没有结束就用下面命令先关闭旧/新工作进程,再关闭主进程号:

kill -TERM 旧/新工作进程号

这样下来,如果要恢复到旧版本,只需要上面的几个步骤都是操作新版主进程号,如果要用新版本就上面的几个步骤都操作旧版主进程号就行了。

上面就是Nginx的一些基本的操作,希望以后Nginx能有更好的方法来处理这些操作,最好是Nginx的命令而不是向Nginx进程发送系统信号

         

 

 

 

 

 

 

 

© 著作权归作者所有

共有 人打赏支持
一枚Sir
粉丝 118
博文 209
码字总数 350904
作品 0
朝阳
架构师
私信 提问
加载中

评论(1)

happywuya054
happywuya054
你好,请问下nginx+gridfs能在window下部署吗?
程序猿DD/SpringCloud-Learning

Spring Cloud教程 本项目内容为Spring Cloud教程的程序样例。如您觉得该项目对您有用,欢迎点击右上方的Star按钮,给予支持!! 我的博客:http://blog.didispace.com 我的小密圈(深度交流与...

程序猿DD
2016/11/03
0
0
看过的书籍

疯狂java讲义(讲得比较细,对全面了解jdk有很大帮助) 疯狂android讲义(当时要做android,买了这本书) oracle从入门到精通(系统讲oracle使用) 精通div+css网页样式与布局(程序员在样式方...

rock912
2016/01/21
128
0
开源力量公开课第二十四期-为何Hadoop是分布式大数据处理的未来&如何掌握Hadoop?

详情:http://www.osforce.cn/?p=1216 课程题目:开源力量公开课第二十四期-为何Hadoop是分布式大数据处理的未来&如何掌握Hadoop? 开课时间:2013年07月30日 18:30 - 21:30 现场或线上参课:...

程开源
2013/07/19
186
2
百度、阿里、腾讯、京东、大型互联网分布式架构必备技能

分布式架构 迎接高并发大数据的挑战,从深度到广度完善知识体系,成为下一个互联网高薪人才。 理论结合实战,透彻理解分布式架构及其解决方案。 面向人群 1、工作1-5年需要突破瓶颈; 2、传统...

Java高级架构
2017/12/21
0
0
开源力量公开课第二十四期-为何Hadoop是分布式大数据处理的未来&如何掌握Hadoop?

详情:http://www.osforce.cn/?p=1216 课程题目:开源力量公开课第二十四期-为何Hadoop是分布式大数据处理的未来&如何掌握Hadoop? 开课时间:2013年07月30日 18:30 - 21:30 现场或线上参课:...

程开源
2013/07/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

四、RabbitMQ3.7在CentOS7下的安装

安装依赖 sudo yum install -y gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel autoconf java-1.8.0-openjdk-devel git 创建yum源 vi /etc/yum.repos.d/rabbitmq-erlang.repo [......

XuePeng77
今天
2
0
android 延长Toast的时长

示例:myToast(5000,"hello"); public void myToast(int showTime, String msg) { Toast hello = Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT); new CountDownTimer(......

雨焰
昨天
4
0
浅谈mybatis的日志适配模式

Java开发中经常用到的日志框架有很多,Log4j、Log4j2、slf4j等等,Mybatis定义了一套统一的日志接口供上层使用,并为上述常用的日志框架提供了相应的适配器。有关适配器模式例子可以参考 设计...

算法之名
昨天
13
0
大数据教程(13.6)sqoop使用教程

上一章节,介绍了sqoop数据迁移工具安装以及简单导入实例的相关知识;本篇博客,博主将继续为小伙伴们分享sqoop的使用。 一、sqoop数据导入 (1)、导入关系表到HIVE ./sqoop import --connect...

em_aaron
昨天
3
0
Git cherry-pick 使用总结

应用背景:假设现在有两个分支:dev_01, dev_02. 如果我想把dev_01分支上的某几个commit合并到dev_02分支, 那么怎么办呢? 这就是cherry-pick的工作了。cherry-pick会捡选某些commit, 即把某...

天王盖地虎626
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部