<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                [TOC] # **文件中心** ## SpringBoot 文件上傳原理 > SpringBoot 中的`DispatcherServlet`在處理請求時會調用`MultipartResolver`中的方法判斷此請求是不是文件上傳請求,如果是的話`DispatcherServlet`將調用`MultipartResolver`的`resolveMultipart(request)`方法對該請求對象進行裝飾并返回一個新的`MultipartHttpServletRequest`供后繼處理流程使用,注意!此時的請求對象會由`HttpServletRequest`類型轉換成`MultipartHttpServletRequest`類型,這個類中會包含所上傳的文件對象可供后續流程直接使用而無需自行在代碼中實現對文件內容的讀取邏輯。 ![](https://img.kancloud.cn/51/4d/514d909e2d015bdaa0a59acceda07bbd_1041x760.png) ## 依賴關系 ![](https://img.kancloud.cn/81/e4/81e46a2ad34763e579d1691a17ead59a_538x401.png) ``` <!-- 資源服務器 --> <dependency> <groupId>com.open.capacity</groupId> <artifactId>uaa-client-spring-boot-starter</artifactId> </dependency> ``` ## swagger測試文件接口 * 查詢接口測試 ![](https://img.kancloud.cn/a5/70/a5708ba2acb12799cf55ab1be3e26b7d_1919x973.png) * 上傳文件測試 ![](https://img.kancloud.cn/96/9b/969bb3ff36fae301037db128dfdda5f0_1918x383.png) * swagger測試 ![](https://img.kancloud.cn/3a/61/3a611a8719f9e690eab02d0a5148c98d_1920x791.png) ## file-center 授權流程 ![](https://box.kancloud.cn/7eea410bb58d317640e825e7a3e7c20e_588x703.png) ``` public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (authentication == null) { throw new InvalidTokenException("Invalid token (token not found)"); } String token = (String) authentication.getPrincipal(); OAuth2Authentication auth = tokenServices.loadAuthentication(token); if (auth == null) { throw new InvalidTokenException("Invalid token: " + token); } Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds(); if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) { throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")"); } checkClientDetails(auth); if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) { OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails(); // Guard against a cached copy of the same details if (!details.equals(auth.getDetails())) { // Preserve the authentication details from the one loaded by token services details.setDecodedDetails(auth.getDetails()); } } auth.setDetails(authentication.getDetails()); auth.setAuthenticated(true); return auth; ``` * token校驗redis配置以及文件數據庫配置 ``` spring: datasource: dynamic: enable: true druid: # JDBC 配置(驅動類自動從url的mysql識別,數據源類型自動識別) core: url: jdbc:mysql://59.110.164.254:3306/file_center?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver log: url: jdbc:mysql://59.110.164.254:3306/log-center?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver #連接池配置(通常來說,只需要修改initialSize、minIdle、maxActive initial-size: 1 max-active: 20 min-idle: 1 # 配置獲取連接等待超時的時間 max-wait: 60000 #打開PSCache,并且指定每個連接上PSCache的大小 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 validation-query: SELECT 'x' test-on-borrow: false test-on-return: false test-while-idle: true #配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 time-between-eviction-runs-millis: 60000 #配置一個連接在池中最小生存的時間,單位是毫秒 min-evictable-idle-time-millis: 300000 filters: stat,wall # WebStatFilter配置,說明請參考Druid Wiki,配置_配置WebStatFilter #是否啟用StatFilter默認值true web-stat-filter.enabled: true web-stat-filter.url-pattern: /* web-stat-filter.exclusions: "*.js , *.gif ,*.jpg ,*.png ,*.css ,*.ico , /druid/*" web-stat-filter.session-stat-max-count: 1000 web-stat-filter.profile-enable: true # StatViewServlet配置 #展示Druid的統計信息,StatViewServlet的用途包括:1.提供監控信息展示的html頁面2.提供監控信息的JSON API #是否啟用StatViewServlet默認值true stat-view-servlet.enabled: true #根據配置中的url-pattern來訪問內置監控頁面,如果是上面的配置,內置監控頁面的首頁是/druid/index.html例如: #http://110.76.43.235:9000/druid/index.html #http://110.76.43.235:8080/mini-web/druid/index.html stat-view-servlet.url-pattern: /druid/* #允許清空統計數據 stat-view-servlet.reset-enable: true stat-view-servlet.login-username: admin stat-view-servlet.login-password: admin #StatViewSerlvet展示出來的監控信息比較敏感,是系統運行的內部情況,如果你需要做訪問控制,可以配置allow和deny這兩個參數 #deny優先于allow,如果在deny列表中,就算在allow列表中,也會被拒絕。如果allow沒有配置或者為空,則允許所有訪問 #配置的格式 #<IP> #或者<IP>/<SUB_NET_MASK_size>其中128.242.127.1/24 #24表示,前面24位是子網掩碼,比對的時候,前面24位相同就匹配,不支持IPV6。 #stat-view-servlet.allow= #stat-view-servlet.deny=128.242.127.1/24,128.242.128.1 # Spring監控配置,說明請參考Druid Github Wiki,配置_Druid和Spring關聯監控配置 #aop-patterns= # Spring監控AOP切入點,如x.y.z.service.*,配置多個英文逗號分隔 ################### mysq end ########################## # zipkin: # base-url: http://127.0.0.1:11008 redis: ################### redis 單機版 start ########################## host: 59.110.164.254 port: 6379 timeout: 6000 database: 1 lettuce: pool: max-active: 10 # 連接池最大連接數(使用負值表示沒有限制),如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis實例,則此時pool的狀態為exhausted(耗盡) max-idle: 8 # 連接池中的最大空閑連接 ,默認值也是8 max-wait: 100 # # 等待可用連接的最大時間,單位毫秒,默認值為-1,表示永不超時。如果超過等待時間,則直接拋出JedisConnectionException min-idle: 2 # 連接池中的最小空閑連接 ,默認值也是0 shutdown-timeout: 100ms ################### redis 單機版 end ########################## # cluster: # nodes: 130.75.131.237:7000,130.75.131.238:7000,130.75.131.239:7000,130.75.131.237:7001,130.75.131.238:7001,130.75.131.239:7001 # #130.75.131.237:7000,130.75.131.238:7000,130.75.131.239:7000,130.75.131.237:7001,130.75.131.238:7001,130.75.131.239:7001 # #192.168.3.157:7000,192.168.3.158:7000,192.168.3.159:7000,192.168.3.157:7001,192.168.3.158:7001,192.168.3.159:7001 # timeout: 1000 # 連接超時時間(毫秒) # lettuce: # pool: # max-active: 10 # 連接池最大連接數(使用負值表示沒有限制),如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis實例,則此時pool的狀態為exhausted(耗盡) # max-idle: 8 # 連接池中的最大空閑連接 ,默認值也是8 # max-wait: 100 # # 等待可用連接的最大時間,單位毫秒,默認值為-1,表示永不超時。如果超過等待時間,則直接拋出JedisConnectionException # min-idle: 2 # 連接池中的最小空閑連接 ,默認值也是0 # shutdown-timeout: 100ms #mybatis: mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl config-location: classpath:mybatis.cfg.xml mapper-locations: classpath*:com/open/**/dao/*.xml security: oauth2: ignored: /files-anon/** , /doc.html ,/upload.html , /uploads.html ,/js/** ,/document.html token: store: type: redis #設置最大超時時間 ribbon: httpclient: enabled: false okhttp: enabled: true ReadTimeout: 90000 ConnectTimeout: 90000 OkToRetryOnAllOperations: true MaxAutoRetries: 1 MaxAutoRetriesNextServer: 1 #設置最大容錯超時時間 hystrix: command: default: execution: timeout: enabled: true isolation: thread: timeoutInMilliseconds: 90000 logging: level: com.open.capacity: INFO org.hibernate: INFO org.hibernate.type.descriptor.sql.BasicBinder: TRACE org.hibernate.type.descriptor.sql.BasicExtractor: TRACE # com.neusoft: DEBUG # com.netflix: DEBUG #用于心跳檢測輸出的日志 ``` ## OSS 存儲服務 ![](https://img.kancloud.cn/06/05/0605a29fa79f2ff7532896095f53aed3_1371x636.png) * 支持阿里云oss,七牛oss,本地,fastdfs四種配置 ![](https://img.kancloud.cn/d8/8c/d88c59385158e3a584f8360bd1ba9ecd_1459x394.png) ``` #阿里云文件上傳 aliyun: oss: access-key: LTAIMjvZWiXRuClW accessKeySecret: YwJar7gkdZx3Q3Zk6TRuEAWaAz6n8y endpoint: oss-cn-beijing.aliyuncs.com bucketName: owenwangwen domain: https://owenwangwen.oss-cn-beijing.aliyuncs.com #七牛文件上傳 qiniu: oss: access-key: owGiAWGn6DpU5zlrfLP4K9iQusahmspTW6PxRABW accessKeySecret: 5CBWKFd1pP-OSiusd1Bvhokp-ih4i3bs2QA2r-U2 endpoint: http://q4c5xw7eb.bkt.clouddn.com bucketName: ocpowenwangwen ## 本地文件上傳 file: oss: domain: http://127.0.0.1:9200/api-file path: d:/uploadshp prefix: /statics #fastDFS配置 fdfs: oss : ##nginx需要安裝fastdfs插件 domain: http://192.168.235.173/ soTimeout: 1500 connectTimeout: 600 pool: jmx-enabled: false trackerList: 192.168.235.173:22122 ??? ``` * 代碼默認采用七牛云上傳,如果要改用別的方式注意修改FileType.QINIU ![](https://img.kancloud.cn/7a/27/7a278bbbfa9bd943ee57cb7a5bb84ee2_1491x466.png) * 七牛云,七牛云核心配置 ![](https://box.kancloud.cn/cf44ac3e04f702f399d69821f7e9363b_1727x647.png) * 七牛云上傳核心類 ![](https://box.kancloud.cn/29c024ee23404cccb6110de75752640f_1107x467.png) ## 大文件分片上傳 ### 前端webuploader 分片與并發結合,將一個大文件分割成多塊,并發上傳,極大地提高大文件的上傳速度。 當網絡問題導致傳輸錯誤時,只需要重傳出錯分片,而不是整個文件。另外分片傳輸能夠更加實時的跟蹤上傳進度。 ### 文件分片 ``` /** * 上傳大文件 * @param file * @param chunks */ @PostMapping(value = "/files-anon/bigFile") // @ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR,reason="server error") public ResponseEntity bigFile( String guid, Integer chunk, MultipartFile file, Integer chunks){ try { fileServiceFactory.getFileService(FileType.LOCAL.toString()).chunk(guid,chunk,file,chunks,localFilePath); return ResponseEntity.succeed("操作成功"); }catch (Exception ex){ return ResponseEntity.failed("操作失敗"); } } ``` ### 文件合并 ``` /** * 合并文件 * @param mergeFileDTO */ @RequestMapping(value = "/files-anon/merge",method =RequestMethod.POST ) public ResponseEntity mergeFile(@RequestBody MergeFileDTO mergeFileDTO){ try { return ResponseEntity.succeed(fileServiceFactory.getFileService(FileType.LOCAL.toString()).merge(mergeFileDTO.getGuid(),mergeFileDTO.getFileName(),localFilePath),"操作成功"); }catch (Exception ex){ return ResponseEntity.failed("操作失敗"); } } ``` ## FastDFS文件系統詳解 ### FastDFS介紹 FastDFS的開發者——淘寶的架構師余慶老師 FastDFS開源地址:https://github.com/happyfish100 ### FastDFS是什么? FastDFS是一個開源的輕量級分布式文件系統 FastDFS 不是通用的文件系統,只能通過裝有API訪問,追求高性能,高擴展性 FastDFS 是一款用戶態的分布式文件系統 ### FastDFS能做什么? 它的主要功能包括:文件存儲,文件同步和文件訪問,以及高容量和負載平衡。主要解決了海量數據存儲問題,特別適合以中小文件(建議范圍:4KB < file_size <500MB)為載體的在線服務。在底層存儲上通過邏輯的分組概念,使得通過在同組內配置多個Storage,從而實現軟RAID10 相關術語   ? Tracker Server:跟蹤服務器,主要做調度工作,起到均衡的作用;負責管理所有的 storage server和 group,每個 storage 在啟動后會連接 Tracker,告知自己所屬 group 等信息,并保持周期性心跳。tracker根據storage的心跳信息,建立group==>[storage server list]的映射表。由此可見Tracker的作用至關重要,也就增加了系統的單點故障,為此FastDFS支持多個備用的Tracker   ? Storage Server:存儲服務器,主要提供容量和備份服務;以 group 為單位,每個 group 內可以有多臺 storage server,數據互為備份。   ? Client:客戶端,上傳下載數據的服務器,也就是我們自己的項目所部署在的服務器。 ? group:組,也可稱為卷。同組內服務器上的文件是完全相同的。 ? 文件標識:包括兩部分:組名和文件名(包含路徑)。 ? meta data:文件相關屬性,鍵值對(Key Value Pair)方式,如:width=1024,heigth=768。 ### FastDFS架構圖 ![](https://img.kancloud.cn/5c/ec/5cec60e49e7522393ba0fe25fce202bb_713x888.png) ### 文件系統的對比 ![](https://img.kancloud.cn/30/4c/304ce8efcd65feecfd7da0000efdc2ac_814x446.png) ### 文件上傳流程 ![](https://img.kancloud.cn/d9/57/d9577e9bdc751da73ea2090580d3c68f_873x604.png) ### 文件下載流程 ![](https://img.kancloud.cn/45/f7/45f7cd0e7ca9e52e510e7eb5675050ec_859x616.png) ### 同步機制 ?同一組內的storage server之間是對等的,文件上傳、刪除等操作可以在任意一臺storage server上進行; ?文件同步只在同組內的storage server之間進行,采用push方式,即源服務器同步給目標服務器; ?源頭數據才需要同步,備份數據不需要再次同步,否則就構成環路了; ?上述第二條規則有個例外,就是新增加一臺storage server時,由已有的一臺storage server將已有的所有數據(包括源頭數據和備份數據)同步給該新增服務器。 ### 運行時目錄結構-tracker server ![](https://img.kancloud.cn/32/b0/32b06b72556da7304f365d9657c5f643_695x220.png) ### 運行時目錄結構-storage server ![](https://img.kancloud.cn/48/2b/482be4d7281482fa728ddb0c44d6e426_745x418.png) ### 快速搭建 服務器192.168.235.173準備 | 軟件 | 版本 | 備注 | | --- | --- |--- | | centos| 7.5 | | | docker-ce| 18.06.1 | | ``` docker pull registry.cn-beijing.aliyuncs.com/tianzuo/fastdfs mkdir /var/local/fdfs docker run \ --net=host \ --name=fastdfs \ -e IP=192.168.235.173 \ -e WEB_PORT=80 \ -v $PWD/fdfs:/var/local/fdfs \ -d registry.cn-beijing.aliyuncs.com/tianzuo/fastdfs ``` 確保80、22122和23000這3個端口未被占用 IP:配置所在服務器的ip WEB_PORT:配置nginx的端口,用于文件下載
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看