TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
任何强大的单一服务器都满足不了大型网站持续增长的业务需求,网站发展到一定程序,应用服务器就要跟文件存储分离,创建文件服务器分摊应用服务器的压力。文件服务器是为网络上各工作站提供完整数据、文件、目录等信息共享,对网络文件实行统一管理的服务器。它能进行文件建立、删除、打开、关闭、读写等操作。当然文件服务器并不是单一存在的,如果存在单点故障,对项目的影响将是巨大的,所以前期分布式文件系统也是项目上线初期必须的,做好容灾备份。对分布式文件系统感兴趣的同学可以看下FastDFS:http://www.52itstyle.top/thread-22615-1-1.html& i$ N; q8 O8 X( S9 B
9 y% v, J1 W1 y9 {: g4 P+ ?; ~; H
一、项目需求
$ Q* l9 e1 L7 B0 L, ~0 ] 在B项目中前台上传一个文件,后台只是负责获取文件,然后需要调用rest接口把文件传给另一个系统A(文件服务系统),文件服务器系统会返回给我需要的状态,然后根据状态判断是否上传成功。
" V B$ Z2 }- O! g& I9 Q" S- e6 z
3 y3 Z, W& `; `" S3 g$ z- K
! k; n1 [; ~! _2 q, W8 S+ Y二、文件服务解决方案
% z V. c$ p4 Q' r6 M/ Q$ x1. 使用NSF 映射远程磁盘目录,将A的某个磁盘目录映射到B的某个文件夹,那么,在B上传文件时,只需要复制一份到这个映射目录就可以了,系统会直接传送的A服务器的目录里,如果实在局域网这个速度是可以忽略速度影响的,但是如果不是在局域网可能会有传输速度影响。5 z3 H; i* w& ~$ o/ j7 J3 A
0 x1 `; K n* m
# E% R# L7 X% m2 M; T
配置详见:http://www.52itstyle.top/thread-10764-1-1.html
5 y" A" T- D! v0 V3 X$ E
+ {' H0 P2 f5 b& }& Z& G$ g4 m& y6 {
2.利用服务器rsync的同步工具。在B架设rsync的服务端,设定需要同步的文件夹,在A设定rsync的客户端,设定同步的来源服务器和对应的文件夹。当B的上传文件夹变动时,rsync会自动同步一份到A的客户目录。. p. t6 E; s0 Q
* C/ ?" `6 g! Z: G/ @& o S) k7 b
6 G+ V4 T$ D, _3 i4 X" M- L, q配置详见:http://www.52itstyle.top/thread-17263-1-1.html
! j8 t( h! b& x4 x! _
1 r/ i6 t) Z, M: Y0 Z. P4 t9 X/ r# m# Y% H8 u' h4 w3 m/ Y6 ]
3.如果以上两种方案你都不想使用,可以在A部署一个底层脚本,用来接收post文件,可以自己设定一个密钥。当B有文件上传时,B服务器用java的httpClient直接重新post一份到A的接口,然后在A的接口设定逻辑存放到相应的目录。
. J& ^% M' \2 p1 [2 p1 e- p* E( b8 g9 k) d
) @4 i: I- z/ U* N3 V$ y- ?4.如果文件大小不是太大,B服务器还可以利用各种中转程序,例如先存到mysql,或者nosql的存储里,然后在A服务器上自动去抓取下来。
" N5 P I7 d& M* P, O: j* u" @( ]$ T8 I. t
/ H) P& X) f$ }1 [: P5.当然你还可以使用静态资源云存储,比如七牛,阿里云,使用它们的接口就能把资源上传到它们的服务器,接口十分简单,费用非常便宜,比自建资源服务器便宜很多,但是毕竟不是自己的。
: N. H" u' g& R# z# v0 Q& z2 T
% W* b- r% O/ i" b8 F% j
7 P3 V: P8 x" a# B; Z/ k这里主要简单实现第三种方案(使用语言JAVA):
}2 D+ r( m, L6 [- j( f% ~
& O6 j- ], g& u6 C, T w- ^
3 d, E5 p5 G# m. }2 j( ?# X+ H( V新建客户端 用于上传
8 p3 x7 d# e) p3 kHttpPostClient:
5 H" Y$ P, x7 z0 c. H: E% v; q- package com.itstyle.web;
) E0 h" U1 s! V4 J3 g
6 F8 g" ^6 y. L# ?- import java.io.File;( y3 s( { ~, y s9 j0 Z
- import java.io.IOException;, ]* i+ Y- X1 z% {% M9 \4 M. D' V
( }7 h9 n+ G6 |8 n8 H% a- import org.apache.http.HttpEntity;' v2 F2 z9 A/ T) Z) f8 ]- U- i- n
- import org.apache.http.HttpResponse;2 d- Q, o4 k; G; U0 Q& Y$ w
- import org.apache.http.HttpStatus;( F- t$ j* |' \9 Y( O& \& ]+ `
- import org.apache.http.ParseException;
3 N+ p* T0 E# r6 Z/ T( w7 J% ^" e - import org.apache.http.client.HttpClient;+ o, ^* C. w5 X1 M9 n
- import org.apache.http.client.methods.HttpPost;- u3 Q3 T. H3 z, ^* d6 O
- import org.apache.http.entity.mime.MultipartEntity;
( }5 r3 w- r, b - import org.apache.http.entity.mime.content.FileBody;
1 Z" z3 Z r& m8 T - import org.apache.http.entity.mime.content.StringBody;
! _: ^% ~% h# B3 Y6 m. A' ^& k - import org.apache.http.impl.client.DefaultHttpClient;
( ?# Z& O' N" X Q3 S2 w) N - import org.apache.http.util.EntityUtils;
+ |- t6 j' w/ {; K* S: Z - /**1 h3 H' V6 U1 R$ L
- * 客服端
+ f& E9 ]7 D3 }( i - * 创建者 张志朋# l; Y8 B& Z( I8 F# B* z4 J) e
- * 创建时间 2016年4月14日
5 U& u4 r; P$ X - * 科帮网 http://www.52itstyle.top7 g; g& P- d. w9 K6 b) p/ L9 w9 n
- *3 S/ }4 O' R( t H/ S% w9 |
- */# Y8 h& _3 X& C, A. i: P
- public class HttpPostClient {0 \9 ~% l6 Z7 ~: T
- public void SubmitPost(String url, String filename, String filepath) { }3 g" _) U2 H6 b9 c+ w, l+ V
- " I5 R& Y) U5 q; _5 p g
- HttpClient httpclient = new DefaultHttpClient();
1 @" I8 S3 ~2 W
9 n8 {+ N/ O5 R+ R( s- try {
; b2 a+ d+ j: F: F; ]# o @3 r: N - 4 H: ~4 [- j, q0 Y( {
- HttpPost httppost = new HttpPost(url);
+ R0 F- {5 l9 g% G- O, C - - S) m% v8 Z6 i3 Z7 R9 |
- FileBody bin = new FileBody(new File(filepath + File.separator + filename));
9 Y3 ]. w6 O5 n# y2 I
; Y8 }! {1 w u- StringBody comment = new StringBody(filename);6 {& V5 T! t- K8 x P9 m# h
- . M0 A8 ^" y. }! U( w
- MultipartEntity reqEntity = new MultipartEntity();, k0 z" e. K4 I0 _
- reqEntity.addPart("file", bin);// file为请求后台的File upload;属性7 {/ ^2 }" l8 B" Y
- reqEntity.addPart("filename", comment);// filename为请求后台的普通参数;属性
7 r; S( h7 Z9 X) x. y - httppost.setEntity(reqEntity);
5 d1 L/ V. u8 b: \+ D
, I, y7 ]+ Q- i- V6 n$ J* O* B- HttpResponse response = httpclient.execute(httppost);
u% O, \ W* n - ; `/ U* J. t1 l
- int statusCode = response.getStatusLine().getStatusCode();
) N- I% ~# `" V0 b2 S - 9 ^" {, F! D! P. J3 h
- if (statusCode == HttpStatus.SC_OK) {
; I! g! z' }1 h8 L# p& ?
$ n3 D3 @2 K# X& w. w, w0 r; t- System.out.println("服务器正常响应.....");' n9 G' R, V7 K
- ! }# ]. F1 U Z
- HttpEntity resEntity = response.getEntity();/ }. ]4 e) J, z @' \3 G$ q
( _" M+ m; G' B5 F1 ^- System.out.println(EntityUtils.toString(resEntity));// httpclient自带的工具类读取返回数据
( L9 ?+ Y, p" a0 s
* k7 r! [9 Z+ _9 s& j- T- System.out.println(resEntity.getContent());/ [+ i* J& b. Y' u( A* I
/ \; I" u# y' M1 F4 }- EntityUtils.consume(resEntity);5 k5 g8 }$ J* F$ J9 y
- }
' o! Q( n8 b: x; w" @
8 V& ?; Y8 `& ~8 w0 a4 M3 q: _- } catch (ParseException e) {, z4 {* d4 r$ e; l6 a/ @
- e.printStackTrace();/ H# y1 i5 E1 U0 z, r
- } catch (IOException e) {
& f, y2 B+ D/ f- O - e.printStackTrace();! @; R) }& Y j$ r
- } finally {
& ^' ~& i4 ?7 p* g5 e" }' ` - try {; n J% T8 p/ n6 j4 Y: _/ W
- httpclient.getConnectionManager().shutdown();( R* s5 p B, x5 v
- } catch (Exception ignore) {
7 ]4 E- h( E$ g -
/ ^3 B( s0 B7 }" O+ s - }1 x5 {& x+ u& e+ i% k# A/ q
- }
# Z; T& Z- O. c7 f; n- r+ L) u' S - }8 J' d& v& b6 Z' K
- /**2 X! L4 {8 x+ [& N
- * 自定义文件名称 和路径 win环境下测试2 x! k2 _" i! N* E4 B! e+ f
- * @param args
! h4 H j0 \! R" ?! E. d - */
) y) b' n0 ?4 b0 R0 \1 c. H - public static void main(String[] args) {
+ W" o& p! y: D/ t - HttpPostClient httpPostClient = new HttpPostClient();
. C( L4 a( }! p9 J) [* y4 t' F1 V* [3 ? - httpPostClient.SubmitPost("http://127.0.0.1:8080/acts_upload/receiveData","test.zip", "D://test");
; u$ _' x- j6 G. S! U - }7 G R$ x' P5 `) l4 @: x
- }3 U' o* q7 \$ b' C
- # Z' S+ L: W& ~3 \2 R' u- W/ V: u6 b
复制代码 2 E" `( P# e7 g3 S' }, K1 \
_: s( c8 x8 ]! U
* `' x% C7 t) U新建服务端 用于接收0 c0 `4 N; l1 }' k& J
HttpPostServer:
/ j$ I8 f8 K/ T4 T$ M3 G$ C+ Z- package com.itstyle.web;
( g6 X) k. ~: T& `% f7 h* P( _ - 1 Q8 u/ h7 ]" h
- import java.io.File;
# L. L/ F: k W2 s - import java.io.FileOutputStream;
2 l& a8 A8 n# ~% E2 X' } - import java.io.IOException;
& m& K) @) N( j# d$ A p) H2 D - import java.io.InputStream;
0 }( Z+ M& x. F8 M& t9 E5 u* ? - import java.io.PrintWriter;
& N% }- E/ ^" b1 |: ?$ w3 G - import java.util.ArrayList; ?# j# Z# C! A- R! Q# J
- import java.util.Iterator;
& S6 g* h$ G, o: o - import java.util.List;! C! L& H3 q/ ~ J0 |
- 6 L0 L- A& F8 X0 C) P% w( V
- import javax.servlet.ServletException;+ o2 l [+ h; ~0 m, K; q
- import javax.servlet.http.HttpServlet;6 h; S4 F" b1 N
- import javax.servlet.http.HttpServletRequest;( ]- h0 ]5 J. Z5 L, S( S
- import javax.servlet.http.HttpServletResponse;: c1 A. X0 o# n5 J. }
- ! Q2 o9 q6 w) g) @9 D6 M7 N
- import org.apache.commons.fileupload.FileItem;+ p0 z1 O' t+ ]
- import org.apache.commons.fileupload.FileItemFactory;
6 G; m8 o9 e- b - import org.apache.commons.fileupload.disk.DiskFileItemFactory;
: e- H' J/ P6 Y2 a- t4 \$ I - import org.apache.commons.fileupload.servlet.ServletFileUpload;
# Z) h+ P( M/ M - /**
+ m( c3 {) |* U6 o4 \" e* F - * 服务端 接收文件5 E8 }# t q4 i9 Q+ E& K
- * 创建者 张志朋$ P1 K$ b2 c- _8 i
- * 创建时间 2016年4月14日& k) F: U. F: b4 i0 x
- * 科帮网 http://www.52itstyle.top
2 x V B3 f* ~! a2 Z3 ?* E/ V" O - */3 K/ H! V: B; k [
- public class HttpPostServer extends HttpServlet {- |2 d4 c0 n, {4 |' j6 _1 V
- private static final long serialVersionUID = -1002826847460469784L;# ~# k( a: J. t* o
: A! l$ f8 ^" ?! I7 e0 w- @Override
# ~; l2 Y- L$ T8 k4 ] - public void init() throws ServletException {
3 o3 m, Y/ R. q' u
5 I) |& h, b9 x2 g% L! N$ Q- R% l- }
# v8 M9 F9 J: b- _( f- @
, F0 ]# E* Q4 M- ^+ H- @SuppressWarnings("unchecked")
9 t; W& {, b; ~1 L' B - public void doGet(HttpServletRequest request, HttpServletResponse response): r1 E; g2 V* s! T& t" m
- throws ServletException, IOException {
1 f( }" }: T2 F0 _# H x - PrintWriter out = null;: v/ k+ I/ A7 ^& X( b
- 5 d& O! R' l' a8 C8 s
- response.setContentType("text/html;charset=UTF-8");
% J" H- Z+ J0 E) A1 Y# Q - String basePath = "d://test1";1 W* n) l0 h8 G" ~' U
- FileItemFactory factory = new DiskFileItemFactory();
- V1 @2 z7 Y7 u% Y+ | - ServletFileUpload upload = new ServletFileUpload(factory);% E9 l j8 Z8 C' J9 H
- File directory = null;" N/ y# X( b) \, l. l( S0 u2 I
- List<FileItem> items = new ArrayList<FileItem>();9 p4 f a* `% G3 I; l
- String message = "";6 M/ {* ~6 A, R1 D5 |
- try {
, q( W1 o3 k) n4 z* X' D - items = upload.parseRequest(request);
3 j7 ?/ c- {7 M# x/ q* ], w% T8 i2 } - // 得到所有的文件. K; j6 ]: l0 ?2 G: s- e
- Iterator<FileItem> it = items.iterator();! A+ Z u2 r" ^% I
- while (it.hasNext()) {
0 Y& d3 V& ~! `& n) F# g - FileItem fItem = (FileItem) it.next();
5 _- ?- S- e) L$ u1 d" M! } - if(!fItem.isFormField()){
) M+ }& o* k, c% [9 ]' [ - String name = fItem.getName();
' X& I4 ^3 q6 y( e2 ? - if (name != null && !("".equals(name))) {; C' t3 i. v" |7 E; T
- name = name.substring(name.lastIndexOf(File.separator) + 1);
/ d- j) d5 F5 T! ^1 ]% o9 y - directory = new File(basePath);$ J$ Q; _3 {1 K6 j: H( S C
- directory.mkdirs();; d9 {, r; Y& J- ?8 H
- String filePath = (basePath) + File.separator + name;: N7 [1 U$ Q6 R9 T
- InputStream is = fItem.getInputStream();' ?* O/ M3 @( B" ]8 p% t. t+ C
- FileOutputStream fos = new FileOutputStream(filePath);, g* i6 p3 Z: w* z2 n5 ]
- byte[] buffer = new byte[1024];
! a! |7 Y6 k! | y, Y7 ~ - while (is.read(buffer) > 0) {
$ p. D p: r6 ~2 q5 P - fos.write(buffer, 0, buffer.length);3 m; ?, h4 Q8 I
- }# I, f' s& t4 o: `% A. i
- fos.flush(); S* Y! j6 z4 Y- H, E- q/ W$ D6 e
- fos.close();
6 _( G2 Z6 D+ S* x4 a' i. | - }
4 H7 ?) u F& E5 c }$ M4 ~$ E2 e - }
, Q! T4 u2 Z( |- w, ^ - }& z; ^8 p! q0 X5 E! U5 X2 B+ i6 n
- message = "{success:true, msg:'接收成功'}";# S3 _/ x I( I9 g+ V' o6 g
- } catch (Exception e) {/ a8 w$ W2 y+ D/ V0 v! G. U9 `
- message = "{success:false, msg:'读取http请求属性值出错!'}";2 I+ ^9 c$ p2 z; k
- e.printStackTrace();, H3 d" B! g1 ] u6 w8 K# F* @. W
- }finally{
) I& h* r3 X" `6 h$ I2 @/ C6 T - out = response.getWriter();+ Z& c; S' T: Q# l
- out.print(message);
4 {5 y: I9 D1 P0 h% R2 B - out.close();
" k, X# H4 F" C+ `9 q) U1 F - }
) ^ i( ^- D2 Z. _# I - }% S- s n G- M$ N Y p! Q* g
- public void doPost(HttpServletRequest request, HttpServletResponse response)' R6 f6 S% d. O' x' y1 P
- throws ServletException, IOException {
3 j( E9 Y2 D9 e* T8 D - doGet(request, response);
$ n& L* o( _3 ` - }
~* J1 L, ^% i; {+ U/ f6 j4 \ - }+ Y- D% | e% P' D# R( n0 Q
- - N, ~2 L' O: v2 ?6 V8 y
复制代码
, T0 _1 k8 O- l$ k* r2 f所需要JAR包
/ n1 j1 Y( U9 U/ z" U$ I u5 i# t Jcommons-codec-1.6.jar
4 U" A3 t- q& m8 O+ Q8 P- Scommons-fileupload-1.2.1.jar. o/ K% ?: d% B g" z% ]: n
commons-io-1.3.2.jar* ~* i) Y1 U& v
commons-logging-1.1.1.jar3 R$ S1 W0 U4 Y5 \$ `6 [
fluent-hc-4.2.jar
5 P# n! T( _5 r0 `( p8 Uhttpclient-4.2.jar
. T. ]' {; f9 w3 g* R Khttpclient-cache-4.2.jar
' u5 R) H) c w& Rhttpcore-4.2.jar9 o4 {& S7 u* L5 J' r
httpmime-4.2.jar; t- S6 w: C) W1 E e4 t6 Z$ |" M
$ P( U0 W6 T0 o4 z1 N6 p
项目下载地址:点击下载' [' A+ m6 D) N
7 u4 `2 [9 M5 z$ p u& T- p
& O& E' G+ C$ m, q& E密码:! w: |5 @2 ]& b; r
; [' R, z4 U" _$ R- l
, ]! S9 A; s* V* z9 U$ a
, z! g$ Q: F4 P/ K' v- p9 v2 v- K/ O5 Y( ]8 l6 X5 i/ X% N+ h$ g
|
|