iModel 缓存云服务器建立

当前 iTwin.js 原生支持 Azure Blob 云存储,用户通过配置 Azure 提供的 accountaccessKey 密钥启动该功能即可。

如需支持其他云服务(阿里云、亚马逊云、腾讯云、华为云等)需扩展 CloudStorageService 类,详情查看

1. 缓存云服务建立

1.1 主要步骤

  1. 获取密钥

    连接云服务提供商的密钥,例如 account,accessKey。通过提供的密钥,采用对于的开发包实现云服务的连接。

  2. 前端配置

    在调用 IModelApp.startup() 方法之前,需要指定云服务提供商,例如

    CloudStorageTileCache.getCache().provider = CloudStorageProvider.Azure;
    
  3. 后端配置

    在调用 IModelHost.startup() 方法时,需配置缓存设置等内容,例如

    const credentials: CloudStorageServiceCredentials = {
      service: "Azure",
      account: "account",
      accessKey: "accessKey",
    };
    CloudStorageTileCache.getCache().provider = CloudStorageProvider.Azure;
    
    hostConfig.compressCachedTiles = true;
    hostConfig.tileCacheCredentials = credentials;
    IModelHost.tileCacheService = new AzureBlobStorage(credentials);
    IModelHost.startup(hostConfig);
    

2. iTwin 云缓存主要流程

云缓存服务主要流程


2.1 以阿里云为例

  1. 获取密钥

    阿里云需要获取的信息有:

    (1)AccessKey

    从 AccessKey 里面需要获取 AccessKey ID 和 AccessKey Secret,具体信息可 点击查看 ,对应 iTwin 关系如下:

    | iTwin | AliCloud | | --------- | ---------------- | | account | AccessKey ID | | accessKey | AccessKey Secret |

    (2)bucketRegion

    指阿里云创建对象存储的位置,如 oss-cn-beijing , 具体检索位置可 点击查看

    OSS Region 查看示例

    (3)bucket

    由于阿里云对象存储(OSS)空间有数量限制,同账号下不超过 100 个,因此建议单独创建一个 bucket 存放 iTwin 缓存数据,bucket 的使用限制可 点击查看

    OSS Bucket 限制示例

    (4)完整配置示例

    {
      "service": "AliCloud",
      "account": "XXXXXXXXXXXXXX",
      "accessKey": "XXXXXXXXXXXXXX",
      "container": "imodel-cache",
      "bucketRegion": "oss-cn-beijing"
    }
    
  2. 前端配置

    CloudStorageTileCache.getCache().provider = CloudStorageProvider.AliCloud;
    await IModelApp.startup(opts);
    
  3. 后端配置

    (1)扩展 CloudStorageService 主要实现的方法有:

    • obtainContainerUrl
     public obtainContainerUrl(
     id: CloudStorageContainerDescriptor,
     expiry: Date,
     // eslint-disable-next-line @typescript-eslint/no-unused-vars
     _clientIp ?: string,
    ): CloudStorageContainerUrl {
     const policy: OSS.SignatureUrlOptions = {
         expires: 1800, //default expire time 30 min
     };
    
     const url: CloudStorageContainerUrl = {
         descriptor: this.makeDescriptor(id),
         valid: 0,
         expires: expiry.getTime(),
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         url: this._client.signatureUrl(id.name + '/' + id.resource!, policy),
         bound: true,
     };
    
     return url;
    }
    
    • upload
     public async upload(
     container: string,
     name: string,
     data: Uint8Array,
     options ? : CloudStorageUploadOptions,
    ): Promise < string > {
     try {
         await this._client.getBucketInfo(this._client.options.bucket);
     } catch (error) {
         // in case of empty bucket info
         if (!this._client.options.bucket) {
             this._client.options.bucket = 'imodel-cache';
         }
         await this._client.putBucket(this._client.options.bucket);
         await this._client.putBucketCORS(this._client.options.bucket, [{
             allowedOrigin: '*',
             allowedMethod: ['GET', 'POST', 'PUT', 'HEAD'],
             allowedHeader: '*',
         }, ]);
     }
     this._client.useBucket(this._client.options.bucket);
    
     const dataStream = new PassThrough();
     dataStream.end(data);
    
     let source: Readable;
    
     const putOptions = {
         mime: options && options.type ? options.type : 'application/octet-stream',
         headers: {
             'Cache-Control': options && options.cacheControl ?
                 options.cacheControl :
                 'private, max-age=31536000, immutable',
         },
     }
     as OSS.PutStreamOptions;
    
     if (options && options.contentEncoding === 'gzip') {
         (putOptions.headers as any)['Content-Encoding'] = options.contentEncoding;
         const compressor = zlib.createGzip();
         source = dataStream.pipe(compressor);
     } else {
         source = dataStream;
     }
     await this._client.putStream(container + '/' + name, source, putOptions);
     return '';
    }
    

    完整实现代码可查看 iPC repo 的 dev 分支,路径为 backend > src > client > AliCloudStorageService.ts 。

  4. 效果展示

    (1) iTwin Viewer

    在 iTwin 请求加载模型的过程中,通过 Network 面板查看到 Viewer 正在请求阿里云服务的缓存数据。

    Network 查看云缓存服务器请求

    (2) 阿里云 OSS 控制面板

    在阿里云控制台中,通过查看 Bucket 列表,可发现该 iModel Cache 存放的文件。

    阿里云对象存储文件查看

3. iTwin.js 非云缓存存储位置

  • 可通过 backend 进行配置,例如

    const hostConfig = new IModelHostConfiguration();
    hostConfig.cacheDir = "D:\\tmp";
    
  • 默认 CacheDir 路径 默认路径

results matching ""

    No results matching ""