TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html. h% }& u$ O( W+ W2 f' j
! q5 l8 P! A( P- Z一、项目需求9 T/ v" o$ S8 U# B# F4 {9 H* G
在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
: y( p1 O) w5 F5 c8 F3 {# L
. O- K" N. G/ y( J9 T% n
1 Y9 W* _: a, U. a二、文件服务解决方案9 h: ~ Q& B2 E8 G( \0 M
1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。
( c0 N" N, `: F* w, Q3 ?
0 M7 Z {; R. V$ ?8 H+ {1 t
2 `4 \- u: b% u3 S6 D9 J- |0 C配置详见:http://www.52itstyle.top/thread-10764-1-1.html! d/ n5 w! r$ w5 y; W
! v% b% ^( N( d/ r8 z" @8 h: ~* R6 O/ @/ v. p& B$ t9 @
2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。0 A% v m9 v: L, @1 F+ k
+ x" b- U( e. J, d
1 x# N; @0 j- R K9 \配置详见:http://www.52itstyle.top/thread-17263-1-1.html
; ^# p4 s$ c3 k) W f
2 n3 W0 h* ~* k! q4 i' b! R S8 ]8 f' c% [" y
3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
$ w, O4 i: D( g# t# i7 n' r. \! y3 x$ Y8 g- I5 _" k' x3 q
! O: S8 M: S+ q/ Q5 b4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。% c& N: p/ X( N9 W# z. }, B
: O* u0 g# R5 }) W0 ~2 Q
; @6 S) a$ d) r9 m1 l, N% ?5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
% ^! @9 _5 i2 n+ ?; Z6 Z
/ [1 m3 ]& P9 P' J) d5 U: n) ~, Z: h% a4 f5 q
这里主要简单实现第三种方案(使用语言JAVA):) _, r/ O0 g3 y
9 P0 d0 q$ R; g/ q E1 J' ~6 n4 D2 J( n, q' Z1 `
新建客户端 用于上传
3 {6 T/ Q7 m0 D& d5 |HttpPostClient:
" k9 y" g$ t$ E+ i" I9 m: A- package com.itstyle.web;
. d5 p6 m: {6 J' x - ' a% O9 @# M _3 z
- import java.io.File;
8 [( W+ w5 l4 R) i* p/ n9 l& ` - import java.io.IOException;. i& Z0 Q! y/ d& J( M
- 4 F [* m8 v0 f3 ] p0 r
- import org.apache.http.HttpEntity;( }$ e2 l+ |6 X B+ e
- import org.apache.http.HttpResponse;+ `1 e0 t. C+ _2 y& X- H% H$ X- n S
- import org.apache.http.HttpStatus;
; ^" A Z9 ?7 {+ [1 | - import org.apache.http.ParseException;. v( i* i% T& S+ }: N1 @. V+ F
- import org.apache.http.client.HttpClient;
o; t* v5 `9 _- H - import org.apache.http.client.methods.HttpPost;
+ x2 k5 ?; U6 L, ` - import org.apache.http.entity.mime.MultipartEntity;
$ P8 Q$ K4 f8 A. p7 ]0 ^" B - import org.apache.http.entity.mime.content.FileBody;, t0 R/ f9 T7 `6 A* T/ D
- import org.apache.http.entity.mime.content.StringBody;
( q$ }" p' _' H! c0 y, r - import org.apache.http.impl.client.DefaultHttpClient;
; I; R4 v- B( c5 F! h - import org.apache.http.util.EntityUtils;
- g7 G1 D* l6 q# d0 Q6 |# ~" U - /**
% ~0 P/ b" @& p4 ^" N4 e - * 客服端
. z9 h% ^7 y! p- t: h' o, x& y$ R/ r. q5 } - * 创建者 张志朋
+ U% l) q7 g& @& k - * 创建时间 2016年4月14日
6 Q } a+ P8 N t5 t/ l2 l, n - * 科帮网 http://www.52itstyle.top
, R) q7 g0 z: ^/ s$ Y+ t - *: j4 r) E# b! k
- */5 Z( U" o( R" }2 o: W
- public class HttpPostClient {
) N5 H7 t! g! j- l: s - public void SubmitPost(String url, String filename, String filepath) {" N/ p4 {( O7 @; c9 }! c6 H' i
- 4 ?( `" v1 U" H) f* [2 e1 d
- HttpClient httpclient = new DefaultHttpClient();' h$ b7 p& K8 N
- 6 H- V) d5 |7 f" K* [( K2 X
- try {3 t, m l" V0 E- R/ k2 T' Y1 a
4 H# l. O! ]9 W) r- }: n" Q6 E$ T9 @- HttpPost httppost = new HttpPost(url);" k, Q: X- b" ?$ a+ R( p8 N
& P2 C, @4 [0 n6 B8 y+ T9 c- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
( L, Q) y# E8 L1 }& p- Q - : N# K6 `" g# I# P# x3 L
- StringBody comment = new StringBody(filename);
2 C+ f) A( V/ [3 @
3 H5 T1 O" m' `( E6 r+ E! }- MultipartEntity reqEntity = new MultipartEntity();
I# u9 b5 D; L - reqEntity.addPart("file", bin);// file为请求后台的File upload;属性1 q8 k2 U8 K4 J; q: C8 O
- reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性5 p4 S% b, W& `
- httppost.setEntity(reqEntity);
+ i0 l2 V: F! Q! ]9 t; v - & p8 K6 c* m# K' p4 J7 q! P2 J
- HttpResponse response = httpclient.execute(httppost);
2 @3 d& V& H! {! ~- a6 z2 U. ~8 e9 [
! }6 Z$ H- S6 g C8 R* T- int statusCode = response.getStatusLine().getStatusCode();
; {8 U$ _& i4 ~+ ~* T$ h
% s6 f! Y& m Q* |4 [' H/ P+ n. P9 M- if (statusCode == HttpStatus.SC_OK) {4 p/ u# L* a3 N! {% V( t6 G
- $ ]" N- b- u3 p$ H
- System.out.println("服务器正常响应.....");
+ p7 }9 k0 n) _# \% n( q$ d! ]8 N - ) _. p& ~( |, s! N! [! d3 c
- HttpEntity resEntity = response.getEntity();. f# L4 ^& @0 v, j( k0 f$ Y
, y. [ E0 r! h6 P1 P. A- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据1 q; P9 _* |+ W1 k) k9 J+ @
4 V% b0 x9 s1 V, L- System.out.println(resEntity.getContent());
8 Y: d \, s9 B5 I - 1 J1 K V+ P7 @! p- h
- EntityUtils.consume(resEntity);
4 ?' k6 x; k6 O) N' } - }
/ Q' |8 w/ v6 p4 \& }) t. N - # ^) l, q& ^0 { I7 x% F
- } catch (ParseException e) {9 k8 j, E4 W( n$ L' C3 \/ v
- e.printStackTrace();9 h% ?2 O& S" w0 {) s
- } catch (IOException e) {
7 P3 {4 o- u0 }* l8 f - e.printStackTrace();
0 z! F0 T4 \: ~, ]4 J - } finally {
' G. n0 V# r9 _$ T6 ] Y4 L - try {5 r- Y/ H% J& S: V: a& i
- httpclient.getConnectionManager().shutdown();
0 [# D( m6 x( p T - } catch (Exception ignore) {% B$ c$ Q' p% W0 T) ~6 }9 J, F: @
- 5 w/ K' n. d u T. [* ~
- }; @9 J4 U% v* s7 v3 L" f; F
- }& ] V. f: f z2 F. Y* j: X9 b7 o
- } _/ n3 c3 \7 `2 T. C! }
- /**
9 K, @2 ^1 _/ V% Q - * 自定义文件名称 和路径 win环境下测试# Y1 |( u" J) l
- * @param args
: d# t! Q' S. } S. g - */! W* ~$ H9 q; H" @
- public static void main(String[] args) {1 Z h# }/ _- D% \/ A. l' @
- HttpPostClient httpPostClient = new HttpPostClient();0 |9 e4 _7 e9 \7 K m. ~
- httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");1 j% t8 s! \2 i8 @- c; V/ G
- }4 D0 Z. B7 j: ~8 Q- i* Q2 ]
- }
9 T" N0 T% ^4 s n: N" G7 H - 6 u3 T% N$ o% ~" ]0 l# B6 U+ p5 ?
复制代码 & A! i6 Q) _# z x' N
0 P+ e, R$ f, R
# J& |$ o1 |- P6 U2 b; p新建服务端 用于接收
1 \( ^5 N; y: K6 z7 sHttpPostServer:5 P, q0 ` B# w2 W
- package com.itstyle.web;
" K) m8 ^9 z$ w: }& n! i0 x - 7 Y+ S, `0 j5 k) z1 }
- import java.io.File;
' ]& b+ e. a5 F# v7 V; b - import java.io.FileOutputStream;; d5 P( q4 O. o; h2 u8 H
- import java.io.IOException;
' {- n9 S2 y; Q4 w3 T - import java.io.InputStream;8 p' m& g$ y) x' j8 ?3 |
- import java.io.PrintWriter;" w& q& O0 L, }8 h6 a
- import java.util.ArrayList;0 ?* r9 g( t# D( ~
- import java.util.Iterator;
! T8 n/ d2 U) R1 }% _8 e - import java.util.List; O, [! S1 R+ q" e( }6 g9 F0 a
- ' \# W E$ L8 b8 M: ?- [
- import javax.servlet.ServletException;# e+ n/ ^, M7 o4 Q! t
- import javax.servlet.http.HttpServlet;; I9 \) ]# o* L
- import javax.servlet.http.HttpServletRequest;
, C* t+ B6 Y- {. v+ x! k* X* | - import javax.servlet.http.HttpServletResponse;% O3 |0 [, m8 w8 ?% ^, E( Q
- . B" D) s8 ^! I, p( c7 ]2 Z
- import org.apache.commons.fileupload.FileItem;4 _! F/ h P7 b5 v
- import org.apache.commons.fileupload.FileItemFactory;
3 M0 j; K5 |4 K. P - import org.apache.commons.fileupload.disk.DiskFileItemFactory;! C+ P% V" S# M$ e
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
$ w: ]* J7 e& p& n - /**
# e$ o9 z% j; b Z+ Q8 @% Q - * 服务端 接收文件
$ `) {9 \ v& E - * 创建者 张志朋
) t; M: x% ~# V6 I - * 创建时间 2016年4月14日
( U; h( e# [- u: D- T - * 科帮网 http://www.52itstyle.top: }* Y% _( K+ ?& {- i
- */- ? I9 [' E: u6 M- G f1 E
- public class HttpPostServer extends HttpServlet {, t2 U2 |( i' u
- private static final long serialVersionUID = -1002826847460469784L;
" s+ Q7 n% Y! }0 A6 K
0 z2 {/ B' @; s' M7 e( \- @Override2 g" J. \: n4 J; V& v
- public void init() throws ServletException {& T1 O0 A/ b% f1 k. F* l( L5 {
- ( g0 c" q- `2 o6 F. o6 K! ?; K$ l' |
- }2 J' e7 S' c. ~2 y
4 w! k# X* H7 h/ }' X* A5 ]! j" E1 B4 D( L- @SuppressWarnings("unchecked")
$ c5 n& R" S2 `% k1 ] - public void doGet(HttpServletRequest request, HttpServletResponse response)
& t( d. M- @ ~* G+ M) v" I6 |- F - throws ServletException, IOException {+ c. Z1 E7 Z/ u& M, S) L
- PrintWriter out = null;
/ w; g& D& l, B9 W) Z; k -
+ V5 d/ c% ]+ r: j0 c/ o3 d% I: U: ]( | - response.setContentType("text/html;charset=UTF-8");8 G% j; e/ M0 h$ v6 K( \
- String basePath = "d://test1";
* H; X% U3 v7 a/ a8 Z3 z - FileItemFactory factory = new DiskFileItemFactory();
+ E: J `7 G) o5 r' y' H - ServletFileUpload upload = new ServletFileUpload(factory);
" R3 F. K* g0 S) f+ ?. T' h: Z - File directory = null;% I% y+ e+ f' l# E! m
- List<FileItem> items = new ArrayList<FileItem>();0 _' _" L/ d, Y- n
- String message = "";
- V1 F/ D2 |# e, A - try {
6 y, ?9 @; R4 f# F) z - items = upload.parseRequest(request); r4 ?* W: O, P. I- O0 S* g
- // 得到所有的文件8 o5 _- D6 _, }4 I( {( K
- Iterator<FileItem> it = items.iterator();+ a$ W. c, \) X
- while (it.hasNext()) {3 L% F- D) c7 c9 b% g
- FileItem fItem = (FileItem) it.next();
- T" {, g0 S& Z - if(!fItem.isFormField()){1 F! L: p, V1 z- v8 S+ c5 X
- String name = fItem.getName();# i3 T2 n$ f8 Y9 \( p2 ? D8 n
- if (name != null && !("".equals(name))) {
% k0 V( p* V4 r8 \ - name = name.substring(name.lastIndexOf(File.separator) + 1); ?+ a9 R! W7 {
- directory = new File(basePath);
/ k* {; t! R. a; |' g6 E - directory.mkdirs();
4 p \) {7 o- t! g - String filePath = (basePath) + File.separator + name;
1 \% l9 L G1 b1 [/ _: j - InputStream is = fItem.getInputStream();
0 f7 w9 C% e6 b& Q - FileOutputStream fos = new FileOutputStream(filePath);
6 c- h8 Z' x/ U; H/ x6 @ - byte[] buffer = new byte[1024];
9 w- B: x0 q( `& y5 a& m4 \ - while (is.read(buffer) > 0) {
6 z1 A w' U7 u3 ]+ z2 O, I8 A, I u - fos.write(buffer, 0, buffer.length);. {( P# t8 M7 C
- }
+ M5 F& Y) J, x - fos.flush();
- I3 `1 L& C1 G* h6 B3 ^ - fos.close();3 a( ~; S8 G$ d5 L! z2 }
- }
; x5 a4 {+ l! a0 N9 Z0 F - }
7 t# F- y" I* a2 k& n3 m3 n8 j6 Q - }
! \( E4 F$ w9 a x+ l - message = "{success:true, msg:'接收成功'}";
4 C* E/ I0 H; ~( R0 @/ E - } catch (Exception e) {
. z# z' k% F8 }8 X% l - message = "{success:false, msg:'读取http请求属性值出错!'}";
- p. m& z! w3 F. I1 f6 J - e.printStackTrace();
) n+ A. v: n/ i0 {. S - }finally{3 b/ d6 A: n9 L( ?
- out = response.getWriter();
6 T( |) z4 |. `# G" a1 d! x+ { - out.print(message);2 G2 i" c" r w% e5 y8 g* H: e
- out.close();
9 m$ b" i+ {0 S' @3 h6 n" c - }# G2 J' ? F0 \2 }& o7 Z7 n5 P% M5 e
- }2 s6 u3 Q5 b$ q" J) K m
- public void doPost(HttpServletRequest request, HttpServletResponse response)
9 y% t' w4 E# ?* Z# q - throws ServletException, IOException {) b" x* r1 W8 q# A* K
- doGet(request, response);
/ g2 l% M' n/ w+ k" D5 m7 M, k - }
$ O- x( A2 j3 C8 `8 V9 M - }* k0 j" d% n' z( k: |! c9 ?7 o
/ h# ^# v* \! s& y$ b! Q# f
复制代码
# I' u3 `# r1 M; ^; c6 p2 H" Y所需要JAR包
2 ^. l, c8 t4 |" U: a" Ucommons-codec-1.6.jar' }1 K+ @5 O' J! t' d7 R/ j
commons-fileupload-1.2.1.jar
4 _: f9 G& r$ e% Mcommons-io-1.3.2.jar, g) \# U2 @2 Y! b) o+ P
commons-logging-1.1.1.jar
+ d. @4 Z" Z1 q* P9 W9 B0 J+ h: p+ Cfluent-hc-4.2.jar
6 f7 l' H- }3 H& k4 Zhttpclient-4.2.jar
, @) S, Q P( vhttpclient-cache-4.2.jar) ]7 ~, C/ r. |
httpcore-4.2.jar' @% d/ W& r. U+ I
httpmime-4.2.jar
5 n5 \2 [" J1 d* e, }) x2 Q7 F1 h$ y; M1 {% ^: t! S
项目下载地址:点击下载
( Z @& { {% ?" N0 F
0 J1 v; z6 a/ i1 ]
+ U! _6 H0 p6 `! M密码:
9 G* l! ?" U" K4 P: M" d& s" R
8 k& r# h+ a- D) y# y- p
7 |1 V5 n& [* i, z7 T" r5 D! I+ H0 f$ S C- _+ m4 e
|
|