• 关于

    置api

    的搜索结果

回答

使用ET工业大脑 阿里云ET工业大脑产品的使用流程如下图所示: 您可以通过以下步骤,在ET工业大脑控制台创建项目并应用到实际生产环境中: 准备云资源:在使用ET工业大脑前,您首先要添加用来存储数据的云资源,为数据接入做准备,详细步骤请参考资源管理。 创建项目:在ET工业大脑控制台创建项目。如果您的数据类型为时序数据,请参考创建项目-时序数据。如果您的数据类型为图像数据,请参考创建项目-图像数据。 配置知识图谱:在知识图谱页面配置业务流程、数据字典和业务规则。如果您的数据类型为时序数据,请参考配置知识图谱。如果您的数据类型为图像数据,则不需要配置知识图谱。 配置数据链路:通过数据链路配置功能,您可以完成从数据接入、数据预处理,到数据映射,再到算法的一系列配置。如果您的数据类型为时序数据,请参考配置数据链路-时序数据。如果您的数据类型为图像数据,请参考配置数据链路-图像数据。 配置数据接入:通过数据接入配置功能,您可以将您的设备数据、数据库数据或本地文件数据接入到工业大脑平台中,实现数据上云。如果您的数据类型为时序数据,请参考配 置数据接入。如果您的数据类型为图像数据,请参考上传图像。配置数据预处理:通过数据预处理功能,您可以对设备数据的缺失值进行填充。如果您的数据类型为时序数据,请参考配置数据预处理。如果您的数据类型为图像数据,则不需要进行数据预处理。配置数据映射:您可以通过知识图谱数据映射功能,将设备数据与相应的设备属性进行关联,作为算法组件的输入源或输出源。如果您的数据类型为时序数据,请参考配置数据映射。如果您的数据类型为图像数据,则不需要进行数据映射配置,但需要对图像进行标注,详细请参考使用外部标注工具。 配置AI算法:配置算法组件的输入输出,实现模型训练和在线预测功能。如果您的数据类型为时序数据,请参考配置算法组件。如果您的数据类型为图像数据,请参考算法训练。算法原理和配置方法请参考算法说明。 调用API:算法运行完成后,会生成相应的API,您可以通过在开发项目中配置API对应的serviceId,并下载SDK开发包,来调用对应的API。详细请参考下载API SDK和API调用方式。

剑曼红尘 2020-03-24 09:45:01 0 浏览量 回答数 0

回答

调用方式 API 描述 请求结构 请求结构 返回结果 调用 API 服务后返回数据采用统一格式: 签名机制 签名机制 域名管理 API 描述 DescribeLiveDomainDetail 调用DescribeLiveDomainDetail获取指定直播域名配置的基本信息。 DescribeLiveCertificateDetail 调用DescribeLiveCertificateDetail获取证书详细信息。 AddLiveDomain 调用AddLiveDomain添加直播域名,一次只能提交一个域名。 AddLiveDomainMapping 调用AddLiveDomainMapping添加直播域名播流域名和推流域名的映射关系配置。 DeleteLiveDomain 调用DeleteLiveDomain删除已添加的直播域名。 DeleteLiveDomainMapping 调用DeleteLiveDomainMapping删除直播域名播流域名和推流域名的映射关系配置。 DescribeLiveUserDomains 调用DescribeLiveUserDomains查询用户名下所有的直播域名。 DescribeLiveCertificateList 调用DescribeLiveCertificateList获取证书列表信息。 SetLiveDomainCertificate 调用SetLiveDomainCertificate设置某域名下证书功能是否启用及修改证书信息。 BatchSetLiveDomainConfigs 调用BatchSetLiveDomainConfigs批量配置域名。 BatchDeleteLiveDomainConfigs 调用BatchDeleteLiveDomainConfigs批量删除域名配置。 DescribeLiveDomainConfigs 调用DescribeLiveDomainConfigs查询直播域名配置,一次可查询多个功能配置。 StartLiveDomain 调用StartLiveDomain启用状态为停用的直播域名,将DomainStatus变更为online。 StopLiveDomain 调用StopLiveDomain停用某个直播域名,将DomainStatus变更为offline。 直播拉流 API 描述 AddLivePullStreamInfoConfig 添加直播拉流信息,仅支持拉取直播流。 支持rtmp,http,flv格式。 DescribeLivePullStreamConfig 调用DescribeLivePullStreamConfig查询域名下拉流配置信息。 DeleteLivePullStreamInfoConfig 调用DeleteLivePullStreamInfoConfig删除拉流信息。 直播流管理 API 描述 DescribeLiveStreamsOnlineList 调用DescribeLiveStreamsOnlineList查看指定域名下(或者指定域名下某个应用)的所有正在推的流的信息。 DescribeLiveStreamsPublishList 调用DescribeLiveStreamsPublishList获取某一时间段内某个域名(或域名下某应用或某个流)的推流记录。 DescribeLiveStreamsBlockList 调用DescribeLiveStreamsBlockList获取域名下直播流播放的黑名单。 DescribeLiveStreamsControlHistory 调用DescribeLiveStreamsControlHistory获取某个域名或应用下的直播流操作记录。 DescribeLiveStreamBitRateData 调用DescribeLiveStreamBitRateData查询RTMP协议的直播流的设置时间范围内的一组帧率和码率,适用于获取历史数据。 ForbidLiveStream 调用ForbidLiveStream禁止某条流的推送,可以预设某个时刻将流恢复。 ResumeLiveStream 调用ResumeLiveStream恢复某条流的推送。 DescribeLiveStreamsFrameRateAndBitRateData 调用DescribeLiveStreamsFrameRateAndBitRateData实时查询直播流帧率和码率数据。 DescribeLiveDomainOnlineUserNum 调用DescribeLiveDomainOnlineUserNum查询域名下所有流某分钟的在线人数信息。 DescribeLiveDomainFrameRateAndBitRateData 调用DescribeLiveDomainFrameRateAndBitRateData查询直播域名下流帧率和码率数据。 推流回调 API 描述 SetLiveStreamsNotifyUrlConfig 调用SetLiveStreamsNotifyUrlConfig设置推流回调配置。 DescribeLiveStreamsNotifyUrlConfig 调用DescribeLiveStreamsNotifyUrlConfig查询推流回调配置。 DeleteLiveStreamsNotifyUrlConfig 调用DeleteLiveStreamsNotifyUrlConfig删除推流回调配置。 回调格式说明 流状态实时信息回调,可以及时通知用户推流或断流操作结果。 直播时移 API 描述 直播时移 直播时移 直播转码 API 描述 AddLiveStreamTranscode 调用AddLiveStreamTranscode添加转码配置信息。 AddCustomLiveStreamTranscode 调用AddCustomLiveStreamTranscode添加自定义转码配置信息。 DeleteLiveStreamTranscode 调用DeleteLiveStreamTranscode删除转码配置信息。 DescribeLiveStreamTranscodeInfo 调用DescribeLiveStreamTranscodeInfo查询转码配置信息。 AddTrancodeSEI 调用AddTrancodeSEI添加转码SEI信息。 直播转点播 API 描述 AddLiveRecordVodConfig 调用AddLiveRecordVodConfig增加直播录制转点播配置,将录制内容保存到点播媒资库。 DeleteLiveRecordVodConfig 调用DeleteLiveRecordVodConfig删除直播录制转点播配置。 DescribeLiveRecordVodConfigs 调用DescribeLiveRecordVodConfigs查询直转点配置列表。 直播录制 API 描述 RealTimeRecordCommand 调用RealTimeRecordCommand按需完成手动录制。例如,动态地启动、停止录制 。 DescribeLiveRecordConfig 调用DescribeLiveRecordConfig查询域名下所有App录制配置。 按需录制回调 进行录制配置之后,您可以选择是否按需录制。 录制事件回调 录制事件回调 AddLiveAppRecordConfig 调用AddLiveAppRecordConfig配置APP录制,输出内容保存到OSS中。 DeleteLiveAppRecordConfig 调用DeleteLiveAppRecordConfig解除录制配置。 DescribeLiveStreamRecordContent 调用DescribeLiveStreamRecordContent查询录制内容。 CreateLiveStreamRecordIndexFiles 调用CreateLiveStreamRecordIndexFiles创建录制索引文件。 DescribeLiveStreamRecordIndexFile 调用DescribeLiveStreamRecordIndexFile查询单个录制索引文件。 DescribeLiveStreamRecordIndexFiles 调用DescribeLiveStreamRecordIndexFiles查询某个时间段内的所有录制索引文件。 AddLiveRecordNotifyConfig 调用AddLiveRecordNotifyConfig添加域名级别录制回调配置。 DeleteLiveRecordNotifyConfig 调用DeleteLiveRecordNotifyConfig删除域名级别录制回调配置。 DescribeLiveRecordNotifyConfig 调用DescribeLiveRecordNotifyConfig查询域名级别录制回调配置。 UpdateLiveRecordNotifyConfig 调用UpdateLiveRecordNotifyConfig更新域名级别录制回调配置。 直播截图 API 描述 DescribeLiveStreamSnapshotInfo 调用DescribeLiveStreamSnapshotInfo查询一段时间内截图内容。 AddLiveAppSnapshotConfig 调用AddLiveAppSnapshotConfig配置截图信息。输出内容保存到OSS中,重新推流即生效。 DeleteLiveAppSnapshotConfig 调用DeleteLiveAppSnapshotConfig解除直播流下AppName的截图配置,重新推流后生效。 DescribeLiveSnapshotConfig 调用DescribeLiveSnapshotConfig查询域名下的截图配置。 UpdateLiveAppSnapshotConfig 调用UpdateLiveAppSnapshotConfig更新直播流下的截图配置。输出内容保存到OSS中,重新推流后生效。 直播审核 API 描述 DescribeLiveSnapshotDetectPornConfig 调用DescribeLiveSnapshotDetectPornConfig查询审核配置。 AddLiveSnapshotDetectPornConfig 调用AddLiveSnapshotDetectPornConfig可按照域名和App级别配置直播流审核服务。 AddLiveDetectNotifyConfig 调用AddLiveDetectNotifyConfig添加回调通知URL。 DescribeLiveDetectNotifyConfig 调用DescribeLiveDetectNotifyConfig查询回调通知URL。 UpdateLiveSnapshotDetectPornConfig 调用UpdateLiveSnapshotDetectPornConfig更新审核配置。 UpdateLiveDetectNotifyConfig 调用UpdateLiveDetectNotifyConfig更新回调通知URL。 DeleteLiveSnapshotDetectPornConfig 调用DeleteLiveSnapshotDetectPornConfig删除直播审核的配置。 DeleteLiveDetectNotifyConfig 调用DeleteLiveDetectNotifyConfig删除回调通知URL。 资源监控 API 描述 DescribeLiveDomainBpsData 调用DescribeLiveDomainBpsData查询直播域名的网络带宽监控数据。 DescribeLiveDomainRecordData 调用DescribeLiveDomainRecordData查询直播域名录制时长数据。 DescribeLiveDomainSnapshotData 调用DescribeLiveDomainSnapshotData查询直播域名截图张数数据。 DescribeLiveDomainTrafficData 调用DescribeLiveDomainTrafficData查询直播域名网络流量监控数据。 DescribeLiveDomainTranscodeData 调用DescribeLiveDomainTranscodeData查询直播域名转码时长数据。 DescribeLiveStreamOnlineUserNum 调用DescribeLiveStreamOnlineUserNum查询直播流实时在线人数。 DescribeLiveDomainRealTimeBpsData 调用DescribeLiveDomainRealTimeBpsData获取域名1分钟粒度带宽数据。 DescribeLiveDomainRealTimeHttpCodeData 调用DescribeLiveDomainRealTimeHttpCodeData获取加速域名1分钟粒度的HTTP返回码占比数据。 DescribeLiveDomainRealTimeTrafficData 调用DescribeLiveDomainRealTimeTrafficData获取加速域名的1分钟流量监控数据。 DescribeLiveStreamHistoryUserNum 调用DescribeLiveStreamHistoryUserNum查询直播流历史在线人数。 导播服务API API 描述 CreateCaster 调用CreateCaster创建导播台。 AddCasterLayout 调用AddCasterLayout添加导播台布局。 AddCasterVideoResource 调用AddCasterVideoResource添加视频源,视频源数量受限于导播台输入路数。 AddCasterEpisode 调用AddCasterEpisode添加导播台节目。 AddCasterComponent 调用AddCasterComponent添加组件。 AddCasterProgram 调用AddCasterProgram添加导播台节目单。 AddCasterEpisodeGroup 调用AddCasterEpisodeGroup添加导播台节目列表。 AddCasterEpisodeGroupContent 调用AddCasterEpisodeGroupContent添加导播台节目列表。 CopyCaster 调用CopyCaster复制导播台,复制指定导播台并返回新导播台实例。 CopyCasterSceneConfig 调用CopyCasterSceneConfig将原场景配置应用至目标场景并生效,仅限PVW场景配置拷贝至PGM场景。 DeleteCaster 调用DeleteCaster删除导播台。 DeleteCasterLayout 调用DeleteCasterLayout删除布局数据。 DeleteCasterVideoResource 调用DeleteCasterVideoResource删除视频资源。 DeleteCasterEpisode 调用DeleteCasterEpisode删除导播台节目。 DeleteCasterProgram 调用DeleteCasterProgram删除导播台节目单。 DeleteCasterEpisodeGroup 调用DeleteCasterEpisodeGroup删除导播台节目列表。 DeleteCasterComponent 调用DeleteCasterComponent删除组件。 DeleteCasterSceneConfig 调用DeleteCasterSceneConfig清除指定场景的配置信息。 DescribeCasterConfig 调用DescribeCasterConfig查询导播台配置信息。 DescribeCasterLayouts 调用DescribeCasterLayouts查询布局列表。 DescribeCasters 调用DescribeCasters查询导播台列表。 DescribeCasterScenes 调用DescribeCasterScenes查询场景信息列表。 DescribeCasterStreamUrl 调用DescribeCasterStreamUrl查询导播台流信息列表。 DescribeCasterVideoResources 调用DescribeCasterVideoResources查询视频源。 DescribeCasterProgram 调用DescribeCasterProgram查询导播台节目单。 DescribeCasterComponents 调用DescribeCasterComponents查询导播台组件列表。 DescribeCasterSceneAudio 调用DescribeCasterSceneAudio查询场景音频配置信息。 DescribeCasterChannels 调用DescribeCasterChannels查询导播台通道信息列表。 EffectCasterUrgent 调用EffectCasterUrgent将指定场景画面紧急切换至备播视频,限制仅用于PGM场景的备播切换。 EffectCasterVideoResource 调用EffectCasterVideoResource将视频资源生效至指定场景,场景引用该视频资源时有效。 ModifyCasterLayout 调用ModifyCasterLayout修改布局配置,传递修改项,非修改内容无需传递。 ModifyCasterComponent 调用ModifyCasterComponent修改组件。 ModifyCasterVideoResource 调用ModifyCasterVideoResource修改视频资源。 ModifyCasterEpisode 调用ModifyCasterEpisode修改导播台节目配置,节目类型不允许修改。 ModifyCasterProgram 调用ModifyCasterProgram修改导播台节目单。 SetCasterConfig 调用SetCasterConfig配置导播台,全量覆盖配置信息,若指定参数置为空则清除导播台该项配置。 SetCasterSceneConfig 调用SetCasterSceneConfig全量设置场景配置,清空场景配置,并将布局信息设置并生效至指定场景。 SetCasterChannel 调用SetCasterChannel在视频源同步模式时,将视频资源设置到通道中。 StartCaster 调用StartCaster启动导播台。若PVW、PGM场景不存在则创建,启动PVW、PGM场景,启动底层音视频处理任务。 StartCasterScene 调用StartCasterScene启动指定场景,限制仅用于PVW的打开。 StopCaster 调用StopCaster停止导播台,停止PVW、PGM场景,清理输出配置,停止底层音视频处理任务。 StopCasterScene 调用StopCasterScene停止指定场景,限制仅用于PVW的关闭。 UpdateCasterSceneConfig 调用UpdateCasterSceneConfig增量设置场景配置,不清空原配置,布局信息在原场景上增量修改,效率较全量设置高。 UpdateCasterSceneAudio 调用UpdateCasterSceneAudio更新场景音频配置。

