TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html
F+ F9 |2 J3 x, _# j1 j0 H- j: m& w6 X [5 K1 _. {2 G. F
一、项目需求
' @* @$ a7 T/ {5 m+ G 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
. C9 J' a$ m+ M3 C; c6 E6 ]$ \
2 ?$ r% ?) `' T# p R6 m _% c+ H; b. Q8 d3 x
二、文件服务解决方案, e; |, F0 Q3 b+ j7 V; R
1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。
' Y5 @7 n9 S7 \* R4 H2 o( u2 U
5 ]; @, C- g1 d" J, [6 S6 e
* B- P5 E$ L, r( x" C' ^配置详见:http://www.52itstyle.top/thread-10764-1-1.html
$ R8 M2 K4 J r* s6 M0 J8 U- `4 K0 _% z* t
: t- ]$ z: T4 k P5 G3 D1 g
2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。
0 ^$ L: `- n( d! W1 g/ p5 T Y
2 J. T1 P( N3 E/ z* e, d+ ?5 c
配置详见:http://www.52itstyle.top/thread-17263-1-1.html
6 `) f7 R$ s0 h7 d# v
8 f6 c2 q a, E5 ]
* _" _5 v7 Y6 t3 _- Y8 v3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。+ ~* e8 D$ a) c% K2 I# `
5 v- a; y9 j* k) n. }, P
( R( B6 x1 G8 K7 H: x; a6 X
4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。
( W& H: F7 t7 c( V1 d7 i
- d- U& _0 A/ c( J: C- B
/ H7 r: T3 B5 s- I; H5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
4 b! F8 w u( D) Q$ m* y2 P) w {( ~* L6 r) k
9 Q9 p9 g4 W+ D0 Z' D! u) x5 L( ~6 Y( p这里主要简单实现第三种方案(使用语言JAVA):; G" G' V5 E+ w: S( o
5 @4 N# J1 e3 X5 |7 a. Y' W
: n3 q: a9 [8 h; f) ~" K2 ~新建客户端 用于上传9 f# A3 _9 Y# y, E$ i6 F3 P
HttpPostClient:
' V* l8 e( e( C5 U* L- package com.itstyle.web;! v4 S' w! p* a' v! i9 N4 J& [
* I! O0 h3 M; e0 {1 ^0 \- import java.io.File;
& }/ E% Z: P- e5 G8 ~' V - import java.io.IOException;( I& Y; l# v' N5 u. ?$ ^: ~
- $ f1 W7 J& ?6 O8 f. D+ P; J3 c/ q9 a
- import org.apache.http.HttpEntity;
6 t3 R4 V. S- h! |$ O0 k( S - import org.apache.http.HttpResponse;) _$ W) j3 }. [) M
- import org.apache.http.HttpStatus;, a. v# p8 a2 U4 d- ], `3 E c F
- import org.apache.http.ParseException;
4 P5 D) d. A+ J2 O9 f3 T8 p - import org.apache.http.client.HttpClient;5 }& B* { R& [
- import org.apache.http.client.methods.HttpPost;
& y6 w4 g* J0 K- f2 V$ Y - import org.apache.http.entity.mime.MultipartEntity;
8 L2 l) e) a3 z - import org.apache.http.entity.mime.content.FileBody;+ O* Z& t3 j6 x1 [! G! Q
- import org.apache.http.entity.mime.content.StringBody;+ J0 h' x, g% J6 s7 f% o! t; a
- import org.apache.http.impl.client.DefaultHttpClient;
# [9 r- ~' `/ g - import org.apache.http.util.EntityUtils;& C' D4 d2 a5 n
- /**
8 x L! `+ @5 v0 U- W# m& z+ C$ r - * 客服端* K: d* A8 ~, p# d6 ~9 ^
- * 创建者 张志朋
7 O7 d' \/ a& M0 q' V) d. d$ D+ N7 k - * 创建时间 2016年4月14日! c) s8 @" H& d: D: ]8 V
- * 科帮网 http://www.52itstyle.top
- C) \/ g: Q4 f8 N" b9 s - *
" L* F4 q8 B' k0 L - */
3 m0 G5 Z8 [3 F - public class HttpPostClient {
! b- i, `5 |4 ]4 A4 K - public void SubmitPost(String url, String filename, String filepath) {
8 [6 m8 P* b3 C* P0 ?( k
% {( G6 [% V% y) Q' R" s* ]- HttpClient httpclient = new DefaultHttpClient();
* U% E8 G5 ^; C% X - % C2 ~8 n* f g, [5 ?- c
- try {- `+ I! m- S" p8 q M$ x
- $ q+ p' Z3 |% {3 R0 q2 L/ u
- HttpPost httppost = new HttpPost(url);% M$ {! X( F( L7 \. w
- 5 l p! Q+ K* r! v# W) U
- FileBody bin = new FileBody(new File(filepath + File.separator + filename));$ o0 h) Y. g3 q
- 0 k; ^) [& @) h
- StringBody comment = new StringBody(filename);
% q$ {2 s6 j; U D/ p+ _: F" m! m - ( m# {7 k5 ^' p% D; E
- MultipartEntity reqEntity = new MultipartEntity(); g: v8 y& U: I) ]
- reqEntity.addPart("file", bin);// file为请求后台的File upload;属性
' G$ G/ V ]% E, d; M - reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性- k& ~% V( Y% e9 c1 i5 c# d7 a
- httppost.setEntity(reqEntity);9 b" B6 g. c4 _
* O7 h4 a' _6 L# z; k5 ]2 j( f6 d- HttpResponse response = httpclient.execute(httppost);" N( s- V2 x. L9 m8 o
- " ]- a6 Z5 D5 {5 A
- int statusCode = response.getStatusLine().getStatusCode();
h2 n& {1 w; i4 [# }7 i - 5 _, E- ~4 {% ?6 y% J; Y
- if (statusCode == HttpStatus.SC_OK) {% o* [4 i' j5 U
- : ?4 M5 Z* h# Y4 u/ B6 Y' ~3 C
- System.out.println("服务器正常响应.....");$ y/ |7 _# V, i. T$ r
7 a9 z- ?! {2 C* }! B, m/ M7 m1 [- HttpEntity resEntity = response.getEntity();+ @: D: s% j5 c' l8 ]% k/ U' v
- ; E1 N$ d' p7 L8 J% H
- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据6 y/ C/ F9 ~. ? \' N
- ' {6 |2 G" i3 {# s1 z4 K' C; {5 s
- System.out.println(resEntity.getContent());
. S6 |4 T. d' G5 K: ~/ E) Y
/ D( a) z5 {& r# t- EntityUtils.consume(resEntity);0 X# a2 o1 z3 j% F0 r: U
- }5 W# S* n7 t& n& p
: A4 B: Y: B' v- g; h3 A+ O- |- } catch (ParseException e) {
( n! @$ X) q$ v8 \ - e.printStackTrace();! {- P/ \. a9 R$ H
- } catch (IOException e) {6 O0 N- L I" F L
- e.printStackTrace();) S, a; ]2 ~- b) |; u
- } finally {/ q: I9 y/ W2 r$ w4 j! M; s9 ^
- try {
) p$ Z3 {* G5 I2 l. { - httpclient.getConnectionManager().shutdown();
# d ^# {( y8 y+ B& F' } - } catch (Exception ignore) {
* g9 u$ F( |% p: R- U - - S( R$ e) R# t4 r4 b" x
- }2 \2 o9 A) X( C6 L4 o
- }
t {$ w. k3 x2 b! r: q; t" y - }
) d4 y% f' x8 h - /**
5 X+ W) `7 @" f0 d- ^' z$ s, Z' l - * 自定义文件名称 和路径 win环境下测试
! ]; h5 F4 w+ I' S f8 v& G - * @param args8 E8 }+ I; y g+ e t& J, y
- */0 ~6 F" J y: @7 a/ z p' L
- public static void main(String[] args) {
$ V( v* V0 w ~5 s8 f - HttpPostClient httpPostClient = new HttpPostClient();. E4 E @. n+ P: s
- httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");# U" X7 N( j3 u: v7 ]5 I. T: A
- }8 l8 j( f. E1 ~0 t4 L# l+ E
- }
3 {8 W. S9 G% Y& Y' t, G
0 ~5 t1 y8 H/ Z L& B
复制代码
; G6 }1 i# v9 F* ?! w& {/ `
, F* F2 R* F& Q. s. l5 A- e# u) l r
新建服务端 用于接收7 j5 N% G. i2 ~) a: z4 ~6 n3 H- q
HttpPostServer:
" K: l/ p1 M# A- package com.itstyle.web;
0 W, Q$ V9 f+ B6 S: I
: `* Y4 T0 w, W* ~, u1 u V- import java.io.File;
+ i( X& d( U7 R$ ?+ u( y$ R - import java.io.FileOutputStream;
7 C3 k. C9 i8 K' l. r5 ?0 b8 _ - import java.io.IOException;1 S; M# C0 ?# p/ ?" G
- import java.io.InputStream;* U( p$ e$ B) Z- D8 M
- import java.io.PrintWriter;- X7 B' s2 h: P
- import java.util.ArrayList;
4 e' B. ~( t* Z8 |5 A" L- | - import java.util.Iterator;5 E: l$ R5 ~( n3 d" Q! v' |: k* j
- import java.util.List;3 S9 _, W% t! O4 A2 d( Y
- / \8 t: o' y& U& b/ V3 l
- import javax.servlet.ServletException;
! x* W0 e! s6 k4 m9 u - import javax.servlet.http.HttpServlet;4 q e: h4 D- ]/ \% p9 Q$ p( i
- import javax.servlet.http.HttpServletRequest;3 y4 j$ @, k- \& o! O5 k
- import javax.servlet.http.HttpServletResponse;+ e% @/ J& z% T9 H) a' {: D
: s6 E2 }- {$ k1 R8 o8 L- import org.apache.commons.fileupload.FileItem;
8 x7 f9 }' R$ p - import org.apache.commons.fileupload.FileItemFactory;
/ M- B; H$ i: E" J) ~7 x- \. k4 {$ D! t - import org.apache.commons.fileupload.disk.DiskFileItemFactory;7 G; k$ S- \# w8 g* y- W
- import org.apache.commons.fileupload.servlet.ServletFileUpload; d8 h6 u* ]5 |" ^% @4 m4 h& G; F
- /** A6 }! W5 ^$ ^
- * 服务端 接收文件! q; w' s0 e4 s3 E' b% D; b
- * 创建者 张志朋
B! P( k% z5 F% h/ W - * 创建时间 2016年4月14日
0 S# X8 f0 u4 o" Z& Q! o- I - * 科帮网 http://www.52itstyle.top4 y. ^% j s+ C9 C% `8 w# Q
- */1 ~) M) |; b8 Q4 ~2 z1 Y
- public class HttpPostServer extends HttpServlet {, n4 W _8 m8 Y& Q/ E
- private static final long serialVersionUID = -1002826847460469784L;
! f" c* ~7 |$ _$ L* u# {8 F- h. j - 3 |4 w& ~4 j' {+ m
- @Override+ g) K* Y0 B0 U2 ]) h. z' r- _1 P
- public void init() throws ServletException {
4 A* `9 }( q* w# f+ G! [9 V8 D
/ b3 o( k O+ V5 Y- }
* t, ~/ A" Y; }2 I2 A* s - 0 g5 W3 @& q" S3 R8 C8 q$ [
- @SuppressWarnings("unchecked")
* F. m7 H/ M- B$ ~/ _ - public void doGet(HttpServletRequest request, HttpServletResponse response)
- Y1 v& F, \0 q( s" U - throws ServletException, IOException {9 e9 {' B/ `# s
- PrintWriter out = null;4 v1 Q8 N# `9 g: C) S, @; W
-
, i4 u8 d$ S2 k+ I. b - response.setContentType("text/html;charset=UTF-8");
+ ^- {; g8 A7 w2 y4 U: A - String basePath = "d://test1";
; l' F- \! O- s4 n2 j; S - FileItemFactory factory = new DiskFileItemFactory();
+ \9 K& z$ q( |) \ - ServletFileUpload upload = new ServletFileUpload(factory);
- b! Q) X' t8 {8 v - File directory = null;
1 P$ ^7 u8 I7 | - List<FileItem> items = new ArrayList<FileItem>();8 ]2 ~$ f3 b( j g
- String message = "";9 h& c' K* l- c: V( {
- try {
' e# n0 z, P$ U5 X/ d1 d; }1 b - items = upload.parseRequest(request);1 O$ m F: ] X! ]8 I" `3 |6 }
- // 得到所有的文件
% f+ h/ h2 n; `2 y$ _3 `" T! N$ G7 G0 z - Iterator<FileItem> it = items.iterator();' R7 J# {7 @- B& _) h5 F% g
- while (it.hasNext()) {
- C$ j& E0 x# O; o* o$ r7 e - FileItem fItem = (FileItem) it.next();. {7 h" T+ v; v0 N4 T; z% o
- if(!fItem.isFormField()){8 \9 [5 o$ n. x
- String name = fItem.getName();
- P% ?8 o# h2 i; r - if (name != null && !("".equals(name))) {2 z P" j. I X) n2 [1 L
- name = name.substring(name.lastIndexOf(File.separator) + 1);
, J! l& ^1 y3 ]- B+ @0 D5 F - directory = new File(basePath);+ z' Y' ]' O4 C; L( Q; \- P, h
- directory.mkdirs();
; l4 f4 n+ A# U( a2 `% K - String filePath = (basePath) + File.separator + name;, L0 M! s5 g1 O. S }" r8 a
- InputStream is = fItem.getInputStream();
* @; x+ W: L# B5 C# E. b5 E - FileOutputStream fos = new FileOutputStream(filePath);
. B' S) A e9 }. K% ?& M - byte[] buffer = new byte[1024];' [, N9 x( ], n% r: I' s7 i7 r
- while (is.read(buffer) > 0) {; j$ F3 {( t& B6 X# U! M
- fos.write(buffer, 0, buffer.length);# Q( e8 `* \6 s3 t) t
- }
5 j# D! q9 P1 Q- P: t6 _ - fos.flush();
) k3 _ T ?# d5 m! ?: {! A- T - fos.close();5 Z. h' i; J$ n) H B) e7 ^7 n
- }
8 r' \4 u R5 M* m- d$ W* j - }" ]3 z/ S0 c" F! ~/ c
- }1 ] P# D$ v7 E
- message = "{success:true, msg:'接收成功'}"; m1 |" a" y7 h
- } catch (Exception e) {( @0 [/ q5 Y+ K \* E% t. T/ E$ v8 [) V
- message = "{success:false, msg:'读取http请求属性值出错!'}";1 j g% Z, x/ C+ L
- e.printStackTrace();2 _( p2 q3 [2 z0 C. t9 I
- }finally{/ j( `" G$ Y* M
- out = response.getWriter();
: k4 I5 j3 R; T( V9 ~; ^! q - out.print(message);: a; x. R( j; C1 s. w# x% l' m
- out.close();
% y2 v+ \6 t1 j4 f) G - }# a; Y& Z2 z, }& I/ H! {) R) p( U4 L
- }
! s" u3 C+ n) K: J! s9 }8 y - public void doPost(HttpServletRequest request, HttpServletResponse response)
( @- z6 m& G& l9 x' x - throws ServletException, IOException {3 c$ G) d4 i4 J+ K' h8 h
- doGet(request, response);
, O7 u6 N! @" r( z8 B - }
9 U& H% H% U: }1 Y8 Y9 T4 O - }
# t: t% ~: n7 e - 8 B" |+ e$ t9 F1 I) d* r
复制代码
$ g5 n* H$ Y. [$ t# W7 V所需要JAR包
0 u! y# Y/ J$ Ocommons-codec-1.6.jar
8 ^ {+ d% p# V* w3 M8 A4 fcommons-fileupload-1.2.1.jar) y# {! g3 I# M
commons-io-1.3.2.jar3 \# |' p5 y# B9 u- \
commons-logging-1.1.1.jar
$ e7 \) F8 g! s4 Y! O4 m; ufluent-hc-4.2.jar
7 y( K% k {: b, Y9 x. Hhttpclient-4.2.jar) u, p7 G v) a- x& G! s; n
httpclient-cache-4.2.jar
( p {8 l8 k" t% W' S/ Phttpcore-4.2.jar
6 p* F" D% \4 J1 [+ i# R; k, Nhttpmime-4.2.jar* Z. y* d5 S5 f: T: q
. A8 K- w7 `1 J' w+ L, P) d
项目下载地址:点击下载5 _/ S7 u- w/ [4 X* P, c0 w" l
( U9 J" a+ M5 Q
$ s9 j: ] B x5 Z1 P* o, ^
密码:
1 s( }; d. }0 b J( c R
1 W- L& d9 r$ l) C
5 V1 p5 u8 i& R0 V- a7 S" F8 C: V; T' T" D, ^% a
. C( P4 g; w- z" F |
|