TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
n5 J6 Q1 m9 P# l* t- \2 i- ]3 n5 E" ^% q) k6 p
一、项目需求
+ e% `/ [/ @7 R Q8 C 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
2 `) q) `, \9 R. u
% j) A/ _6 ^) C2 L+ U3 m7 f1 r' o, E3 k; A
二、文件服务解决方案
5 M% ?0 y! k1 O* ^. J) g( l1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。! |; r6 j1 q5 s T2 y
2 a1 {- P }4 L4 D, P
/ {7 [, @5 s% m6 d# L配置详见:http://www.52itstyle.top/thread-10764-1-1.html" y7 j4 j6 F5 `7 L% o/ F! r
3 x/ V i9 H# V- i: H6 N& L; M! n
5 D- O6 @$ k& E) i0 {2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。
0 F2 B) D& ~; [% D
; ^% {* K& k3 d2 _+ y" F" v
8 g3 Q, c8 ^# l! r- M& ~7 G配置详见:http://www.52itstyle.top/thread-17263-1-1.html
/ E8 P) s+ ^5 N6 X5 _8 v9 L: l1 n/ m) | g6 }0 v7 g
. W) {8 ]- V+ g( H
3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
* f' l: j0 o( w' u) f; I% b9 R. M) S' [4 ^1 A
`0 d A% C+ _5 C
4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。3 @6 Q; x: ^$ [: I
0 H! a4 Q# w. P5 f. h# B
6 D& u, l" O. D3 m% k2 E5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
: a8 D9 @4 H ?! f* A" W7 C
5 @3 p! e7 n) W
$ ?5 e1 s! z9 {: z# c6 Z' _4 t* ?这里主要简单实现第三种方案(使用语言JAVA):% w2 x0 }0 [1 ]4 x' ~
7 Q8 K* U) @6 X6 h% D) m: ^
" J$ n4 Y! e* L) _新建客户端 用于上传5 R- f D( ]7 {- S9 W5 A' G
HttpPostClient:6 v: W- H7 N1 N8 l# X, }
- package com.itstyle.web;
5 v! H( }: f( t% ?4 f9 @ - # h( ]1 _5 {. W( ~/ X
- import java.io.File;4 ^9 ^; J( i5 t! H( f6 M+ |6 g3 R" p
- import java.io.IOException;6 x2 q. Y( w- B/ V6 A
, e: V8 B4 |; U5 D0 V- c3 E- import org.apache.http.HttpEntity;. N- \5 `9 Y5 v: M; l5 {
- import org.apache.http.HttpResponse;2 O# E+ Q* Q' z& O
- import org.apache.http.HttpStatus;! \% q7 M" W5 b# s# l
- import org.apache.http.ParseException;0 t3 a9 {; C9 Q
- import org.apache.http.client.HttpClient;
& x6 k- L7 D& o- d' ]2 a - import org.apache.http.client.methods.HttpPost;
4 ~; P0 S* }% t' m3 n* P9 T - import org.apache.http.entity.mime.MultipartEntity;' U9 x+ I( C$ X- l; t
- import org.apache.http.entity.mime.content.FileBody; d$ \6 v5 R1 @2 @. B' u3 K" k
- import org.apache.http.entity.mime.content.StringBody;* J8 L" ~* z3 P6 y
- import org.apache.http.impl.client.DefaultHttpClient;7 t* a( t0 W" @+ H7 L
- import org.apache.http.util.EntityUtils;) K5 v+ k$ S1 d5 X- F. l) }$ {) K! A
- /**$ |9 H) B, [9 M% \) R
- * 客服端# `; c/ V- x$ b
- * 创建者 张志朋0 Z; R" s5 ^+ @2 m* B
- * 创建时间 2016年4月14日! K. g, l9 B9 K# q
- * 科帮网 http://www.52itstyle.top9 B1 E- P. q4 s' N8 v; I! N
- *
' Y+ \1 u- \. Z: y8 V5 y+ m& } - */
# `' g, i# ^1 o6 V - public class HttpPostClient {' C1 S j" O8 ?1 P! U l6 d
- public void SubmitPost(String url, String filename, String filepath) {3 o' ~5 r* B- z3 b- F/ _
5 `3 l$ N5 G, j$ R4 x' k2 a. f- HttpClient httpclient = new DefaultHttpClient();/ ]- g4 ~6 ^8 S% R4 f& z
- + l N9 k* B7 V! S" m
- try {: t- c' y7 f7 _( ]8 A5 K7 p
- / T$ a$ f3 Y' r; T. T0 @
- HttpPost httppost = new HttpPost(url);% `" @' ?' u9 w8 j5 s
! ]/ j1 @ n/ S- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
3 Q0 a2 F, s$ ]* |, h9 r" t
) g. r$ n7 h- Y+ W# U- StringBody comment = new StringBody(filename);
1 m. y, b* f' Y! c! ?/ g. ? - ( Y4 j7 [4 R1 g! R( [# \: P% T$ O& s
- MultipartEntity reqEntity = new MultipartEntity();
! S, {1 Q1 L, N/ l8 N - reqEntity.addPart("file", bin);// file为请求后台的File upload;属性
8 I7 G! v$ [+ f/ z' @2 x Q - reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性
: ] B2 M6 P& a; P2 \) Y8 O% n$ | - httppost.setEntity(reqEntity);% z- V7 D- X4 U7 Q' o6 J! ]
- . U- ^" Y- z: F! U6 _1 i8 x
- HttpResponse response = httpclient.execute(httppost);& s: q/ i$ P6 V9 J7 ~
- 1 B* L) r- L6 e; C
- int statusCode = response.getStatusLine().getStatusCode();0 g2 H9 }( s5 _, x: K- a
- " Q" ?. r) I+ L8 r( C8 T
- if (statusCode == HttpStatus.SC_OK) {! b; j, P4 \) W Q8 m: |
* ?" M. d4 P. j- System.out.println("服务器正常响应.....");
6 t% ?3 o8 T) i. J! x8 F
" p2 a% I/ A) `! J( h- HttpEntity resEntity = response.getEntity();
0 I( s0 h/ D( q+ P, G. b. p% b1 r - * [/ x) W6 O& s' y4 {9 p
- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据
' f6 x1 q Y8 l6 E1 o/ {9 X k7 O( T
/ M7 t. c2 s$ n( k l- System.out.println(resEntity.getContent());6 o! M( ^1 _' z; W8 \
: g3 m0 F5 |% P) E) g" M4 R- EntityUtils.consume(resEntity);5 }( |) J4 R% Z# x; j0 _5 Q
- }# N) M8 |! }/ |' w# e% k4 S" d
7 Y" f7 A1 j4 Z9 L" A- } catch (ParseException e) {( [: A) \# d1 c0 [
- e.printStackTrace();% _: O+ b3 d6 p7 b$ u) q$ G$ o, M, n
- } catch (IOException e) {
6 q% y; P- P O1 E- t# J - e.printStackTrace();/ }( K ?' m+ V
- } finally {
: b+ U: E4 ]" K) T1 m, Q4 y - try {
7 I. @5 Y5 G Y - httpclient.getConnectionManager().shutdown();$ \) a: ^8 \8 M; g
- } catch (Exception ignore) {0 i" M. I: g0 f& m1 n
- 9 g# D$ b$ T9 B: p& C+ A
- }0 G% a1 S+ `$ `" |8 [, k7 N g
- }
$ @# e A: I5 H$ Q5 T5 {' E! Z - }
6 u; F# i8 ~) }" ^ - /**. X* `) W9 G6 F8 j# n E V U
- * 自定义文件名称 和路径 win环境下测试
" ^' a5 E5 T- \. P A5 {! z8 Q - * @param args9 ]$ `- y' w# S2 W
- */
4 D5 j d0 A, c) i! Y( F - public static void main(String[] args) {
& ?* q+ E& E9 O/ X - HttpPostClient httpPostClient = new HttpPostClient();
) |4 {9 I" h. O3 D$ H - httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");5 R8 s- e, E1 b4 h3 f/ g+ t( O* |
- }+ Q; F2 O% c4 V- I! o$ q
- }4 s9 g; U0 l B0 D; [3 O/ n+ C: {
- ) [0 g7 y! ?; g" X
复制代码
' y; S6 o" C% i) ~1 ~
# \; b2 B2 u( _6 \1 t' L6 Q! h" C$ m q
新建服务端 用于接收
- c5 Y Q. k }: RHttpPostServer:" s9 M, H9 }% h* C
- package com.itstyle.web;! |9 O/ ^% r. h
- # u5 }' y6 }" q3 E
- import java.io.File;
$ c% x7 [1 |4 M8 G7 |$ ~) X& z - import java.io.FileOutputStream;
P' U5 k/ [! G. x7 [ - import java.io.IOException;! F9 t1 R$ l7 ] r' ?' I" i& l
- import java.io.InputStream;. o% A( e$ A% H: g1 e) P. r7 I, y
- import java.io.PrintWriter;
+ x9 [' h- e% U% f& l8 S% y - import java.util.ArrayList;, N6 d* \3 ]& l9 e
- import java.util.Iterator;
# ^* L( L* G& U/ N3 Z4 B, b8 [$ I8 Y - import java.util.List;
1 L5 p8 _% @$ y3 A
; n% l* a- P( o' u2 w! z N0 M- import javax.servlet.ServletException;
& ?/ v6 S5 @9 Y3 \. }' r6 [5 F% s - import javax.servlet.http.HttpServlet;
- {, q7 e3 J! i" I4 v: w - import javax.servlet.http.HttpServletRequest;9 `. N k* v& e ^ u4 m0 z
- import javax.servlet.http.HttpServletResponse;6 p' Y: S4 Y: z0 y( u+ ~
* f3 ^* ~, n! R- ]# o- import org.apache.commons.fileupload.FileItem;
9 V4 O# J# a2 x, L v; [% m$ G- c - import org.apache.commons.fileupload.FileItemFactory;
! Y8 K. P/ x5 M" q - import org.apache.commons.fileupload.disk.DiskFileItemFactory;9 O8 b3 y4 _% j& u9 Y
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
+ n$ C! Q) H5 u - /**
7 S& U, G3 \" p' w! h' s0 Z. B+ {* x - * 服务端 接收文件, j1 ^5 }/ v+ f& n! ~' s1 S
- * 创建者 张志朋
. b- E% U6 t/ x7 F+ w/ m9 T' \ - * 创建时间 2016年4月14日
5 A( E0 ~: Z( M+ o0 I& K% R - * 科帮网 http://www.52itstyle.top6 @% D4 A/ P; a8 w" M- f
- */- r4 }6 V( r# u0 S3 f' p: C4 y
- public class HttpPostServer extends HttpServlet {
/ O% d O! g! n: J) a - private static final long serialVersionUID = -1002826847460469784L;
$ U7 |- b2 P( y - " \% B) x# @6 r3 a" a1 m' V
- @Override
. ?! D# Y5 r L: E6 N' F - public void init() throws ServletException {
2 a* R* t2 b$ {' P9 J7 Z9 Z( u* _
+ X' J) M, L4 W% P9 P d' ?8 f+ y3 L- }
5 w6 O9 }1 z6 N+ p# Y - 0 z+ j1 h4 G" Z
- @SuppressWarnings("unchecked")
9 ~6 h$ |" {. L3 N. o8 K) I3 u - public void doGet(HttpServletRequest request, HttpServletResponse response)
$ X2 ~4 N6 g( L0 ]1 l8 D - throws ServletException, IOException {
, X4 f+ G9 a& B; q' u% R' c5 x - PrintWriter out = null;
S8 I7 U( c2 u" @4 c9 e - 7 P# S. x- k# w+ H8 @, K6 A
- response.setContentType("text/html;charset=UTF-8");
5 `8 p* r/ G( n. j( V% J6 }& b, T - String basePath = "d://test1";
- K3 w% O2 F3 b+ G* i% X - FileItemFactory factory = new DiskFileItemFactory();
# b5 w* @, X. [# h, c - ServletFileUpload upload = new ServletFileUpload(factory);
9 q& n h! b% w' H* j; V - File directory = null;3 U" `9 k" Y8 z8 ]
- List<FileItem> items = new ArrayList<FileItem>();
. _ K8 m( W: x/ n" J8 E. t( { - String message = "";
3 j T* F: ?- N/ z: | - try {
# V- \1 @' r8 {" u. j" e$ o4 A+ f - items = upload.parseRequest(request);
1 q1 O$ Y$ ~" H% z8 R( { - // 得到所有的文件9 ?! h7 w# L, y, u x
- Iterator<FileItem> it = items.iterator();
j: K8 c& d1 H' S. H4 @ - while (it.hasNext()) { ]. e5 \5 x) C
- FileItem fItem = (FileItem) it.next();9 f, W M. e. M
- if(!fItem.isFormField()){2 c6 q* m4 |% y
- String name = fItem.getName();
0 o8 y0 a3 d* b7 b, A( u - if (name != null && !("".equals(name))) {
+ e- V. T7 K) X+ D5 |' v3 _ - name = name.substring(name.lastIndexOf(File.separator) + 1);
) k' G- r$ m3 p b( V - directory = new File(basePath);
q: W8 t5 a! G" F2 l% ?; `9 _5 t; @ - directory.mkdirs();
! m! S( @$ x' [5 }. p$ f' l m - String filePath = (basePath) + File.separator + name;
' h3 n2 t( ~0 o; a6 [/ X - InputStream is = fItem.getInputStream();. e$ m0 w- y2 i
- FileOutputStream fos = new FileOutputStream(filePath);
* ~5 T! i5 J7 |# j - byte[] buffer = new byte[1024];
5 U) Q% ~2 u0 a# h6 F/ I - while (is.read(buffer) > 0) {
5 }, x" S# c2 a - fos.write(buffer, 0, buffer.length);2 g. |5 o3 g4 h2 p0 {
- }" C0 U) u4 r1 r7 f1 D; ^
- fos.flush();
2 e" _" H4 Q: }+ O/ _ - fos.close();% ]; b1 f7 \" j: b) \9 G
- }9 a4 A. {8 w! T/ Q" D! i
- }' w# Z' }6 e1 y* ]* Z
- }
" U; V& Y! P8 |6 D t6 @ - message = "{success:true, msg:'接收成功'}";6 N5 E! \0 y `" r
- } catch (Exception e) {: l# k$ a. R) K8 K) I# l
- message = "{success:false, msg:'读取http请求属性值出错!'}";: Z; ^; `0 q; a \1 @& c
- e.printStackTrace();4 \+ K1 b/ D4 d$ ^& A2 _
- }finally{
8 `- Q* T9 Z2 {$ \& n! Q4 N# B L - out = response.getWriter();
- Q" x( i$ l- H - out.print(message);
! c' n- ~4 ]' @3 u$ X - out.close();
: t0 C) D3 V% E) z - }" o" h) w7 L& V! j( y
- }$ m: v0 p% E* ], \7 Q9 ~
- public void doPost(HttpServletRequest request, HttpServletResponse response)
) [7 Q% ?/ x K - throws ServletException, IOException {
; Q. @8 T* D- l2 ] - doGet(request, response);3 ^% r" L* o% V
- }( D0 o9 V4 u+ W+ v; ^
- }
% W3 I% k( e# R& ? - 5 H- U& h/ l5 E" S$ J8 L" H! K+ e
复制代码 & w' w0 E6 c' }' G: B
所需要JAR包: r6 K0 O% C; p1 g
commons-codec-1.6.jar# `. e; {$ R: p1 B0 Y
commons-fileupload-1.2.1.jar
" q/ L( o2 f9 S+ M4 o- o& _/ zcommons-io-1.3.2.jar
3 Z3 K8 i( F, P& qcommons-logging-1.1.1.jar; @# D7 u) v; q: \4 c4 S3 R0 ]
fluent-hc-4.2.jar, X& P" A6 e) }5 f; Q9 c4 @
httpclient-4.2.jar0 Y/ e- e+ l& r2 ^! x
httpclient-cache-4.2.jar
4 l7 h; W S1 s/ H) Q5 ~httpcore-4.2.jar' u0 B" w9 W+ {* P9 M( J
httpmime-4.2.jar6 X" Y# K" a3 A
$ X) C/ T: v5 j% Z& B* U* y+ k
项目下载地址:点击下载
" |+ t- A# c6 s9 S! [9 [7 p6 B6 y1 c& k
, t5 J/ }/ h2 c; U4 \0 X密码:
$ c% y* B8 x) I: k- F: R: Z, j7 |5 B$ y' X4 \
& S$ s' F" K, e: q
, j! r( R5 f; X' N: R, M# Y
, u1 _ B9 v9 f3 y% f" Y7 u |
|