TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html( K, C# v6 i" d! y! i% r( u% d
: N2 [" M# m. o) j( j
一、项目需求0 e1 J3 P" `. Y* X) X
在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
) A' y6 H6 x" r, L& v$ r0 H0 w5 P, i3 \. X! T; m
5 e `" e% A, u- y N8 U( U% o二、文件服务解决方案
8 K( ]3 q9 S8 H9 V K- m" C; G1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。8 r1 s! X; }" }# P7 ~
8 @7 K& Q4 ]/ D$ o, ]% H" {7 R- m
配置详见:http://www.52itstyle.top/thread-10764-1-1.html r8 n8 w# |# N
- h; Z B6 z1 Q0 S- o s" _
. M1 M1 P X: K2 i8 {4 O2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。
$ O7 a3 ?$ l& ~- E# R( s! ?
2 o5 L3 }# m ~6 a @ a4 g W3 z& a
配置详见:http://www.52itstyle.top/thread-17263-1-1.html0 u; ]) o7 ~+ }+ u; B+ I
: ~! o# w* O9 f- C, ?- P( O4 ~; O. }8 X Y
3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
5 [8 P3 v7 @" q4 E; M+ }5 A8 d- G& {; ~+ I" u( o3 n: u$ h' D
& J1 s/ }7 f0 M* ]4 L0 _4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。
* i7 F& W$ d1 @; V: B
0 y( Q9 g4 R# g! u$ N; o
1 Q- m+ }7 ]+ }3 c9 F6 S6 t5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
2 H! Y( ? W& p" ~
& t! x0 r) @% |3 L X, b+ _# O& r& O
这里主要简单实现第三种方案(使用语言JAVA):& q8 n+ V# A g( u3 j5 y0 ^
1 e9 ~, Y# |+ |# {7 o( \
8 p5 }- y+ \$ T$ g( m9 v新建客户端 用于上传- Z/ ]" p' @6 R7 }- @
HttpPostClient:
$ R6 I. V' {; D- S! [2 @- package com.itstyle.web;
; s5 r) {- B. G" W# N' Y; ?9 |. N
+ r" ~2 m& I: v8 z4 ^$ }- import java.io.File;" X; m( w, J+ ~& r
- import java.io.IOException;7 j$ l" w# i$ o' v+ Q; N' o) g
- " F8 ~# ?) z2 H, ]/ |' t1 w
- import org.apache.http.HttpEntity;
! q* e8 |/ {6 v2 w1 X& r - import org.apache.http.HttpResponse;
* h, }! e' ^2 j# k! L1 j8 L - import org.apache.http.HttpStatus;
( U" U6 w C/ Q4 ~1 Z# Q8 Y$ m4 p' r - import org.apache.http.ParseException;7 ^5 [- G# O% L: _5 H$ x" z+ p4 r; ~
- import org.apache.http.client.HttpClient;
" |: I; W0 t- V% W9 N3 ?' m - import org.apache.http.client.methods.HttpPost;. j M4 G6 h7 k$ z0 {
- import org.apache.http.entity.mime.MultipartEntity;; a+ M$ w7 a8 o8 {1 [ K9 R. i
- import org.apache.http.entity.mime.content.FileBody;+ J: S! U- `: x ]5 w) C+ o
- import org.apache.http.entity.mime.content.StringBody;
/ ^/ R7 Q9 i' r8 L4 a) W. c0 A1 m - import org.apache.http.impl.client.DefaultHttpClient;+ Y. I2 Y: }+ [& k7 q8 W9 @! o
- import org.apache.http.util.EntityUtils;
* n9 S' x8 [: ]% h0 i - /**
- [) [( o1 W" ]1 L! m/ a5 [2 R - * 客服端. R1 x: l) c, s1 r- E$ d) V
- * 创建者 张志朋' v6 q0 I7 G" H: ]* u( A7 R
- * 创建时间 2016年4月14日
, p" T7 p. j" J! g1 a - * 科帮网 http://www.52itstyle.top$ X) c/ g$ l \7 S3 E- @
- *6 M& b$ i T4 c; W+ f4 J
- */3 [ `7 ~& t4 k: Z
- public class HttpPostClient {
" \2 L: b+ Q" i- {* _! M5 ~ - public void SubmitPost(String url, String filename, String filepath) {
% d6 `/ W& g& q) K; A
* R& u, x& ]9 x% W, h& V: R) M- HttpClient httpclient = new DefaultHttpClient();
; y& m( P- [. f8 E/ x7 b
" u6 r: k Y8 h- try {
+ C& _" z4 j t3 X U& t2 K# x - 7 ]4 O5 R, S- P% g
- HttpPost httppost = new HttpPost(url);; G6 Q) L8 n3 \' r1 | h
- ) [: [% j' [1 e
- FileBody bin = new FileBody(new File(filepath + File.separator + filename));: _3 ^3 Y1 i2 D
, r8 Q$ h0 c0 v" }8 t; o; O3 D- StringBody comment = new StringBody(filename);
/ M; o9 J8 T2 g/ w+ a7 d3 n - 5 g; x4 ^0 R4 i2 I+ R* q
- MultipartEntity reqEntity = new MultipartEntity();
( [' j. x6 T4 B' Z- z7 F - reqEntity.addPart("file", bin);// file为请求后台的File upload;属性
! N N+ W; E* N' M6 C$ q6 P - reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性
5 z% w+ P2 g. _! C% e - httppost.setEntity(reqEntity);
: T1 c" H. ]9 j* W: |
8 c/ V3 Y% P/ b+ [, Z1 a/ Z" U- HttpResponse response = httpclient.execute(httppost);
# J! a& ?$ X4 b5 W5 F' x( l _ - ( K6 E: Q& s9 O
- int statusCode = response.getStatusLine().getStatusCode();
$ Q9 ]* I# J4 E8 Y: R3 W - # a& T' ]3 s2 F; p
- if (statusCode == HttpStatus.SC_OK) {
' T4 P* L& f; x' \
/ g4 o, w! I: d. M0 U- System.out.println("服务器正常响应.....");3 R( \, ~0 v6 k6 l* }) k4 v# `. z
$ X) [% R4 A( k- HttpEntity resEntity = response.getEntity();
" V2 r0 H0 R3 k6 k - 2 j! _" v2 k/ c# M* K, T
- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据8 ~# J' b/ o5 \; b h
- : Q% O/ F( F5 A. M& A k0 t
- System.out.println(resEntity.getContent());9 t9 V* X" I1 c5 o! s
* P: c1 Z+ U; |- EntityUtils.consume(resEntity);
4 {; ]8 R# P \ j$ q - }) J1 D4 ?/ Y/ x0 k8 A4 a4 w8 ^
* B+ O; A8 i" `' |; s% g: O- } catch (ParseException e) {
% i, u4 Z1 u+ M& x - e.printStackTrace();, K2 S+ p( V* \- u2 }/ N, }0 y
- } catch (IOException e) {
- o* \5 t: x5 [3 j4 y - e.printStackTrace();
+ \9 R# l5 i& D" q+ Q3 L3 Q - } finally {
: e7 l1 U4 ~+ S) z1 ?3 ?3 B - try {
% s5 W7 c6 }$ w: J" c4 ]/ M- A - httpclient.getConnectionManager().shutdown();
7 _( ^7 |% i+ b - } catch (Exception ignore) {) M6 @1 W% r; a! u; O, u
- . F/ f/ q. V, b
- }
2 K! D6 q( e" x: W) s - }4 S3 x) l* C9 e2 G# F, ^
- }
0 c: O* C4 \* l; N - /**
# `1 E6 T8 G, Y6 }7 H3 G$ b4 s - * 自定义文件名称 和路径 win环境下测试
: O1 A( k, q, o4 W9 {* p m+ P' A - * @param args C8 `! o1 ]4 ]' b
- */
( r' @' i: ]$ N9 b* f! ~ - public static void main(String[] args) {* B6 [& Y" T. Y# w* \0 E
- HttpPostClient httpPostClient = new HttpPostClient();6 A: {9 D7 q/ _) O/ H
- httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");4 m+ j3 z! W O7 K" c, ~
- } F& Q5 o2 T: \ f$ P' J8 {0 Y+ x. p V
- }& m& p. c: O: \6 P. W
- ) a9 i. P @( H
复制代码 4 f% \+ b _+ s; v$ L, j
# N. Q* ]( y8 T; d0 X# y
( t9 H3 Y2 {- y+ F新建服务端 用于接收
6 Q3 y2 x8 s' Q' E5 f# ZHttpPostServer:
. K y+ K H" z' o/ m. g4 }; K- package com.itstyle.web;" J) H+ q6 s( ]' f* Z |2 d
7 E e) y5 _: A) P0 m) g- import java.io.File;
2 ~! N- x2 Q8 n0 Z P- p - import java.io.FileOutputStream;% X" O+ j/ c$ ?- s
- import java.io.IOException;/ }# k! X7 c* P& W. o, N
- import java.io.InputStream;9 f4 t- ~# W6 b1 L
- import java.io.PrintWriter;6 B8 T/ `% |( s" p8 p
- import java.util.ArrayList;* p5 ?! q% q/ s
- import java.util.Iterator;
" W$ s3 L1 E& n6 G - import java.util.List;# C/ m0 Z+ w, k( X( b
( Q b8 i- ]% p, }9 x# d- import javax.servlet.ServletException;& m% Q1 a2 z; p% M; M0 Y3 u# N4 |/ x. Q
- import javax.servlet.http.HttpServlet;
/ n1 M/ ~* Y# w6 K - import javax.servlet.http.HttpServletRequest;
7 B% y& U, D3 } - import javax.servlet.http.HttpServletResponse;8 Z7 V' g4 r- d8 N8 a
m9 V/ n' {: r: P0 j- import org.apache.commons.fileupload.FileItem;6 c6 _# e9 ~( [# S2 r5 {
- import org.apache.commons.fileupload.FileItemFactory;
3 L% R$ }4 K7 J7 w9 k/ R - import org.apache.commons.fileupload.disk.DiskFileItemFactory;8 r' X: }- P; G
- import org.apache.commons.fileupload.servlet.ServletFileUpload;8 f9 w F7 |% |1 M' S( V4 w: ? V
- /**9 _' R) f7 {' w. ^" @+ `' B! n, b
- * 服务端 接收文件
, j8 E9 h% c6 D; n - * 创建者 张志朋$ |2 Q |% e- ^8 @0 t
- * 创建时间 2016年4月14日2 b$ _8 E& M. z4 \8 B; I( f1 \
- * 科帮网 http://www.52itstyle.top
6 G i1 g3 I4 u' {1 A5 { - */" k. i/ c# _: J
- public class HttpPostServer extends HttpServlet {, y' Y- @2 u6 R6 o) R/ V
- private static final long serialVersionUID = -1002826847460469784L;& X$ b- b7 }. Y6 P# Z* o g& ]
. {' N% C. O( y! `3 v- @Override; n! f1 l+ p7 }
- public void init() throws ServletException {* E/ c' |" r+ ]1 n+ }& |
- 2 a6 U9 f2 }% T% n) |$ [! n! u& F. z
- }5 n* v6 E$ a' ~! @, T o
- 7 a% m1 ]/ B6 Z; @
- @SuppressWarnings("unchecked")
# U2 L2 C$ e8 g5 C. b& r# L: c, F - public void doGet(HttpServletRequest request, HttpServletResponse response)
0 t1 e0 P" o6 K& U5 S - throws ServletException, IOException {# F8 i0 e7 x2 @1 d. _( N' C
- PrintWriter out = null;
$ @" a: P- j, E - & R* w. z- u9 z! p2 U' ?
- response.setContentType("text/html;charset=UTF-8");
; x$ `8 @4 F) l" Y* | - String basePath = "d://test1";& i; Q" X: B9 G( `/ Q- S% Q
- FileItemFactory factory = new DiskFileItemFactory();
; L6 {9 Q: K s' x9 [ - ServletFileUpload upload = new ServletFileUpload(factory);
% T7 f( @( l+ ? - File directory = null;
& `9 Z1 {' }5 o - List<FileItem> items = new ArrayList<FileItem>();
5 _" Z/ z+ a& `( B' t - String message = "";
, Z' S8 X, [" P! J6 F1 y - try {
) V6 r; U2 l: F! o+ \ - items = upload.parseRequest(request);- e+ n. f& s5 c0 Z) v3 ^
- // 得到所有的文件8 N- j/ k; {7 f, k4 C! z6 S. l1 Z# P
- Iterator<FileItem> it = items.iterator();
) u s0 p @. S4 V1 c0 q - while (it.hasNext()) {8 B6 B9 d$ r) a6 f$ T
- FileItem fItem = (FileItem) it.next();
8 b6 N% t2 c. p l1 Y) m( p; e - if(!fItem.isFormField()){
0 g/ E5 L9 M- M: ?2 Q( l9 Q* H - String name = fItem.getName();
1 N! y* X& [3 q: ]+ Y, n7 b$ Y - if (name != null && !("".equals(name))) {, D& E- |' P+ w! O3 h
- name = name.substring(name.lastIndexOf(File.separator) + 1);
9 R( e( r8 g- K - directory = new File(basePath);$ p$ z) N' e1 C+ {& l
- directory.mkdirs();
5 M; \7 \# J/ p% u. @ i - String filePath = (basePath) + File.separator + name;
% Q. W" L! S' T - InputStream is = fItem.getInputStream();# Z' e9 W+ C: m# \9 m4 ?# G
- FileOutputStream fos = new FileOutputStream(filePath);
8 g$ F& h o2 ^7 ^ - byte[] buffer = new byte[1024];
9 m' z# l8 B/ C- p - while (is.read(buffer) > 0) {4 G* X( i9 Q7 ?2 b# Z- l
- fos.write(buffer, 0, buffer.length); a5 R) S# D; s# u3 b3 f
- }) g& Y9 k( K `* B& H: ~' Y5 c& U3 ^/ q
- fos.flush();
1 r! n. L- T3 T# |2 V2 F - fos.close();
) e3 L) t! b6 Y0 x - }7 O4 W& g- o! N$ D
- }
) z% D+ U/ I- T - }
) j! k7 q9 M- t2 I - message = "{success:true, msg:'接收成功'}";
( z" P( ~9 d: m- U' ?- c - } catch (Exception e) {
8 |+ Q3 t" L, W# C - message = "{success:false, msg:'读取http请求属性值出错!'}";( g" I6 ]6 x6 T3 p' `( R8 l6 z
- e.printStackTrace();/ F) m! O0 Y2 x* O0 s
- }finally{
. ]! i4 h; Z0 k2 d* t - out = response.getWriter();
6 l; G$ _) ]( `$ x. `" ` - out.print(message);* _( u# L5 D- o0 x8 w2 l9 v
- out.close();
8 d- H4 G: D( V( R - }1 o8 j" q# ]. ~- i9 b
- }
7 Y/ z1 N. W: ?% G5 b5 y5 u' ~# A - public void doPost(HttpServletRequest request, HttpServletResponse response)" A- f% w- g$ d' V( C) v2 i
- throws ServletException, IOException {
7 |% T- Y$ v' D( S! d8 l& \2 \ - doGet(request, response);
7 g1 Z& X9 r M6 N8 T - }; q @! l5 H; L4 g/ |7 F
- }
E+ R7 @# q7 q
$ ~+ l+ z( X& D/ ~) v. E. q
复制代码
/ W, U& f0 `- `所需要JAR包
2 b; v' H5 p b" R+ g0 U- xcommons-codec-1.6.jar
* J# T* t5 m9 ]( Qcommons-fileupload-1.2.1.jar
8 s7 D! t% m/ I1 V0 ecommons-io-1.3.2.jar+ N: v# R0 S! T( e% K
commons-logging-1.1.1.jar
% F8 _# f/ m: f. W; i# y: Hfluent-hc-4.2.jar$ C# x& ?; a: _: e& M
httpclient-4.2.jar
! r/ V/ h# k( ^2 J/ w& a* Z' phttpclient-cache-4.2.jar
9 p* P0 ?8 t) W6 Ghttpcore-4.2.jar1 s9 L s4 {5 ?5 ]% H
httpmime-4.2.jar
. B! j9 L9 ]$ n3 E- D
/ k7 d( y1 [) _1 w" q8 H, M! Y7 K4 A项目下载地址:点击下载* u7 T8 \ u, D& Q$ x
' B9 o5 Q- _0 i
: ?( v$ ]. o8 ]- Y; X' b
密码:/ Q* d: l+ T/ J# g0 {
. K G: ~" Z" t0 v: ?1 i& W
8 K4 j ]; [( P+ I8 }- s, a0 q; |" r! ?( ?& m9 H6 s
8 t) I8 e: {3 ?/ J# `5 V. _0 j
|
|