保持可爱mmm 2020-03-29 22:06:33 0 浏览量 回答数 0

回答

Re为阿里云ECS(Windows 2012)创建IPv6隧道地址 我已置完成 目前我本地没有可以测试ipv6的环境,所以是否能帮我测试如下地址,以验证ipv6配置是否成功: ipv6地址 : 2001:470:18:d6::2 域名 : api2.ihyoo.com 域名我已配置AAAA解析 ------------------------- Re为阿里云ECS(Windows 2012)创建IPv6隧道地址 补充图片

robin_tian 2019-12-02 02:58:12 0 浏览量 回答数 0

阿里云高校特惠,助力学生创业梦!0元体验,快速入门云计算!

学生动手场景应用,快速了解并掌握云服务器的各种新奇玩法!

回答

Re为阿里云ECS(Windows 2012)创建IPv6隧道地址 我已置完成 目前我本地没有可以测试ipv6的环境,所以是否能帮我测试如下地址,以验证ipv6配置是否成功: ipv6地址 : 2001:470:18:d6::2 域名 : api2.ihyoo.com 域名我已配置AAAA解析 ------------------------- Re为阿里云ECS(Windows 2012)创建IPv6隧道地址 补充图片

robin_tian 2019-12-02 02:58:25 0 浏览量 回答数 0

回答

户调用MNS HTTP API发送请求时,需要在Authorization header里带上签名值,当签名值和服务器端计算的不一致时,请求会被拒绝,服务器返回403 SignatureDoesNotMatch。 当遇到这种问题,请检查以下几项: 一,请求url是否正确 举ReceiveMessage(curl)为例: curl -X GET http://44404.mns.cn-beijing.aliyuncs.com/queues/queue1/messages?waitseconds=10 -H "Authorization:MNS ijljkhkhlkjklshiojo................." -H "Date:Mon, 09 Nov 2015 06:24:41 GMT" -H "x-mns-version:2015-06-06" 新协议(x-mns-version:2015-06-06, Authorization:MNS xxxxxxxx...)url为: http://$AccountID.mns.cn-beijing.aliyuncs.com/queues/$queueName/messages 旧协议(x-mqs-version:2014-07-08, Authorization:MQS xxxxxxxx...)url为: http://$AccountID.mns.cn-beijing.aliyuncs.com/$queueName/messages 关于新旧协议更多差异,请参考官方API文档: https://docs.aliyun.com/?spm=5176.7400025.9.11.uXUeIQ#/pub/mns/api_reference/api_spec&message_operation 队列地址中的AccountID即云账户的账号ID。 账号id.jpg 二,AccessKeyId和AccessKeySecrete是否正确 三,加密信息源是否正确 下面给出两种常见的错误信息源例子。 错误一: GET n text/xml;charset=utf-8 Date:Thu, 21 May 2015 03:50:03 GMT x-mqs-version:2014-07-08 /queue1/messages?waitseconds=10 正确一: GET n text/xml;charset=utf-8 Thu, 21 May 2015 03:50:03 GMT x-mqs-version:2014-07-08 /queue1/messages?waitseconds=10 解决方法:去掉“Date:”。 错误二: GET n text/xml;charset=utf-8 Thu, 21 May 2015 03:50:03 GMT x-mns-version:2015-06-06 /queue1/messages?waitseconds=10 正确二: GET n text/xml;charset=utf-8 Thu, 21 May 2015 03:50:03 GMT x-mns-version:2015-06-06 /queues/queue1/messages?waitseconds=10 解决方法:如果使用新协议,请使用新协议支持的请求格式。 错误三: GET n text/xml;charset=utf-8 Thu, 21 May 2015 03:58:23 GMT n /queues/queue1/messages?waitseconds=10 正确三: GET n text/xml;charset=utf-8 Thu, 21 May 2015 03:58:23 GMT /queues/queue1/messages?waitseconds=10 解决方法:如果没有以x-mns-开头的head,直接置为空,没有n。 关于Signature计算方法,请参考官方文档: https://docs.aliyun.com/?spm=5176.7400025.9.11.uXUeIQ#/pub/mns/api_reference/invoke&signature 官网提供了一个demo, 方便用户验证自己的签名过程是否正确,请见问题“为什么我的签名总是没算对?”: https://docs.aliyun.com/?spm=5176.7400025.9.11.uXUeIQ#/pub/mns/product-manual/FAQ

毕来生 2019-12-01 23:42:16 0 浏览量 回答数 0

回答

本节以 IDE 内的 Todo App 模板小程序为例,介绍支付宝小程序的文件结构, 以及每种文件类型在小程序中的作用。 Todo App 是一个简单的待办事项管理小程序,实现了用户登录、新增自定义待 办事项、划除或恢复待办事项的功能。 app.json app.json 是小程序的全局配置,用于配置小程序的页面列表、默认窗口标题、导 航栏背景色等。更多配置请参见 文档配置。 app.acss 定义了全局样式,作用于当前小程序的所有页面。 上例中的 page 为框架支持的特殊选择器,会匹配框架提供的页面根节点容器。 app.js app.js 用于注册小程序应用,可配置小程序的生命周期,声明全局数据,调用丰 富的 API,如以下获取用户授权及获取用户信息 API 等,更多 API 信息请参见 API 文档。 可以看到,全局的逻辑代码放在 App({})中,声明了全局数据 todos 、 userInfo ,以及全局方法 getUserInfo()。 todos 全局数据中已经存储了一些数据,即 Todo App 小程序中已有的一些待办 事项。 全局方法 getUserInfo() 调用了授权 API my.getAuthCode,以及获取用户信息 API my.getAuthUserInfo ,并将获取到的用户信息存储在 userInfo 中。 小程序页面 此示例中有两个页面,Todo List 页面和 Add Todo 页面,都位于 pages 目录 下。小程序的所有页面路径必须在 app.json 中申明,路径从项目根目录开始且 不能包括后缀名,pages 的第一个页面就是小程序的首页。 每一个页面 由同路径下的四种类型文件组成,即 .json 后缀的配置文件,.axml 后缀的模板文件,.acss 后缀的样式文件,.js 后缀的逻辑脚本文件。 todo List 页面 todos.json 用于配置当前页面的窗口表现。此处定义了使用一个自定义组件 add-button ,指定它的组件名称及对应的路径。自定义组件的具体使用后面会讲 述。 页面配置文件不是必须的。当存在页面配置文件时,各个页面配置项会优先于 app.json 中 window 的同名配置项。当不存在页面配置文件,则直接使用 app.json 中的默认配置。因此,Todo List 页面的标题为 app.json 中指定的 defaultTitle ,即 Todo App。 todos.axml 为页面结构模板文件。使用 ,, ,,, , 来搭建页面结构以及通过 Mustache 语法两对大括号({{}})绑定 todos 数据。  绑定数据请参见此文档  绑定事件请参见此文档 todos.js 是页面的逻辑脚本文件,小程序页面的逻辑代码必需包含在 Page({}) 中。在这个文件中可实现:  监听并处理页面的生命周期函数 onShow onLoad  获取小程序实例以及其他页面实例 getApp getCurrentPages  声明并处理数据 data  响应页面交互事件,调用 API 等  这里需要注意的是 app.todos 是来自 app.js 中全局的变量定义 todos.acss 定义页面局部样式。指定 todos.axml 中不同元素的样式,包括位 置、背景颜色、字体、字体颜色等。 ACSS 语法参见 样式 文档。页面的 .acss 文件不是必须的,但对于相同选择器,页面局部样式会覆盖 app.acss 全局样 式。 Add Todo 页面 add-todo.json 声明自定义组件名称和路径。 add-todo.axml 为页面结构模板文件。 此页面的两个核心功能为: 1. 使用 组件接收用户输入。 2. 是一个自定义组件,可将一些功能完整的代码封装为自定义组件,便于 在其他地方复用。 add-todo.js 为页面逻辑代码。add-todo.acss 同 todos.acss 用法一致,不再 赘述 内容来源:https://developer.aliyun.com/article/756818?spm=a2c6h.12873581.0.dArticle756818.26162b70Su1GZy&groupCode=tech_library

KaFei 2020-04-27 13:49:46 0 浏览量 回答数 0

回答

尝试删除 Kubernetes 命名空间后,长时间停留在终止状态。 本文介绍如何解决命名空间处于终止状态的问题。 问题现象 尝试删除 Kubernetes 命名空间后,长时间停留在终止状态。 $ kubectl delete ns Error from server (Conflict): Operation cannot be fulfilled on namespaces " ": The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system. $ kubectl describe ns Name: Labels: Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":" ","namespace":""}} Status: Terminating 可能原因 通常是因为从集群中删除的这些命名空间下存在资源。 解决方案 选项 1:识别并手动删除无法自动删除的资源。 此选项不太直接,但在大多数情况下可能是更好的解决方案。因为删除命名空间后,它不会将该命名空间下的资源保留在集群中。 检查没有自动删除的命名空间资源。 尝试删除命名空间后,某些资源可能尚未删除。如果可以识别并手动删除所有剩余资源,则命名空间将终止。 kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n 检查所有不可用且不提供资源的 API Service。 kubectl get apiservice | grep False 选项 2:删除命名空间的 finalizers。 该选项将会快速清除处于终止状态的命名空间,但可能会导致属于该命名空间的资源留在集群中,因为无法自动删除它们。在 finalizers 数组为空并且状态为终止之后,Kubernetes 将删除命名空间。 打开 shell 终端,为您的 Kubernetes 集群创建一个反向代理。 kubectl proxy 输出示例如下: Starting to serve on 127.0.0.1:8001 打开一个新的 shell 终端,通过定义环境变量来连接到 Kubernetes 集群,使用 cURL 测试连接性和授权。 export TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t') curl http://localhost:8001/api/v1/namespaces --header "Authorization: Bearer $TOKEN" --insecure 获取命名空间定义的内容。 kubectl get namespace -o json > .json 将 finalizers 数组置为空,并重新保存文件。 "spec": { "finalizers": [ ] }, 执行以下命令去除 finalizers。 curl -X PUT --data-binary @ .json http://localhost:8001/api/v1/namespaces/logging/finalize

1934890530796658 2020-03-20 20:25:50 0 浏览量 回答数 0

问题

Swarm 集群访问控制

反向一觉 2019-12-01 21:19:53 1468 浏览量 回答数 0

问题

Swarm mode 集群的访问控制

反向一觉 2019-12-01 21:22:31 1659 浏览量 回答数 0

问题

如何做到 Laravel 配置可以网站后台配置

ThinkSNS 2019-12-01 21:27:39 2464 浏览量 回答数 0

问题

通过 API 使用实例 RAM 角色

