TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
3 h( v" d. g* y1 z0 x9 w' B, @4 z. i+ l2 A3 o9 } E
一、项目需求
/ d% i$ H; {: d Z' @. _- \ 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
1 {4 V) E! B% \# H, u. k+ | F4 W
) F- _+ Y# b8 U) Y. b二、文件服务解决方案: w4 Q$ A6 I( F) E9 r* x% V. L8 E
1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。 K: I8 V. W- W- w; u
7 a0 N! A2 g1 F9 N; z& ]) h
7 P+ M/ c3 c1 l3 S; `配置详见:http://www.52itstyle.top/thread-10764-1-1.html
: x1 V' P$ m* V, a8 ]$ }
% n9 ^7 e4 ^7 O. Y8 \+ z4 m# L! `! D3 X
2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。6 z0 P5 z1 {5 N* d: O
# F' Z7 T, m4 O
6 {) J: ? O5 `
配置详见:http://www.52itstyle.top/thread-17263-1-1.html3 p7 y) `/ o+ W( `9 Q6 l- E5 _
\' F1 x: y/ q- I& \. t% j% B. @% _' u/ O0 S8 A
3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
: i, s, v+ A5 m' d1 O# m
) g+ M9 R" [" d! k0 z; b
5 y: h2 |2 V7 S% a% s0 P% g4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。! ^: e: r+ T4 \
3 U* F1 m- m8 Z7 I- p
+ Z$ \+ r% I3 i+ M* k: T5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。9 H- K4 u' V3 {
6 j+ Y8 V$ ?* D) F* p
6 c7 p2 B _) d. Y
这里主要简单实现第三种方案(使用语言JAVA):
! B6 R, \+ ?9 M( z7 p/ [, e5 J9 l2 G% \$ P/ R2 U. G; f5 F
$ ]( _! c) X% x
新建客户端 用于上传+ r# S" K' i/ O2 m
HttpPostClient:
' U' T8 t5 m4 H% z- package com.itstyle.web;, J% H5 _/ j% e. f. v/ j: f
- ) g6 _1 i. z+ P* Q3 U8 }
- import java.io.File;- i+ ?0 T8 [+ W( Z6 w& t* p. }4 \
- import java.io.IOException;% f& z% `- _ E7 Z r
9 q3 h! h2 A; E* L3 d9 }9 K- import org.apache.http.HttpEntity;* h& J4 [3 ?9 \
- import org.apache.http.HttpResponse;8 V3 `. g0 S% X" Q$ U5 @1 d
- import org.apache.http.HttpStatus;8 f4 W6 a7 F: {$ O7 |
- import org.apache.http.ParseException;
1 @! |% ?" Q0 X% T1 Q - import org.apache.http.client.HttpClient;# D* ^8 R/ v1 Y' A7 B+ b
- import org.apache.http.client.methods.HttpPost;
+ _5 ]% ~9 S7 {- I - import org.apache.http.entity.mime.MultipartEntity;* N% D9 i6 _& [
- import org.apache.http.entity.mime.content.FileBody;
* G7 n+ g. B; s! k- n - import org.apache.http.entity.mime.content.StringBody;
# |" T* T) Z" h3 B) R4 K - import org.apache.http.impl.client.DefaultHttpClient;
: W3 e2 j* E5 I9 S5 E& C( U* M8 I - import org.apache.http.util.EntityUtils;$ D8 M/ A% W, O# M5 W
- /**( x6 ~1 V: F5 \! Z5 v4 N8 Z
- * 客服端
7 N) Z! a6 y1 k1 O, \! d - * 创建者 张志朋# T4 i9 [8 F8 r- b' E
- * 创建时间 2016年4月14日
( k' x4 v% v+ V6 U( I. r9 B Y" F - * 科帮网 http://www.52itstyle.top
4 a3 q. K# R' @$ Q. |; A - *' _* G0 @, Z1 L5 j
- */
# @- m: n% T* {6 v7 p - public class HttpPostClient {
+ y' {5 V- E3 c- R& Z B z, b - public void SubmitPost(String url, String filename, String filepath) {1 |# T ]4 Y3 x8 W3 v+ ?
[9 k2 l) q) X) v* x( ?& u3 m' U) b- HttpClient httpclient = new DefaultHttpClient();
! E( c1 \% p# _
0 e: N: k; H, Y- try {% G7 _, P7 ]; }; J
- 8 K- f- G/ t* v) k: i, E* f; V, S2 a
- HttpPost httppost = new HttpPost(url);- Y; J" p) y0 W; Z5 d. x$ ]
. G& w1 x) ^( c2 Y$ s* N1 ~2 l- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
; Z. A- p6 b& H8 j: X - 0 L- n5 e2 j0 Q# S% e0 v8 r
- StringBody comment = new StringBody(filename);- h+ V. G1 y* l0 @/ O4 R; t; X
c- T/ L h* b5 Q0 H- MultipartEntity reqEntity = new MultipartEntity();
7 t7 F/ ]+ r" k/ t - reqEntity.addPart("file", bin);// file为请求后台的File upload;属性
; C: V/ e0 ~1 r0 y$ b; ?) Y8 ] - reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性
9 v( p0 P$ m4 O3 z! J# } - httppost.setEntity(reqEntity);
% E( e1 H$ s- _) F3 z& f. j/ p( E
# [% E4 i F! ^9 \0 j: X1 H- HttpResponse response = httpclient.execute(httppost);
7 `/ c: }- Y# s% e& K: N8 P" C% q - & O8 d9 _6 l) N! D# E1 |0 j3 s+ N8 t
- int statusCode = response.getStatusLine().getStatusCode();
" g' `$ Z7 w9 n) z* G+ e - & D. E- \9 K/ q) E3 [- ]- [7 h/ l/ A3 x! f
- if (statusCode == HttpStatus.SC_OK) {+ W, T+ [1 P9 A9 K0 Q
- 8 [8 d' W! b# C0 D( }) D7 {, W
- System.out.println("服务器正常响应.....");
6 `5 ]% }' _# |5 {' o" |# e
$ r |' S7 Z" a9 n% _' f* M- J/ I& V- HttpEntity resEntity = response.getEntity();
, w, J. D) w0 y4 q! o5 |" I
8 m$ _3 o* M# E, Y. O7 k1 ?4 ^- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据; a/ P2 ?' X, S+ T
- # F/ r3 Y4 u: j- h
- System.out.println(resEntity.getContent());( Z6 w6 u Q+ ^9 K
- & P$ T# J4 F, |) q! A3 |+ A
- EntityUtils.consume(resEntity);
, ?- V6 \! r! b* l! L, v" K - } g5 y2 F$ C2 J* g- _
- ) }+ O8 o+ T5 E
- } catch (ParseException e) {
- x. p; R6 U( g' R. _4 w; @ - e.printStackTrace();/ l. B$ C5 i- Z
- } catch (IOException e) {
* K9 z; y. V1 T6 ?: O' c: s5 E& X - e.printStackTrace();0 c4 T% q' j0 J& Z! P. y6 s
- } finally {
$ T3 Y; y0 j; A3 c7 Z9 v - try {
& E6 F. J8 F E. m8 Z3 x4 l2 l - httpclient.getConnectionManager().shutdown();
9 g. {$ p' x; T* m6 d' H& J - } catch (Exception ignore) {
) v$ o6 | P: t- k- D! _ -
5 r# h( ^5 N8 S/ Z4 D! _4 D8 r - }1 n6 ~3 A, G% l/ v
- }- l, t; F6 u: V& }( E$ y1 n
- }0 D: c! V' U- A n# C5 F
- /**, f8 r/ e6 m; y1 Z4 F3 M6 O! _
- * 自定义文件名称 和路径 win环境下测试% Z/ F" A/ j& A* U
- * @param args; w# F8 R& ~; T' `- [
- */* I# w# S/ A+ K! J0 _ ^0 o, R
- public static void main(String[] args) {/ [* v$ ?* y" C+ W% {0 {/ E1 R3 l
- HttpPostClient httpPostClient = new HttpPostClient();
6 s# J, C# d% K' x - httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");
0 y _: B! j) n$ [" i- o% ] @ - }
1 s9 u; ^* O5 F9 z - }0 m5 K6 o9 w" t' |9 b2 b9 W
! t3 d) H; v7 n$ e9 W# c7 x$ X% [
复制代码 : |. [5 V9 |7 ^4 I
. L/ [9 O: A( `) k8 Y& A/ H# v. U( D/ L
新建服务端 用于接收
) J% \" a% }5 P! uHttpPostServer:
2 p; m) U% P P9 ]- package com.itstyle.web;
. P* ~8 i( b3 t
2 h2 K' z$ V( o! B- import java.io.File;
- O* K& y0 @, L. U; z$ ? - import java.io.FileOutputStream;
. e' M: X) b& w* E7 N$ }8 J - import java.io.IOException;
, P; G$ r: f" k1 F0 O - import java.io.InputStream;
& P6 D3 J+ w& ] Y - import java.io.PrintWriter;
" d, ]; l7 I9 V; ]0 s9 H3 o0 F - import java.util.ArrayList;1 j0 t, |9 v" o1 r5 P
- import java.util.Iterator;5 `0 p# e; v* ?' f
- import java.util.List;
3 ?: M& X2 _" c) C - ! h1 O: ^ Y' P+ L- V! c
- import javax.servlet.ServletException;
0 ^9 P4 U0 q/ F) _* p - import javax.servlet.http.HttpServlet;: h0 a' O5 K8 k9 |6 I9 y* E
- import javax.servlet.http.HttpServletRequest;) ]: F5 [ ?3 b- N$ [- a! g6 M2 [
- import javax.servlet.http.HttpServletResponse;
8 }* _, D h1 Q/ U2 Z
, B t0 w2 b7 y3 t- import org.apache.commons.fileupload.FileItem;3 x) a5 C/ \+ v4 \
- import org.apache.commons.fileupload.FileItemFactory;
% h" E! n z; J - import org.apache.commons.fileupload.disk.DiskFileItemFactory;
9 |9 Y. G; x( w! U9 C/ f2 B0 R - import org.apache.commons.fileupload.servlet.ServletFileUpload;" }* u+ u( e3 g. ^, ~5 l) F- G. g5 c
- /**/ X5 W% w7 y. E1 L3 I
- * 服务端 接收文件: C& y" z( i A" H. R, o
- * 创建者 张志朋. w% b$ G/ A; v, W
- * 创建时间 2016年4月14日
* f7 `7 n% ? ? - * 科帮网 http://www.52itstyle.top: h" K* ]3 c5 M3 L: ~ n
- */& }7 a* R/ w5 T; {4 n. c
- public class HttpPostServer extends HttpServlet {; F6 ]& B M8 l, u' H) Q; N( @4 q8 H
- private static final long serialVersionUID = -1002826847460469784L;/ F( ]9 _2 R& B$ n
+ w% J; d8 R1 w5 S- @Override+ o3 ?% j/ y/ P/ E
- public void init() throws ServletException {0 E% o9 _% V' M; v$ d% _# I
- 6 R) k% {7 _0 M4 V8 q% z0 ?) }
- }
* e" _% n' I/ D- Z% \
: v, k% }. Y/ a/ o* z5 }' n- @SuppressWarnings("unchecked")
. ~- w9 g' }' w! u& n- U, z. e - public void doGet(HttpServletRequest request, HttpServletResponse response), W$ B5 ~' ^/ Q' ^7 o
- throws ServletException, IOException {. I1 E w% O. q U: t( W
- PrintWriter out = null;
+ }% W% a; ~4 z$ d2 I. k3 Y% [ - 0 ^1 r8 f: w1 {" n8 [
- response.setContentType("text/html;charset=UTF-8");% a3 M0 e2 s. X8 F# U7 @
- String basePath = "d://test1";
: y3 B. M6 y, D+ n - FileItemFactory factory = new DiskFileItemFactory();9 E2 p5 D4 p2 \; V( ~' F
- ServletFileUpload upload = new ServletFileUpload(factory);( g R' C: X" P$ E
- File directory = null;
5 l! t7 I. ^7 g' t - List<FileItem> items = new ArrayList<FileItem>();7 O6 A. K! r5 e8 ~8 S' @% R6 \
- String message = "";
' v3 [ H( r& l8 P - try {
9 H8 S" U# I7 ?- z - items = upload.parseRequest(request);
4 F. \2 j1 b" ? - // 得到所有的文件
0 u% K' A) B7 N - Iterator<FileItem> it = items.iterator();
# E) i: S1 ^- q1 z# L. A q - while (it.hasNext()) {
" i. v8 a- }- ?( N7 T - FileItem fItem = (FileItem) it.next();+ t7 q# M; ]. I" \
- if(!fItem.isFormField()){* y2 _% ?4 T( {: u1 ^
- String name = fItem.getName();
/ Q6 E: d. X- `' x# v/ k q1 Q- K - if (name != null && !("".equals(name))) {' g6 E2 Y2 ^+ o8 `& P9 Q, K. p, B
- name = name.substring(name.lastIndexOf(File.separator) + 1);& C7 @0 [0 M0 A' E l$ g" K
- directory = new File(basePath);/ w5 m/ \. q' ~" f3 v
- directory.mkdirs();; f: T- q( Y! J) G: k9 A
- String filePath = (basePath) + File.separator + name;. o# e0 @4 \! \8 y* s/ B
- InputStream is = fItem.getInputStream();
- H; D5 g$ ]! r6 j$ M8 b. c - FileOutputStream fos = new FileOutputStream(filePath);& _: X5 @2 ^ Z
- byte[] buffer = new byte[1024];
) N1 y) e0 x5 Q# A! T# P - while (is.read(buffer) > 0) {
" Y& e/ l7 ~# E r& ~0 B0 |! Z - fos.write(buffer, 0, buffer.length);0 v! b9 k% K+ t& e: H5 i) Y/ q
- }
9 l1 J" T/ I1 `( p$ q+ z1 r$ x - fos.flush();" H* @+ a+ _' i0 T7 _) Y7 E7 r7 X
- fos.close();
0 y1 R7 [: q/ q, u! T6 Z7 z - }
9 x4 @/ g }( s - }
9 I. ?9 a1 @: `/ }. x - }
2 {0 M7 g! }. {/ s% k: G7 }7 E - message = "{success:true, msg:'接收成功'}";% |' d" U" G) [, Z
- } catch (Exception e) {
& I( u; y& O \% S9 n7 }9 L/ P - message = "{success:false, msg:'读取http请求属性值出错!'}";
0 n' D4 x6 @/ Y& f; y+ L7 Y - e.printStackTrace();
9 y) P1 t% a! p: M. ]5 a4 y3 [ - }finally{
1 k. W; @; I7 o2 E - out = response.getWriter();! m& M7 h! |6 R& t+ t; k
- out.print(message);
( u% h& V- c- P3 F' \6 \. _$ y; p - out.close();
% z' `7 P ]( u( Q - }6 i( O: M o: u" w( C. J
- }
, H# U8 t2 o* e6 o. }& d' n - public void doPost(HttpServletRequest request, HttpServletResponse response)0 ^) V9 e- H1 n5 u7 `
- throws ServletException, IOException {1 U6 U- f7 R& P4 ^- V! q# ^
- doGet(request, response);
! W I2 l+ O4 l7 v* `& Q M% O - }
9 W- u" i+ x: |8 [ - }
( ]7 {/ G. F& G* N6 ]( t$ q - 1 A6 j7 J; H( b6 X4 p* J0 i
复制代码 ! S( d+ v- o/ Y
所需要JAR包3 m1 u0 O1 G) d, d, W5 [
commons-codec-1.6.jar* L$ d7 S9 [+ B) N! W
commons-fileupload-1.2.1.jar+ }4 N) N0 O: j$ N; I
commons-io-1.3.2.jar% _ I X- T- |! b+ S6 f
commons-logging-1.1.1.jar; X( u/ A2 w% l% c+ d1 X
fluent-hc-4.2.jar
: n& ]$ G8 j. r5 }: T3 f$ ]* z. g2 _. ehttpclient-4.2.jar. h& b% J( H. R) J
httpclient-cache-4.2.jar
5 N7 A+ g4 c/ U6 {( G& t) ~httpcore-4.2.jar: c( x; D# m3 l8 c
httpmime-4.2.jar
: d+ Q* E! m* j/ P& N/ ^
& ]# y! N/ y, B9 a3 V项目下载地址:点击下载- _. U8 A3 X+ ?) I; Q
" Z" ^% L# y6 g/ q
' i# G3 ^' T* V E9 T& O, C
密码:" a" Q+ s# H/ h
$ o9 L" s# z, f' v7 `) _; j( C
) J$ G- K" _1 I( H' E0 h/ L9 k6 k
, z, k/ H* j0 f
6 L4 o6 b1 I0 B; {7 o |
|