TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
' [5 e) r0 r! ], H$ o' D$ p2 L
1 `( `- N8 l0 N一、项目需求
# M" ^# }0 j" a7 u( k( q" ` 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
( _' ^$ \+ y+ K3 t4 q# L! b, E
2 t6 A! }. h4 i: h; z( J2 Y: ]
* q% Q- ?. N4 ~二、文件服务解决方案
) O ]- S5 E L! U6 u0 \/ ^1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。
6 r1 i+ b& F/ q8 ^7 Z! z) ~- d; I# t) J1 z6 k! Z, v
" x( ?6 ] S) [: k2 c
配置详见:http://www.52itstyle.top/thread-10764-1-1.html0 ^( _4 g4 }* {
3 S8 \! T, f. w9 I% C' w& S0 ^- D8 F. V) Z. R: o% O, ~
2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。8 s4 F7 s- N7 H3 M+ ?1 I* \
% W& O+ ^0 Y( t4 p7 H, X" I7 G. `+ n
配置详见:http://www.52itstyle.top/thread-17263-1-1.html
# H1 ~7 l, R; B3 a4 D+ ]( E3 g; R9 Y! c4 c* W3 y4 k
( X& X5 I5 F9 w* }3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
) m) M- p( S. J! H0 ]9 e$ ^1 u: X( ^+ H
: ^* Q; R7 Q* H+ |4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。' ~- X& A% P, a7 p$ g& C1 C h
7 [* E' ]1 u- t1 y, h9 P* n
h& @0 Z0 s! M# G3 J( h
5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
+ }, U' ?1 g0 J, v+ ?1 z* D$ U2 W' B! u! Y h" ?' n: t) g
& Q0 a( n8 T4 k$ Q
这里主要简单实现第三种方案(使用语言JAVA):
0 B7 h( A" L# E5 {- ?
/ a- C+ [3 j+ w) Z, i0 a! W! ^9 H* t& E( q' F* |5 Q
新建客户端 用于上传
/ P/ M% H o3 q. z/ b% t( C# _HttpPostClient:
: o; D! U; C$ R! Q% d$ ?( v- package com.itstyle.web;" r) L* R, V! j0 C' Q
: h+ Z8 D2 D& F8 c3 o% c7 o- import java.io.File;2 k7 ?$ a+ u7 f3 f. b: t* p! d# }
- import java.io.IOException;
* t7 u" E6 a, M A, |! Y - $ k4 e& A' p6 o3 U) M: }9 h
- import org.apache.http.HttpEntity;8 y. A0 A4 S; [9 \. ?% L
- import org.apache.http.HttpResponse;! C) u$ k( M- z) ?
- import org.apache.http.HttpStatus;
8 V- h7 c5 J$ Q7 L ? y. u" d - import org.apache.http.ParseException;5 E$ x0 s" {8 r# j" A4 D2 c
- import org.apache.http.client.HttpClient;
7 q- R. J0 ^5 K" Q: E. A$ E - import org.apache.http.client.methods.HttpPost;
v% J3 u# d+ X7 b& K! T/ A - import org.apache.http.entity.mime.MultipartEntity;
+ C6 w0 [$ ~$ q2 R/ Y/ [9 `$ I - import org.apache.http.entity.mime.content.FileBody;
, X$ s' H+ D" l) |+ L' f1 T - import org.apache.http.entity.mime.content.StringBody;
' p; d: Z) E: _1 E; n1 ~5 C; o# m0 X - import org.apache.http.impl.client.DefaultHttpClient;
4 L8 u! j- a$ K# |8 G8 e - import org.apache.http.util.EntityUtils;2 E2 H z. D0 A' z! J O: U6 U7 @" E
- /**
0 ]/ ~5 i$ H* C8 ~0 s/ [* O! e - * 客服端
0 X! A4 H4 ^# J$ C9 ], F - * 创建者 张志朋
" M" t: r9 G( y( h) { - * 创建时间 2016年4月14日+ ?1 L0 m2 Q8 n: Z. r
- * 科帮网 http://www.52itstyle.top% L; ]4 X$ ^2 |2 p% K0 c
- *! V1 \8 L! R4 [# `3 D
- */1 x7 @- c7 J, M$ H* }$ c/ D, A
- public class HttpPostClient {4 Z$ n7 ~: `6 z8 g" c
- public void SubmitPost(String url, String filename, String filepath) {
/ ?& n( j% g0 g( j. m3 e - 0 ^& l6 B. c" U3 j
- HttpClient httpclient = new DefaultHttpClient();- ?3 U0 U/ s2 _9 _
2 q4 q2 f9 a+ Z4 o- try {
1 L* V+ {1 X/ ]- n1 v6 Q8 v - a3 x9 [; _ n5 I/ \
- HttpPost httppost = new HttpPost(url);
+ C' P' X* i8 r3 m
$ q3 i" A+ I- F! [- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
: b" |$ F' h* [& o
5 s" H. j. Y& ]1 w9 E- StringBody comment = new StringBody(filename);
) U% q7 z' r( U D& Q, `) M
8 ~) [5 ~8 u. J- MultipartEntity reqEntity = new MultipartEntity();
" _& C, r% ]/ x! X6 ~ - reqEntity.addPart("file", bin);// file为请求后台的File upload;属性
* M" L# `: H6 q. f8 h1 E5 P - reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性) I6 g: q+ o* M" O' @/ R
- httppost.setEntity(reqEntity);! V6 }, F7 f+ j- g5 n( S) t
5 I- U5 v* K3 r6 s q7 |- HttpResponse response = httpclient.execute(httppost);
5 D1 G5 p! n0 f3 p4 y& t
8 x: h( x; X! w5 z/ J- int statusCode = response.getStatusLine().getStatusCode();
0 J' x& G: X$ c
+ g; |3 ^# v7 o6 J- if (statusCode == HttpStatus.SC_OK) {
6 r2 W z& N! |2 ^4 l7 b
! J. h. b. P( R2 M3 k- System.out.println("服务器正常响应.....");
! E# K. |+ ]5 b5 h/ P. _ - : Y# {) _! ]+ e3 W$ r( c9 `
- HttpEntity resEntity = response.getEntity();2 [- E! h# B1 m( x3 B( ]
3 s# \; `. t: R- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据
& S( M3 M+ D7 a
. M5 n: d4 s' j( t$ t- System.out.println(resEntity.getContent());: p3 p+ ~# J5 g4 x
( ^$ i- K0 m- ]- p8 G0 b( R- EntityUtils.consume(resEntity);3 M8 X* k6 d( z/ V' w( F/ W" \- E
- }
4 y9 u1 d$ D) `* g% _
- S- G6 P3 w7 T2 ~- } catch (ParseException e) {
5 }, O! L& G: f7 K& Q - e.printStackTrace();) [1 b" h7 j2 O1 z9 _
- } catch (IOException e) {
' U, g; Q* E7 V9 k( J9 C - e.printStackTrace();
, Q! u7 s* r* \3 D3 ?3 A - } finally {
F# c! v& @" R; Y. N - try {9 M6 B- K8 j0 k& V; T
- httpclient.getConnectionManager().shutdown();
; i: t9 m6 {! ~ - } catch (Exception ignore) {
% p4 k @; Z: w( M3 F% X -
0 a" L+ ~$ L) X0 T7 J% G5 _8 \ - }
+ h4 F1 b! O s1 |7 d" G c9 _ - }' E! Q/ R; w. `" f
- }5 W/ _8 R; V3 k% P; R
- /**, ]# k2 ?6 ^! t
- * 自定义文件名称 和路径 win环境下测试
+ W& a. p |7 i - * @param args/ ]& H3 b ^* s) P3 v
- */
v: v8 H% u- ]7 H* V7 Y2 ~ - public static void main(String[] args) {
2 R" ^- D1 w$ i. }, [. c - HttpPostClient httpPostClient = new HttpPostClient();
# q4 @' _: L' h$ j: X& y8 @6 h - httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");$ }3 g( Z V6 m7 q
- }
: L" L; `: m1 I: g6 ^9 T1 m$ Z- h - }
5 N% R) X8 A' q* |; i - 6 j! U! S. \/ e# Z; a
复制代码
' O; w1 \3 z" m1 e- c; N3 I. A3 D8 v6 P5 ?' X: q
0 K+ b: e- j+ j) A2 r
新建服务端 用于接收( _. [* r% m1 d6 [, B
HttpPostServer:- o$ o3 w# I/ o% c: ]
- package com.itstyle.web;) O) X8 g% [7 ?9 v3 `
( d* Y- F. D4 T1 p- import java.io.File;
. z9 G. d' j- _( x& a* B+ Z) g0 F - import java.io.FileOutputStream; Z+ f! N" h5 ~& a
- import java.io.IOException;- f1 ]0 O1 ~0 L+ W
- import java.io.InputStream;
6 ]/ K% n- B' w7 a r: ]7 Z6 ` - import java.io.PrintWriter;9 \0 h5 }% g5 k2 j2 p5 W9 T; \
- import java.util.ArrayList;' {7 O! a/ q a6 O2 D
- import java.util.Iterator;( ^/ N% ^4 L8 q7 Q, I3 s
- import java.util.List;
4 J% z: \) y" o' H6 y6 a
' J8 Q( l1 V: n- import javax.servlet.ServletException;
& v3 A2 y1 v* l - import javax.servlet.http.HttpServlet;
* l& r1 j9 ?& c) v4 J - import javax.servlet.http.HttpServletRequest;! ]4 e5 P& z% V+ V, i# y
- import javax.servlet.http.HttpServletResponse;8 S% Q* x: ~' O: J# i& }" L
" L7 S, M$ h6 h4 r9 r- import org.apache.commons.fileupload.FileItem;" ~% w% W; A8 r o
- import org.apache.commons.fileupload.FileItemFactory;
; ^: U3 T R h6 M - import org.apache.commons.fileupload.disk.DiskFileItemFactory;
( O9 E8 d/ J' R B- A: _ - import org.apache.commons.fileupload.servlet.ServletFileUpload;
; r5 q' ]: p: d& l! g9 f; ?* e - /**
6 O9 Q! V7 L4 J( h* G0 c - * 服务端 接收文件% H% ~1 f0 F* L6 M4 d- Z
- * 创建者 张志朋
9 a; [& G) b1 j7 ^7 R. _) K - * 创建时间 2016年4月14日6 w, \6 j' \3 I g6 H: P& b
- * 科帮网 http://www.52itstyle.top/ n% r$ N, Q/ b h6 f2 E
- */
$ F; x: G% x& {/ Q - public class HttpPostServer extends HttpServlet { V, P: F/ z0 Q/ A9 j7 R' |
- private static final long serialVersionUID = -1002826847460469784L;7 r$ I0 r% g: {% L/ f
2 ]+ ]9 R3 h" @1 Y4 A- @Override
/ X& u4 w$ v( u9 [# \! d - public void init() throws ServletException {: B6 I7 U% X/ R. f: m( ]" z
% r9 b% ~, I* Q5 v5 }! [- }
7 E! T8 |, ]' u- X6 \8 [ - + t" X/ ~; v, ]# J& L# G- {: Y& o
- @SuppressWarnings("unchecked")4 X1 l$ ^/ ] `
- public void doGet(HttpServletRequest request, HttpServletResponse response)7 T v0 J2 Q& ]' X, x
- throws ServletException, IOException {
; ^9 t5 m3 i3 y B, M - PrintWriter out = null;
. ?4 f* |- [. ~: {7 u1 e0 h: ^ - & A1 P8 ~5 F2 j1 N$ P" J# ]
- response.setContentType("text/html;charset=UTF-8");
7 O7 g4 u0 H B - String basePath = "d://test1";
6 i, R6 @7 k+ m {7 n% S. P- D - FileItemFactory factory = new DiskFileItemFactory();
$ \; t3 q8 `: a7 ]6 k3 L - ServletFileUpload upload = new ServletFileUpload(factory);: X; G9 L8 H, _+ U* o
- File directory = null;
! p' L3 g; | t( n. [+ l - List<FileItem> items = new ArrayList<FileItem>();
5 P8 K" A- f7 ~ - String message = "";" S7 x2 L- F% k. f3 T8 O# B# [
- try {
3 x3 U! R5 i. i* c: T - items = upload.parseRequest(request);
' ]5 M# X }0 S5 u8 P - // 得到所有的文件
. r4 Y9 H q) Z" I - Iterator<FileItem> it = items.iterator();
8 f- ?5 A8 s* m! n - while (it.hasNext()) {
, U: v; Q) o/ Q7 L7 n! ?$ | - FileItem fItem = (FileItem) it.next();, G# B; b1 m1 b+ \: u; O
- if(!fItem.isFormField()){, ^* X# Q( ~' i V: @, S0 O, d9 A
- String name = fItem.getName();
/ P6 B7 o3 u6 |4 o: ]9 g+ H/ ~ - if (name != null && !("".equals(name))) {+ g: `/ |1 q% u
- name = name.substring(name.lastIndexOf(File.separator) + 1);
3 K E. _( x5 ]/ Y; D# \; N# e- Q - directory = new File(basePath);* s2 X5 H* d. W& P9 N
- directory.mkdirs();& l. K! H2 a* F: W
- String filePath = (basePath) + File.separator + name;
# W# b+ F- I0 b1 Z - InputStream is = fItem.getInputStream();
5 w. F# H( x0 a5 k% w+ C9 q - FileOutputStream fos = new FileOutputStream(filePath);
1 L: B0 R; g9 D7 s, M - byte[] buffer = new byte[1024];! F% i+ c1 z' i9 f" s5 `
- while (is.read(buffer) > 0) {
! m: i' D2 y3 Y" X j( w - fos.write(buffer, 0, buffer.length);/ U- f# w- `0 m" E
- }
7 o9 |* r' b; P - fos.flush();1 m$ h- t8 d4 L) T
- fos.close(); j; O' H& N8 t) [2 ^3 X
- }
q/ e6 Q9 o! Z - }
7 @& Z W4 G+ b3 A; j1 X - }
% g; }) |6 e d; b9 q - message = "{success:true, msg:'接收成功'}";
% M* C4 O# N2 P% O; H - } catch (Exception e) {
" |5 O9 T' H6 b- q" } - message = "{success:false, msg:'读取http请求属性值出错!'}";( z, h/ J( z$ z+ r1 c
- e.printStackTrace();
" H: u' K0 R: c: b' U+ k6 J& Q( z - }finally{
7 d, Z7 k/ ?" {/ s - out = response.getWriter();
0 M4 s. U1 G! J" F1 Z - out.print(message);
4 X. y3 V! m. m7 F b - out.close();
9 z: @4 F+ E) i1 d4 ^. j - }
* t; O3 H. q$ J) B' `7 l8 f7 R - }% F0 I' L3 U, D; N2 ?
- public void doPost(HttpServletRequest request, HttpServletResponse response)
: I A! q: |, | - throws ServletException, IOException {$ w7 T( P; D% s: v$ ~" v* {
- doGet(request, response);1 i( {4 Z; N% G3 n: w* f
- }$ P, K" u9 s0 X+ i6 L
- }( {, K0 D* N+ C& P
' Z, I! d: F6 c- U) w8 Y- ]4 j# H: E
复制代码 + R6 j. f# p* ?( n; ?3 |+ V0 ?
所需要JAR包
7 ~+ c- h9 g* O" d7 h4 e4 icommons-codec-1.6.jar
0 K9 G, ~% ^& W W5 pcommons-fileupload-1.2.1.jar
! e/ p" L4 W7 N2 o" B Z0 @% y6 ocommons-io-1.3.2.jar* q& g5 N5 _2 p
commons-logging-1.1.1.jar
# ?$ h. V! B! t! `; }0 B% }fluent-hc-4.2.jar
" X7 ]& v8 E: x: C Ahttpclient-4.2.jar- G: A4 G: U7 j; v' M
httpclient-cache-4.2.jar
1 x1 h, @( G# G0 h0 o/ Qhttpcore-4.2.jar- g0 j4 p; X, x, v" i; @! j
httpmime-4.2.jar1 r) ]9 E4 I6 _0 T @
( p* L% s- N" D1 {! N V项目下载地址:点击下载
2 m; i5 v t% D; X6 z( d. ]6 N+ p! h
1 F! L) r# f& X
' L& u: ?' o7 n/ W. O密码:9 c6 ], T% [2 a& y$ Z' g3 s
% M5 q0 B3 P. N8 G+ p! m$ o+ J5 ^7 m6 ^# S5 s0 ]0 x, Q7 b
( z0 d3 h3 `0 X) Y
3 h: L% m2 ?+ A |
|