TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
c" k1 V" {' C# p. j: h8 C
! P1 d7 Q6 w* D1 K一、项目需求
4 O; w2 `; e$ B 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。! \' h( R& K2 O( V8 S6 d3 u" N
* _6 M3 G( B# A3 ]+ ]* M5 j6 d/ L" _
) y4 H5 H. h9 S' `4 ^1 v二、文件服务解决方案: f1 ?1 a A1 s6 O2 J/ }6 w# S
1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。/ q- z: V1 q- P# ?% E2 l2 q
+ g3 A; Z. h( _; I3 T) b+ }, S1 R! t/ G; n9 s/ F1 b9 |0 r
配置详见:http://www.52itstyle.top/thread-10764-1-1.html
{) a4 t# l& {- j7 Z$ J
! k5 G" g4 y+ z6 ~
1 `4 ?) H& p% L2 Z9 s0 P$ A2 W$ B2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。 ]$ m, n3 |! d0 j% t/ i
6 C' t4 o/ h9 W" p! v9 N% S- J$ u: b, S9 F4 c" E9 t6 G! ]/ E
配置详见:http://www.52itstyle.top/thread-17263-1-1.html; c$ L, ^ ^2 m7 S6 U; G
; g: q) w( y$ _0 |/ ~& d5 b" v
, M. T2 L- W7 [) Y( V% ^7 H" Q3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
+ Z- w6 h7 H/ {- ?6 u
# f& }: i6 U* m0 f6 u
. W' o7 B6 Q) o3 [4 H7 l" m4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。+ C( `. k: z) C2 q# e/ b' k/ q
; o7 a; }$ n3 o
* R0 \/ ~0 j1 c u. I5 z. m0 m+ ~5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。' L' m4 Z& f! L& n
& X5 s' S# u! ~; w% z: R% q. @; b8 g" f" N4 |! ~4 R) y! D3 @. R& B/ f
这里主要简单实现第三种方案(使用语言JAVA):$ k/ J8 V+ Q, n+ L/ f6 L
# N" S% G" r& D4 ?! d: \3 T, ~6 B" i; W5 Y
新建客户端 用于上传# L3 v7 Z9 l0 L7 x) S
HttpPostClient:
0 Z% u: A4 B+ t3 R0 J0 i- package com.itstyle.web;8 l3 r8 v+ v9 e1 T; E9 t8 o& T
- 0 Z) ~+ A' T) q6 F8 m
- import java.io.File;2 K1 M7 a: A7 Q# R
- import java.io.IOException;& R# |6 N/ H- H1 u# R1 h0 _1 n
- - B3 `* ^' k# c6 g# |' I/ F
- import org.apache.http.HttpEntity;/ _7 ?+ h! h0 T$ o; [
- import org.apache.http.HttpResponse;
, M3 _8 | G+ }- n, @/ q6 t1 |/ | e) K# { - import org.apache.http.HttpStatus;
3 a: C" C- b) Q" Z* N( Y" v$ v - import org.apache.http.ParseException;
5 i5 S G, B6 o - import org.apache.http.client.HttpClient; w: E% ]' \( R9 a1 O% @3 {
- import org.apache.http.client.methods.HttpPost;% u4 x' \7 g6 M" h4 G
- import org.apache.http.entity.mime.MultipartEntity;
" i6 \, v) H% d! ^; P& _1 v# K$ w - import org.apache.http.entity.mime.content.FileBody;
0 G9 `) r. ^- ^- Z4 E/ K - import org.apache.http.entity.mime.content.StringBody;- j' \) S1 H/ s# a+ U; e$ f
- import org.apache.http.impl.client.DefaultHttpClient;4 r. T' f9 h. F% {3 p
- import org.apache.http.util.EntityUtils;
4 S( f6 i$ ~* I u: Q( }- W - /**1 q9 t3 x* z' ?
- * 客服端1 r- ^- o2 H( z3 a8 H
- * 创建者 张志朋7 D) V* T9 i/ T+ u1 u
- * 创建时间 2016年4月14日
- @+ V+ r: I* d, Q, `& S& W - * 科帮网 http://www.52itstyle.top
& W6 H5 r& k( w. F - *4 L7 y5 M+ n4 r+ r4 U0 h1 K
- */
5 r" g2 T: A1 d4 z+ T - public class HttpPostClient {5 i' J3 _" D; Q: J: O
- public void SubmitPost(String url, String filename, String filepath) {
8 S: R; x9 b' A. I; x
; ^! e: h8 m' r1 T! Q- HttpClient httpclient = new DefaultHttpClient();9 R" u9 o1 v# }. a
% {; Y1 v1 A( S. N& a {- try {1 }$ j* s8 ^& {4 W( \
( h3 ~9 d% m. M9 I2 r! ~- HttpPost httppost = new HttpPost(url);2 R+ Z1 v/ @$ K k3 p
- $ D( q0 \ B) e, o, e
- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
$ Q! Q0 b6 n2 r6 d% s/ h, }0 [, G1 j
! K' }' m/ S% \8 t1 J4 ^; J- StringBody comment = new StringBody(filename);+ q( I7 I8 G3 S; n8 G7 v2 a
z$ ?. g9 M* R) X! U' h- MultipartEntity reqEntity = new MultipartEntity();
3 y# t7 @- p% T0 z1 \( O- P/ w: ] - reqEntity.addPart("file", bin);// file为请求后台的File upload;属性9 p. n/ @2 _' f y1 H J
- reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性$ J2 |3 S/ e4 D5 U" _8 \
- httppost.setEntity(reqEntity);
" k" z4 S/ i4 `% F7 t5 o5 H
# g i- h% x* |( H9 x7 y& P& X- HttpResponse response = httpclient.execute(httppost);
' J) o6 Z, Z5 @9 S7 B/ m
0 }! x% R. \# i- int statusCode = response.getStatusLine().getStatusCode();4 s8 I) u, f% s8 A% J7 a4 _, w
4 Y+ m- x) ^7 s" f/ L* a- if (statusCode == HttpStatus.SC_OK) {
5 T; i8 l: @- u
5 `( @% d; g& S" N- System.out.println("服务器正常响应.....");$ L$ e( w/ P% Q, y H$ E" R
1 x" B) @4 Q" I- HttpEntity resEntity = response.getEntity();- X# m! V9 b0 w- p( J, s# m$ M8 X; X
- 9 ?* K3 A" k* {! T
- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据
& x1 s3 ~, J9 m' A- v5 ~ d
- O! b" T7 X0 e; t' x1 V3 d- System.out.println(resEntity.getContent());
0 n1 v; L- _: O- }
* e l0 ~/ Q; H/ e- y, o$ w" G- EntityUtils.consume(resEntity);8 `/ A( {# z) C
- }4 R2 \8 p/ A% T& q, |4 Q' s
, k, m6 }- `8 H! R- } catch (ParseException e) {7 T) x7 E% d7 p0 h' b3 m' l4 Z) w. w
- e.printStackTrace();
# S% f7 f( p7 E* Y- S, @, i6 q' y - } catch (IOException e) {
3 _6 {' T7 a5 f* G# a - e.printStackTrace();9 `$ F& {3 V" C0 E+ K
- } finally {, T' ]2 z& w) L
- try {
) s9 D, Z0 l: h" L - httpclient.getConnectionManager().shutdown();0 y W" n; ^0 Y. ]& ]
- } catch (Exception ignore) {" {& h4 {2 T/ b( E0 h6 `
-
) X, y: {8 _- _' g - }& f; `' k6 z; y& D* J. M1 n
- }
4 ?7 X0 M& Z9 n6 u) o: g& l - }
X! W+ L6 A: u( |' z9 _ - /**
& i0 B7 r0 k- t$ N- W: V4 o, J - * 自定义文件名称 和路径 win环境下测试
7 b. P0 m7 z5 u9 S - * @param args0 x3 C+ W& G; B; |7 `
- */
8 W) _1 z6 ^4 P9 k j% E' }5 j - public static void main(String[] args) {
- f0 B5 F& f% N: j' d - HttpPostClient httpPostClient = new HttpPostClient();
c! @- v+ E8 u1 b. w7 D - httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");$ `' i/ ^: m, P4 {
- }0 k8 i V" J7 R4 G( V" A1 B2 Y$ n9 _
- }7 {- N& ? ~- b0 j, V6 Q
4 e% s/ B7 V" _# y5 _7 ]1 M( B2 F6 S! B. x
复制代码
6 ~' M, ~, R* R* V6 a1 T# M
5 t4 E" R# I' l$ U9 M$ c1 D
0 |" c& X' j+ `+ Q2 R: Y新建服务端 用于接收" }: x" |& v2 e, h% c' E" K
HttpPostServer:
G) X B4 K A/ Q- package com.itstyle.web;% r: t3 f! u' z
1 B" _" Z2 y" x* W# P9 X- import java.io.File;# z" K; w' h! ^0 ]- A" M/ ~" Y
- import java.io.FileOutputStream;: N' [7 E1 Z b: l1 H, \
- import java.io.IOException;; `" X# H) W" G x' O' }% u
- import java.io.InputStream;
4 d5 D B l. N8 a% u" f' w - import java.io.PrintWriter;
1 w; q. y: j. O- S; @1 B - import java.util.ArrayList;
8 G$ ~5 ^8 A! F4 E, l* z - import java.util.Iterator;8 O; W% U0 K- e
- import java.util.List;, j+ c: M8 m! B; l
- - h( A: `6 T8 R- t" W" _
- import javax.servlet.ServletException;' T2 H6 d8 ~# o1 H
- import javax.servlet.http.HttpServlet;
2 U" T/ [+ B: ?3 R. c# y - import javax.servlet.http.HttpServletRequest;! @9 G5 V9 w. y4 W3 |; w5 I0 N
- import javax.servlet.http.HttpServletResponse;" u- r' e2 B3 u( ^8 P u6 f/ w. G) n
- " v9 ^/ {9 ~. Q% ~: Z* M1 U
- import org.apache.commons.fileupload.FileItem;
5 M; `+ E2 U4 O, R - import org.apache.commons.fileupload.FileItemFactory;9 C# {- |) }: h( Z* G9 G. B! t# F) K
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
7 H9 W2 l# R1 l' b' g5 ~1 ~( f7 p7 q, v - import org.apache.commons.fileupload.servlet.ServletFileUpload;4 L" X" S% a. w- x0 d r' Y
- /**1 ^$ Z( W5 p @
- * 服务端 接收文件, g, a$ i; y2 d9 T
- * 创建者 张志朋; w0 p& {* t5 ~) _
- * 创建时间 2016年4月14日& n) p0 A2 C5 S8 @4 P* d+ p
- * 科帮网 http://www.52itstyle.top8 p2 m8 V1 x- U+ a6 _$ [: c
- */4 V" O& g$ G* x, o- l4 E; U
- public class HttpPostServer extends HttpServlet {2 m! V# e# f5 M5 _5 ?/ V7 r& W+ g% F
- private static final long serialVersionUID = -1002826847460469784L;
- n- F$ D# D% W( _. }
9 l; w$ J' [$ O- @Override- W8 f9 J# [. T4 c
- public void init() throws ServletException {
4 y$ _% e5 R7 L0 Z
; G. m/ z3 |3 @6 ~) m" l- }
6 P8 ^' F9 Q7 N8 C7 r
! K# s3 ]0 r) |0 ]5 t9 H- @SuppressWarnings("unchecked")
J! I. _) ^; J1 U - public void doGet(HttpServletRequest request, HttpServletResponse response)
3 l6 x! e" Z6 a M' C( i - throws ServletException, IOException {
( w- A7 J+ }+ i, E0 A; H$ d9 C - PrintWriter out = null;+ L( M/ q& k+ g* B) ~
-
9 k/ ^; ]5 |0 i+ d; Y* R9 j - response.setContentType("text/html;charset=UTF-8");9 M/ l2 |9 h. o# D! B" {
- String basePath = "d://test1";: P/ W. R3 ~, J3 c4 s
- FileItemFactory factory = new DiskFileItemFactory();
7 U; B& k/ d9 f6 t8 s7 Q - ServletFileUpload upload = new ServletFileUpload(factory);
1 E9 F3 w# y. z* p- j8 V: U - File directory = null;$ G3 s( d( ~6 b
- List<FileItem> items = new ArrayList<FileItem>(); Z7 i+ G- I) x. a, l+ S
- String message = "";: b; O$ [7 w; W
- try {
6 B6 |9 a/ }/ e( H5 W$ ~ - items = upload.parseRequest(request);4 f( t2 A! B" K6 M3 X3 E- v: }7 T9 c
- // 得到所有的文件 P6 K' V; x# A7 i
- Iterator<FileItem> it = items.iterator();8 `, z! a6 U. C y' J2 }
- while (it.hasNext()) {0 r7 H5 ^" k! h4 V, G0 Q$ D
- FileItem fItem = (FileItem) it.next();; \' f7 ~! {5 E6 {2 [
- if(!fItem.isFormField()){
& k% `2 x2 Q& g- v j/ t - String name = fItem.getName();2 C. C! l) I% p& B* U- t
- if (name != null && !("".equals(name))) {, r7 |! C6 j# ~3 J
- name = name.substring(name.lastIndexOf(File.separator) + 1);
! V$ d" H- o' }, x0 V, }1 x: t2 B - directory = new File(basePath);' Q3 V; S' {0 m# A( N
- directory.mkdirs();2 L% u; k5 l _: Q
- String filePath = (basePath) + File.separator + name;8 n- z9 \% ^: f0 m
- InputStream is = fItem.getInputStream();
* D2 O! ]' [! Q B7 X& F - FileOutputStream fos = new FileOutputStream(filePath);* ^* z% N% k% T& A1 S/ l& O, a
- byte[] buffer = new byte[1024];
, U$ C* n( d) ]9 o; g' s, f& m - while (is.read(buffer) > 0) { i, I3 E7 f) L! u% l9 W+ w
- fos.write(buffer, 0, buffer.length);
. i: U8 k9 A: r - }$ o' O% r! N \9 J- i! ~6 v- f
- fos.flush();3 C$ {+ @3 |$ e) N O
- fos.close();
$ e! P) i; N6 J4 X( f1 p& P1 T - }" l" |: a- ^7 }( l; ]0 U
- }$ s+ o$ w: z* H* x' L* Z5 M" J6 O
- }9 e2 L" D: \2 ]; F3 g) W; R/ k
- message = "{success:true, msg:'接收成功'}";. V2 B: W; X+ c/ y! t
- } catch (Exception e) {
# V) P6 P; R O& @- ^& |+ \8 [ - message = "{success:false, msg:'读取http请求属性值出错!'}";0 O$ W+ u1 Z3 e# B( _! d
- e.printStackTrace();1 L1 k6 D7 n3 ^9 W6 B' F
- }finally{
( E, O1 O T- z& `+ Z5 y5 i+ q0 g) q - out = response.getWriter();
' M- e5 o# M/ a$ L2 X - out.print(message);9 L! V' |7 V% ?9 W3 e' I5 t1 ?
- out.close();
$ M- A4 X+ i4 g - }% v5 F) s/ |# P" m2 G+ a9 V2 ~
- }
: X1 S* X. s2 M$ ?7 A0 Y. `; U- S - public void doPost(HttpServletRequest request, HttpServletResponse response)# w$ j4 w) V# H2 _' `. A/ F2 h0 E
- throws ServletException, IOException {
- D, ?' ?/ O/ _ - doGet(request, response);: y* U0 r0 u J& c* q: g
- }0 B% A6 F3 \4 K6 b
- }
2 W* m8 j7 n8 v$ B& q5 c - ; z* h2 S4 U. d5 I" n0 }# q
复制代码 * C- B7 }% \$ U6 v/ {
所需要JAR包# N4 d# [6 W+ m; f
commons-codec-1.6.jar# y% @! M' y1 [2 ?- m' T
commons-fileupload-1.2.1.jar
9 b+ z. c8 Z9 q. f* U4 xcommons-io-1.3.2.jar1 p0 O% Y+ I6 |9 V# ?
commons-logging-1.1.1.jar; ^* y6 b) ?1 |) Z- r# J
fluent-hc-4.2.jar( O7 g2 S- m- P9 ~" y
httpclient-4.2.jar' D2 j( X; E, q' A: ?" S* h; e
httpclient-cache-4.2.jar
7 k1 T+ e2 P/ b$ O7 e1 M2 {httpcore-4.2.jar
$ T/ p! Q. w5 f" zhttpmime-4.2.jar0 y- X" @- D/ R x
! ~1 l0 T0 }3 o$ n( S
项目下载地址:点击下载2 v7 y4 g7 p2 L2 g- \" d
1 E8 k0 ^( I3 N8 ] `$ n0 ~8 }3 y- C8 `, u2 \$ H$ ~' |4 c; O
密码:* M8 ?$ O. [4 V
0 g6 H5 I6 ]' |/ i
. z/ v9 O% `' P# @: \
1 G) M3 ~0 |" c" D- Y& B: D4 u( g( [: e
. \& ?! y+ N$ m |
|