chenchuan 2019-12-01 21:34:16 532 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档如果用户需要不经过任何授权,通过浏览器即可匿名访问图片服务来处理图片,需要在创建Bucket的时候将Bucket的权限设置为公共读。 创建Bucket 控制台:创建Bucket SDK:Java SDK-Bucket中新建Bucket API:Put Bucket 设置Bucket权限 控制台: 创建Bucket权限设置 SDK:Java SDK-Bucket中设置Bucket ACL API:Put BucketACL 默认创建的Bucket权限是私有读写,Object默认继承Bucket的权限。 如果用户需要通过图片服务访问私有的Object,需要进行身份鉴权。 图片服务的用户鉴权方式和OSS是一致的,有两种鉴权方式: 在Header中包含签名 在URL中包含签名 具体可参考在Header中包含签名和在URL中包含签名。 在URL中包含签名 假定用户绑定的域名www.test.com对应的频道名字为image-demo,object名字为example.jpg,转换字符串为100w.jpg。 首先需要计算Signature字段,计算方法如下: Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Expires表示授权给用户URL签名过期时间 CanonicalizedOSSHeaders表示HTTP中的ObjectMeta组合,对于图片处理服务这里为空字符串 CanonicalizedResource 表示用户想要访问的OSS资源,在图片处理服务中这项的组成,格式为/channelname/object@处理参数。 构建CanonicalizedResource的方法如下: 将CanonicalizedResource置成空字符串("") 放入要访问的图片服务资源:“`/channelname/object”(无Object则不填) 在结尾添加处理参数:@处理参数,(无处理参数则不填)。此时CanonicalizedResource例子如:/channelname/object@100w.jpg。 如果涉及样式管理操作,那么将这些查询字符串及其请求值按照字典序,以&分割,添加到CanonicalizedResource中。此时的CanonicalizedResource例子:/channelname?style&styleName=YourStyleName 例子中的CanonicalizedResource为/image-demo/example.jpg@100w.jpg。 注意:上例中的转换字符串可以是简单缩略,文字水印,图片水印、管道和样式(样式的分隔符是@!) 这里需要注意的是,使用URL签名中Expires和CanonicalizedResource不能为空。 最后生成在URL签名,必须在参数后包含OSSAccessKeyId、Expires、Signature这三项,具体生成方法可以参考OSS的API文档中的在URL中包含签名,上文的例子生成的URL签名如下: http://www.test.com/example.jpg%40100w.jpg?OSSAccessKeyId=j4y55h3z88ihxxhlr9nhjjis&Expires=1392949804&Signature=IDBJ09e8Ow4GaPRM1yIf7plH/CI%3D 在Header中包含签名 除了在URL中包含签名之外,还可以在HTTP请求的Header中包含签名,签名是由Authorization这个Header指定的,具体的构成规则如下: "Authorization: OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式 CanonicalizedOSSHeaders表示 http中的object meta组合,对于图片处理服务这里为空字符串 CanonicalizedResource构造方法请参考上文URL签名中的CanonicalizedResource的生成方法。 需要注意的 Date和CanonicalizedResource不能为空 如果请求中的Date时间和OSS服务器的时间差正负15分钟以上,OSS图片处理服务将拒绝该服务,并返回HTTP 403错误。

2019-12-01 23:15:20 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档如果用户需要不经过任何授权,通过浏览器即可匿名访问图片服务来处理图片,需要在创建Bucket的时候将Bucket的权限设置为公共读。 创建Bucket 控制台:创建Bucket SDK:Java SDK-Bucket中新建Bucket API:Put Bucket 设置Bucket权限 控制台: 创建Bucket权限设置 SDK:Java SDK-Bucket中设置Bucket ACL API:Put BucketACL 默认创建的Bucket权限是私有读写,Object默认继承Bucket的权限。 如果用户需要通过图片服务访问私有的Object,需要进行身份鉴权。 图片服务的用户鉴权方式和OSS是一致的,有两种鉴权方式: 在Header中包含签名 在URL中包含签名 具体可参考在Header中包含签名和在URL中包含签名。 在URL中包含签名 假定用户绑定的域名www.test.com对应的频道名字为image-demo,object名字为example.jpg,转换字符串为100w.jpg。 首先需要计算Signature字段,计算方法如下: Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Expires表示授权给用户URL签名过期时间 CanonicalizedOSSHeaders表示HTTP中的ObjectMeta组合,对于图片处理服务这里为空字符串 CanonicalizedResource 表示用户想要访问的OSS资源,在图片处理服务中这项的组成,格式为/channelname/object@处理参数。 构建CanonicalizedResource的方法如下: 将CanonicalizedResource置成空字符串("") 放入要访问的图片服务资源:“`/channelname/object”(无Object则不填) 在结尾添加处理参数:@处理参数,(无处理参数则不填)。此时CanonicalizedResource例子如:/channelname/object@100w.jpg。 如果涉及样式管理操作,那么将这些查询字符串及其请求值按照字典序,以&分割,添加到CanonicalizedResource中。此时的CanonicalizedResource例子:/channelname?style&styleName=YourStyleName 例子中的CanonicalizedResource为/image-demo/example.jpg@100w.jpg。 注意:上例中的转换字符串可以是简单缩略,文字水印,图片水印、管道和样式(样式的分隔符是@!) 这里需要注意的是,使用URL签名中Expires和CanonicalizedResource不能为空。 最后生成在URL签名,必须在参数后包含OSSAccessKeyId、Expires、Signature这三项,具体生成方法可以参考OSS的API文档中的在URL中包含签名,上文的例子生成的URL签名如下: http://www.test.com/example.jpg%40100w.jpg?OSSAccessKeyId=j4y55h3z88ihxxhlr9nhjjis&Expires=1392949804&Signature=IDBJ09e8Ow4GaPRM1yIf7plH/CI%3D 在Header中包含签名 除了在URL中包含签名之外,还可以在HTTP请求的Header中包含签名,签名是由Authorization这个Header指定的,具体的构成规则如下: "Authorization: OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式 CanonicalizedOSSHeaders表示 http中的object meta组合,对于图片处理服务这里为空字符串 CanonicalizedResource构造方法请参考上文URL签名中的CanonicalizedResource的生成方法。 需要注意的 Date和CanonicalizedResource不能为空 如果请求中的Date时间和OSS服务器的时间差正负15分钟以上,OSS图片处理服务将拒绝该服务,并返回HTTP 403错误。

2019-12-01 23:15:20 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档如果用户需要不经过任何授权,通过浏览器即可匿名访问图片服务来处理图片,需要在创建Bucket的时候将Bucket的权限设置为公共读。 创建Bucket 控制台:创建Bucket SDK:Java SDK-Bucket中新建Bucket API:Put Bucket 设置Bucket权限 控制台: 创建Bucket权限设置 SDK:Java SDK-Bucket中设置Bucket ACL API:Put BucketACL 默认创建的Bucket权限是私有读写,Object默认继承Bucket的权限。 如果用户需要通过图片服务访问私有的Object,需要进行身份鉴权。 图片服务的用户鉴权方式和OSS是一致的,有两种鉴权方式: 在Header中包含签名 在URL中包含签名 具体可参考在Header中包含签名和在URL中包含签名。 在URL中包含签名 假定用户绑定的域名www.test.com对应的频道名字为image-demo,object名字为example.jpg,转换字符串为100w.jpg。 首先需要计算Signature字段,计算方法如下: Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Expires表示授权给用户URL签名过期时间 CanonicalizedOSSHeaders表示HTTP中的ObjectMeta组合,对于图片处理服务这里为空字符串 CanonicalizedResource 表示用户想要访问的OSS资源,在图片处理服务中这项的组成,格式为/channelname/object@处理参数。 构建CanonicalizedResource的方法如下: 将CanonicalizedResource置成空字符串("") 放入要访问的图片服务资源:“`/channelname/object”(无Object则不填) 在结尾添加处理参数:@处理参数,(无处理参数则不填)。此时CanonicalizedResource例子如:/channelname/object@100w.jpg。 如果涉及样式管理操作,那么将这些查询字符串及其请求值按照字典序,以&分割,添加到CanonicalizedResource中。此时的CanonicalizedResource例子:/channelname?style&styleName=YourStyleName 例子中的CanonicalizedResource为/image-demo/example.jpg@100w.jpg。 注意:上例中的转换字符串可以是简单缩略,文字水印,图片水印、管道和样式(样式的分隔符是@!) 这里需要注意的是,使用URL签名中Expires和CanonicalizedResource不能为空。 最后生成在URL签名,必须在参数后包含OSSAccessKeyId、Expires、Signature这三项,具体生成方法可以参考OSS的API文档中的在URL中包含签名,上文的例子生成的URL签名如下: http://www.test.com/example.jpg%40100w.jpg?OSSAccessKeyId=j4y55h3z88ihxxhlr9nhjjis&Expires=1392949804&Signature=IDBJ09e8Ow4GaPRM1yIf7plH/CI%3D 在Header中包含签名 除了在URL中包含签名之外,还可以在HTTP请求的Header中包含签名,签名是由Authorization这个Header指定的,具体的构成规则如下: "Authorization: OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式 CanonicalizedOSSHeaders表示 http中的object meta组合,对于图片处理服务这里为空字符串 CanonicalizedResource构造方法请参考上文URL签名中的CanonicalizedResource的生成方法。 需要注意的 Date和CanonicalizedResource不能为空 如果请求中的Date时间和OSS服务器的时间差正负15分钟以上,OSS图片处理服务将拒绝该服务,并返回HTTP 403错误。

2019-12-01 23:15:21 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档如果用户需要不经过任何授权,通过浏览器即可匿名访问图片服务来处理图片,需要在创建Bucket的时候将Bucket的权限设置为公共读。 创建Bucket 控制台:创建Bucket SDK:Java SDK-Bucket中新建Bucket API:Put Bucket 设置Bucket权限 控制台: 创建Bucket权限设置 SDK:Java SDK-Bucket中设置Bucket ACL API:Put BucketACL 默认创建的Bucket权限是私有读写,Object默认继承Bucket的权限。 如果用户需要通过图片服务访问私有的Object,需要进行身份鉴权。 图片服务的用户鉴权方式和OSS是一致的,有两种鉴权方式: 在Header中包含签名 在URL中包含签名 具体可参考在Header中包含签名和在URL中包含签名。 在URL中包含签名 假定用户绑定的域名www.test.com对应的频道名字为image-demo,object名字为example.jpg,转换字符串为100w.jpg。 首先需要计算Signature字段,计算方法如下: Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Expires表示授权给用户URL签名过期时间 CanonicalizedOSSHeaders表示HTTP中的ObjectMeta组合,对于图片处理服务这里为空字符串 CanonicalizedResource 表示用户想要访问的OSS资源,在图片处理服务中这项的组成,格式为/channelname/object@处理参数。 构建CanonicalizedResource的方法如下: 将CanonicalizedResource置成空字符串("") 放入要访问的图片服务资源:“`/channelname/object”(无Object则不填) 在结尾添加处理参数:@处理参数,(无处理参数则不填)。此时CanonicalizedResource例子如:/channelname/object@100w.jpg。 如果涉及样式管理操作,那么将这些查询字符串及其请求值按照字典序,以&分割,添加到CanonicalizedResource中。此时的CanonicalizedResource例子:/channelname?style&styleName=YourStyleName 例子中的CanonicalizedResource为/image-demo/example.jpg@100w.jpg。 注意:上例中的转换字符串可以是简单缩略,文字水印,图片水印、管道和样式(样式的分隔符是@!) 这里需要注意的是,使用URL签名中Expires和CanonicalizedResource不能为空。 最后生成在URL签名,必须在参数后包含OSSAccessKeyId、Expires、Signature这三项,具体生成方法可以参考OSS的API文档中的在URL中包含签名,上文的例子生成的URL签名如下: http://www.test.com/example.jpg%40100w.jpg?OSSAccessKeyId=j4y55h3z88ihxxhlr9nhjjis&Expires=1392949804&Signature=IDBJ09e8Ow4GaPRM1yIf7plH/CI%3D 在Header中包含签名 除了在URL中包含签名之外,还可以在HTTP请求的Header中包含签名,签名是由Authorization这个Header指定的,具体的构成规则如下: "Authorization: OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式 CanonicalizedOSSHeaders表示 http中的object meta组合,对于图片处理服务这里为空字符串 CanonicalizedResource构造方法请参考上文URL签名中的CanonicalizedResource的生成方法。 需要注意的 Date和CanonicalizedResource不能为空 如果请求中的Date时间和OSS服务器的时间差正负15分钟以上,OSS图片处理服务将拒绝该服务,并返回HTTP 403错误。

