TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
( Y* k( @1 F! o- j* d9 E+ J3 @3 [# B: \1 P! Y2 _
一、项目需求
3 D# ~1 T7 `+ P9 s- b1 f$ }1 J- K7 V2 C9 l 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
- N4 E) K' A6 S6 N6 }4 ?; t5 H/ l* s% A
) n% ^4 z: h& |' M0 E: n二、文件服务解决方案7 Y: S ^; a; C1 A5 i7 B2 P
1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。
4 N& c2 l9 H. D( A5 o% U4 ^: d* e4 Q& c, I* `! ^# y9 o
; g$ e; k- H& o% N# X7 c& }; \, c配置详见:http://www.52itstyle.top/thread-10764-1-1.html' q% e Z. O9 m. N5 n
- g( U# e: ?8 q% d* y! Z
( V: T T/ V3 s) E4 h& Y- N
2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。. m# i6 ?+ G* x3 o
' F6 A# y' D% n
. C; o6 U8 X; s B4 E
配置详见:http://www.52itstyle.top/thread-17263-1-1.html6 D4 d; c; [4 J
2 I2 x, y/ u" i; ?& Q; H. h
T% h% N# P/ z) w3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。, M* ?- S1 z. o3 Y+ h
1 e# J( G0 z) H+ e5 q
% o6 J% z. c6 U) I8 L4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。
; C0 f2 C' m5 X' z' [) O3 a2 b4 F( a$ |+ c- ~& f+ G1 w0 R( d* }
! b+ M6 q+ w& C# O2 ?
5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
' B1 M$ g2 ^0 M+ c6 `9 K# J' _* c8 j, w( x/ I& l0 W1 f" G
3 ~# u2 d/ @, x" U) ]) ?/ T( o- I( U
这里主要简单实现第三种方案(使用语言JAVA):* T0 g9 _+ ] a& U& _8 i C
8 ^, W5 d. @6 V+ s6 ]( S& n
4 W5 m3 t3 |2 A7 O' n) }% j7 ?, Q新建客户端 用于上传
) x$ P# t+ x b, ]1 y" z2 [HttpPostClient:
4 C. j6 }4 D5 K: V) n0 L8 F% {: j- package com.itstyle.web;0 L/ I9 \( C( {- r
- + |- n4 O* `3 Q/ I) F
- import java.io.File;$ s5 ]8 u! a- ?5 V% k* ^; b3 y+ P
- import java.io.IOException;8 ^4 n/ A! R$ P+ _
/ L( R w Y+ Q7 \9 o) Q- e& j- import org.apache.http.HttpEntity;
' Z0 k4 H4 h. X4 |1 s2 L - import org.apache.http.HttpResponse;
. }5 ?) @. `! l" h - import org.apache.http.HttpStatus;9 z2 ~: @& v- H9 L# P
- import org.apache.http.ParseException;9 ?4 z" n( q& h, n: j( W" o
- import org.apache.http.client.HttpClient;: p' G: F) i8 r5 a, Q: F- s3 ?+ ?& N
- import org.apache.http.client.methods.HttpPost;
! Y( v. Y/ Z; R2 W/ A6 w% B4 q0 U - import org.apache.http.entity.mime.MultipartEntity;
' |" m6 M. P& Y. C - import org.apache.http.entity.mime.content.FileBody;$ k6 W, n+ d8 \
- import org.apache.http.entity.mime.content.StringBody;
- ^: o3 _9 ?& ^1 j7 k - import org.apache.http.impl.client.DefaultHttpClient;
0 r8 l1 h' z. [$ V% e - import org.apache.http.util.EntityUtils;
8 J2 a$ p- M, i2 F$ r - /**
, B$ h- X `; [9 Y1 `% B4 a - * 客服端
w( ~7 s, S( Y' w* t0 j0 k - * 创建者 张志朋
) a5 x" I/ A! _5 E( M) }" _1 D - * 创建时间 2016年4月14日" [! W; J6 r! N) ]: [0 K7 n3 L
- * 科帮网 http://www.52itstyle.top
* b \, }" u) f1 i# f. Y - *) r% G+ f' M) B! g6 a% _1 H% P
- */
1 F8 N- n/ X+ D) s - public class HttpPostClient {
3 m' y8 C! a; h% J. k& y c( c - public void SubmitPost(String url, String filename, String filepath) {
7 {$ J5 _- y# j! R
4 _* p7 I4 G. L2 J# x3 S7 d- HttpClient httpclient = new DefaultHttpClient();" k( e O H7 m" O0 |% V6 q
- $ K. s# g' Q, `! i- F, h- K
- try {7 G$ L2 f& H& t. _3 X8 V
* a" h% E7 |: G3 u- HttpPost httppost = new HttpPost(url);4 G7 V- L3 j, b& r0 l+ N7 o
- . b( c; h. S T4 U3 y% p6 u
- FileBody bin = new FileBody(new File(filepath + File.separator + filename));: \& t/ C, z0 @
- 0 S' q, |+ O$ J* M! b& b
- StringBody comment = new StringBody(filename);
8 I8 C2 J( N; }6 n
' U7 y% t+ h6 o' C% A, U- MultipartEntity reqEntity = new MultipartEntity();
' Q+ C2 W4 s5 T( f- s; _: E* E; d - reqEntity.addPart("file", bin);// file为请求后台的File upload;属性- d- F9 z1 M( r9 T/ B B
- reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性7 x; a7 L6 w4 y# ^! a
- httppost.setEntity(reqEntity);
9 i; O+ E1 z' }% f5 g
1 G& T7 ~$ J g1 ]1 D6 n7 ^- HttpResponse response = httpclient.execute(httppost);
! ]* R! n @3 H% V2 X# w( v
; s- W4 J1 @* T$ L- int statusCode = response.getStatusLine().getStatusCode();& w6 c! c/ C" ~1 `0 z. V; d
- - S: Q$ I! ?% @/ i8 _
- if (statusCode == HttpStatus.SC_OK) {* t/ d1 f* b% h. A! R0 y2 N
6 Q$ [+ ?4 T, }8 j- System.out.println("服务器正常响应.....");% a z% |: X6 n9 e: b" y
& ^' v4 _5 M7 d/ u- HttpEntity resEntity = response.getEntity();
' q6 t: H* H" X, v% S! c+ g - 8 {) Q9 l& N1 ^! K8 f3 B+ C9 e5 t
- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据
) I. K# O1 `0 _% m* m% [
- W; ^+ P; z1 a! Y/ j) F2 v! Y- System.out.println(resEntity.getContent());, p- {, k4 S# |4 d7 L$ r# g) u2 G
- : }/ ]1 k* g4 S4 x2 i' h, R7 `% V
- EntityUtils.consume(resEntity);" W# o+ m1 v1 S% ?* R# c+ A
- }8 o5 B5 Q, w3 C
- ! D B: a3 A- J* m: Y7 |6 N3 A
- } catch (ParseException e) {
0 ~) f' L R1 a: ~ - e.printStackTrace();
8 I W9 F% H- V# t - } catch (IOException e) {
$ q8 ?0 h+ a0 \ - e.printStackTrace();5 G1 |( }( P; Q9 ^) y8 \3 {
- } finally {9 z4 l4 @) |& u/ t* I5 z* k3 i
- try {* ]" p& q4 ^6 x1 y
- httpclient.getConnectionManager().shutdown();
9 g- ^; N, d, @+ ~1 b2 [0 ` - } catch (Exception ignore) {! S3 P: f. o; x
-
3 o+ J6 l P9 y8 r# M3 M - }
* g7 L# [( N, D& Z5 {; K6 P3 |/ S - }" a5 I; C+ z. y O
- }' P% q1 J# I( w" G! C( [
- /**
+ c( W2 I( t" e* C$ u7 l9 {9 r/ T - * 自定义文件名称 和路径 win环境下测试; e3 |% V$ m, I- Z4 ^% \" p
- * @param args
3 x1 q ]0 B! U7 c) T7 _ - */
6 O0 j3 G! _* ]# B5 ?$ t6 F - public static void main(String[] args) {
: [7 Z q2 l2 N3 K# C- R# O - HttpPostClient httpPostClient = new HttpPostClient();
1 o" o, ~" x1 v. A - httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");& v- w; v6 H+ m. n& g2 o6 \5 I
- }/ }: M" D x9 E B1 o1 Z/ X& B
- }
& q' _2 O& W( `: ? - # C T# v$ b4 f
复制代码
U# ]1 H3 b" g) H; b/ y$ E
$ e1 v5 O! c8 G8 b" h. a, E$ T$ ~! ^' E6 C
新建服务端 用于接收
4 a' B4 N, U* O! S9 cHttpPostServer:4 x2 r; r9 k7 ^. N& G! X
- package com.itstyle.web;
; x" I+ z- ]; r# N. I0 G! n+ u
& r0 W' b2 k: {' c# e4 G- import java.io.File;* r1 }1 M& f# R1 P0 r
- import java.io.FileOutputStream;
3 P' ~$ A* F) r, c" g3 L& P - import java.io.IOException;
' m4 P+ z! b$ W4 d! I% n, r - import java.io.InputStream;
+ w: v5 g7 B, G9 W* ` - import java.io.PrintWriter;
* `* p7 |" O+ N: e9 a. J7 A - import java.util.ArrayList;% u6 W3 u2 j" I0 e
- import java.util.Iterator;. A1 K5 H5 u. P( W9 K
- import java.util.List;% C8 ] ?# y; o+ i
- + W) g, l0 h5 G' \
- import javax.servlet.ServletException;* t3 f7 _' ]0 U! k, [* Z+ n/ o
- import javax.servlet.http.HttpServlet;
( T: d' o& \: J' q. M - import javax.servlet.http.HttpServletRequest;/ a) x" @5 |8 E3 x
- import javax.servlet.http.HttpServletResponse;
- q5 N6 }8 s; N% `0 ^4 ~3 T1 m/ e
; {. z; r6 T8 X4 \& q" g! F$ @" U- import org.apache.commons.fileupload.FileItem;8 m1 f1 ^: }" H& Z
- import org.apache.commons.fileupload.FileItemFactory;
5 R/ f& O7 c& [5 k: h' A - import org.apache.commons.fileupload.disk.DiskFileItemFactory;
6 V- h0 z. n5 ^3 v7 l u* I - import org.apache.commons.fileupload.servlet.ServletFileUpload;
* C6 U2 v3 @3 D* i; D Y% x( n; e - /**7 G( j( S z+ ?" c9 y
- * 服务端 接收文件, x9 B' p. H0 v
- * 创建者 张志朋
5 Z; H/ M$ o9 L9 s& r! ~7 j - * 创建时间 2016年4月14日, _1 i; k$ T" q3 \/ }
- * 科帮网 http://www.52itstyle.top( z9 J% G+ |& e: u. h x; }
- */
$ G4 N1 o1 X8 x% i5 E - public class HttpPostServer extends HttpServlet {4 u2 a$ @ W; b" q) B
- private static final long serialVersionUID = -1002826847460469784L;
; W1 ]* _2 Z% ]0 R O - 8 W2 B g. R; A2 t/ n" m8 Y
- @Override
1 y* K* W- A* O* b - public void init() throws ServletException {2 P9 L" p( ~5 s: O4 }0 i
- ( U: y2 N) b9 B5 S& q9 T) Y
- }
2 `+ D4 |2 E& y9 c8 v, u - $ K; g) ?# }! s" D6 v/ a
- @SuppressWarnings("unchecked")
' D9 S) A6 y8 d8 c" }& O3 u - public void doGet(HttpServletRequest request, HttpServletResponse response)& ?0 Y9 s4 B0 R5 z" ~5 N
- throws ServletException, IOException {! t# q6 x" d; h2 Y9 {
- PrintWriter out = null;0 t+ j- p/ J4 r" g+ Q5 p
-
7 h( @% n1 _1 Z* Q - response.setContentType("text/html;charset=UTF-8");
p2 G2 N! R n& O u) ` - String basePath = "d://test1";
8 q, V5 L9 }# ~+ U( `1 G- n9 g - FileItemFactory factory = new DiskFileItemFactory();* [1 ]) G5 d& ^, l0 c7 z8 E
- ServletFileUpload upload = new ServletFileUpload(factory);# l8 m3 U& {7 I
- File directory = null; ]$ i, |$ i4 Q$ N4 T( L
- List<FileItem> items = new ArrayList<FileItem>();
! c7 ?: Y, f0 d - String message = "";. s& w& N! j' Y" A; g
- try {/ E3 q5 Y# W0 E: G$ ~
- items = upload.parseRequest(request);
1 n7 f `: ^! X5 e$ Y& B - // 得到所有的文件
+ u" M w8 ^' K% l7 h# ]0 h - Iterator<FileItem> it = items.iterator();
/ x5 G- ?( M- @8 C9 D - while (it.hasNext()) {
4 _: ?4 b: B7 J - FileItem fItem = (FileItem) it.next();
: s( m) {6 s0 S. v! B - if(!fItem.isFormField()){
+ b2 i* b+ D0 C; s - String name = fItem.getName();- L% K3 i& o5 H$ y7 ` U
- if (name != null && !("".equals(name))) {# e+ Z/ T& C5 W% \( p" L' f$ B( o0 b: [0 ]
- name = name.substring(name.lastIndexOf(File.separator) + 1);: k1 i6 }, D, n: Y1 C0 \: u
- directory = new File(basePath);
) z" G; @ ]1 |; e0 x" p - directory.mkdirs();
. z3 i6 a! M) b - String filePath = (basePath) + File.separator + name;) z5 i* ?: V \8 {# [
- InputStream is = fItem.getInputStream();/ F# o) L* |- m
- FileOutputStream fos = new FileOutputStream(filePath);4 }9 F3 O" n6 y
- byte[] buffer = new byte[1024];6 v. F$ ^& Q2 K: K' [# { `
- while (is.read(buffer) > 0) {* s5 d6 i7 _1 R' P$ ]9 C; X
- fos.write(buffer, 0, buffer.length);# s' h+ P; x3 k
- }- O5 Q! n5 Y+ `% D4 y9 F
- fos.flush();$ g: G* ]6 A- h9 I! ~9 X; [9 b+ v- l
- fos.close();# K& ^; [( L' y; J6 t& b& ^
- }
+ F/ V3 h% \& J" i# @3 w - }, r4 V6 f, E% R; d% @( |# J2 K
- }
8 d' T+ A, `; t$ {1 N0 B - message = "{success:true, msg:'接收成功'}";4 N) z' O+ T$ D( ?. v
- } catch (Exception e) {: n2 b2 o- z! X- }' M. y
- message = "{success:false, msg:'读取http请求属性值出错!'}";- L& V+ k+ w2 e* R2 ]) |6 M5 A
- e.printStackTrace();+ H( r4 d$ K0 t* ?
- }finally{# P& x: L0 s7 j
- out = response.getWriter();
5 _3 M; e6 V3 ^' z& \' { - out.print(message);
( A7 X3 y' M2 M9 e2 ?2 n - out.close();4 E( B0 d: b: H4 q
- }
# v& Q' W0 }6 V - }* D. A4 X4 B! R
- public void doPost(HttpServletRequest request, HttpServletResponse response)
. E8 c3 a9 ]5 M - throws ServletException, IOException {
6 i1 B' ?0 }/ `8 J( \ - doGet(request, response);5 [# S2 Z1 v1 G% N
- }
) w M9 c8 j1 v- I1 E4 h) A - }
% ^. J3 H: K! O9 ]3 h
. T" R! O& A6 D
复制代码 9 E! }+ Q( S4 j; A* f5 Q+ A; M
所需要JAR包) K! t1 p8 G2 w- |4 t) E* B
commons-codec-1.6.jar6 M3 l( M: [; r2 g. @$ d2 j6 m
commons-fileupload-1.2.1.jar
; h7 q% t: u% Q# S' ^' lcommons-io-1.3.2.jar
) H$ ] ~1 S) M5 zcommons-logging-1.1.1.jar
5 c& q% x$ c% \1 Q- c- cfluent-hc-4.2.jar2 k; W, a. Q! L# q
httpclient-4.2.jar+ ?; \ i1 k/ U9 b
httpclient-cache-4.2.jar. x/ _! r# H3 F
httpcore-4.2.jar" j9 R% T3 q- ^+ ~
httpmime-4.2.jar. h' c7 u' C d+ R! M. l
, c* i; H: z5 n1 A( `* Z
项目下载地址:点击下载# t$ Z# w# |, _; X8 n0 j% w. j
! f( z& f( h. Q; j* v v2 ?3 Z
+ O, X V8 F s& \+ p [
密码:# N' V. T: |# G0 O
, S) _5 h! O/ {
8 C0 m% B3 D9 L4 D( q$ r9 H, s% v9 R2 O/ d0 ~4 r; d
7 m% z# ?- V1 R" J) G; x- i |
|