升讯威在线客服系统的并发高性能数据处理技术:高性能OSS文件存储
我在業(yè)余時(shí)間開發(fā)維護(hù)了一款免費(fèi)開源的升訊威在線客服系統(tǒng),也收獲了許多用戶。對(duì)我來說,只要能獲得用戶的認(rèn)可,就是我最大的動(dòng)力。
最近客服系統(tǒng)成功經(jīng)受住了客戶現(xiàn)場(chǎng)組織的壓力測(cè)試,獲得了客戶的認(rèn)可。
客戶組織多名客服上線后,所有員工同一時(shí)間打開訪客頁面瘋狂不停的給在線客服發(fā)消息,系統(tǒng)穩(wěn)定無異常無掉線,客服回復(fù)消息正常。消息實(shí)時(shí)到達(dá)無任何延遲。
https://kf.shengxunwei.com/
我會(huì)通過一系列的文章詳細(xì)分析升訊威在線客服系統(tǒng)的并發(fā)高性能技術(shù)是如何實(shí)現(xiàn)的,使用了哪些方案以及具體的做法。本文將介紹如何為多線程處理同步數(shù)據(jù)。
先看實(shí)現(xiàn)效果
客服端
訪客端
什么是對(duì)象存儲(chǔ)OSS
OSS具有與平臺(tái)無關(guān)的RESTful API接口,您可以在任何應(yīng)用、任何時(shí)間、任何地點(diǎn)存儲(chǔ)和訪問任意類型的數(shù)據(jù)。
您可以使用API、SDK包或者OSS遷移工具輕松地將海量數(shù)據(jù)移入或移出阿里云OSS。數(shù)據(jù)存儲(chǔ)到OSS以后,您可以選擇標(biāo)準(zhǔn)存儲(chǔ)(Standard)作為移動(dòng)應(yīng)用、大型網(wǎng)站、圖片分享或熱點(diǎn)音視頻的主要存儲(chǔ)方式,也可以選擇成本更低、存儲(chǔ)期限更長(zhǎng)的低頻訪問存儲(chǔ)(Infrequent Access)、歸檔存儲(chǔ)(Archive)、冷歸檔存儲(chǔ)(Cold Archive)或者深度冷歸檔(Deep Cold Archive)作為不經(jīng)常訪問數(shù)據(jù)的存儲(chǔ)方式。
OSS工作原理
數(shù)據(jù)以對(duì)象(Object)的形式存儲(chǔ)在OSS的存儲(chǔ)空間(Bucket )中。如果要使用OSS存儲(chǔ)數(shù)據(jù),您需要先創(chuàng)建Bucket,并指定Bucket的地域、訪問權(quán)限、存儲(chǔ)類型等屬性。創(chuàng)建Bucket后,您可以將數(shù)據(jù)以O(shè)bject的形式上傳到Bucket,并指定Object的文件名(Key)作為其唯一標(biāo)識(shí)。
OSS以HTTP RESTful API的形式對(duì)外提供服務(wù),訪問不同地域需要不同的訪問域名(Endpoint)。當(dāng)您請(qǐng)求訪問OSS時(shí),OSS通過使用訪問密鑰(AccessKey ID和AccessKey Secret)對(duì)稱加密的方法來驗(yàn)證某個(gè)請(qǐng)求的發(fā)送者身份。
Object操作在OSS上具有原子性和強(qiáng)一致性。
開始配置訪問憑證
您可以選擇以下類型的訪問憑證。
-
臨時(shí)訪問憑證:對(duì)于需要高安全性的場(chǎng)景,例如臨時(shí)授權(quán)應(yīng)用訪問OSS,建議使用臨時(shí)訪問憑證。臨時(shí)訪問憑證可以限制訪問的有效期,從而減少訪問憑證泄露的風(fēng)險(xiǎn)。此外,臨時(shí)訪問憑證支持權(quán)限控制,可以有效地避免權(quán)限過大的問題。更多信息,請(qǐng)參見使用臨時(shí)訪問憑證。
-
長(zhǎng)期訪問憑證:出于安全性考慮,不建議您使用長(zhǎng)期訪問憑證,建議您使用臨時(shí)訪問憑證。對(duì)于需要便利性的場(chǎng)景,長(zhǎng)期訪問憑證可以在較長(zhǎng)時(shí)間內(nèi)免除多次刷新的麻煩。建議每三個(gè)月更換一次長(zhǎng)期訪問憑證,以提高賬號(hào)的安全性。當(dāng)長(zhǎng)期訪問憑證泄露或者不再使用時(shí),應(yīng)該及時(shí)刪除或者禁用相關(guān)的訪問憑證,以免造成安全風(fēng)險(xiǎn)。更多信息,請(qǐng)參見使用長(zhǎng)期訪問憑證。
創(chuàng)建 OSS 存儲(chǔ)空間
在支持資源組的地域創(chuàng)建存儲(chǔ)空間時(shí),您可以為Bucket配置資源組。關(guān)于資源組的更多信息。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.DataRedundancyType;
import com.aliyun.oss.model.StorageClass;
public class CreateBucket {
public static void main(String[] args) throws Exception {
// yourEndpoint填寫B(tài)ucket所在地域?qū)?yīng)的Endpoint。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環(huán)境變量中獲取訪問憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫B(tài)ucket名稱。
String bucketName = "examplebucket";
// 填寫資源組ID。如果不填寫資源組ID,則創(chuàng)建的Bucket屬于默認(rèn)資源組。
//String rsId = "rg-aek27tc****";
// 創(chuàng)建OSSClient實(shí)例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// 創(chuàng)建CreateBucketRequest對(duì)象。
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
// 如果創(chuàng)建存儲(chǔ)空間的同時(shí)需要指定存儲(chǔ)類型、存儲(chǔ)空間的讀寫權(quán)限、數(shù)據(jù)容災(zāi)類型, 請(qǐng)參考如下代碼。
// 此處以設(shè)置存儲(chǔ)空間的存儲(chǔ)類型為標(biāo)準(zhǔn)存儲(chǔ)為例介紹。
//createBucketRequest.setStorageClass(StorageClass.Standard);
// 數(shù)據(jù)容災(zāi)類型默認(rèn)為本地冗余存儲(chǔ),即DataRedundancyType.LRS。如果需要設(shè)置數(shù)據(jù)容災(zāi)類型為同城冗余存儲(chǔ),請(qǐng)?jiān)O(shè)置為DataRedundancyType.ZRS。
//createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS);
// 設(shè)置存儲(chǔ)空間讀寫權(quán)限為公共讀,默認(rèn)為私有。
//createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
// 在支持資源組的地域創(chuàng)建Bucket時(shí),您可以為Bucket配置資源組。
//createBucketRequest.setResourceGroupId(rsId);
// 創(chuàng)建存儲(chǔ)空間。
ossClient.createBucket(createBucketRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
簡(jiǎn)單上傳
簡(jiǎn)單上傳是指通過PutObject方法上傳單個(gè)文件(Object)。簡(jiǎn)單上傳包括流式上傳和文件上傳,流式上傳使用InputStream作為OSS文件的數(shù)據(jù)源,文件上傳使用本地文件作為OSS文件的數(shù)據(jù)源。本文介紹如何使用流式上傳和文件上傳方式上傳文件。
以下代碼用于將字符串上傳到目標(biāo)存儲(chǔ)空間examplebucket中exampledir目錄下的exampleobject.txt文件。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.ByteArrayInputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以華東1(杭州)為例,其它Region請(qǐng)按實(shí)際情況填寫。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環(huán)境變量中獲取訪問憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
String objectName = "exampledir/exampleobject.txt";
// 創(chuàng)建OSSClient實(shí)例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// 填寫字符串。
String content = "Hello OSS,你好世界";
// 創(chuàng)建PutObjectRequest對(duì)象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
// 如果需要上傳時(shí)設(shè)置存儲(chǔ)類型和訪問權(quán)限,請(qǐng)參考以下示例代碼。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);
// 上傳字符串。
PutObjectResult result = ossClient.putObject(putObjectRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
簡(jiǎn)介
升訊威在線客服與營(yíng)銷系統(tǒng)是一款客服軟件,但更重要的是一款營(yíng)銷利器。
https://kf.shengxunwei.com/
- 可以追蹤正在訪問網(wǎng)站或使用 APP 的所有訪客,收集他們的瀏覽情況,使客服能夠主動(dòng)出擊,施展話術(shù),促進(jìn)成單。
訪* 客端在 PC 支持所有新老瀏覽器。包括不支持 WebSocket 的 IE8 也能正常使用。 - 移動(dòng)端支持所有手機(jī)瀏覽器、APP、各大平臺(tái)的公眾號(hào)對(duì)接。
- 支持訪客信息互通,可傳輸訪客標(biāo)識(shí)、名稱和其它任意信息到客服系統(tǒng)。
- 具備一線專業(yè)技術(shù)水平,網(wǎng)絡(luò)中斷,拔掉網(wǎng)線,手機(jī)飛行模式,不丟消息。同類軟件可以按視頻方式對(duì)比測(cè)試。
-
- 優(yōu)酷視頻:https://v.youku.com/v_show/id_XNTEwNzQ5Mzg2OA==.html
-
- bilibili 視頻:https://www.bilibili.com/video/BV1pK4y1N7UP?t=22
希望能夠打造: 開放、開源、共享。努力打造 .net 社區(qū)的一款優(yōu)秀開源產(chǎn)品。
鐘意的話請(qǐng)給個(gè)贊支持一下吧,謝謝~
總結(jié)
以上是生活随笔為你收集整理的升讯威在线客服系统的并发高性能数据处理技术:高性能OSS文件存储的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 神经网络入门篇:详解多样本向量化(Vec
- 下一篇: dsBlog前后台博客系统