2019-12-01 23:15:20 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档如果用户需要不经过任何授权,通过浏览器即可匿名访问图片服务来处理图片,需要在创建Bucket的时候将Bucket的权限设置为公共读。 创建Bucket 控制台:创建Bucket SDK:Java SDK-Bucket中新建Bucket API:Put Bucket 设置Bucket权限 控制台: 创建Bucket权限设置 SDK:Java SDK-Bucket中设置Bucket ACL API:Put BucketACL 默认创建的Bucket权限是私有读写,Object默认继承Bucket的权限。 如果用户需要通过图片服务访问私有的Object,需要进行身份鉴权。 图片服务的用户鉴权方式和OSS是一致的,有两种鉴权方式: 在Header中包含签名 在URL中包含签名 具体可参考在Header中包含签名和在URL中包含签名。 在URL中包含签名 假定用户绑定的域名www.test.com对应的频道名字为image-demo,object名字为example.jpg,转换字符串为100w.jpg。 首先需要计算Signature字段,计算方法如下: Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Expires表示授权给用户URL签名过期时间 CanonicalizedOSSHeaders表示HTTP中的ObjectMeta组合,对于图片处理服务这里为空字符串 CanonicalizedResource 表示用户想要访问的OSS资源,在图片处理服务中这项的组成,格式为/channelname/object@处理参数。 构建CanonicalizedResource的方法如下: 将CanonicalizedResource置成空字符串("") 放入要访问的图片服务资源:“`/channelname/object”(无Object则不填) 在结尾添加处理参数:@处理参数,(无处理参数则不填)。此时CanonicalizedResource例子如:/channelname/object@100w.jpg。 如果涉及样式管理操作,那么将这些查询字符串及其请求值按照字典序,以&分割,添加到CanonicalizedResource中。此时的CanonicalizedResource例子:/channelname?style&styleName=YourStyleName 例子中的CanonicalizedResource为/image-demo/example.jpg@100w.jpg。 注意:上例中的转换字符串可以是简单缩略,文字水印,图片水印、管道和样式(样式的分隔符是@!) 这里需要注意的是,使用URL签名中Expires和CanonicalizedResource不能为空。 最后生成在URL签名,必须在参数后包含OSSAccessKeyId、Expires、Signature这三项,具体生成方法可以参考OSS的API文档中的在URL中包含签名,上文的例子生成的URL签名如下: http://www.test.com/example.jpg%40100w.jpg?OSSAccessKeyId=j4y55h3z88ihxxhlr9nhjjis&Expires=1392949804&Signature=IDBJ09e8Ow4GaPRM1yIf7plH/CI%3D 在Header中包含签名 除了在URL中包含签名之外,还可以在HTTP请求的Header中包含签名,签名是由Authorization这个Header指定的,具体的构成规则如下: "Authorization: OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式 CanonicalizedOSSHeaders表示 http中的object meta组合,对于图片处理服务这里为空字符串 CanonicalizedResource构造方法请参考上文URL签名中的CanonicalizedResource的生成方法。 需要注意的 Date和CanonicalizedResource不能为空 如果请求中的Date时间和OSS服务器的时间差正负15分钟以上,OSS图片处理服务将拒绝该服务,并返回HTTP 403错误。

2019-12-01 23:15:20 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档如果用户需要不经过任何授权,通过浏览器即可匿名访问图片服务来处理图片,需要在创建Bucket的时候将Bucket的权限设置为公共读。 创建Bucket 控制台:创建Bucket SDK:Java SDK-Bucket中新建Bucket API:Put Bucket 设置Bucket权限 控制台: 创建Bucket权限设置 SDK:Java SDK-Bucket中设置Bucket ACL API:Put BucketACL 默认创建的Bucket权限是私有读写,Object默认继承Bucket的权限。 如果用户需要通过图片服务访问私有的Object,需要进行身份鉴权。 图片服务的用户鉴权方式和OSS是一致的,有两种鉴权方式: 在Header中包含签名 在URL中包含签名 具体可参考在Header中包含签名和在URL中包含签名。 在URL中包含签名 假定用户绑定的域名www.test.com对应的频道名字为image-demo,object名字为example.jpg,转换字符串为100w.jpg。 首先需要计算Signature字段,计算方法如下: Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Expires表示授权给用户URL签名过期时间 CanonicalizedOSSHeaders表示HTTP中的ObjectMeta组合,对于图片处理服务这里为空字符串 CanonicalizedResource 表示用户想要访问的OSS资源,在图片处理服务中这项的组成,格式为/channelname/object@处理参数。 构建CanonicalizedResource的方法如下: 将CanonicalizedResource置成空字符串("") 放入要访问的图片服务资源:“`/channelname/object”(无Object则不填) 在结尾添加处理参数:@处理参数,(无处理参数则不填)。此时CanonicalizedResource例子如:/channelname/object@100w.jpg。 如果涉及样式管理操作,那么将这些查询字符串及其请求值按照字典序,以&分割,添加到CanonicalizedResource中。此时的CanonicalizedResource例子:/channelname?style&styleName=YourStyleName 例子中的CanonicalizedResource为/image-demo/example.jpg@100w.jpg。 注意:上例中的转换字符串可以是简单缩略,文字水印,图片水印、管道和样式(样式的分隔符是@!) 这里需要注意的是,使用URL签名中Expires和CanonicalizedResource不能为空。 最后生成在URL签名,必须在参数后包含OSSAccessKeyId、Expires、Signature这三项,具体生成方法可以参考OSS的API文档中的在URL中包含签名,上文的例子生成的URL签名如下: http://www.test.com/example.jpg%40100w.jpg?OSSAccessKeyId=j4y55h3z88ihxxhlr9nhjjis&Expires=1392949804&Signature=IDBJ09e8Ow4GaPRM1yIf7plH/CI%3D 在Header中包含签名 除了在URL中包含签名之外,还可以在HTTP请求的Header中包含签名,签名是由Authorization这个Header指定的,具体的构成规则如下: "Authorization: OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret表示签名所需的秘钥 VERB表示HTTP请求方法,例如PUT,GET,DELETE等 Content-MD5表示请求内容数据的MD5值,对于图片处理服务这里为空字符串 Content-Type表示请求内容的类型,对于图片处理服务这里为空字符串 Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式 CanonicalizedOSSHeaders表示 http中的object meta组合,对于图片处理服务这里为空字符串 CanonicalizedResource构造方法请参考上文URL签名中的CanonicalizedResource的生成方法。 需要注意的 Date和CanonicalizedResource不能为空 如果请求中的Date时间和OSS服务器的时间差正负15分钟以上,OSS图片处理服务将拒绝该服务,并返回HTTP 403错误。

2019-12-01 23:15:20 0 浏览量 回答数 0

问题

SDK客户端是什么?

轩墨 2019-12-01 20:58:01 987 浏览量 回答数 0

问题

用户指南:设置实例备用状态

青蛙跳 2019-12-01 21:31:47 469 浏览量 回答数 0

回答

媒体处理的媒体资源存储在OSS中,启用状态的工作流会自动监听Bucket输入路径下新增文件的操作。因此,视频文件可以通过OSS上传,也可以通过媒体处理上传。主要包括以下几种方式: 控制台上传 OSS控制台、工具上传 OSS控制台提供上传文件的功能,您可以进入OSS控制台的bucket输入路径下上传媒体资源即可触发工作流执行实例。 注意:这种方式操作简便,但是批量上传较为麻烦,不适合应用于业务系统。 1 同时,OSS提供一些官方和第三方的工具,用户可以使用这些工具向工作流的输入路径上传文件,同样可以触发工作流执行实例。工具的链接参见:osscmd工具、OSS控制台客户端。 媒体处理控制台上传 媒体处理控制台同样也提供了上传媒体资源的功能,用户在配置完成工作流后,将工作流状态置为启用状态即可在媒体库中对该工作流上传视频。 登录 媒体处理控制台,单击 媒体管理 > 媒体库 > 上传视频。 2 选择需要上传媒体资源对应的工作流,单击 选择工作流。 2 选择待处理的输入视频的路径后即可下发上传请求,这里是通过OSS的分块上传方式上传数据的,因此,需要配置输入Bucket的跨域规则,其中包括媒体处理控制台的跨域请求规则。在这里触发上传请求时会自动给输入Bucket添加跨域规则,因此不需您自行设置。 2 媒体处理SDK上传 媒体处理结合OSS的API实现了一套媒体处理使用的上传逻辑的SDK,您可以使用这套SDK直接上传媒体信息到媒体Bucket中触发工作流的执行实例。现在提供了JavaScript、Android和IOS版本的SDK。SDK使用说明和示例代码参见 使用说明、上传SDK下载。 注意: 初始化过程支持AK/SK方式以及STS方式,其中AK/SK方式包括主账号的AK/SK和子账号的AK/SK两种方式,主账号的AK/SK拥有整个账号下资源的所有权限,因此直接添加即可。子账号的AK/SK需要保证您对媒体Bucket的对应输入路径拥有oss:PutObject权限。 上传操作通过SDK的addFile方法实现,上传媒体的目录以及名称通过该方法的第四个参数定义,如果工作流设置的子目录,请注意中需要包含该相对目录,OSS目录的概念参见:OSS中的目录/文件夹概念。 JavaScript SDK上传时将代码部署到您的站点,通过您自己的域名来操作有可能遇到跨域的问题,建议这里在输入Bucket的跨域配置中配置一条如下的跨域规则然后测试。 2 OSS API/SDK上传 如前所述,媒体处理的媒体资源存储在媒体Bucket中。因此,OSS服务本身的API/SDK的上传文件方法同样适用于媒体处理并且触发工作流执行实例。OSS服务提供了更加丰富的SDK,供不同的代码语言的调用,您可以根据业务要求进行选择,SDK列表参见 OSS SDK开发包。 常见OSS服务的上传方法包括:PutObject、CopyObject、PostObject 和 MultipartUpload。四个方法的使用场景和优缺点如下: PutObject:该方法是最基本的OSS上传方法,内网和外网均可以调用,该方法是一个PUT请求将数据传输给OSS,对上传的文件限制5GB大小。 CopyObject:该方法是拷贝文件的方法,如果需要将OSS上的媒体信息拷贝到工作流的输入路径,可以使用该方法。该方法仅能够通过内网传输数据,要求源端和目标端的Bucket在同一个数据中心内,并且对于拷贝文件限制1GB大小。 PostObject:该方法主要适用于web前端直接通过POST请求数据到OSS,而不经过用户的服务器传输。对于媒体资源等大文件不建议通过该方法上传,因为该方法对于客户端的网络质量要求较高,其方法限制请求的body不超过5GB。 MultipartUpload:该方法是OSS提供的分块上传方法,主要适用于大文件或者网络质量较差的场景进行使用。对于媒体处理中使用的文件通常是较大的文件,建议您通过该方法上传。该方法针对于前述的PutObject和CopyObject方法分别提供了UploadPart和UploadPartCopy来替代。该方法最大支持上传48.8TB的文件。

保持可爱mmm 2020-03-30 11:55:05 0 浏览量 回答数 0

回答

