TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
, N; |6 R; f6 ~8 D
. Y7 x: ~, Q" |% L4 H一、项目需求
+ F+ g) `/ D) |6 W' R+ T" ^; e 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。. P. R9 Y' U/ {$ p( Y
9 O! s0 W" a* Q0 S. O* t4 c
2 _8 x% g. d$ f3 g+ ~, F, ?. h3 C7 X
二、文件服务解决方案
0 U2 q- O+ P! g9 Y7 t2 U' ]; T1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。: D# H5 Q7 Y7 @/ s) N m$ d& y
* Y, R0 T, S) E7 o2 |
+ S( d4 _, Y! F0 ]" u: Q- Y- r配置详见:http://www.52itstyle.top/thread-10764-1-1.html
" t9 O$ }5 o. W! g8 S7 |* ]2 Q4 I& Z) E. V" P w
8 R$ b* m( Q3 \3 O2 e2 N2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。" J5 j+ Y3 C9 r [3 I
" B6 R' Y* N/ `( W7 D7 z6 v
5 ~5 g, F3 ~+ @- }! i配置详见:http://www.52itstyle.top/thread-17263-1-1.html
: P B8 v1 _% D w/ i- a: O5 h
! R+ z0 q; f% X$ I, ~
4 S# U3 z" a2 q/ _7 t; y/ u( Z3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。5 D! U. q: C% ^! q( ?
8 N5 {/ K$ W6 A2 B) G. {
4 _1 H1 [+ A! h0 z4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。+ S, r. }: m" P- [# i$ p( @
" F9 E. u$ v; F- N4 |0 u6 A# q/ f) ]) ]
5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
- I& H) c- G5 n1 D4 t
- M1 [' ]5 A* R) n
; e7 I: G% \( F" M5 n这里主要简单实现第三种方案(使用语言JAVA):# E# e+ m$ o5 H1 T N
8 R7 @" d6 j& @, y: W- A( g1 ^! Q$ U8 g7 H; E1 E
新建客户端 用于上传& \/ p& m5 C: T6 J W3 V8 I% K
HttpPostClient:
: {/ b# w8 U7 X7 x7 o6 Q6 y( C$ l- package com.itstyle.web;
( q, N1 F2 R' O) S( O1 H( Z; \
/ |0 \2 W8 \; O5 r8 i% U% A- import java.io.File;
, D" \8 ]/ d0 C - import java.io.IOException;
. g# x* {8 [+ t- q8 P* Q
; W F* m0 g, T5 {' W' P- import org.apache.http.HttpEntity;
1 [2 K) B, r! X/ n: g6 m$ l - import org.apache.http.HttpResponse;
w7 r# h* _. k- O* ? - import org.apache.http.HttpStatus;" L& s a, O' Y0 {2 h
- import org.apache.http.ParseException;
1 O. G, J: h, I/ D! ] - import org.apache.http.client.HttpClient;
6 D5 h( A" w0 |: J - import org.apache.http.client.methods.HttpPost;7 ]' n9 u, d0 Z: Z. m
- import org.apache.http.entity.mime.MultipartEntity;! X9 m- h: Z2 L* \! m
- import org.apache.http.entity.mime.content.FileBody;
, v6 @( H6 [8 V( I; \9 n) ` - import org.apache.http.entity.mime.content.StringBody; n$ w% u4 b1 N
- import org.apache.http.impl.client.DefaultHttpClient;/ S, @7 Z- _1 z; [& O% Z
- import org.apache.http.util.EntityUtils;
# `$ d6 a4 y4 f6 G - /**
. x$ G0 _. V( K% S5 T - * 客服端
" V; W7 b0 w, T& z* p - * 创建者 张志朋6 K: t8 C Y+ B7 O' U: f, h' ~+ l
- * 创建时间 2016年4月14日
I5 @0 {2 K* C- U. ~+ e/ x) T - * 科帮网 http://www.52itstyle.top6 ^3 }; W/ [- H2 n: A
- *
$ \, U e% a1 Y# P( K& o - */
0 u4 d! P+ Y/ a8 w, p7 y% B. L: W - public class HttpPostClient {7 T1 {/ h+ W3 C; z6 ]# C) @
- public void SubmitPost(String url, String filename, String filepath) {; L4 w- }, Y% _: J" y! [2 @# a( I
- 7 u! S/ n. d5 D4 G6 u0 Q
- HttpClient httpclient = new DefaultHttpClient();
* d' I4 s3 N( E- U/ C. ? - + e( c/ b/ j* Q6 j; v9 |1 @+ p
- try {
8 [5 b. U( Y# B9 w
7 Q# z- R5 i: {- HttpPost httppost = new HttpPost(url);
1 x3 W6 f* [# d4 @1 d1 n7 u
( g9 c1 h2 ^/ l1 p% d5 |/ U( b b- P- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
+ A$ X: X+ [ L2 G7 I+ h - ! P2 b: G, b% U
- StringBody comment = new StringBody(filename);/ O* k$ N9 e2 q: T$ K; S o( {
- * f; H( V# Q7 ^9 d
- MultipartEntity reqEntity = new MultipartEntity();& R5 S: T3 g$ T1 b$ w
- reqEntity.addPart("file", bin);// file为请求后台的File upload;属性; U4 S' E% J# q ?3 c. {6 A
- reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性0 q2 w! {" i! y/ V
- httppost.setEntity(reqEntity);- _( Y* V: H1 f7 N% E
- 3 a y( V. g9 b$ }, C, ^
- HttpResponse response = httpclient.execute(httppost);. l2 c2 E: } A" M
- 0 ^8 V! e9 \" O E
- int statusCode = response.getStatusLine().getStatusCode();
b$ b0 q! {) b! _2 z! W4 B - & n, O4 \3 M1 @) G+ G1 l' _
- if (statusCode == HttpStatus.SC_OK) {. v2 X: Y0 i, c* w* P: z! @: }
: Q5 J7 T. n9 {5 V4 ~- System.out.println("服务器正常响应.....");
' g$ t8 T% y, G1 @, }6 {
5 p% h: \/ P1 Z) ~- HttpEntity resEntity = response.getEntity();1 P& P. X- ^1 u& a0 k3 T y1 y
) n* G \0 f! }1 M* C7 ]0 z- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据
0 H3 B/ D+ m/ _% E
6 ^% p2 v0 k/ x, [7 R- System.out.println(resEntity.getContent());+ F+ o% C. x* @
- 0 n* X5 J( P4 ?# M
- EntityUtils.consume(resEntity);% P0 f/ V) n4 y' q1 ]$ h
- }+ {9 T0 k9 L( d b
- 0 [( ]9 @' J3 F* C0 c
- } catch (ParseException e) {( O' D7 R+ d5 D& D* J
- e.printStackTrace();
# j( a; M/ Z, \, O" Q- P - } catch (IOException e) {6 ?1 @2 a. u5 v( B+ [1 U, X
- e.printStackTrace();
( p6 j1 P. e4 [. { - } finally {
% `2 Y2 U- }! S: L - try {
6 e0 i7 q# o- P0 r- V - httpclient.getConnectionManager().shutdown();
* Q! J& a5 \9 C3 j) n' a - } catch (Exception ignore) { ^) r$ P6 W5 f5 h: l
- + J* C! c: y) j0 @! [. G+ P" n# M
- }" o% D# Q" e9 o7 Q& }9 c
- }: j& N/ b1 v; J4 s
- }
2 I% s3 E' D. y% m6 ]: H& Z i& Z - /**& |* b: A- |2 t/ K8 |8 b
- * 自定义文件名称 和路径 win环境下测试
3 P0 M( I* p2 u1 ^ - * @param args
. [! j: {" S+ @/ [. {6 Y - */
+ o% O* v, e" x, \" u - public static void main(String[] args) {
" {8 n- T$ A' a$ D- u - HttpPostClient httpPostClient = new HttpPostClient();
0 Z1 I: R( o- K9 d1 A - httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");
, ~' w i7 t: ~0 o0 Z0 p - }
* Y* q0 X* b9 ?5 _) a* @4 c - }6 N2 J3 ]8 K, c. M
- ! z( v- p! W q* d
复制代码 4 j9 a7 ]8 o, j4 S+ l, e) H) _
* o4 |. `/ v8 {# M! i9 `
2 J3 i6 {( |0 { [( m5 q3 f) p1 `
新建服务端 用于接收
: R3 N1 |* F& n* S9 W0 G6 ~* h+ K8 e5 bHttpPostServer:
4 f' @5 k& _* a9 i; t5 H4 J8 p- package com.itstyle.web;
8 p2 i% ?- s; H% X
9 }( w" ~+ H# m1 `- ` }- import java.io.File;+ U# Q/ f6 B# o
- import java.io.FileOutputStream;4 @& ]& h" H: c) h3 c
- import java.io.IOException;2 q/ L/ Z! ]; i+ ]- I8 h% v
- import java.io.InputStream;% a/ m$ q- g( V+ c
- import java.io.PrintWriter;
+ `5 s1 y% M! J, r, u4 }4 O - import java.util.ArrayList;
$ y# x6 C: y9 X" D+ B - import java.util.Iterator;2 T8 e3 h- o3 k! N4 R) z
- import java.util.List;
q+ ]$ M S. ?* D4 i) @" p4 C% f - ! j! T' t( l2 L1 K) Q
- import javax.servlet.ServletException;9 `9 {7 x3 A* J& k1 G& w. ?
- import javax.servlet.http.HttpServlet;
" C& j/ J$ ~ b6 W( M6 ? ^5 a - import javax.servlet.http.HttpServletRequest;" H+ @ U4 y' Q9 M& h
- import javax.servlet.http.HttpServletResponse;0 e# s+ G, q8 J) U2 u- O
- ; B( ^6 C {% S9 K- B9 A
- import org.apache.commons.fileupload.FileItem;. }2 F, Q4 G; v0 A, ^
- import org.apache.commons.fileupload.FileItemFactory;
% U r! t$ @- E1 | - import org.apache.commons.fileupload.disk.DiskFileItemFactory;8 [" E. m$ w7 _7 v; W
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
+ o8 v j; g% Z& B: u - /**
1 I; l; k7 j$ M6 e - * 服务端 接收文件
3 K/ f8 w' a/ T8 T. X& l, k - * 创建者 张志朋
& Q* U: i2 J# l3 }1 c+ E - * 创建时间 2016年4月14日
% B# L; Z6 b" W - * 科帮网 http://www.52itstyle.top9 j& L4 Y+ B* [) ~, R% c
- */
8 K5 s$ R; o% {, ]0 x - public class HttpPostServer extends HttpServlet {
; d; {7 _# K! D2 E/ }, _+ N- Q - private static final long serialVersionUID = -1002826847460469784L;& J- B: w+ x0 Y/ n
- : q: n d" y# z
- @Override! c4 m4 y |+ S! {4 z# ?$ I
- public void init() throws ServletException {
7 U6 j% `% U) R* U* N
6 W6 R/ ^( m v; B8 j; c( f3 r- }5 a# g; [4 h- W$ H# M
- ; ~+ k; [ h; N8 p7 P
- @SuppressWarnings("unchecked")1 K, p* g* d; `0 G( a, W; f
- public void doGet(HttpServletRequest request, HttpServletResponse response)
$ `* E" E4 K& `* @. \ - throws ServletException, IOException {
. O8 l8 N( O/ a2 d- M - PrintWriter out = null;; p8 ~7 W B6 p6 F0 i( T
-
# _$ z, S% s$ J& u& ~$ Y( Q h4 Q - response.setContentType("text/html;charset=UTF-8");
. ?* r# M$ l3 U1 z+ L9 y - String basePath = "d://test1";) ]* k( Y) C ]
- FileItemFactory factory = new DiskFileItemFactory();
, w% O9 K3 F& Q0 d - ServletFileUpload upload = new ServletFileUpload(factory);% ]- n% C5 q% i" K- ^' R+ {9 a
- File directory = null;
% j# b- j8 i* t# D% ?' A - List<FileItem> items = new ArrayList<FileItem>();
0 Q w* e( X" N4 x8 ~8 ] - String message = "";$ ?% _" ]4 K( f
- try {( G6 l' P: _' }3 G6 R
- items = upload.parseRequest(request);
8 P+ O, C7 I7 _9 y/ C$ o5 { - // 得到所有的文件2 y( `9 f' c8 j6 D, |
- Iterator<FileItem> it = items.iterator();2 M0 ~0 T Z' c: v- Z
- while (it.hasNext()) {
! ]9 H- M R7 S) N, m/ p& n - FileItem fItem = (FileItem) it.next();
& i+ `7 D& R3 C& R1 s) I, N: z( g - if(!fItem.isFormField()){
) e9 A$ K8 n+ N0 Q - String name = fItem.getName();
0 e4 \7 b+ ~% X! y, e* \1 V - if (name != null && !("".equals(name))) {* ?0 r, G$ n- N9 V
- name = name.substring(name.lastIndexOf(File.separator) + 1);
8 E3 H' s! ]& N+ n, M - directory = new File(basePath);! |) I8 G F6 O# S
- directory.mkdirs();2 a% r: P; k' B$ W8 x) l
- String filePath = (basePath) + File.separator + name;
! o! Q# x* G8 ^* a7 x% [- w - InputStream is = fItem.getInputStream();; h7 g% z0 b5 p: ?2 S6 _
- FileOutputStream fos = new FileOutputStream(filePath);' k5 d1 ]; m x+ c& Z& q
- byte[] buffer = new byte[1024];$ d& {' h" P9 O: Y8 @% v& i
- while (is.read(buffer) > 0) {, R0 H* l- @7 b; t
- fos.write(buffer, 0, buffer.length);
& H9 [/ ~: o: z" R; X - }1 Q6 X$ Y3 _7 s/ ~ E: v
- fos.flush();" a7 d/ w8 s# B
- fos.close();8 ~% _, S6 c0 i
- }( U, J7 G7 ]; Q/ k
- }
( b- A+ Q8 I$ z/ k" D* T - }. V }2 D$ K2 z- Q2 h' V- i
- message = "{success:true, msg:'接收成功'}";0 x' l# h7 c' k' ~
- } catch (Exception e) {
+ q( V: Y: S- h0 R - message = "{success:false, msg:'读取http请求属性值出错!'}";2 Y; f O& E G( k( Y
- e.printStackTrace();. a& `4 u4 W/ i+ X
- }finally{ g8 X0 `6 r0 j' p( o
- out = response.getWriter();
) N7 i1 a. [& O4 ?/ e" l X" w - out.print(message);( O8 A# u* X3 u5 j5 I
- out.close();: |: ?+ @6 D6 i
- }) i+ J2 d5 w9 Z+ D& x6 G0 b7 Q" |
- }: d( Q0 H1 ~$ C
- public void doPost(HttpServletRequest request, HttpServletResponse response)
2 E3 D4 n* m2 F4 e1 e$ q3 y - throws ServletException, IOException {
$ {, Y4 M _8 |1 q" Z - doGet(request, response);
& h! w$ v" s" p( ^4 ] - }
/ |! y# v) N: a, l/ P - }( m u W, ^" i
- * ]4 w# ~, Y5 v0 r
复制代码 ) u- ~# Q7 x8 d( x& ^
所需要JAR包5 r( F8 l$ F& V" @1 R
commons-codec-1.6.jar
" X- q' B* |; W' @/ C) m7 Gcommons-fileupload-1.2.1.jar& C4 b' m2 Y1 L! P+ B" p8 I) v
commons-io-1.3.2.jar
% u! _( W0 B3 y v; m$ lcommons-logging-1.1.1.jar4 D/ F9 t% j0 m( Z* g
fluent-hc-4.2.jar* t2 Z# Y; ~5 p
httpclient-4.2.jar% ^% S L5 g, x
httpclient-cache-4.2.jar3 ^% H* ~" Z1 [) D+ _
httpcore-4.2.jar
. ?/ e: _ e5 F( Y2 Lhttpmime-4.2.jar( A j9 z/ t D7 q0 |* M- |
' |3 \' q0 }# c: B% K1 b
项目下载地址:点击下载+ F! _( a) { [ w) }; X& t6 A
s/ J& L6 S }. l
9 L9 ]8 d" W/ _4 u3 ]. g密码:& d5 ~ M. Q3 g& [( ~
" T$ h S3 l: _) W. h1 X! C* _* e3 ~+ R
5 b8 d; {% L( V) q$ g$ ?+ O$ g/ l: z0 i9 [* K3 X! N
|
|