升訊威在線客服系統的併發高性能數據處理技術:高性能OSS文件存儲

我在業餘時間開發維護了一款免費開源的升訊威在線客服系統,也收穫了許多用戶。對我來說,只要能獲得用戶的認可,就是我最大的動力。

最近客服系統成功經受住了客戶現場組織的壓力測試,獲得了客戶的認可。
客戶組織多名客服上線後,所有員工同一時間打開訪客頁面瘋狂不停的給在線客服發消息,系統穩定無異常無掉線,客服回覆消息正常。消息實時到達無任何延遲。

https://kf.shengxunwei.com/


我會通過一系列的文章詳細分析升訊威在線客服系統的併發高性能技術是如何實現的,使用了哪些方案以及具體的做法。本文將介紹如何爲多線程處理同步數據。

先看實現效果

客服端

訪客端

什麼是對象存儲OSS

OSS具有與平臺無關的RESTful API接口,您可以在任何應用、任何時間、任何地點存儲和訪問任意類型的數據。

您可以使用API、SDK包或者OSS遷移工具輕鬆地將海量數據移入或移出阿里雲OSS。數據存儲到OSS以後,您可以選擇標準存儲(Standard)作爲移動應用、大型網站、圖片分享或熱點音視頻的主要存儲方式,也可以選擇成本更低、存儲期限更長的低頻訪問存儲(Infrequent Access)、歸檔存儲(Archive)、冷歸檔存儲(Cold Archive)或者深度冷歸檔(Deep Cold Archive)作爲不經常訪問數據的存儲方式。

OSS工作原理

數據以對象(Object)的形式存儲在OSS的存儲空間(Bucket )中。如果要使用OSS存儲數據,您需要先創建Bucket,並指定Bucket的地域、訪問權限、存儲類型等屬性。創建Bucket後,您可以將數據以Object的形式上傳到Bucket,並指定Object的文件名(Key)作爲其唯一標識。

OSS以HTTP RESTful API的形式對外提供服務,訪問不同地域需要不同的訪問域名(Endpoint)。當您請求訪問OSS時,OSS通過使用訪問密鑰(AccessKey ID和AccessKey Secret)對稱加密的方法來驗證某個請求的發送者身份。

Object操作在OSS上具有原子性和強一致性。

開始配置訪問憑證

您可以選擇以下類型的訪問憑證。

  • 臨時訪問憑證:對於需要高安全性的場景,例如臨時授權應用訪問OSS,建議使用臨時訪問憑證。臨時訪問憑證可以限制訪問的有效期,從而減少訪問憑證泄露的風險。此外,臨時訪問憑證支持權限控制,可以有效地避免權限過大的問題。更多信息,請參見使用臨時訪問憑證。

  • 長期訪問憑證:出於安全性考慮,不建議您使用長期訪問憑證,建議您使用臨時訪問憑證。對於需要便利性的場景,長期訪問憑證可以在較長時間內免除多次刷新的麻煩。建議每三個月更換一次長期訪問憑證,以提高賬號的安全性。當長期訪問憑證泄露或者不再使用時,應該及時刪除或者禁用相關的訪問憑證,以免造成安全風險。更多信息,請參見使用長期訪問憑證。

創建 OSS 存儲空間

在支持資源組的地域創建存儲空間時,您可以爲Bucket配置資源組。關於資源組的更多信息。


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填寫Bucket所在地域對應的Endpoint。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱。
        String bucketName = "examplebucket";
        // 填寫資源組ID。如果不填寫資源組ID,則創建的Bucket屬於默認資源組。
        //String rsId = "rg-aek27tc****";


        // 創建OSSClient實例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            // 創建CreateBucketRequest對象。
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);

            // 如果創建存儲空間的同時需要指定存儲類型、存儲空間的讀寫權限、數據容災類型, 請參考如下代碼。
            // 此處以設置存儲空間的存儲類型爲標準存儲爲例介紹。
            //createBucketRequest.setStorageClass(StorageClass.Standard);
            // 數據容災類型默認爲本地冗餘存儲,即DataRedundancyType.LRS。如果需要設置數據容災類型爲同城冗餘存儲,請設置爲DataRedundancyType.ZRS。
            //createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS);
            // 設置存儲空間讀寫權限爲公共讀,默認爲私有。
            //createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);

            // 在支持資源組的地域創建Bucket時,您可以爲Bucket配置資源組。
            //createBucketRequest.setResourceGroupId(rsId);

            // 創建存儲空間。
            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();
            }
        }
    }
}

簡單上傳

簡單上傳是指通過PutObject方法上傳單個文件(Object)。簡單上傳包括流式上傳和文件上傳,流式上傳使用InputStream作爲OSS文件的數據源,文件上傳使用本地文件作爲OSS文件的數據源。本文介紹如何使用流式上傳和文件上傳方式上傳文件。

以下代碼用於將字符串上傳到目標存儲空間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請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
        String objectName = "exampledir/exampleobject.txt";

        // 創建OSSClient實例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            // 填寫字符串。
            String content = "Hello OSS,你好世界";

            // 創建PutObjectRequest對象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));

            // 如果需要上傳時設置存儲類型和訪問權限,請參考以下示例代碼。
            // 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();
            }
        }
    }
}   


簡介

升訊威在線客服與營銷系統是一款客服軟件,但更重要的是一款營銷利器。

https://kf.shengxunwei.com/

  • 可以追蹤正在訪問網站或使用 APP 的所有訪客,收集他們的瀏覽情況,使客服能夠主動出擊,施展話術,促進成單。
    訪* 客端在 PC 支持所有新老瀏覽器。包括不支持 WebSocket 的 IE8 也能正常使用。
  • 移動端支持所有手機瀏覽器、APP、各大平臺的公衆號對接。
  • 支持訪客信息互通,可傳輸訪客標識、名稱和其它任意信息到客服系統。
  • 具備一線專業技術水平,網絡中斷,拔掉網線,手機飛行模式,不丟消息。同類軟件可以按視頻方式對比測試。

希望能夠打造: 開放、開源、共享。努力打造 .net 社區的一款優秀開源產品。

鐘意的話請給個贊支持一下吧,謝謝~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章