TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
7 l, u; S5 u% a5 N) t
# f: Y$ {9 o% D; S- b一、项目需求% Q) m) Y$ s' ]4 q
在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。7 C& A3 Z2 u# Z I9 m% h
% T) F A* {! R* a8 `7 i5 } }
2 U9 C# H! \, {" W
二、文件服务解决方案
+ i, Y8 v: q8 f7 r3 t, x1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。
/ R; b) w! A7 p1 h
, K6 o% H7 Z U( q( N) [" W! e. R8 ?) b4 }% |
配置详见:http://www.52itstyle.top/thread-10764-1-1.html
4 z F. c9 C, u3 \. z7 t
* y5 a$ T% ]+ Y; _2 x& k* B5 y6 \- d9 F0 h3 e
2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。2 c- o; t+ i! B) z
3 [2 W! c0 l7 F6 _* ?9 y& G" F9 k0 N4 v: \/ m
配置详见:http://www.52itstyle.top/thread-17263-1-1.html+ x+ E& U1 F9 t
* I( @( |. y2 v q( r7 O/ N$ {9 P7 Z$ c. G
3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
, s2 i9 n* h) T) W, O. O: ]8 `3 a! V. G$ h7 a+ v3 W' N
' d1 M7 c' o4 c* x) D1 A! a4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。
' _7 N6 B5 Q- f) h( g h+ o) j- Q
: p2 S- _4 u2 \* u; J; X) T8 V$ Q+ k5 v8 ^. O) Y
5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。- Q6 T: o2 X# J% I. l' q
% b. |& g P; a" a$ |! u: [: d3 n
" B, M R8 s' X8 o7 N这里主要简单实现第三种方案(使用语言JAVA):$ d& b: W# d D
0 E6 e3 b& X$ k# {/ Z" _6 U
! z- l: P& @ N新建客户端 用于上传. L$ Y4 K$ z, x+ h) s
HttpPostClient:
, i' T3 E- ]/ I8 i: p7 P3 s# k6 j/ Q$ D4 V- package com.itstyle.web;
3 n4 e& |2 u5 l$ i) J5 _$ H
9 L/ I& f A- N* f- import java.io.File;
/ t( _ K1 Q- Z: J' Q2 X - import java.io.IOException;
. d$ ~! g5 {( y( O
( y* Q1 V# T; F" ]9 k" Q( U& p- import org.apache.http.HttpEntity;& C5 {2 u% n# N, Q; G4 v
- import org.apache.http.HttpResponse; K6 v$ K$ q. R
- import org.apache.http.HttpStatus;
4 N7 ?2 A3 Y* @* \) | - import org.apache.http.ParseException;4 m1 g3 s4 { h8 } g
- import org.apache.http.client.HttpClient;3 m5 b2 w% |) f5 V" Q! I# I8 e
- import org.apache.http.client.methods.HttpPost;
: ?. b9 L$ Q+ u# q) q) j - import org.apache.http.entity.mime.MultipartEntity;
1 d; T" T f; `0 x* D& x, p - import org.apache.http.entity.mime.content.FileBody;
# r% v% D/ C8 v/ _ b+ `3 o1 G - import org.apache.http.entity.mime.content.StringBody;
7 c$ B' X, D8 D9 ` - import org.apache.http.impl.client.DefaultHttpClient;+ S8 W- P3 u& _3 g
- import org.apache.http.util.EntityUtils;
6 b9 W* M* Y( H# ?, M! v - /**8 f( [8 }& k2 y% ^
- * 客服端" m) `8 W1 H% C+ |
- * 创建者 张志朋
& S4 }) U9 O5 W+ \" G - * 创建时间 2016年4月14日2 n6 @! M6 `( M& b" h4 W6 f
- * 科帮网 http://www.52itstyle.top
" X& n1 U+ j0 Q, m, W+ } - *. M' n, I4 P; u# k8 V' u5 d% z+ b
- */+ Y, g" s/ z/ S
- public class HttpPostClient {, T8 M3 _. e) K) x
- public void SubmitPost(String url, String filename, String filepath) {3 v! d4 r( \" b& g! f% P1 [
+ q9 b8 w6 |. a4 d- HttpClient httpclient = new DefaultHttpClient();4 C% _& H) D2 g' g. R1 X0 Y! E
6 Y3 u0 O$ L! n- U- try {
2 T% n5 _3 c0 |" U' n
! ]: G; O) d" P- HttpPost httppost = new HttpPost(url);% T4 ]! i2 J/ x4 i% l1 W# F
- * h% E; C5 I6 s: A" }( o: j/ W3 G& J: [
- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
$ e0 h3 z9 V4 j0 z2 f1 _, Q* m
& F8 M+ S+ c) r: m- StringBody comment = new StringBody(filename);( o8 ~! a0 w: l6 s6 |0 I- a- g
) G. l4 G2 p3 I, @3 t0 `- MultipartEntity reqEntity = new MultipartEntity();2 J0 m) k }7 X( d
- reqEntity.addPart("file", bin);// file为请求后台的File upload;属性4 c! Y5 E6 r) ~ N5 g$ p
- reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性
% }- |; ]* L% M - httppost.setEntity(reqEntity);" Z8 H1 Y S1 x" D5 c6 _6 ]1 _$ f
( S5 z- J$ y2 S5 G7 A- HttpResponse response = httpclient.execute(httppost);& D- Y0 o' Y. o. J
9 M3 J9 T6 f+ r- int statusCode = response.getStatusLine().getStatusCode();0 C4 H: [5 }0 ` [$ J6 m) B% T
9 J* `/ ~8 [( ~/ k- if (statusCode == HttpStatus.SC_OK) {
8 h# Q) s& M1 @2 g2 G. Y9 K2 K - 7 C. i- v8 j) }0 t
- System.out.println("服务器正常响应.....");$ ]0 G9 Q5 y' F0 S% F' g
% K- Z. ]+ \' Q3 a4 c" w# I$ S2 ?- HttpEntity resEntity = response.getEntity();2 T" H: i4 p2 V8 P# [/ L; l
7 l% Y5 E \/ q; H+ C$ F- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据/ z! M" }* T M
- ) O" ^- |) `" P: G" r- c
- System.out.println(resEntity.getContent());* m/ p! D: I" G: ~! F
- 3 [! g! X7 G0 R$ A* {
- EntityUtils.consume(resEntity);3 |8 j, q3 r: Z% [; [1 C
- }0 h7 U9 x' o- A+ a5 L/ b
- & R# Z6 @& b ^
- } catch (ParseException e) {
/ o; p; b2 Q8 I6 B" L - e.printStackTrace();
. Y5 Q6 F- d4 R; A - } catch (IOException e) {
# K: y9 [7 ^& o' C/ g4 g - e.printStackTrace();9 S1 d/ ]# q. D( t2 j1 @
- } finally {
( i8 f2 G2 M, a6 }; o- u - try {
k0 B* R4 `6 ?$ h3 u - httpclient.getConnectionManager().shutdown(); ~0 J. `" {5 N! D
- } catch (Exception ignore) {
; h4 X) D, @( H0 | - 8 h! W5 W* r/ ]2 Z2 P" T
- }- F3 e: g- y& F- O8 a8 x p; e+ r; a
- }9 @7 I7 z. `5 h7 ^( b
- }( c) L" i' n2 H- b
- /**
* V) Y: A6 a; M" Z - * 自定义文件名称 和路径 win环境下测试
7 w9 I% a* e2 n+ a- O - * @param args/ s* F& Q; O5 h( s
- */0 V! u, m9 a. d8 e4 b
- public static void main(String[] args) {! _2 |. ~$ i1 `! L
- HttpPostClient httpPostClient = new HttpPostClient();+ k f/ M' Z7 h8 W+ J0 ]/ u; N& k
- httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");
! E9 i+ F. e5 [2 H$ n/ G - }" a+ B' L2 R- F
- }
; Z0 O7 T9 C V1 L! U+ e - & k/ V8 J: l s
复制代码
* \+ r, w& v$ Z3 ]6 t+ z% f9 K; x) ^
% T- L, r5 S; W
新建服务端 用于接收: C- z, {( C* f @( q$ j$ O
HttpPostServer:! |+ U7 A; l6 J% B& g6 y% G) d
- package com.itstyle.web;# L O3 U( v3 E) @1 d! X
- 1 L9 y6 `5 n& J
- import java.io.File;+ Y |; a% w# M5 c7 V' j! \
- import java.io.FileOutputStream;+ C4 F3 g/ v) ^* H
- import java.io.IOException;8 r. \' ~) ]0 R' j/ v0 Q
- import java.io.InputStream;5 T6 N- P" c- h9 c; W
- import java.io.PrintWriter;
+ m+ y" f% P0 }& ] - import java.util.ArrayList;
+ ~6 |7 u \0 p! |8 k% v - import java.util.Iterator;) M, U) q. T# ~. [7 k* G7 \. [
- import java.util.List;! k/ b6 z- w6 [& K. ]
6 i1 F2 z+ J9 Z1 A, W% e) b( r- import javax.servlet.ServletException;8 B6 @, ~$ W! |9 Z; v
- import javax.servlet.http.HttpServlet;- |: a6 n5 S" r; H! Z* @ f
- import javax.servlet.http.HttpServletRequest;
1 S. k( h8 v- {' j - import javax.servlet.http.HttpServletResponse;
* k$ l" _8 l6 c( _ - k- {0 t) a8 U9 {7 w$ c8 G
- import org.apache.commons.fileupload.FileItem;1 L: f4 F! `) i/ b$ v# ~$ i5 L
- import org.apache.commons.fileupload.FileItemFactory;2 v8 p8 u: Y0 y3 C* |
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;2 j2 f- ]/ q3 L0 }0 f
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
, P% j. }1 G8 L% r: j | - /**
/ e" M7 d0 Z! k/ O- V - * 服务端 接收文件
2 @* p7 e9 `( s, M5 r" b+ y+ H - * 创建者 张志朋
5 D4 T2 [4 o0 j2 Z/ K - * 创建时间 2016年4月14日+ W- m* G- x8 I6 {$ f
- * 科帮网 http://www.52itstyle.top* a a6 U, |9 } t* A e
- */
6 ]" ], R9 H8 w+ j7 ^. R - public class HttpPostServer extends HttpServlet {0 l. m9 L; D r% U8 f
- private static final long serialVersionUID = -1002826847460469784L;
3 R# r, l3 }1 F, W9 u
! W8 t2 i# q. J$ M5 N; L; E: o3 H7 z- @Override
( I$ Y* t5 J( j& j8 j - public void init() throws ServletException {$ y1 X5 h' @' ^" p: Z
3 k+ B6 T! e! Q$ D- }
( A" T3 w( v2 S `3 U4 H* [
$ v6 j+ o5 A) m2 e2 A- @SuppressWarnings("unchecked")
' ]3 L# |+ C" s( @1 B+ | - public void doGet(HttpServletRequest request, HttpServletResponse response)
9 A- Y% U! y( Y" A7 s2 v+ g4 | - throws ServletException, IOException {, r- ^4 f: s4 @0 \ I
- PrintWriter out = null;6 u) b/ g' a1 J) M0 g! u
-
. ^4 q9 k$ S; ~ - response.setContentType("text/html;charset=UTF-8");# O3 o, k2 l& I4 Q/ F9 |
- String basePath = "d://test1";
5 e7 l2 f5 a. M& H0 Q' ~% Z - FileItemFactory factory = new DiskFileItemFactory();8 l3 C3 \, J. @$ {" G! d
- ServletFileUpload upload = new ServletFileUpload(factory);
' a9 ?2 D y Y; `3 H" c' T - File directory = null;8 x8 H, |' Q1 `9 k$ Q# T
- List<FileItem> items = new ArrayList<FileItem>();0 x. w7 D) Z8 t( O: F* b
- String message = "";6 q/ U1 M; \! r) s; l
- try {& y" W) \& R, O b5 K7 s5 e( f
- items = upload.parseRequest(request);4 G, ^& r9 s: f ?8 R0 R' W
- // 得到所有的文件
& l2 C/ H6 S) v' K% q' N) j - Iterator<FileItem> it = items.iterator();
7 Z G1 ~8 c3 |9 h# a' g - while (it.hasNext()) {1 D f9 { {$ y' m
- FileItem fItem = (FileItem) it.next();7 v; \+ q4 J4 b# J' v1 C4 P
- if(!fItem.isFormField()){
. ]: E- u7 {( j3 d9 R/ D, _+ B - String name = fItem.getName(); U+ a- O5 D0 C w
- if (name != null && !("".equals(name))) {
* i7 K: `# g) S9 |1 M+ y( i - name = name.substring(name.lastIndexOf(File.separator) + 1);+ t9 ]. G% n0 J. J
- directory = new File(basePath);
9 a. F1 R) R4 x$ R' E9 y* N* M - directory.mkdirs();
9 ~+ o7 y# F$ H+ e - String filePath = (basePath) + File.separator + name;* C" \: m6 W$ f k. e3 F
- InputStream is = fItem.getInputStream();" P* ~0 E! W$ i% z7 F7 H
- FileOutputStream fos = new FileOutputStream(filePath);1 x/ a+ @7 I- B/ p6 a- [
- byte[] buffer = new byte[1024];
|6 }1 ?( R$ K/ f: V2 }# b - while (is.read(buffer) > 0) {
: s# S0 |4 m ^ - fos.write(buffer, 0, buffer.length);
& T, v) Y& [3 p" z' `3 e: ~2 L - }+ D) L9 a) g( d2 a* G' A* Z
- fos.flush();" b. u5 x8 f/ Q4 a9 p- U
- fos.close();8 Q1 t/ f& s( F* q$ U
- }8 S. c$ d6 N& W" `0 ]0 F. f
- }
& R2 e3 ^- C* P; J' S3 k, j$ B - }: s% a8 N" W' Z6 n
- message = "{success:true, msg:'接收成功'}";
; I7 ]5 n, R7 A% h3 ^4 r3 x. ? - } catch (Exception e) {% m' Y+ z! Q/ Y9 c' Y
- message = "{success:false, msg:'读取http请求属性值出错!'}";
$ b1 Z% G V+ R' b# g/ A - e.printStackTrace();
. e, y% W6 X1 K+ D% y - }finally{
' x4 n+ w% _2 c" u - out = response.getWriter();$ i; I) W- E7 x* R$ T9 b
- out.print(message);2 I' l$ Q8 I3 L! q. s# r
- out.close();
# F) U5 O* c2 ` - }
: e6 r' u! _" q e/ W6 Q9 \1 n - }; u4 p( u9 w- H2 V8 E9 Y
- public void doPost(HttpServletRequest request, HttpServletResponse response)
! @$ x* `, Y3 ?' X% y4 X y% o7 s - throws ServletException, IOException {8 j* k! d; K2 i0 h+ V3 y3 C
- doGet(request, response);. J! [ u7 L" ]3 D
- }
3 i9 p- } V, n0 |7 W - }
$ L' z. e9 S O9 N4 F$ @+ M - 2 G' h( u4 a+ G7 B! T; `
复制代码
* N# b) T Z6 o1 |: d所需要JAR包# f4 g6 A5 w2 r! _; E
commons-codec-1.6.jar
+ \5 F. W" E& d: d/ } S! V0 Fcommons-fileupload-1.2.1.jar
0 F9 U" C! r8 D$ r- b8 `7 [2 C* `commons-io-1.3.2.jar
- f9 O/ ~8 c* Ccommons-logging-1.1.1.jar4 d9 }) |# ]: U* L
fluent-hc-4.2.jar/ X0 Q8 L* J" ?3 c# F
httpclient-4.2.jar; Z) g7 H) {" Q! @7 [2 C; \0 B
httpclient-cache-4.2.jar
6 _# p7 W* `: U" t$ K* k% t) Bhttpcore-4.2.jar1 T2 a: ?+ h% p+ ], d+ H& S
httpmime-4.2.jar3 a/ }2 L6 c: r, z( j
( ~! d1 Q7 n" A5 j9 e项目下载地址:点击下载
7 y9 q1 q3 G e# A% z: b; A1 s* F/ Y" o$ `5 n4 i0 v+ j
& ^3 {2 Y# X j- s- ]密码:
- n' i3 C L: Q# m" {7 J6 k$ ?" K( Y, J
( X# Z, Y" P* z- {7 C: }1 ~/ M3 z& }: I+ w
' S, p9 M* N* ^3 P" Q' S
|
|