请求结构 发起 API 请求的 URL 由不同参数拼凑而成,有固定的请求结构。URL 中包含如下: 服务地址 通讯协议 请求方法 公共头参数 每个 API 的特有参数 每篇 API 文档均给出了 URL 请求示例供您参考,我们并没有编码这些 URL 示例,您需要在发起请求前自行编码。如果你使用 SDK 来发起 API 请求,您只需要设置一些公共参数和 API 的具体参数,SDK 会自动会编码。 公共HTTP头定义 公共请求头 对于访问授权,BatchCompute 采用阿里云通用的签名方式,即请求头部包含特定以”x-acs”开头的字段,通过计算签名和比较签名进行用户验证。其中头部必须包含的字段如下: 标准头 Header名称 类型 说明 Authorization 字符串 签名内容。该字段必选,它为非签名字段。参阅 签名机制 Content-Length 数字 Body 部分实际请求长度。如果传输是压缩格式,则为压缩后大小;如果请求不包含 Body,则数值为 0,它为非签名字段。 Content-MD5 字符串 Body 经过 MD5 计算后的字符串,计算结果为大写;如果没有 Body 部分,则不需要填写该请求头。 Content-Type 字符串 Body 类型。类型为字符串,分为 application/json 和 application/json-rpc 两种类型,默认值为 application/json;如果没有 Body 部分,则不需要填写该请求头。 Date 字符串 当前发送时刻的时间,参数目前只支持 RFC 822 格式,使用 GMT 标准时间。格式化字符串如下:%a, %d %b %Y %H:%M:%S GMT (如:Mon, 3 Jan 2010 08:33:47 GMT)。Date 所表示的时间与服务器接收到 request 的时间最大误差为 15 分钟。如果超过 15 分钟的时间误差则服务器端拒绝该请求。 Accept 字符串 客户端需要的返回值类型,支持 application/json 和application/json-rpc。默认值:无。 Host 字符串 请求 host 完整名字(不加 http:// ),例如:batchcompute.cn-qingdao.aliyuncs.com。 自定义头 Header名称 类型 说明 x-acs-version 字符串 当前 API 版本,目前版本为 2015-11-11 x-acs-compress-type 字符串 压缩方式。目前只支持 deflate,如果不压缩可以不填写该字段。 x-acs-body-rawsize 数字 Body 原始大小,当压缩时用以解压,当无 Body 时该字段为 0。范围为 0-256KB。 x-acs-signature-method 字符串 签名计算方式,目前支持“hmac-sha1”。 x-acs-signature-nonce 字符串 唯一随机数,用于防止网络重放攻击。用户在不同请求间,要使用不同的随机数值。 x-acs-access-id 字符串 用户访问 BatchCompute 的 AccessId,默认值:无。 x-acs-request-id 字符串 用户自动生成的请求 ID,以便日志跟踪。 示例 HTTP 头部格式如下: Authorization: acs [Access Key Id]:[Signature] Content-Length: 2324 contentMd5: 871bd77924e76fb320f2d13f55e8a7a2 Content-Type: application/json Date: Tue, 06 Nov 2018 06:12:40 GMT Accept: application/json Host: batchcompute.[Region].aliyuncs.com Accept-Encoding: identity User-Agent: Mozilla/5.0 (Windows NT 6.1) x-acs-version: 2015-11-11 x-acs-signature-method: HMAC-SHA1 x-acs-signature-nonce: f76e8ab8-e18a-11e8-bc78-645aede9015d x-acs-signature-version: 1.0 x-acs-access-key-id: [Access Key Id] x-acs-region-id: [Region] 返回结果 调用 API 服务后返回数据采用统一格式,具体包括: 状态码 响应头 响应数据 成功结果 返回的 HTTP 状态码为 2xx,代表调用成功; 响应数据格式为 JSON 格式,在每个 API 中有具体的描述响应数据的内容。 以下是创建集群返回 成功的示例: HTTP/1.1 201 Created Date: Tue, 06 Nov 2018 06:12:41 GMT Content-Type: application/json; charset=utf-8 Content-Length: 35 Connection: close Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-Requested-With, X-Sequence, _aop_secret, _aop_signature Access-Control-Max-Age: 172800 x-acs-request-id: D874CC9A-C2D4-4DAE-A351-1699550F11A9 Server: AliyunBatchCompute {"Id":"cls-6ki3sg6sqlno7nt8fu0007"} 错误结果 返回的 HTTP 状态码为 4xx 或 5xx ,代表调用失败,具体状态码参考 公共错误码 以及各个 API 的错误码。 返回的 Body 中包含 “Code” 和 “Message” 字段,您可以根据此信息来排查错误。 响应头中的 x-acs-request-id 包含请求的 request id。当您无法排查错误时,可以提交工单联系我们,并在工单中注明 request id。 以下是一个请求错误的示例: HTTP/1.1 400 Bad Request Date: Tue, 06 Nov 2018 08:30:40 GMT Content-Type: application/json; charset=utf-8 Content-Length: 90 Connection: close Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-Requested-With, X-Sequence, _aop_secret, _aop_signature Access-Control-Max-Age: 172800 x-acs-request-id: F067DAB7-57C4-4D08-BE49-CDB63BF5C6D2 Server: AliyunBatchCompute {"Code":"InvalidParameter.ImageId","Message":"Specified parameter ImageId is not valid. "} 公共错误码 在对 BatchCompute API 进行访问时,不同请求可能会返回不同的错误码,如下是所有公共的错误码。 状态码 错误码 错误信息 400 InvalidJsonFormat The request body has an invalid json format. 400 BadDAG It is a cyclic dag. 400 InvalidUrlPattern Specified url pattern contains some illegal words. 400 MethodNotAllowed The request http method is not supported for this resource. 400 Missing {Parameter Name} {Parameter Name} is mandatory for this action. 400 Invalid {Parameter Name} Specified parameter {Parameter Name} is not valid. {Message}. 400 IdempotentTokenMismatch Specified idempotent token mismatch. 403 InvalidVersion.NotFound Specified version is not found. 403 InvalidResource.AlreadyExisting Specified resource already exists. 403 InvalidQueryString {Message}. 403 InvalidHttpBody {Message}. 403 QuotaExhausted The {QuotaName} ({Value}) quota is exhausted. 403 Forbidden User not authorized to operate on the specified resource. 404 InvalidResource.NotFound Specified resource is not found. 409 StateConflict User operation is invalid. The current resource state is {State}. 500 InternalError The request processing has been failed due to some unknown error. 签名机制 BatchCompute 通过使用 Access Key ID/ Access Key Secret 方法来验证某个请求的发送者身份。Access Key ID 用于标示用户,Access Key Secret 是用户用于加密签名字符串和 BatchCompute 用来验证签名字符串的密钥,其中 Access Key Secret 必须保密,只有用户和 BatchCompute 知道。 当用户想以个人身份向 BatchCompute 发送请求时,需要首先将发送的请求按照 BatchCompute 指定的格式生成签名字符串;然后使用 Access Key Secret 对签名字符串进行加密产生验证码。 BatchCompute 收到请求以后,会通过 Access Key ID 找到对应的 Access Key Secret,以同样的方法提取签名字符串和验证码,如果计算出来的验证码和提供的一样即认为该请求是有效的;否则,BatchCompute 将拒绝处理这次请求,并返回 HTTP 400 错误。 用户可以在 HTTP 请求中增加 Authorization(授权)的 Head 来包含签名(Signature)信息,表明这个消息已被授权。 Authorization 字段计算方法如下: Authorization: "acs " + Access Key Id + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, + VERB + "\n" + ACCEPT + "\n" + CONTENT-MD5 + "\n" + CONTENT-TYPE + "\n" + DATE + "\n" + CanonicalizedBatchComputeHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的秘钥 VERB 表示 HTTP 请求的 Method,主要有 PUT,GET,POST,HEAD,DELETE 等(大写) CONTENT-MD5 表示请求内容数据的 MD5 值,详情参看(十六进制序列,字母小写) ACCEPT 表示 HTTP 请求期望接受的类型 CONTENT-TYPE 表示请求内容的类型 DATE 表示此次操作的时间,且必须为 HTTP1.1 中支持的 GMT 格式 CanonicalizedOSSHeaders 表示以“x-acs-”为前缀的 http header 的组合 CanonicalizedResource 表示 API 想要访问的 BatchCompute 资源 其中,CanonicalizedBatchComputeHeaders 表示 http 中的 object meta 组合。CanonicalizedResource 表示 API 想要访问的 BatchCompute 资源。DATE 和 CanonicalizedResource 不能为空。如果请求中的 DATE 时间和 BatchCompute 服务器的时间差正负 15 分钟以上,BatchCompute 服务器将拒绝该服务,并返回 HTTP 400 错误。其他字段请参考公共请求头参数。 构建 CanonicalizedBatchComputeHeaders 的方法: 所有以“x-acs-”为前缀的 HTTP Header 被称为 CanonicalizedBatchComputeHeaders,它的构建方法如下: 将所有以“x-acs-”为前缀的 HTTP 请求头的名字转换成小写字母。如“X-Acs-Meta-Name: TaoBao”转换成“x-acs-meta-name: TaoBao”; 将上一步得到的所有 HTTP 请求头按照字典序进行升序排列; 如果有相同名字的请求头,则根据标准 RFC 2616, 4.2 章进行合并(两个值之间只用逗号分隔)。如有两个名为“x-acs-meta-name”的请求头,对应的值分别为“TaoBao”和“Alipay”,则合并后为:“x-acs-meta-name:TaoBao,Alipay”; 删除请求头和内容之间分隔符两端出现的任何空格。如“x-acs-meta-name: TaoBao,Alipay”转换成:“x-acs-meta-name:TaoBao,Alipay”; 将所有的头和内容用“\n”分隔符分隔拼成最后的CanonicalizedBatchComputeHeader。 构建CanonicalizedResource的方法: 用户发送请求中想访问的 BatchCompute 目标资源被称为 CanonicalizedResource。它的构建方法如下: 将 CanonicalizedResource 置成空字符串(“”); 放入要访问的 BatchCompute 资源:“/ResourceName/ResourceId”(无 ResourceId 则不填); 如果请求的资源包括子资源(sub-resource) ,那么将所有的子资源按照字典序,从小到大排列并以“&”为分隔符生成子资源字符串。在 CanonicalizedResource 字符串尾添加“?”和子资源字符串。此时的 CanonicalizedResource 例子如:/jobs/(id)/tasks?Marker=(Marer)&MaxItemCount=(MaxItemCount)。 例如,需要签名以下信息: PUT /jobs/job-000000005645B53B0000AEA300000001 HTTP/1.0 Content-Md5: 900150983cd24fb0d6963f7d28e17f72 Content-Type: application/json Date: Thu, 17 Nov 2005 18:49:58 GMT Host: batchcompute.cn-qingdao.aliyuncs.com x-acs-signature-method: HMAC-SHA1 x-acs-signature-version: 1.0 其中,Access Key ID 是:“44CF9590006BF252F707”, Access Key Secret 是“OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV”,可用以下方法签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\n900150983cd24fb0d6963f7d28e17f72\napplication/json\nThu, 17 Nov 2005 18:49:58 GMT\nx-acs-signature-method:HMAC-SHA1\nx-acs-signature-version:1.0\n/jobs/job-000000005645B53B0000AEA300000001", sha) base64.encodestring(h.digest()).strip() 签名(Signature)计算结果应该为“26NBxoKdsyly4EDv6inkoDft/yA=”, 然后加上 Authorization 头来组成最后需要发送的消息: PUT /jobs/job-000000005645B53B0000AEA300000001 HTTP/1.0 Authorization: acs 44CF9590006BF252F707: 26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: 900150983cd24fb0d6963f7d28e17f72 Content-Type: application/json Date: Thu, 17 Nov 2005 18:49:58 GMT Host: batchcompute.cn-qingdao.aliyuncs.com x-acs-signature-method: HMAC-SHA1 x-acs-signature-version: 1.0 在计算签名头的时候请遵循如下规则: 用来签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进 UTF-8 编码,再与 Access Key Secret 计算最终签名。 签名的方法用 RFC 2104 中定义的 HMAC-SHA1 方法,其中 Key 为 Access Key Secret。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符“\n”代替。 在所有非 HTTP 标准定义的 header 中,只有以“x-acs-”开头的 header,需要加入签名字符串;其他非 HTTP 标准 header 将被忽略。 以“x-acs-”开头的 head 在签名验证前需要符合以下规范: head 的名字需要变成小写。 head 按字典序自小到大排序。 分割 head name 和 value 的冒号前后不能有空格。 每个Head之后都有一个换行符“\n”,如果没有 Head,CanonicalizedBatchComputeHeaders 就设置为空。 备注:BatchCompute 所有的请求都必须使用 HTTP 1.1 协议规定的 GMT 时间格式 。其中,日期的格式有三种: date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982) date2 = 2DIGIT “-“ month “-“ 2DIGIT; day-month-year (e.g., 02-Jun-82) date3 = month SP ( 2DIGIT or ( SP 1DIGIT )); month day (e.g., Jun 2) 【注意“2”前面有两个空格】 述这三种日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。

1934890530796658 2020-03-30 11:47:50 0 浏览量 回答数 0

回答

Layout Go工程项目的整体组织 首先我们看一下整个 Go 工程是怎么组织起来的。 很多同事都在用 GitLab 的,GitLab 的一个 group 里面可以创建很多 project。如果我们进行微服务化改造,以前很多巨石架构的应用可能就拆成了很多个独立的小应用。那么这么多小应用,你是要建 N 个 project 去维护,还是说按照部门或者组来组织这些项目呢?在 B 站的话,我们之前因为是 Monorepo,现在是按照部门去组织管理代码,就是说在单个 GitLab 的 project 里面是有多个 app 的,每一个 app 就表示一个独立的微服务,它可以独立去交付部署。所以说我们看到下面这张图里面,app 的目录里面是有好多个子目录的,比方说我们的评论服务,会员服务。跟 app 同级的目录有一个叫 pkg,可以存放业务有关的公共库。这是我们的一个组织方式。当然,还有一种方式,你可以按照 GitLab 的 project 去组织,但我觉得这样的话可能相对要创建的 project 会非常多。 如果你按部门组织的话,部门里面有很多 app,app 目录怎么去组织?我们实际上会给每一个 app 取一个全局唯一名称,可以理解为有点像 DNS 那个名称。我们对业务的命名也是一样的,我们基本上是三段式的命名,比如账号业务,它是一个账号业务、服务、子服务的三段命名。三段命名以后,在这个 app 目录里面,你也可以按照这三层来组织。比如我们刚刚说的账号目录,我可能就是 account 目录,然后 VIP,在 VIP 目录下可能会放各种各样的不同角色的微服务,比方说可能有一些是做 job,做定时任务或者流式处理的一些任务,有可能是做对外暴露的 API 的一些服务,这个就是我们关于整个大的 app 的组织的一种形式。 微服务中的 app 服务分类 微服务中单个 app 的服务里又分为几类不同的角色。我们基本上会把 app 分为 interface(BFF)、service、job(补充:还有一个 task,偏向定时执行,job 偏向流式) 和 admin。 Interface 是对外的业务网关服务,因为我们最终是面向终端用户的 API,面向 app,面向 PC 场景的,我们把这个叫成业务网关。因为我们不是统一的网关,我们可能是按照大的业务线去独立分拆的一些子网关,这个的话可以作为一个对外暴露的 HTTP 接口的一个目录去组织它的代码,当然也可能是 gRPC 的(参考 B 站对外的 gRPC Moss 分享)。 Service 这个角色主要是面向对内通信的微服务,它不直接对外。也就是说,业务网关的请求会转发或者是会 call 我们的内部的 service,它们之间的通讯可能是使用自己的 RPC,在 b 站我们主要是使用 gRPC。使用 gRPC 通讯以后,service 它因为不直接对外,service 之间可能也可以相互去 call。 Admin 区别于 service,很多应用除了有面向用户的一些接口,实际上还有面向企业内部的一些运营侧的需求,通常数据权限更高,从安全设计角度需要代码物理层面隔离,避免意外。 第四个是 ecode。我们当时也在内部争论了很久,我们的错误码定义到底是放在哪里?我们目前的做法是,一个应用里面,假设你有多种角色,它们可能会复用一些错误码。所以说我们会把我们的 ecode 给单独抽出来,在这一个应用里面是可以复用的。注意,它只在这一个应用里面复用,它不会去跨服跨目录应用,它是针对业务场景的一个业务错误码的组织。 App 目录组织 我们除了一个应用里面多种角色的这种情况,现在展开讲一下具体到一个 service 里面,它到底是怎么组织的。我们的 app 目录下大概会有 api、cmd、configs、 internal 目录,目录里一般还会放置 README、CHANGELOG、OWNERS。 API 是放置 api 定义以及对应的生成的 client 代码,包含基于 pb 定义(我们使用 PB 作为 DSL 描述 API) 生成的 swagger.json。 而 cmd,就是放 main 函数的。Configs 目录主要是放一些服务所需的配置文件,比方说说我们可能会使用 TOML 或者是使用 YAML 文件。 Internal 的话,它里面有四个子目录,分别是 model、dao、service 和 server。Model 的定位职责就是对我们底层存储的持久化层或者存储层的数据的映射,它是具体的 Go 的一个 struct。我们再看 dao,你实际就是要操作 MySQL 或者 Redis,最终返回的就是这些 model(存储映射)。Service 组织起来比较简单,就是我们通过 dao 里面的各个方法来完成一个完整的业务逻辑。我们还看到有个 server,因为我一个微服务有可能企业内部不一定所有 RPC 都统一,那我们处于过渡阶段,所以 server 里面会有两个小目录,一个是 HTTP 目录,暴露的是 HTTP 接口,还有一个是 gRPC 目录,我们会暴露 gRPC 的协议。所以在 server 里面,两个不同的启动的 server,就是说一个服务和启动两个端口,然后去暴露不同的协议,HTTP 接 RPC,它实际上会先 call 到 service,service 再 call 到 dao,dao 实际上会使用 model 的一些数据定义 struct。但这里面有一个非常重要的就是,因为这个结构体不能够直接返回给我们的 api 做外对外暴露来使用,为什么?因为可能从数据库里面取的敏感字段,当我们实际要返回到 api 的时候,可能要隐藏掉一些字段,在 Java 里面,会抽象的一个叫 DTO 的对象,它只是用来传输用的,同理,在我们 Go 里面,实际也会把这些 model 的一些结构体映射成 api 里面的结构体(基于 PB Message 生成代码后的 struct)。 Rob Pike 当时说过的一句话,a little copying is better than a little dependency,我们就遵循了这个理念。在我们这个目录结构里面,有 internal 目录,我们知道 Go 的目录只允许这个目录里面的人去 import 到它,跨目录的人实际是不能直接引用到它的。所以说,我们看到 service 有一个 model,那我的 job 代码,我做一些定时任务的代码或者是我的网关代码有可能会映射同一个 model,那是不是要把这个 model 放到上一级目录让大家共享?对于这个问题,其实我们当时内部也争论过很久。我们认为,每一个微服务应该只对自己的 model 负责,所以我们宁愿去做一小部分的代码 copy,也不会去为了几个服务之间要共享这一点点代码,去把这个 model 提到和 app 目录级别去共用,因为你一改全错,当然了,你如果是拷贝的话,就是每个地方都要去改,那我们觉得,依赖的问题可能会比拷贝代码相对来说还是要更复杂的。 这个是一个标准的 PB 文件,就是我们内部的一个 demo 的 service。最上面的 package 是 PB 的包名,demo.service.v1,这个包使用的是三段式命名,全局唯一的名称。那这个名称为什么不是用 ID?我见过有些公司对内部做的 CMDB 或者做服务树去管理企业内部微服务的时候,是用了一些名称加上 ID 来搞定唯一性,但是我们知道后面那一串 ID 数字是不容易被传播或者是不容易被记住的,这也是 DNS 出来的一个意义,所以我们用绝对唯一的一个名称来表示这个包的名字,在后面带上这一个 PB 文件的版本号 V1。 我们看第二段定义,它有个 Service Demo 代码,其实就表示了我们这个服务要启动的服务的一个名称,我们看到这个服务名称里面有很多个 RPC 的方法,表示最终这一个应用或者这个 service 要对外暴露这几个 RPC 的方法。这里面有个小细节,我们看一下 SayHello 这个方法,实际它有 option 的一个选项。通过这一个 PB 文件,你既可以描述出你要暴露的是 gRPC 协议,又暴露出 HTTP 的一个接口,这个好处是你只需要一个 PB 文件描述你暴露的所有 api。我们回想一下,我们刚刚目录里面有个 api 目录,实际这里面就是放这一个 PB 文件,描述这一个工程到底返回的接口是什么。不管是 gRPC 还是 HTTP 都是这一个文件。还有一个好处是什么?实际上我们可以在 PB 文件里面加上很多的注释。用 PB 文件的好处是你不需要额外地再去写文档,因为写文档和写服务的定义,它本质上是两个步骤,特别容易不一致,接口改了,文档不同步。我们如果基于这一个 PB 文件,它生成的 service 代码或者调用代码或者是文档都是唯一的。 依赖顺序与 api 维护 就像我刚刚讲到的,model 是一个存储层的结构体的一一映射,dao 处理一些数据读写包,比方说数据库缓存,server 的话就是启动了一些 gRPC 或者 HTTP Server,所以它整个依赖顺序如下:main 函数启动 server,server 会依赖 api 定义好的 PB 文件,定义好这些方法或者是服务名之后,实际上生成代码的时候,比方说 protocbuf 生成代码的时候,它会把抽象 interface 生成好。然后我们看一下 service,它实际上是弱依赖的 api,就是说我的 server 启动以后,要注册一个具体的业务代码的逻辑,映射方法,映射名字,实际上是弱依赖的 api 生成的 interface 的代码,你就可以很方便地启动你的 server,把你具体的 service 的业务逻辑给注入到这个 server,和方法进行一一绑定。最后,dao 和 service 实际上都会依赖这个 model。 因为我们在 PB 里面定义了一些 message,这些 message 生成的 Go 的 struct 和刚刚 model 的 struct 是两个不同的对象,所以说你要去手动 copy 它,把它最终返回。但是为了快捷,你不可能每次手动去写这些代码,因为它要做 mapping,所以我们又把 K8s 里类似 DeepCopy 的两个结构体相互拷贝的工具给抠出来了,方便我们内部 model 和 api 的 message 两个代码相互拷贝的时候,可以少写一些代码,减少一些工作量。 上面讲的就是我们关于工程的一些 layout 实践。简单回溯一下,大概分为几块,第一就是 app 是怎么组织的,app 里面有多种角色的服务是怎么组织的,第三就是一个 app 里面的目录是怎么组织的,最后我重点讲了一下 api 是怎么维护的。 Unittest 测试方法论 现在回顾一下单元测试。我们先看这张图,这张图是我从《Google 软件测试之道》这本书里面抠出来的,它想表达的意思就是最小型的测试不能给我们的最终项目的质量带来最大的信心,它比较容易带来一些优秀的代码质量,良好的异常处理等等。但是对于一个面向用户场景的服务,你只有做大型测试,比方做接口测试,在 App 上验收功能的这种测试,你应用交付的信心可能会更足。这个其实要表达的就是一个“721 原则”。我们就是 70% 写小型测试,可以理解为单元测试,因为它相对来说好写,针对方法级别。20% 是做一些中型测试,可能你要连调几个项目去完成你的 api。剩下 10% 是大型测试,因为它是最终面向用户场景的,你要去使用我们的 App,或者用一些测试 App 去测试它。这个就是测试的一些简单的方法论。 单元测试原则 我们怎么去对待 Go 里面的单元测试?在《Google 软件测试之道》这本书里面,它强调的是对于一个小型测试,一个单元测试,它要有几个特质。它不能依赖外部的一些环境,比如我们公司有测试环境,有持续集成环境,有功能测试环境,你不能依赖这些环境构建自己的单元测试,因为测试环境容易被破坏,它容易有数据的变更,数据容易不一致,你之前构建的案例重跑的话可能就会失败。 我觉得单元测试主要有四点要求。第一,快速,你不能说你跑个单元测试要几分钟。第二,要环境一致,也就是说你跑测试前和跑测试后,它的环境是一致的。第三,你写的所有单元测试的方法可以以任意顺序执行,不应该有先后的依赖,如果有依赖,也是在你测试的这个方法里面,自己去 setup 和 teardown,不应该有 Test Stub 函数存在顺序依赖。第四,基于第三点,你可以做并行的单元测试,假设我写了一百个单元测试,一个个跑肯定特别慢。 doker-compose 最近一段时间,我们演进到基于 docker-compose 实现跨平台跨语言环境的容器依赖管理方案,以解决运行 unittest 场景下的容器依赖问题。 首先,你要跑单元测试,你不应该用 VPN 连到公司的环境,好比我在星巴克点杯咖啡也可以写单元测试,也可以跑成功。基于这一点,Docker 实际上是非常好的解决方式。我们也有同学说,其他语言有一些 in-process 的 mock,是不是可以启动 MySQL 的 mock ,然后在 in-process 上跑?可以,但是有一个问题,你每一个语言都要写一个这样的 mock ,而且要写非常多种,因为我们中间件越来越多,MySQL,HBase,Kafka,什么都有,你很难覆盖所有的组件 Mock。这种 mock 或者 in-process 的实现不能完整地代表线上的情况,比方说,你可能 mock 了一个 MySQL,检测到 query 或者 insert ,没问题,但是你实际要跑一个 transaction,要验证一些功能就未必能做得非常完善了。所以基于这个原因,我们当时选择了 docker-compose,可以很好地解决这个问题。 我们对开发人员的要求就是,你本地需要装 Docker,我们开发人员大部分都是用 Mac,相对来说也比较简单,Windows 也能搞定,如果是 Linux 的话就更简单了。本地安装 Docker,本质上的理解就是无侵入式的环境初始化,因为你在容器里面,你拉起一个 MySQL,你自己来初始化数据。在这个容器被销毁以后,它的环境实际上就满足了我们刚刚提的环境一致的问题,因为它相当于被重置了,也可以很方便地快速重置环境,也可以随时随地运行,你不需要依赖任何外部服务,这个外部服务指的是像 MySQL 这种外部服务。当然,如果你的单元测试依赖另外一个 RPC 的 service 的话,PB 的定义会生成一个 interface,你可以把那个 interface 代码给 mock 掉,所以这个也是能做掉的。对于小型测试来说,你不依赖任何外部环境,你也能够快速完成。 另外,docker-compose 是声明式的 API,你可以声明你要用 MySQL,Redis,这个其实就是一个配置文件,非常简单。这个就是我们在单元测试上的一些实践。 我们现在看一下,service 目录里面多了一个 test 目录,我们会在这个里面放 docker-compose 的 YAML 文件来表示这次单元化测试需要初始化哪些资源,你要构建自己的一些测试的数据集。因为是这样的,你是写 dao 层的单元测试的话,可能就需要 database.sql 做一些数据的初始化,如果你是做 service 的单元测试的话,实际你可以把整个 dao 给 mock 掉,我觉得反而还相对简单,所以我们主要针对场景就是在 dao 里面偏持久层的,利用 docker-compose 来解决。 容器的拉起,容器的销毁,这些工作到底谁来做?是开发同学自己去拉起和销毁,还是说你能够把它做成一个 Library,让我们的同学写单元测试的时候比较方便?我倾向的是后者。所以在我们最终写单元测试的时候,你可以很方便地 setup 一个依赖文件,去 setup 你的容器的一些信息,或者把它销毁掉。所以说,你把环境准备好以后,最终可以跑测试代码也非常方便。当然我们也提供了一些命令函,就是 binary 的一些工具,它可以针对各个语言方便地拉起容器和销毁容器,然后再去执行代码,所以我们也提供了一些快捷的方式。 刚刚我也提到了,就是我们对于 service 也好,API 也好,因为依赖下层的 dao 或者依赖下层的 service,你都很方便 mock 掉,这个写单元测试相对简单,这个我不展开讲,你可以使用 GoMock 或者 GoMonkey 实现这个功能。 Toolchain 我们利用多个 docker-compose 来解决 dao 层的单元测试,那对于我刚刚提到的项目的一些规范,单元测试的一些模板,甚至是我写了一些 dao 的一些占位符,或者写了一些 service 代码的一些占位符,你有没有考虑过这种约束有没有人会去遵循?所以我这里要强调一点,工具一定要大于约束和文档,你写了约束,写了文档,那么你最终要通过工具把它落实。所以在我们内部会有一个类似 go tool 的脚手架,叫 Kratos Tool,把我们刚刚说的约定规范都通过这个工具一键初始化。 对于我们内部的工具集,我们大概会分为几块。第一块就是 API 的,就是你写一个 PB 文件,你可以基于这个 PB 文件生成 gRPC,HTTP 的框架代码,你也可以基于这个 PB 文件生成 swagger 的一些 JSON 文件或者是 Markdown 文件。当然了,我们还会生成一些 API,用于 debug 的 client 方便去调试,因为我们知道,gRPC 调试起来相对麻烦一些,你要去写代码。 还有一些工具是针对 project 的,一键生成整个应用的 layout,非常方便。我们还提了 model,就是方便 model 和 DTO,DTO 就是 API 里面定义的 message 的 struct 做 DeepCopy,这个也是一个工具。 对于 cache 的话,我们操作 memcache,操作 Redis 经常会要做什么逻辑?假如我们有一个 cache aside 场景,你读了一个 cache,cache miss 要回原 DB,你要把这个缓存回塞回去,甚至你可能这个回塞缓存想异步化,甚至是你要去读这个 DB 的时候要做归并回源(singleflight),我们把这些东西做成一些工具,让它整个回源到 DB 的逻辑更加简单,就是把这些场景描述出来,然后你通过工具可以一键生成这些代码,所以也是会比较方便。 我们再看最后一个,就是 test 的一些工具。我们会基于项目里面,比方说 dao 或者是 service 定义的 interface 去帮你写好 mock 的代码,我直接在里面填,只要填代码逻辑就行了,所以也会加速我们的生产。 上图是 Kratos 的一个 demo,基本就是支持了一些 command。这里就是一个 kratos new kratos-demo 的一个工程,-d YourPath 把它导到某一个路径去,--proto 顺便把 API 里面的 proto 代码也生成了,所以非常简单,一行就可以很快速启动一个 HTTP 或者 gRPC 服务。 我们知道,一个微服务的框架实际非常重,有很多初始化的方式等等,非常麻烦。所以说,你通过脚手架的方式就会非常方便,工具大于约定和文档这个这个理念就是这么来的。 Configuration 讲完工具以后,最后讲一下配置文件。我为什么单独提一下配置文件?实际它也是工程化的一部分。我们一个线上的业务服务包含三大块,第一,应用程序,第二,配置文件,第三,数据集。配置文件最容易导致线上出 bug,因为你改一行配置,整个行为可能跟 App 想要的行为完全不一样。而且我们的代码的开发交付需要经过哪些流程?需要 commit 代码,需要 review,需要单元测试,需要 CD,需要交付到线上,需要灰度,它的整个流程是非常长的。在一步步的环境里面,你的 bug 需要前置解决,越前置解决,成本越低。因为你的代码的开发流程是这么一个 pipeline,所以 bug 最终流到线上的概率很低,但是配置文件没有经过这么复杂的流程,可能大家发现线上有个问题,决定要改个线上配置,就去配置中心或者配置文件改,然后 push 上线,接着就问题了,这个其实很常见。 从 SRE 的角度来说,导致线上故障的主因就是来自配置变更,所以 SRE 很大的工作是控制变更管理,如果能把变更管理做好,实际上很多问题都不会出现。配置既然在整个应用里面这么重要,那在我们整个框架或者在 Go 的工程化实践里面,我们应该对配置文件做一些什么事情? 我觉得是几个。第一,我们的目标是什么?配置文件不应该太复杂,我见过很多框架,或者是业务的一些框架,它实际功能非常强大,但是它的配置文件超级多。我就发现有个习惯,只要有一个同事写错了这个配置,当我新起一个项目的时候,一定会有人把这个错误的配置拷贝到另外一个系统里面去。然后当发现这个应用出问题的时候,我们一般都会内部说一下,你看看其他同事有没有也配错的,实际这个配错概率非常高。因为你的配置选项越多,复杂性越高,它越容易出错。所以第一个要素就是说,尽量避免复杂的配置文件。配得越多,越容易出错。 第二,实际我们的配置方式也非常多,有些用 JSON,有些用 YAML,有些用 Properties,有些用 INI。那能不能收敛成通用的一种方式呢?无论它是用 Python 的脚本也好,或者是用 JSON 也好,你只要有一种唯一的约定,不需要太多样的配置方式,对我们的运维,对我们的 SRE 同时来说,他跨项目的变更成本会变低。 第三,一定要往简单化去努力。这句话其实包含了几个方面的含义。首先,我们很多配置它到底是必须的还是可选的,如果是可选,配置文件是不是就可以把它踢掉,甚至不要出现?我曾经有一次看到我们 Java 同事的配置 retry 有一个重试默认是零,内部重试是 80 次,直接把 Redis cluster 打故障了,为什么?其实这种事故很低级,所以简单化努力的另外一层含义是指,我们在框架层面,尤其是提供 SDK 或者是提供 framework 的这些同事尽量要做一些防御编程,让这种错配漏配也处于一个可控的范围,比方重试 80 次,你觉得哪个 SDK 会这么做?所以这个是我们要考虑的。但是还有一点要强调的是,我们对于业务开发的同事,我们的配置应该足够的简单,这个简单还包含,如果你的日志基本上都是写在这个目录,你就不要提供这个配置给他,反而不容易出错。但是对于我们内部的一些 infrastructure,它可能需要非常复杂的配置来优化,根据我的场景去做优化,所以它是两种场景,一种是业务场景,足够简单,一种是我要针对我的通用的 infrastructure 去做场景的优化,需要很复杂的配置,所以它是两种场景,所以我们要想清楚你的业务到底是哪一种形态。 还有一个问题就是我们配置文件一定要做好权限的变更和跟踪,因为我们知道上线出问题的时候,我们的第一想法不是查 bug,是先止损,止损先找最近有没有变更。如果发现有变更,一般是先回滚,回滚的时候,我们通常只回滚了应用程序,而忘记回滚了配置。每个公司可能内部的配置中心,或者是配置场景,或者跟我们的二进制的交付上线都不一样,那么这里的理念就是你的应用程序和配置文件一定是同一个版本,或者是某种意义上让他们产生一个版本的映射,比方说你的应用程序 1.0,你的配置文件 2.0,它们之间存在一个强绑定关系,我们在回滚的时候应该是一起回滚的。我们曾经也因为类似的一些不兼容的配置的变更,二进制程序上线,但配置文件忘记回滚,出现过事故,所以这个是要强调的。 另外,配置的变更也要经过 review,如果没问题,应该也是按照 App 发布一样,先灰度,再放量,再全量等等类似的一种方式去推,演进式的这种发布,我们也叫滚动发布,我觉得配置文件也是一样的思路。 加入阿里云钉钉群享福利:每周技术直播,定期群内有奖活动、大咖问答 原文链接

有只黑白猫 2020-01-09 17:29:54 0 浏览量 回答数 0

回答

执行交互执行命令。 描述 用户针对单个集群的节点提交并执行交互执行命令。 请求参数 字段 类型 是否必须 默认值 描述 Action String 是 - 操作接口名,系统规定参数,取值:InvokeShellCommand RegionId String 是 - 地域ID ClusterId String 是 - 集群ID Instance.n.Id String 否 - 第n个执行命令的目标节点ecs实例ID。用于限定执行范围,不指定则默认在集群所有节点上执行。 Command String 是 - 命令内容,长度小于2048。 WorkingDir String 否 /root 命令工作目录。默认为 /root。 Timeout Integer 否 3600 超时时间(秒)。超时将终止命令进程。参数取值最小为60,如果取值小于60将置为60秒。默认值:3600。 返回参数 除公共返回参数外返回如下结果: 字段 类型 描述 CommandId String 命令ID,用于后续查询 InstanceIds Array 执行命令的实例ID 示例 请求示例 https://ehpc.cn-hangzhou.aliyuncs.com/?Action=InvokeShellCommand&RegionId=cn-hangzhou&ClusterId=<集群ID>&Command=echo "hello world"&<公共请求参数> 返回示例 XML格式 04F0F334-1335-436C-A1D7-6C044FE73368 c-f4682204a89949979d75e76700e05521 i-uf68t1zu3jkhs8wyxhii i-uf6abz34m2714bp4nydi i-uf65bh2113hlqvyrx3us i-uf68t1zu3jkhs8wyxhil i-uf6b0mtpx166fxxiskm4 i-uf6faknz4dy1bit7zg2n JSON格式 { "RequestId": "04F0F334-1335-436C-A1D7-6C044FE73368", "CommandId": "c-f4682204a89949979d75e76700e05521", "InstanceIds": { "InstanceId": ["i-uf68t1zu3jkhs8wyxhii", "i-uf6abz34m2714bp4nydi", "i-uf65bh2113hlqvyrx3us", "i-uf68t1zu3jkhs8wyxhil", "i-uf6b0mtpx166fxxiskm4", "i-uf6faknz4dy1bit7zg2n"] } } 错误码 查询E-HPC接口错误码请访问 错误码。更多错误码,请访问 API 错误中心。

1934890530796658 2020-03-23 18:29:07 0 浏览量 回答数 0

问题

API如何批量消费消息?

轩墨 2019-12-01 22:10:17 1133 浏览量 回答数 0

回答

基础库 基础库与客户端的关系 基础库是负责小程序框架的加载的容器,提供小程序框架需要的标准组件和标准 API 接口。小程序能力需要支付宝客户端来支撑,每一版基础库新增能力都需要 特定版本以上客户端才能运行,高版本基础库的某些新能力无法兼容低版本客户 端,关于基础库兼容方法,可以查看兼容章节。可以通过 my.SDKVersion 查看当 前基础库版本号。 基础库更新时机 当基础库准备更新时,会在客户端内进行逐步灰度直到全量发布。当用户客户端更 新至最新基础库后,小程序就会运行在最新的基础库上。 随着基础库的不断更新,老版本客户端不支持的能力越来越多,所以基础库支持范 围有一个最低客户端版本的要求,即部分老版本客户端以后将无法更新到最新的基 础库,会停留在某一历史版本。例如,如果用户的支付宝客户端版本是 1.0.0 版 本,那么基础库最多更新到 1.1.0。 基础库版本分布 更新时间:2019 年 12 月 4 日 基础库版本 用户占比 支付宝客户端最低版本 =1.21.4 93.64% 10.1.70 1.20.5 0.79% 10.1.68 1.20.1 0.33% 10.1.68 1.19.4 0.53% 10.1.65 1.16.4 0.35% 10.1.58 1.13.15 0.98% 10.1.32 其它 3.38% - 130 设置最低基础库版本 从 开发中心 > 小程序应用 > 我的小程序,进入小程序详情页,点击左侧栏 设 置,在 基础设置 栏,可设置小程序的最低基础库版本。若小程序用户使用的基 础库版本低于设置的最低版本要求,则无法正常使用小程序,并将提示用户更新支 付宝版本。设置版本号后,小程序需重新发版才会生效。 点击 最低基础库版本 对应的 设置 按钮,可看到不同的最低基础库版本对应的 受影响用户 UV 占比,即近 30 天内访问小程序的用户的基础库版本小于所选版 本的占比。开发者可据此设置小程序的最低基础库版本。 选中需设置为最低基础库版本的版本号,点击 确定 按钮,即设置成功。 131 此时,最低基础库版本 设置项对应的 状态 变为 已设置。 内容来源:https://developer.aliyun.com/article/756818?spm=a2c6h.12873581.0.dArticle756818.26162b70Su1GZy&groupCode=tech_library

KaFei 2020-04-27 15:37:42 0 浏览量 回答数 0

回答

原理 如果设备可以发送、接收消息,那么该设备的通信是没问题的,并且一定在线。 消息收发是物联网平台的核心能力。因此,这种判定方法不会因为物联网平台架构升级或业务变动而变化,也不会因为设备使用的客户端不同而不同。是设备端检测自己是否在线最通用的一种原理。 该原理的一种特殊实现就是设备端消息的自发自收。 流程 创建js Topic = /yourProductKey/yourDeviceName/user/checkstatus 。 Topic可以自定义,但权限必须为发布和订阅。 设备端订阅上一步创建的Topic 。 设备端发送消息js {"id":123,"version":"1.0","time":1234567890123} , 请一定使用QoS=0 。 消息内容可自定义,但建议使用此格式。 参数说明: 字段类型说明idObject用于验证收发的消息是否是同一个,请自行业务层保证唯一versionString版本号固定1.0timeLong发送消息的时间戳,可以计算消息来回的延时,评估当前的通信质量 设备端收到消息上一步发送的消息。 离线判定逻辑 严格的:发送消息后,5秒内没有收到消息算失败,出现1次失败,判定为离线 普通的:发送消息后,5秒内没有收到消息算失败,连续2次失败,判定为离线宽松的:发送消息后,5秒内没有收到消息算失败,连续3次失败,判定为离线 实现 为方便体验,本例基于Java SDK Demo开发,实现设备端检测自己是否在线的严格判定逻辑。 Java SDK开发具体细节,请查看相关文档。 首先,下载Demo工程,添加本类,并填写设备证书信息。设备端代码如下: import java.io.UnsupportedEncodingException; import com.aliyun.alink.dm.api.DeviceInfo; import com.aliyun.alink.dm.api.InitResult; import com.aliyun.alink.linkkit.api.ILinkKitConnectListener; import com.aliyun.alink.linkkit.api.IoTMqttClientConfig; import com.aliyun.alink.linkkit.api.LinkKit; import com.aliyun.alink.linkkit.api.LinkKitInitParams; import com.aliyun.alink.linksdk.cmp.connect.channel.MqttPublishRequest; import com.aliyun.alink.linksdk.cmp.connect.channel.MqttSubscribeRequest; import com.aliyun.alink.linksdk.cmp.core.base.AMessage; import com.aliyun.alink.linksdk.cmp.core.base.ARequest; import com.aliyun.alink.linksdk.cmp.core.base.AResponse; import com.aliyun.alink.linksdk.cmp.core.base.ConnectState; import com.aliyun.alink.linksdk.cmp.core.listener.IConnectNotifyListener; import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSendListener; import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSubscribeListener; import com.aliyun.alink.linksdk.tools.AError; public class CheckDeviceStatusOnDevice { // ===================需要用户填写的参数,开始=========================== // 产品productKey,设备证书参数之一 private static String productKey = ""; // 设备名字deviceName,设备证书参数之一 private static String deviceName = ""; // 设备密钥deviceSecret,设备证书参数之一 private static String deviceSecret = ""; // 消息通信的Topic,需要在控制台定义,权限必须为发布和订阅 private static String checkStatusTopic = "/" + productKey + "/" + deviceName + "/user/checkstatus"; // ===================需要用户填写的参数结束=========================== // 接收到的消息 private static String subInfo = ""; public static void main(String[] args) throws InterruptedException { CheckDeviceStatusOnDevice device = new CheckDeviceStatusOnDevice(); // 初始化 device.init(productKey, deviceName, deviceSecret); // 下行数据监听 device.registerNotifyListener(); // 订阅Topic device.subscribe(checkStatusTopic); // 测试设备状态 System.out.println("we will check device online status now."); device.checkStatus(); // 准备测试设备离线状态,请拔掉网线 System.out.println("pls close network,we will check device offline status after 60 seconds."); for (int i = 0; i < 6; i++) { Thread.sleep(10000); } device.checkStatus(); } /** * 测试设备状态 * * @throws InterruptedException */ public void checkStatus() throws InterruptedException { // ------------------------------------------------------------------- // 要发送的消息,可以自定义,建议使用当前格式 // ------------------------------------------------------------------- // Field | Tyep | Desc // ------------------------------------------------------------------- // id | Object | 用于验证收发的消息是否是同一个,请自行业务层保证唯一 // ------------------------------------------------------------------- // version | String | 版本号固定1.0 // ------------------------------------------------------------------- // time | Long | 发送消息的时间戳,可以计算消息来回的延时,评估当前的通信质量 // ------------------------------------------------------------------- String payload = "{\"id\":123, \"version\":\"1.0\",\"time\":" + System.currentTimeMillis() + "}"; // 发送消息 publish(checkStatusTopic, payload); // 严格的离线判定逻辑:发送消息后,5秒内没有收到消息算失败,出现1次失败,判定为离线 boolean isTimeout = true; for (int i = 0; i < 5; i++) { Thread.sleep(1000); if (!subInfo.isEmpty()) { isTimeout = false; break; } } if (!isTimeout && payload.equals(subInfo)) { System.out.println("Device is online !!"); } else { System.out.println("Device is offline !!"); } // 置空接收到的消息,方便下一次测试 subInfo = ""; } /** * 初始化 * * @param pk productKey * @param dn devcieName * @param ds deviceSecret * @throws InterruptedException */ public void init(String pk, String dn, String ds) throws InterruptedException { LinkKitInitParams params = new LinkKitInitParams(); // 设置 MQTT 初始化参数 IoTMqttClientConfig config = new IoTMqttClientConfig(); config.productKey = pk; config.deviceName = dn; config.deviceSecret = ds; params.mqttClientConfig = config; // 设置初始化设备证书信息,用户传入 DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.productKey = pk; deviceInfo.deviceName = dn; deviceInfo.deviceSecret = ds; params.deviceInfo = deviceInfo; LinkKit.getInstance().init(params, new ILinkKitConnectListener() { @Override public void onInitDone(InitResult initResult) { System.out.println("init success !!"); } @Override public void onError(AError aError) { System.out.println("init failed !! code=" + aError.getCode() + ",msg=" + aError.getMsg() + ",subCode=" + aError.getSubCode() + ",subMsg=" + aError.getSubMsg()); } }); // 确保初始化成功后才执行后面的步骤,可以根据实际情况适当延长这里的延时 Thread.sleep(2000); } /** * 监听下行数据 */ public void registerNotifyListener() { LinkKit.getInstance().registerOnNotifyListener(new IConnectNotifyListener() { @Override public boolean shouldHandle(String connectId, String topic) { // 只处理特定Topic的消息 if (checkStatusTopic.equals(topic)) { return true; } else { return false; } } @Override public void onNotify(String connectId, String topic, AMessage aMessage) { // 接收消息 try { subInfo = new String((byte[]) aMessage.getData(), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } @Override public void onConnectStateChange(String connectId, ConnectState connectState) { } }); } /** * 发布消息 * * @param topic 发送消息的Topic * @param payload 发送的消息内容 */ public void publish(String topic, String payload) { MqttPublishRequest request = new MqttPublishRequest(); request.topic = topic; request.payloadObj = payload; request.qos = 0; LinkKit.getInstance().getMqttClient().publish(request, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { } @Override public void onFailure(ARequest aRequest, AError aError) { } }); } /** * 订阅消息 * * @param topic 订阅消息的Topic */ public void subscribe(String topic) { MqttSubscribeRequest request = new MqttSubscribeRequest(); request.topic = topic; LinkKit.getInstance().getMqttClient().subscribe(request, new IConnectSubscribeListener() { @Override public void onSuccess() { } @Override public void onFailure(AError aError) { } }); } }

剑曼红尘 2020-03-05 16:55:24 0 浏览量 回答数 0

回答

背景 目前支付宝推出了新的签名方式,除了使用RSA2普通公钥方式签名外,新增了公钥证书的签名方式,但是2者使用有什么不同呢? 从公钥设置方式、sdk版本、sdk签名方式、sdk验签方式 一、接口加签方式 根据应用中“接口加签方式”的“选择加签模式”,进行对应的模式签名。 1、RSA2普通公钥 RSA2普通公钥签名需选择“选择加签模式”的“公钥”模式。 普通公钥设置密钥方式详见【如何设置普通公钥】。 2、公钥证书 公钥证书签名需选择“选择加签模式”的“公钥证书”模式。 公钥证书置密钥方式详见【如何设置公钥证书】。 200325-1.png 二、sdk版本 目前新版的sdk都是支持RSA2普通公钥和公钥证书,但是低版本的sdk是只支持RSA2普通公钥的签名方式。 证书签名SDK版本Java版SDK支持4.4.5.ALL及以上版本。 证书签名SDK版本php版SDK支持alipay-sdk-PHP-4.1.0及以上版本; 证书签名SDK版本.Net版SDK支持alipay-sdk-NET-4.0.0及以上版本; 注:Python、NodeJS还未出证书签名sdk版本,待后续更新。 三、签名验签方式 不同语言的RSA2普通公钥和公钥证书签名验签方法不同。 RSA2普通公钥签名验签方法详见【如何使用RSA2签名验签】。 公钥证书验签签名验签方法详见【如何使用证书签名验签】。 四、sdk封装签名方式 由于第三步的签名验签方法未讲述sdk封装方法类请求的方式,RSA2普通公钥和公钥证书签名方式主要在于初始化方式不同,但是请求参数设置是相同的。 注意:实例化具体API对应的request类和response类,类名称和接口名称对应。 如接口名称:alipay.trade.pay,request类:AlipayTradePayRequest,response类:AlipayTradePayResponse 如接口名称:alipay.trade.app.pay,request类:AlipayTradeAppPayRequest,response类:AlipayTradeAppPayResponse 1、Java语言 (1)RSA2普通公钥签名 请求示例 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2"); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.pay AlipayTradePayRequest request = new AlipayTradePayRequest(); request.setBizContent("{"out_trade_no":"2018092031012228432"," + ""total_amount":"0.01"," + ""subject":"subject"}"); request.setNotifyUrl("商户外网可以访问的异步地址"); AlipayTradePayResponse response = alipayClient.execute(request); if(response.isSuccess()){ System.out.println("调用成功"); } else { System.out.println("调用失败"); } System.out.println(response.getBody()); (2)公钥证书签名 请求示例 //构造client CertAlipayRequest certAlipayRequest = new CertAlipayRequest(); //设置网关地址 certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do"); //设置应用Id certAlipayRequest.setAppId(app_id); //设置应用私钥 certAlipayRequest.setPrivateKey(privateKey); //设置请求格式,固定值json certAlipayRequest.setFormat("json"); //设置字符集 certAlipayRequest.setCharset(charset); //设置签名类型 certAlipayRequest.setSignType(sign_type); //设置应用公钥证书路径 certAlipayRequest.setCertPath(app_cert_path); //设置支付宝公钥证书路径 certAlipayRequest.setAlipayPublicCertPath(alipay_cert_path); //设置支付宝根证书路径 certAlipayRequest.setRootCertPath(alipay_root_cert_path); //构造client AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.pay AlipayTradePayRequest request = new AlipayTradePayRequest(); request.setBizContent("{"out_trade_no":"2018092031012228432"," + ""total_amount":"0.01"," + ""subject":"subject"}"); request.setNotifyUrl("商户外网可以访问的异步地址"); AlipayTradePayResponse response = alipayClient.certificateExecute(request); if(response.isSuccess()){ System.out.println("调用成功"); } else { System.out.println("调用失败"); } System.out.println(response.getBody()); (3)请求方法 //(1)服务端请求返回,RSA2密钥和公钥证书请求方式不同,如当面付 //RSA2密钥请求 response = alipayClient.execute(request); //公钥证书请求请求 response = alipayClient.certificateExecute(request); //(2)网站类适用接口请求,RSA2密钥和公钥证书请求方式相同,如手机网站支付、电脑网站支付 response = alipayClient.pageExecute(request); //(3)客户端类适用接口请求请求,RSA2密钥和公钥证书请求方式相同,如app支付 response = alipayClient.sdkExecute(request); 2、php语言 (1)普通公钥签名 请求示例 $aop = new AopClient; $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do"; $aop->appId = "app_id"; $aop->rsaPrivateKey = '请填写开发者私钥去头去尾去回车,一行字符串'; $aop->format = "json"; $aop->charset = "UTF-8"; $aop->signType = "RSA2"; $aop->alipayrsaPublicKey = '请填写支付宝公钥,一行字符串'; //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay $request = new AlipayTradeAppPayRequest(); //SDK已经封装掉了公共参数,这里只需要传入业务参数 $request->setBizContent("{"body":"我是测试数据"," . ""subject": "App支付测试"," . ""out_trade_no": "20170125test01"," . ""timeout_express": "30m"," . ""total_amount": "0.01"," . ""product_code":"QUICK_MSECURITY_PAY"" . "}"); $request->setNotifyUrl("商户外网可以访问的异步地址"); //这里和普通的接口调用不同,使用的是sdkExecute $response = $aop->sdkExecute($request); //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题 echo htmlspecialchars($response);//就是orderString 可以直接给客户端请求,无需再做处理。 (2)公钥证书签名 $aop = new AopCertClient; $appCertPath = "应用证书路径(要确保证书文件可读),例如:/home/admin/cert/appCertPublicKey.crt"; $alipayCertPath = "支付宝公钥证书路径(要确保证书文件可读),例如:/home/admin/cert/alipayCertPublicKey_RSA2.crt"; $rootCertPath = "支付宝根证书路径(要确保证书文件可读),例如:/home/admin/cert/alipayRootCert.crt"; $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do"; $aop->appId = "app_id"; $aop->rsaPrivateKey = '请填写开发者私钥去头去尾去回车,一行字符串' ; $aop->format = "json"; $aop->charset= "GBK"; $aop->signType= "RSA2"; //调用getPublicKey从支付宝公钥证书中提取公钥 $aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath); //是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内 $aop->isCheckAlipayPublicCert = true; //调用getCertSN获取证书序列号 $aop->appCertSN = $aop->getCertSN($appCertPath); //调用getRootCertSN获取支付宝根证书序列号 $aop->alipayRootCertSN = $aop->getRootCertSN($rootCertPath); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay $request = new AlipayTradeAppPayRequest(); //SDK已经封装掉了公共参数,这里只需要传入业务参数 $request->setBizContent("{"body":"我是测试数据"," . ""subject": "App支付测试"," . ""out_trade_no": "20170125test01"," . ""timeout_express": "30m"," . ""total_amount": "0.01"," . ""product_code":"QUICK_MSECURITY_PAY"" . "}"); $request->setNotifyUrl("商户外网可以访问的异步地址"); //这里和普通的接口调用不同,使用的是sdkExecute $response = $aop->sdkExecute($request); //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题 echo htmlspecialchars($response);//就是orderString 可以直接给客户端请求,无需再做处理。 (3)请求方法 //RSA2普通公钥和公钥证书请求方法一致。 //服务端请求返回,如当面付 $response = $aop->execute($request); //网站类适用接口请求返回,如手机网站支付、电脑网站支付 $response = $aop->pageExecute($request); //客户类适用接口请求返回,如app支付 $response = $aop->sdkExecute($request); 3、.net语言 (1)RSA2普通公钥签名 请求示例 IAopClient client = new DefaultAopClient("https://openapi.alipay.com/gateway.do", APPID, APP_PRIVATE_KEY, "json", "1.0", "RSA2", ALIPAY_PUBLIC_KEY, CHARSET, false); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.pay AlipayTradePayRequest request = new AlipayTradePayRequest(); request.BizContent="{"out_trade_no":"2018092031012228432"," + ""total_amount":"0.01"," + ""subject":"subject"}"; request.setNotifyUrl("商户外网可以访问的异步地址"); AlipayTradePayResponse response = client.Execute(request); Console.WriteLine(response.Body); (2)公钥证书签名 请求示例 //设置证书相关参数 CertParams certParams = new CertParams { AlipayPublicCertPath = "支付宝公钥证书路径", AppCertPath = "商户应用证书路径", RootCertPath = "支付宝根证书路径" }; IAopClient client = new DefaultAopClient("https://openapi.alipay.com/gateway.do", APPID, APP_PRIVATE_KEY, "json", "1.0", "RSA2", "utf-8", false, certParams); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.pay AlipayTradePayRequest request = new AlipayTradePayRequest(); request.BizContent="{"out_trade_no":"2018092031012228432"," + ""total_amount":"0.01"," + ""subject":"subject"}"; request.setNotifyUrl("商户外网可以访问的异步地址"); AlipayTradePayResponse response = client.CertificateExecute(request); Console.WriteLine(response.Body); (3)请求方法 //(1)服务端请求,RSA2密钥和公钥证书请求方式相同,如当面付 //RSA2密钥请求 response = client.Execute(request); //公钥证书请求请求 response = client.CertificateExecute(request); //(2)网站类适用接口请求,RSA2密钥和公钥证书请求方式相同如手机网站支付、电脑网站支付 response = client.pageExecute(request); //(3)客户端类适用接口请求,RSA2密钥和公钥证书请求方式相同如app支付 response = client.sdkExecute(request);

保持可爱mmm 2020-05-05 16:49:11 0 浏览量 回答数 0

问题

接入图片服务之如何实现用户鉴权?

青衫无名 2019-12-01 21:57:21 1667 浏览量 回答数 0

问题

Mantis 安装配置手册:报错

kun坤 2020-06-06 14:10:01 0 浏览量 回答数 1

问题

Swift2.0到底「新」在哪?

忆远0711 2019-12-01 21:30:17 8367 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站