高並發架構的搭建(二)
一、Ceph Swift API介面開發
Swift是由Rackspace開發的用來為雲計算提供可擴展存儲的項目。專註於對象存儲, 並提供一套REST風格的Api來訪問, 與Ceph強一致性不同, 它是最終一致性。兩者都是優秀的開源項目, 並無明顯優劣之分,在使用場景上有所不同, 如果是專註於對象存儲, 那麼可以選擇swift即可滿足需要, 如果還有塊存儲要求, 那麼選擇Ceph更為合適。這裡選擇Ceph, 因為通過網關可以適配兼容swift api, 同時在數據訪問上具有較強的擴展性。
1.1準備工作
創建Swift用戶, 用於介面請求認證,在140上執行下面命令
sudo radosgw-admin user create --subuser="cephtester:subtester" -- uid="cephtester" --display-name="cephtester" --key-type=swift --secret="ljx" - -access=full
uid 為主用戶, subuser為子用戶資訊, secret指定密鑰, 不指定則隨機生成, access擁有許可權設定,程式碼中需使用返回資訊中的user和secret_key。
{ "user_id": "cephtester", "display_name": "cephtester", "email": "", "suspended": 0, "max_buckets": 1000, "auid": 0, "subusers": [ { "id": "cephtester:subtester", "permissions": "full-control" } ], "keys": [], "swift_keys": [ { "user": "cephtester:subtester", "secret_key": "ljx" } ], "caps": [], "op_mask": "read, write, delete", "default_placement": "", "placement_tags": [], "bucket_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "user_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "temp_url_keys": [], "type": "rgw", "mfa_ids": [] }
創建管理員帳號:
radosgw-admin user create --uid=mgruser --display-name=mgruser --system
{ "user_id": "mgruser", "display_name": "mgruser", "email": "", "suspended": 0, "max_buckets": 1000, "auid": 0, "subusers": [], "keys": [ { "user": "mgruser", "access_key": "KI0XONO70L11Q9XGRE3C", "secret_key": "RHkmPPMvkvy10mi4kmJA3vStJe2bmcoArYYsDwn6" } ], "swift_keys": [], "caps": [], "op_mask": "read, write, delete", "system": "true", "default_placement": "", "placement_tags": [], "bucket_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "user_quota": { "enabled": false, "check_on_raw": false, "max_size": -1, "max_size_kb": 0, "max_objects": -1 }, "temp_url_keys": [], "type": "rgw", "mfa_ids": [] }
根據生成的access_key與secret_key, 執行:這兩個值是上面生成的
ceph dashboard set-rgw-api-access-key KI0XONO70L11Q9XGRE3C ceph dashboard set-rgw-api-secret-key RHkmPPMvkvy10mi4kmJA3vStJe2bmcoArYYsDwn6
打開管理介面,//192.168.32.140:8443/#/rgw/user 可以查看到我們剛才創建的兩個用戶:
1.2、文件伺服器搭建
搭建一個單獨的Maven工程,專門用於實現文件上傳和文件下載,工程坐標如下:
POM.XML
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-cloud-service</artifactId> <groupId>com.ghy</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.ghy</groupId> <artifactId>spring-cloud-file-service</artifactId> <description> 文件上傳服務 </description> <dependencies> <!-- Rados Java Api依賴 --> <dependency> <groupId>com.ceph</groupId> <artifactId>rados</artifactId> <version>0.6.0</version> </dependency> <!-- Cephfs 文件系統依賴 --> <dependency> <groupId>com.ceph</groupId> <artifactId>libcephfs</artifactId> <version>0.80.5</version> </dependency> <!--swift--> <dependency> <groupId>org.javaswift</groupId> <artifactId>joss</artifactId> <version>0.10.2</version> </dependency> </dependencies> </project>
bootstrap.yml
server: port: 8082 spring: application: name: spring-cloud-file-service cloud: nacos: config: file-extension: yaml server-addr: 192.168.32.197:8848 discovery: #Nacos的註冊地址 server-addr: 192.168.32.197:8848 ceph: username: cephtester:subtester #Ceph配置 主用戶名:子用戶名 password: ljx #秘鑰 authUrl: http://192.168.32.195:8443/auth/1.0 #介面訪問路徑 defaultContainerName: user_datainfo #默認容器名字(可以自己隨便寫無所謂) #圖片路徑 cephurl: http://localhost:8082/file/download/ #日誌配置 logging: pattern: console: "%msg%n"
接下來創建一個ContainerConfig類來完成配置文件中ceph的初始化操作
@Data @Configuration @ConfigurationProperties(prefix = "ceph") public class ContainerConfig { private String username; private String password; private String authUrl; private String defaultContainerName; /***** * 1、創建帳號資訊 */ @Bean public Account account(){ AccountConfig config = new AccountConfig(); config.setUsername(username); config.setPassword(password); config.setAuthUrl(authUrl); config.setAuthenticationMethod(AuthenticationMethod.BASIC); return new AccountFactory(config).createAccount(); } /***** * 2、創建容器對象 */ @Bean public Container container(){ Container container = account().getContainer(defaultContainerName); if(!container.exists()){ return container.create(); } return container; } }
@Component public class FileHandler { @Autowired private Container container; /**** * 文件上傳 */ public void upload(String filename,byte[] buffer){ //獲取容器 StoredObject object = container.getObject(filename); //文件上傳 object.uploadObject(buffer); } /*** * 文件下載 */ public byte[] download(String filename){ //獲取容器 StoredObject object = container.getObject(filename); //下載 byte[] bytes = object.downloadObject(); return bytes; } }
@RestController @RequestMapping(value = "/file") public class FileController { @Autowired private FileHandler fileHandler; /**** * 文件上傳 * @param file * @return */ @PostMapping(value = "/upload") public RespResult upload(MultipartFile file) throws IOException { //調用 fileHandler.upload(file.getOriginalFilename(),file.getBytes()); return RespResult.ok(); } /**** * 文件下載 * @return */ @GetMapping(value = "/download/{filename}") public void download(@PathVariable String filename, HttpServletResponse response) throws IOException { //調用 byte[] buffer = fileHandler.download(filename); ServletOutputStream os = response.getOutputStream(); os.write(buffer); os.flush(); os.close(); } }
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class SpringCloudFileServiceApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFileServiceApplication.class,args); } }

