• 关于 分用未响应 的搜索结果

问题

关于postgresql在实际场景下所碰到的问题

jaywu 2019-12-01 19:44:32 1369 浏览量 回答数 1

问题

如何授权账号管理类 API 应用

猫饭先生 2019-12-01 21:05:34 900 浏览量 回答数 0

回答

问题定义 A -> B 发起TCP请求,A端为请求侧,B端为服务侧TCP 三次握手已完成TCP 三次握手后双方没有任何数据交互B 在无预警情况下掉线(类似意外掉电重启状态) 问题答案 A侧的TCP链路状态在未发送任何数据的情况下与等待的时间相关,如果在多个超时值范围以内那么状态为established;如果触发了某一个超时的情况那么视情况的不同会有不同的改变。 一般情况下不管是KeepAlive超时还是内核超时,只要出现超时,那么必然会抛出异常,只是这个异常截获的时机会因编码方式的差异而有所不同。(同步异步IO,以及有无使用select、poll、epoll等IO多路复用机制) 原因与相关细节 大前提 基于IP网络的无状态特征,A侧系统不会在无动作情况下收到任何通知获知到B侧掉线的情况(除非AB是直连状态,那么A可以获知到自己网卡掉线的异常) 在此大前提的基础上,会因为链路环境、SOCKET设定、以及内核相关配置的不同,A侧会在不同的时机获知到B侧无响应的结果,但总归是以异常的形式获得这个结果。 <关于内核对待无数据传递SOCKET的方式> 操作系统有一堆时间超级长的兜底用timeout参数,用于在不同的时候给TCP栈一个异常退出的机会,避免无效连接过多而耗尽系统资源 其中,TCP KeepAive 特性能让应用层配置一个远小于内核timeout参数的值,用于在这一堆时间超长的兜底参数生效之前,判断链路是否为有效状态。 <关于超时的各个节点> 以下仅讨论三次握手成功之后的兜底情况 TCP链路在建立之后,内核会初始化一个由<nf_conntrack_tcp_timeout_established>参数控制的计时器(这个计时器在Ubuntu 18.04里面长达5天),以防止在未开启TCP KeepAlive的情况下连接因各种原因导致的长时间无动作而过度消耗系统资源,这个计时器会在每次TCP链路活动后重置 TCP正常传输过程中,每一次数据发送之后,必然伴随对端的ACK确认信息。如果对端因为各种原因失去反应(网络链路中断、意外掉电等)这个ACK将永远不会到来,内核在每次发送之后都会重置一个由<nf_conntrack_tcp_timeout_unacknowledged>参数控制的计时器,以防止对端以外断网导致的资源过度消耗。(这个计时器在Ubuntu 18.04里面是300秒/5分钟) 以上两个计时器作为keepalive参数未指定情况下的兜底参数,为内核自保特性,所以事件都很长,建议实际开发与运维中用更为合理的参数覆盖这些数值 <关于链路异常后发生的操作> A侧在超时退出之后一般会发送一个RST包用于告知对端重置链路,并给应用层一个异常的状态信息,视乎同步IO与异步IO的差异,这个异常获知的时机会有所不同。 B侧重启之后,因为不存有之前A-B之间建立链路相关的信息,这时候收到任何A侧来的数据都会以RST作为响应,以告知A侧链路发生异常 RST的设计用意在于链路发生意料之外的故障时告知链路上的各方释放资源(一般指的是NAT网关与收发两端);FIN的设计是用于在链路正常情况下的正常单向终止与结束。二者不可混淆。 关于阻塞 应用层到底层网卡发送的过程中,数据包会经历多个缓冲区,也会经历一到多次的分片操作,阻塞这一结果的发生是具有从底向上传递的特性。 这一过程中有一个需要强调的关键点:socket.send这个操作只是把数据发送到了内核缓冲区,只要数据量不大那么这个调用必然是在拷贝完之后立即返回的。而数据量大的时候,必然会产生阻塞。 在TCP传输中,决定阻塞与否的最终节点,是TCP的可靠传输特性。此特性决定了必须要有ACK数据包回复响应正确接收的数据段范围,内核才会把对应的数据从TCP发送缓冲区中移除,腾出空间让新的数据可以写入进来。 这个过程意味着,只要应用层发送了大于内核缓冲区可容容纳的数据量,那么必然会在应用层出现阻塞,等待ACK的到来,然后把新数据压入缓冲队列,循环往复,直到数据发送完毕。

九旬 2020-05-24 22:22:41 0 浏览量 回答数 0

新用户福利专场,云服务器ECS低至102元/年

新用户专场,1核2G 102元/年起,2核4G 699.8元/年起

问题

Nginx性能为什么如此吊

小柒2012 2019-12-01 21:20:47 15038 浏览量 回答数 3

回答

web压力测试通过产生真实压力来发现问题需要关注以下方面: 1、对要测试的系统进行分析,明确需要对哪一块做压力测试。比如:淘宝网站双十一期间,秒杀跟支付,此模式用户操作中占比比较大 再比如:游戏,登录--开始战斗--结束战斗这种混合模式在用户操作中占比较大 那么就可以针对这种占比比较大的模式进行压力测试 2、明确了要测试的点后,如何对这些测试点进行施压呢? 第一种方式可以通过写脚本产生压力机器人对服务器进行发包收包操作; 第二种方式就是借助一些压力测试工具如:JMeter或LoadRunner 3、如何对这些测试点进行正确的施压呢? 那么就需要用压力测试工具或者其它方法来录制脚本,模拟用户的操作 4、对测试点该施加多大的压力比较合适?该施加多少的数据才能找出系统的瓶颈? 那么就需要明确压力测试所限制的数量,即用户并发量,这里分3种情况来明确: 1)根据上级的明确规定数量,来设定最确大值,然后根据情况往上或往下增减 2)上级未规定,由自己判断,从1开始慢慢递增。如:1,5,10,20等等 3)若做过压力测试,则可以根据上次的压力测试结果为基数进行测试 5、测试完之后,如何通过这些数据来定位性能问题呢? 虽然通过这些测试结果我们可以得到TPS(吞吐量),平均响应时间等这些数据,可判断出服务器是否存在问题,但却不能定位问题。 答案来源于网络

养狐狸的猫 2019-12-02 03:02:01 0 浏览量 回答数 0

问题

DDos分析三:攻击实例 - SYN Flood攻击[续]

千鸟 2019-12-01 21:46:28 14353 浏览量 回答数 3

问题

【重要消息】中间件大赛提前开放试跑(7月3日截止)

凝岚 2019-12-01 21:21:47 9023 浏览量 回答数 12

问题

PHP多个版本爆出远程DoS漏洞深入分析及防护方案

中国好人 2019-12-01 21:56:36 6922 浏览量 回答数 1

回答

详细解答可以参考官方帮助文档 创建HTTP监听。 说明 新建的监听的状态为stopped。创建完成后,需调用StartLoadBalancerListener接口启动监听进行流量转发。 请求参数 名称 类型 是否必须 描述 Action String 是 要执行的操作。取值: CreateLoadBalancerHTTPListener RegionId String 是 负载均衡实例的地域。 您可以通过调用 DescribeRegions接口获取地域ID。 LoadBalancerId String 是 负载均衡实例ID。 ListenerPort Integer 是 负载均衡实例前端使用的端口,取值: 1-65535 BackendServerPort Integer 是 负载均衡实例后端使用的端口。取值: 1-6553 说明 如果不使用服务器组(不指定VServerGroupId参数),则该参数必选。 VServerGroupId String 否 服务器组ID。 Bandwidth Integer 是 监听的带宽峰值,取值: -1:不限制带宽峰值。 [1-5000]:监听的带宽峰值,所有监听的带宽峰值之和不能超过实例的带宽峰值。 AclStatus String 否 是否开启访问控制功能。 取值:on | off(默认值) AclType String 否 访问控制类型: white: 仅转发来自所选访问控制策略组中设置的IP地址或地址段的请求,白名单适用于应用只允许特定IP访问的场景。 设置白名单存在一定业务风险。一旦设置白名单,就只有白名单中的IP可以访问负载均衡监听。如果开启了白名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 black: 来自所选访问控制策略组中设置的IP地址或地址段的所有请求都不会转发,黑名单适用于应用只限制某些特定IP访问的场景。 如果开启了黑名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 当AclStatus参数的值为on时,该参数必选。 AclId String 否 监听绑定的访问策略组ID。 当AclStatus参数的值为on时,该参数必选。 XForwardedFor String 否 是否开启通过X-Forwarded-For头字段获取来访者真实 IP,取值: on(默认值) | off XForwardedFor_SLBIP String 否 是否通过SLB-IP头字段获取客户端请求的真实IP,取值: on | off(默认值) IdleTimeout String 否 指定连接空闲超时时间,取值范围为1-60秒,默认值为15秒。 在超时时间内一直没有访问请求,负载均衡会暂时中断当前连接,直到一下次请求来临时重新建立新的连接。 RequestTimeout String 否 指定请求超时时间,取值范围为1-180秒,默认值为60秒。 在超时时间内后端服务器一直没有响应,负载均衡将放弃等待,给客户端返回HTTP 504错误码。 XForwardedFor_SLBID String 否 是否通过SLB-ID头字段获取负载均衡实例ID,取值: on | off(默认值) XForwardedFor_proto String 否 是否通过X-Forwarded-Proto头字段获取负载均衡实例的监听协议,取值: on | off(默认值) Scheduler String 否 调度算法。取值: wrr(默认值):权重值越高的后端服务器,被轮询到的次数(概率)也越高。 wlc:除了根据每台后端服务器设定的权重值来进行轮询,同时还考虑后端服务器的实际负载(即连接数)。当权重值相同时,当前连接数越小的后端服务器被轮询到的次数(概率)也越高。 rr:按照访问顺序依次将外部请求依序分发到后端服务器。 StickySession String 是 是否开启会话保持,取值: on | off StickySessionType String 否 cookie的处理方式。取值: insert:植入Cookie。 客户端第一次访问时,负载均衡会在返回请求中植入Cookie(即在HTTP/HTTPS响应报文中插入SERVERID),下次客户端携带此Cookie访问,负载均衡服务会将请求定向转发给之前记录到的后端服务器上。 server:重写Cookie。 负载均衡发现用户自定义了Cookie,将会对原来的Cookie进行重写,下次客户端携带新的Cookie访问,负载均衡服务会将请求定向转发给之前记录到的后端服务器。 说明 当StickySession的值为on时,必须指定该参数。 CookieTimeout Integer 否 Cookie超时时间。取值: 1-86400(秒) 说明 当StickySession为on且StickySessionType为insert时,该参数必选。 Cookie String 否 服务器上配置的Cookie。 长度为1-200个字符,只能包含ASCII英文字母和数字字符,不能包含逗号、分号或空格,也不能以$开头。 当StickySession为on且StickySessionType为server时,该参数必选。 HealthCheck String 是 是否开启健康检查。取值: on | off HealthCheckDomain String 否 用于健康检查的域名,取值: $_ip: 后端服务器的私网IP。当指定了IP或该参数未指定时,负载均衡会使用各后端服务器的私网IP当做健康检查使用的域名。 domain:域名长度为1-80字符,只能包含字母、数字、点号(.)和连字符(-)。 HealthCheckURI String 否 用于健康检查的URI。 HealthCheckConnectPort Integer 否 健康检查使用的端口。取值: 1-65535:健康检查的后端服务器的端口。 HealthyThreshold Integer 否 健康检查连续成功多少次后,将后端服务器的健康检查状态由fail判定为success。 取值:2-10 UnhealthyThreshold Integer 否 健康检查连续失败多少次后,将后端服务器的健康检查状态由success判定为fail。 取值:2-10 HealthCheckTimeout Integer 否 接收来自运行状况检查的响应需要等待的时间。如果后端ECS在指定的时间内没有正确响应,则判定为健康检查失败。 取值:1-300(秒) 说明 如果HealthCHeckTimeout的值小于HealthCheckInterval的值,则HealthCHeckTimeout无效,超时时间为HealthCheckInterval的值。 HealthCheckInterval Integer 否 健康检查的时间间隔。 取值:1-50(秒) HealthCheckHttpCode String 否 健康检查正常的HTTP状态码,多个状态码用逗号分隔。 取值:http_2xx(默认值) | http_3xx | http_4xx | http_5xx Gzip String 否 是否开启Gzip压缩,对特定文件类型进行压缩。 取值:on(默认值)| off 返回参数 名称 类型 说明 RequestId String 请求ID。 示例 请求示例 https://slb.aliyuncs.com/?Action=CreateLoadBalancerHTTPListener &LoadBalancerId=lb-t4nj5vuz8ish9emfk1f20 &ListenerPort=80 &BackendServerPort=80 &Bandwidth=-1 &HealthCheck=on &HealthCheckDomain=$_ip &HealthCheckURI=/test/index.html &HealthCheckConnectPort=8080 &HealthyThreshold=4 &UnhealthyThreshold=4 &HealthCheckTimeout=3 &HealthCheckInterval=5 &VServerGroupId=rsp-cige6j5e7p &公共请求参数 返回示例 XML格式 <?xml version="1.0" encoding="UTF-8"?> <CreateLoadBalancerHTTPListenerResponse> <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId> </CreateLoadBalancerHTTPListenerResponse> JSON格式 { "RequestId": " CEF72CEB-54B6-4AE8-B225-F876FF7BA984" }

2019-12-01 23:10:40 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 创建HTTP监听。 说明 新建的监听的状态为stopped。创建完成后,需调用StartLoadBalancerListener接口启动监听进行流量转发。 请求参数 名称 类型 是否必须 描述 Action String 是 要执行的操作。取值: CreateLoadBalancerHTTPListener RegionId String 是 负载均衡实例的地域。 您可以通过调用 DescribeRegions接口获取地域ID。 LoadBalancerId String 是 负载均衡实例ID。 ListenerPort Integer 是 负载均衡实例前端使用的端口,取值: 1-65535 BackendServerPort Integer 是 负载均衡实例后端使用的端口。取值: 1-6553 说明 如果不使用服务器组(不指定VServerGroupId参数),则该参数必选。 VServerGroupId String 否 服务器组ID。 Bandwidth Integer 是 监听的带宽峰值,取值: -1:不限制带宽峰值。 [1-5000]:监听的带宽峰值,所有监听的带宽峰值之和不能超过实例的带宽峰值。 AclStatus String 否 是否开启访问控制功能。 取值:on | off(默认值) AclType String 否 访问控制类型: white: 仅转发来自所选访问控制策略组中设置的IP地址或地址段的请求,白名单适用于应用只允许特定IP访问的场景。 设置白名单存在一定业务风险。一旦设置白名单,就只有白名单中的IP可以访问负载均衡监听。如果开启了白名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 black: 来自所选访问控制策略组中设置的IP地址或地址段的所有请求都不会转发,黑名单适用于应用只限制某些特定IP访问的场景。 如果开启了黑名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 当AclStatus参数的值为on时,该参数必选。 AclId String 否 监听绑定的访问策略组ID。 当AclStatus参数的值为on时,该参数必选。 XForwardedFor String 否 是否开启通过X-Forwarded-For头字段获取来访者真实 IP,取值: on(默认值) | off XForwardedFor_SLBIP String 否 是否通过SLB-IP头字段获取客户端请求的真实IP,取值: on | off(默认值) IdleTimeout String 否 指定连接空闲超时时间,取值范围为1-60秒,默认值为15秒。 在超时时间内一直没有访问请求,负载均衡会暂时中断当前连接,直到一下次请求来临时重新建立新的连接。 RequestTimeout String 否 指定请求超时时间,取值范围为1-180秒,默认值为60秒。 在超时时间内后端服务器一直没有响应,负载均衡将放弃等待,给客户端返回HTTP 504错误码。 XForwardedFor_SLBID String 否 是否通过SLB-ID头字段获取负载均衡实例ID,取值: on | off(默认值) XForwardedFor_proto String 否 是否通过X-Forwarded-Proto头字段获取负载均衡实例的监听协议,取值: on | off(默认值) Scheduler String 否 调度算法。取值: wrr(默认值):权重值越高的后端服务器,被轮询到的次数(概率)也越高。 wlc:除了根据每台后端服务器设定的权重值来进行轮询,同时还考虑后端服务器的实际负载(即连接数)。当权重值相同时,当前连接数越小的后端服务器被轮询到的次数(概率)也越高。 rr:按照访问顺序依次将外部请求依序分发到后端服务器。 StickySession String 是 是否开启会话保持,取值: on | off StickySessionType String 否 cookie的处理方式。取值: insert:植入Cookie。 客户端第一次访问时,负载均衡会在返回请求中植入Cookie(即在HTTP/HTTPS响应报文中插入SERVERID),下次客户端携带此Cookie访问,负载均衡服务会将请求定向转发给之前记录到的后端服务器上。 server:重写Cookie。 负载均衡发现用户自定义了Cookie,将会对原来的Cookie进行重写,下次客户端携带新的Cookie访问,负载均衡服务会将请求定向转发给之前记录到的后端服务器。 说明 当StickySession的值为on时,必须指定该参数。 CookieTimeout Integer 否 Cookie超时时间。取值: 1-86400(秒) 说明 当StickySession为on且StickySessionType为insert时,该参数必选。 Cookie String 否 服务器上配置的Cookie。 长度为1-200个字符,只能包含ASCII英文字母和数字字符,不能包含逗号、分号或空格,也不能以$开头。 当StickySession为on且StickySessionType为server时,该参数必选。 HealthCheck String 是 是否开启健康检查。取值: on | off HealthCheckDomain String 否 用于健康检查的域名,取值: $_ip: 后端服务器的私网IP。当指定了IP或该参数未指定时,负载均衡会使用各后端服务器的私网IP当做健康检查使用的域名。 domain:域名长度为1-80字符,只能包含字母、数字、点号(.)和连字符(-)。 HealthCheckURI String 否 用于健康检查的URI。 HealthCheckConnectPort Integer 否 健康检查使用的端口。取值: 1-65535:健康检查的后端服务器的端口。 HealthyThreshold Integer 否 健康检查连续成功多少次后,将后端服务器的健康检查状态由fail判定为success。 取值:2-10 UnhealthyThreshold Integer 否 健康检查连续失败多少次后,将后端服务器的健康检查状态由success判定为fail。 取值:2-10 HealthCheckTimeout Integer 否 接收来自运行状况检查的响应需要等待的时间。如果后端ECS在指定的时间内没有正确响应,则判定为健康检查失败。 取值:1-300(秒) 说明 如果HealthCHeckTimeout的值小于HealthCheckInterval的值,则HealthCHeckTimeout无效,超时时间为HealthCheckInterval的值。 HealthCheckInterval Integer 否 健康检查的时间间隔。 取值:1-50(秒) HealthCheckHttpCode String 否 健康检查正常的HTTP状态码,多个状态码用逗号分隔。 取值:http_2xx(默认值) | http_3xx | http_4xx | http_5xx Gzip String 否 是否开启Gzip压缩,对特定文件类型进行压缩。 取值:on(默认值)| off 返回参数 名称 类型 说明 RequestId String 请求ID。 示例 请求示例 https://slb.aliyuncs.com/?Action=CreateLoadBalancerHTTPListener &LoadBalancerId=lb-t4nj5vuz8ish9emfk1f20 &ListenerPort=80 &BackendServerPort=80 &Bandwidth=-1 &HealthCheck=on &HealthCheckDomain=$_ip &HealthCheckURI=/test/index.html &HealthCheckConnectPort=8080 &HealthyThreshold=4 &UnhealthyThreshold=4 &HealthCheckTimeout=3 &HealthCheckInterval=5 &VServerGroupId=rsp-cige6j5e7p &公共请求参数 返回示例 XML格式 <?xml version="1.0" encoding="UTF-8"?> <CreateLoadBalancerHTTPListenerResponse> <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId> </CreateLoadBalancerHTTPListenerResponse> JSON格式 { "RequestId": " CEF72CEB-54B6-4AE8-B225-F876FF7BA984" }

2019-12-01 23:10:40 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

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

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

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

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

2019-12-01 23:14:00 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

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

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

2019-12-01 23:14:00 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

2019-12-01 23:14:02 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

2019-12-01 23:14:02 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档在OSS中,操作的基本数据单元是文件(Object)。OSS Python SDK提供了丰富的文件上传方式: 简单上传:文件最大不能超过5GB。追加上传:文件最大不能超过5GB。断点续传上传:支持并发、断点续传、自定义分片大小。大文件上传推荐使用断点续传。最大不能超过48.8TB。分片上传:当文件较大时,可以使用分片上传,最大不能超过48.8TB。 说明:各种上传方式的适用场景请参见开发指南中的上传文件。 上传过程中,您还可以通过进度条功能查看上传进度。上传完成后,您还可以进行上传回调。 简单上传通过bucket.put_object方法上传文件。上传方法支持多种类型的输入源,输入源有如下几种类型: 类型 上传方式 字符串 直接上传 Bytes 直接上传 Unicode 自动转换为UTF-8编码的Bytes进行上传 本地文件 文件对象(File Object),必须以二进制方式打开(如“rb”模式) 网络流 可迭代对象(Iterable),以Chunked Encoding的方式上传 上传字符串以下代码用于上传字符串: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 返回值。result = bucket.put_object('<yourObjectName>', 'content of object')# HTTP返回码。print('http status: {0}'.format(result.status))# 请求ID。请求ID是请求的唯一标识,强烈建议在程序日志中添加此参数。print('request_id: {0}'.format(result.request_id))# ETag是put_object方法返回值特有的属性。print('ETag: {0}'.format(result.etag))# HTTP响应头部。print('date: {0}'.format(result.headers['date'])) 上传Bytes以下代码用于上传Bytes: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', b'content of object') 上传Unicode以下代码用于上传Unicode: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')bucket.put_object('<yourObjectName>', u'content of object') 上传本地文件以下代码用于上传本地文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 必须以二进制的方式打开文件,因为需要知道文件包含的字节数。with open('<yourLocalFile>', 'rb') as fileobj: # Seek方法用于指定从第1000个字节位置开始读写。上传时会从您指定的第1000个字节位置开始上传,直到文件结束。 fileobj.seek(1000, os.SEEK_SET) # Tell方法用于返回当前位置。 current = fileobj.tell() bucket.put_object('<yourObjectName>', fileobj) Python SDK还提供了一个更加便捷的方法用于上传本地文件: bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>') 上传网络流以下代码用于上传网络流: # -*- coding: utf-8 -*-import oss2import requests# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# requests.get返回的是一个可迭代对象(Iterable),此时Python SDK会通过Chunked Encoding方式上传。input = requests.get('http://www.aliyun.com')bucket.put_object('<yourObjectName>', input) 追加上传以下代码用于追加上传文件: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 设置首次上传的追加位置(Position参数)为0。result = bucket.append_object('<yourObjectName>', 0, 'content of first append')# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。bucket.append_object('<yourObjectName>', result.next_position, 'content of second append') 如果文件已经存在,如下两种情况将会抛出异常: 不是可追加文件,则抛出ObjectNotAppendable异常。是可追加文件,但设置的追加位置和文件当前长度不等,则抛出PositionNotEqualToLength异常。 断点续传上传断点续传上传将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。 您可以通过oss2.resumable_upload方法断点续传上传指定文件,该方法包含以下参数: 参数 描述 是否必需 默认值 bucket 存储空间名称 是 无 key 文件名称 是 无 filename 待上传的本地文件名称 是 无 store 指定保存断点信息的目录 否 HOME目录下建立的.py-oss-upload目录 headers HTTP头部 否 无 multipart_threshold 文件长度大于该值时,则用分片上传 否 10MB part_size 分片大小 否 自动计算 progress_callback 上传进度回调函数 否 无 num_threads 并发上传的线程数 否 1 以下代码用于断点续传上传: # -*- coding: utf-8 -*-import oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当文件长度大于或等于可选参数multipart_threshold(默认值为10MB)时,会使用分片上传。如未使用参数store指定目录,则会在HOME目录下建立.py-oss-upload目录来保存断点信息。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>') Python SDK 2.1.0以上版本支持设置可选参数进行断点续传上传,代码如下: # 如使用store指定了目录,则保存断点信息在指定目录中。如使用num_threads设置上传并发数,请将oss2.defaults.connection_pool_size设成大于或等于线程数。默认线程数为1。oss2.resumable_upload(bucket, '<yourObjectName>', '<yourLocalFile>', store=oss2.ResumableStore(root='/tmp'), multipart_threshold=100*1024, part_size=100*1024, num_threads=4) 断点续传详情请参见开发指南中的断点续传。 分片上传分片上传(Multipart Upload)分为以下三个步骤: 初始化(bucket.init_multipart_upload):获得Upload ID。上传分片(bucket.upload_part):上传分片数据。这一步可以并发进行。完成上传(bucket.complete_multipart_upload):所有分片上传完成后,合并分片,生成OSS文件。 以下代码用于分片上传文件: # -*- coding: utf-8 -*-import osfrom oss2 import SizedFileAdapter, determine_part_sizefrom oss2.models import PartInfoimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')key = '<yourObjectName>'filename = '<yourLocalFile>'total_size = os.path.getsize(filename)# determine_part_size方法用来确定分片大小。part_size = determine_part_size(total_size, preferred_size=100 * 1024)# 初始化分片。upload_id = bucket.init_multipart_upload(key).upload_idparts = []# 逐个上传分片。with open(filename, 'rb') as fileobj: part_number = 1 offset = 0 while offset < total_size: num_to_upload = min(part_size, total_size - offset) # SizedFileAdapter(fileobj, size)方法会生成一个新的文件对象,重新计算起始追加位置。 result = bucket.upload_part(key, upload_id, part_number, SizedFileAdapter(fileobj, num_to_upload)) parts.append(PartInfo(part_number, result.etag)) offset += num_to_upload part_number += 1# 完成分片上传。bucket.complete_multipart_upload(key, upload_id, parts)# 验证分片上传。with open(filename, 'rb') as fileobj: assert bucket.get_object(key).read() == fileobj.read() 进度条进度条用于指示上传或下载的进度。下面的代码以bucket.put_object方法为例,介绍如何使用进度条。 # -*- coding: utf-8 -*-from __future__ import print_functionimport os, sysimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 当无法确定待上传的数据长度时,total_bytes的值为None。def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end='') sys.stdout.flush()# progress_callback为可选参数,用于实现进度条功能。bucket.put_object('<yourObjectName>', 'a'*1024*1024, progress_callback=percentage) 进度条的完整示例代码请参见GitHub。 上传回调以下代码用于上传回调: # -*- coding: utf-8 -*-import jsonimport base64import osimport oss2# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')# Endpoint以杭州为例,其它Region请按实际情况填写。bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')# 准备回调参数。callback_dict = {}# 设置回调请求的服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。callback_dict['callbackUrl'] = 'http://oss-demo.aliyuncs.com:23450'# 设置回调请求消息头中Host的值, 如oss-cn-hangzhou.aliyuncs.com。callback_dict['callbackHost'] = 'oss-cn-hangzhou.aliyuncs.com'# 设置发起回调时请求body的值。callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}'# 设置发起回调请求的Content-Type。callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded'# 回调参数是Json格式,并且需要Base64编码。callback_param = json.dumps(callback_dict).strip()base64_callback_body = base64.b64encode(callback_param)# 回调参数编码后放在Header中发送给OSS。headers = {'x-oss-callback': base64_callback_body}# 上传并回调。result = bucket.put_object('<yourObjectName>', 'a'*1024*1024, headers) put_object、put_object_from_file、complete_multipart_upload支持上传回调功能。上传回调的详细说明请参见API参考中的上传回调。上传回调的完整示例代码请参见GitHub。

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

回答

详细解答可以参考官方帮助文档 修改TCP监听的配置。 请求参数 名称 类型 是否必须 描述 Action String 是 要执行的操作。取值: SetLoadBalancerTCPListenerAttribute RegionId String 是 负载均衡实例的地域。 您可以通过调用 DescribeRegions接口获取地域ID。 LoadBalancerId String 是 负载均衡实例ID。 ListenerPort Integer 是 负载均衡实例前端使用的端口,取值: 1-65535 VServerGroupId String 否 服务器组ID。 MasterSlaveServerGroupId String 否 主备服务器组ID。 说明 VServerGroupId和MasterSlaveServerGroupId参数不能同时指定。 Bandwidth Integer 是 监听的带宽峰值,取值: -1:不限制带宽峰值。 [1-5000]:监听的带宽峰值,所有监听的带宽峰值之和不能超过实例的带宽峰值。 Scheduler String 否 调度算法。取值: wrr(默认值):权重值越高的后端服务器,被轮询到的次数(概率)也越高。 wlc:除了根据每台后端服务器设定的权重值来进行轮询,同时还考虑后端服务器的实际负载(即连接数)。当权重值相同时,当前连接数越小的后端服务器被轮询到的次数(概率)也越高。 rr:按照访问顺序依次将外部请求依序分发到后端服务器。 sch:基于源IP地址的一致性hash,相同的源地址会调度到相同的后端服务器。 tch:基于四元组的一致性hash(源IP+目的IP+源端口+目的端口),相同的流会调度到相同的后端服务器。 说明 仅有性能保障型实例支持sch和tch和一致性hash算法。 PersistenceTimeout Integer 否 会话保持的超时时间。 取值:0-3600(秒) 默认值为0,关闭会话保持。 EstablishedTimeout Integer 否 连接超时时间。 取值:10-900(秒) AclStatus String 否 是否开启访问控制功能。 取值:on | off(默认值) AclType String 否 访问控制类型: white: 仅转发来自所选访问控制策略组中设置的IP地址或地址段的请求,白名单适用于应用只允许特定IP访问的场景。 设置白名单存在一定业务风险。一旦设置白名单,就只有白名单中的IP可以访问负载均衡监听。如果开启了白名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 black: 来自所选访问控制策略组中设置的IP地址或地址段的所有请求都不会转发,黑名单适用于应用只限制某些特定IP访问的场景。 如果开启了黑名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 当AclStatus参数的值为on时,该参数必选。 AclId String 否 监听绑定的访问策略组ID。 当AclStatus参数的值为on时,该参数必选。 HealthCheckType String 否 健康检查类型。 取值:tcp(默认值) | http HealthCheckDomain String 否 用于健康检查的域名,取值: $_ip: 后端服务器的私网IP。当指定了IP或该参数未指定时,负载均衡会使用各后端服务器的私网IP当做健康检查使用的域名。 domain:域名长度为1-80字符,只能包含字母、数字、点号(.)和连字符(-)。 说明 当健康检查类型为TCP模式时,无需配置该参数。 HealthCheckURI String 否 用于健康检查的URI。 说明 当健康检查类型为TCP模式时,无需配置该参数。 HealthCheckConnectPort Integer 否 健康检查使用的端口。取值: 1-65535:健康检查的后端服务器的端口。 HealthyThreshold Integer 否 健康检查连续成功多少次后,将后端服务器的健康检查状态由fail判定为success。 取值:2-10 UnhealthyThreshold Integer 否 健康检查连续失败多少次后,将后端服务器的健康检查状态由success判定为fail。 取值:2-10 HealthCheckConnectTimeout Integer 否 接收来自运行状况检查的响应需要等待的时间。如果后端ECS在指定的时间内没有正确响应,则判定为健康检查失败。 取值:1-300(秒) 说明 如果HealthCheckConnectTimeout的值小于HealthCheckInterval的值,则HealthCheckConnectTimeout无效,超时时间为HealthCheckInterval的值。 HealthCheckInterval Integer 否 健康检查的时间间隔。 取值:1-50(秒) HealthCheckHttpCode String 否 健康检查正常的HTTP状态码,多个状态码用逗号分隔。 取值:http_2xx(默认值) | http_3xx | http_4xx | http_5xx SynProxy String 否 是否开启SynProxy,SynProxy是负载均衡的攻击防护功能。 建议一般情况下不要调整这个参数,由负载均衡控制。 取值:enable|disable(默认值) VServerGroup String 否 是否使用虚拟服务器组。 取值:on|off(默认值) 说明 VserverGroup和MasterSlaveServerGroup只允许一个值为on。 PersistenceTimeout Integer 否 会话保持的超时时间。 取值:0-3600(秒) 默认值为0,关闭会话保持。 MasterSlaveServerGroup 是否使用主备服务器组。 取值:on|off(默认值) 说明 VserverGroup和MasterSlaveServerGroup只允许一个值为on。 返回参数 名称 类型 说明 RequestId String 请求ID。 示例 请求示例 https://slb.aliyuncs.com/?Action=SetLoadBalancerTCPListenerAttribute &LoadBalancerId=lb-t4nj5vuz8ish9emfk1f20 &ListenerPort=443 &Bandwidth=-1 &VServerGroupId=rsp-cige6j5e7p &公共请求参数 返回示例 XML格式 <?xml version="1.0" encoding="UTF-8"?> <SetLoadBalancerTCPListenerAttributeResponse> <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId> </SetLoadBalancerTCPListenerAttributeResponse> JSON格式 { "RequestId": " CEF72CEB-54B6-4AE8-B225-F876FF7BA984" }

2019-12-01 23:10:41 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 修改TCP监听的配置。 请求参数 名称 类型 是否必须 描述 Action String 是 要执行的操作。取值: SetLoadBalancerTCPListenerAttribute RegionId String 是 负载均衡实例的地域。 您可以通过调用 DescribeRegions接口获取地域ID。 LoadBalancerId String 是 负载均衡实例ID。 ListenerPort Integer 是 负载均衡实例前端使用的端口,取值: 1-65535 VServerGroupId String 否 服务器组ID。 MasterSlaveServerGroupId String 否 主备服务器组ID。 说明 VServerGroupId和MasterSlaveServerGroupId参数不能同时指定。 Bandwidth Integer 是 监听的带宽峰值,取值: -1:不限制带宽峰值。 [1-5000]:监听的带宽峰值,所有监听的带宽峰值之和不能超过实例的带宽峰值。 Scheduler String 否 调度算法。取值: wrr(默认值):权重值越高的后端服务器,被轮询到的次数(概率)也越高。 wlc:除了根据每台后端服务器设定的权重值来进行轮询,同时还考虑后端服务器的实际负载(即连接数)。当权重值相同时,当前连接数越小的后端服务器被轮询到的次数(概率)也越高。 rr:按照访问顺序依次将外部请求依序分发到后端服务器。 sch:基于源IP地址的一致性hash,相同的源地址会调度到相同的后端服务器。 tch:基于四元组的一致性hash(源IP+目的IP+源端口+目的端口),相同的流会调度到相同的后端服务器。 说明 仅有性能保障型实例支持sch和tch和一致性hash算法。 PersistenceTimeout Integer 否 会话保持的超时时间。 取值:0-3600(秒) 默认值为0,关闭会话保持。 EstablishedTimeout Integer 否 连接超时时间。 取值:10-900(秒) AclStatus String 否 是否开启访问控制功能。 取值:on | off(默认值) AclType String 否 访问控制类型: white: 仅转发来自所选访问控制策略组中设置的IP地址或地址段的请求,白名单适用于应用只允许特定IP访问的场景。 设置白名单存在一定业务风险。一旦设置白名单,就只有白名单中的IP可以访问负载均衡监听。如果开启了白名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 black: 来自所选访问控制策略组中设置的IP地址或地址段的所有请求都不会转发,黑名单适用于应用只限制某些特定IP访问的场景。 如果开启了黑名单访问,但访问策略组中没有添加任何IP,则负载均衡监听会转发全部请求。 当AclStatus参数的值为on时,该参数必选。 AclId String 否 监听绑定的访问策略组ID。 当AclStatus参数的值为on时,该参数必选。 HealthCheckType String 否 健康检查类型。 取值:tcp(默认值) | http HealthCheckDomain String 否 用于健康检查的域名,取值: $_ip: 后端服务器的私网IP。当指定了IP或该参数未指定时,负载均衡会使用各后端服务器的私网IP当做健康检查使用的域名。 domain:域名长度为1-80字符,只能包含字母、数字、点号(.)和连字符(-)。 说明 当健康检查类型为TCP模式时,无需配置该参数。 HealthCheckURI String 否 用于健康检查的URI。 说明 当健康检查类型为TCP模式时,无需配置该参数。 HealthCheckConnectPort Integer 否 健康检查使用的端口。取值: 1-65535:健康检查的后端服务器的端口。 HealthyThreshold Integer 否 健康检查连续成功多少次后,将后端服务器的健康检查状态由fail判定为success。 取值:2-10 UnhealthyThreshold Integer 否 健康检查连续失败多少次后,将后端服务器的健康检查状态由success判定为fail。 取值:2-10 HealthCheckConnectTimeout Integer 否 接收来自运行状况检查的响应需要等待的时间。如果后端ECS在指定的时间内没有正确响应,则判定为健康检查失败。 取值:1-300(秒) 说明 如果HealthCheckConnectTimeout的值小于HealthCheckInterval的值,则HealthCheckConnectTimeout无效,超时时间为HealthCheckInterval的值。 HealthCheckInterval Integer 否 健康检查的时间间隔。 取值:1-50(秒) HealthCheckHttpCode String 否 健康检查正常的HTTP状态码,多个状态码用逗号分隔。 取值:http_2xx(默认值) | http_3xx | http_4xx | http_5xx SynProxy String 否 是否开启SynProxy,SynProxy是负载均衡的攻击防护功能。 建议一般情况下不要调整这个参数,由负载均衡控制。 取值:enable|disable(默认值) VServerGroup String 否 是否使用虚拟服务器组。 取值:on|off(默认值) 说明 VserverGroup和MasterSlaveServerGroup只允许一个值为on。 PersistenceTimeout Integer 否 会话保持的超时时间。 取值:0-3600(秒) 默认值为0,关闭会话保持。 MasterSlaveServerGroup 是否使用主备服务器组。 取值:on|off(默认值) 说明 VserverGroup和MasterSlaveServerGroup只允许一个值为on。 返回参数 名称 类型 说明 RequestId String 请求ID。 示例 请求示例 https://slb.aliyuncs.com/?Action=SetLoadBalancerTCPListenerAttribute &LoadBalancerId=lb-t4nj5vuz8ish9emfk1f20 &ListenerPort=443 &Bandwidth=-1 &VServerGroupId=rsp-cige6j5e7p &公共请求参数 返回示例 XML格式 <?xml version="1.0" encoding="UTF-8"?> <SetLoadBalancerTCPListenerAttributeResponse> <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId> </SetLoadBalancerTCPListenerAttributeResponse> JSON格式 { "RequestId": " CEF72CEB-54B6-4AE8-B225-F876FF7BA984" }

2019-12-01 23:10:41 0 浏览量 回答数 0

问题

支付宝的性能测试

云效平台 2019-12-01 21:47:13 5472 浏览量 回答数 1

问题

IIS7.5安装配置UrlScan3.1应用防火墙

虎笑 2019-12-01 21:00:19 11275 浏览量 回答数 2

问题

API调用方式

云栖大讲堂 2019-12-01 21:07:55 1412 浏览量 回答数 0

回答

Java之JVM垃圾回收 内存结构以及垃圾回收算法前言:由于小组技术分享的需要,懂的不是很多所以我就找了这个我自己感兴趣的知识点给大家做个简单的介绍。由于是新人,算不了很懂,只是总结性的讲了些概念性的东西。给大家分享的同时,算是给自己做个笔记吧。作为Java语言的核心之一,JVM垃圾回收帮我们解决了让我们很头疼的垃圾回收问题。我们不需要像VC++一样,作为内存管理的统治者需要我们对我们分配的每一块内存进行回收,否则就会造成内存泄露问题。是不是只要有JVM存在我们就不会出现内存泄露问题,出现内存泄露问题我们又该怎么办,如果我们想提高我们程序的稳定性和其他性能我们能从什么地方下手!!!相信这些问题是我们程序过程中不可逾越的。了解JVM的内存分配及其相应的垃圾回收机制,不仅仅是可以了解底层的JVM运行机制,而且对于程序性能的优化和提升还是很有必要的。一、JVM内存分配区域结构图一从图一可以看出JVM中的内存分配包括PC Register(PC寄存器) JVM栈 堆(Heap) 方法区域(MethodArea)运行时常量池(RuntimeConstant Pool) 本地方法堆栈(NativeMethod Stacks),这几部分区域但是从程序员的角度来看我们只关注JVM Heap和JVM Stack,因为这两部分是直接关系程序运行期间的内存状态,所以我会主要介绍这两部分内存,其他的我只是给出了简单的一些概念性解释:PC Register(Program Counter 寄存器):主要作用是记录当前线程所执行的字节码的行号。方法区域(MethodArea):方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,法区域也是全局共享的,它在虚拟机启动时在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。运行时常量池(RuntimeConstant Pool):存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。本地方法堆栈(NativeMethod Stacks):JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。JVM栈:主要存放一些基本类型的变量和对象的引用变量。JVM堆:用来存放由 new 创建的对象和数组Java 虚拟机的自动垃圾回收器来管理(注意数组也是对象,所以说数组也是存放在JVM堆中)。由于栈中存放的是主要存放一些基本类型的变量和对象的引用变量,所以当过了变量的作用区域或者是当程序运行结束后它所占用的内存会自动的释放掉,所以不用来关心,下面我们主要来说的是堆内存的分配以及回收的算法。二、JVM堆内存介绍工欲善其事,必先利其器。所以了解堆内存的内部结构是很必要的。在Jvm中堆空间划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)。年轻带主要是动态的存储,年轻带主要储存新产生的对象,年老代储存年龄大些的对象,永久带主要是存储的是java的类信息,包括解析得到的方法、属性、字段等。永久带基本不参与垃圾回收。所以说我们说的垃圾回收主要是针对年轻代和年老代。图二年轻代又分成3个部分,一个eden区和两个相同的survior区。刚开始创建的对象都是放置在eden区的。分成这样3个部分,主要是为了生命周期短的对象尽量留在年轻带。当eden区申请不到空间的时候,进行minorGC,把存活的对象拷贝到survior。年老代主要存放生命周期比较长的对象,比如缓存对象。(经过IBM的一个研究机构研究数据表明,基本上80%-98%的对象都会在年轻代的Eden区死掉从而本回收掉,所以说真正进入到老年代的对象很少,这也是为什么MinorGC比MajorGC更加频繁的原因)具体JVM内存垃圾回收过程描述如下 :1、对象在Eden区完成内存分配2、当Eden区满了,再创建对象,会因为申请不到空间,触发minorGC,进行young(eden+1survivor)区的垃圾回收3、minorGC时,Eden不能被回收的对象被放入到空的survivor(Eden肯定会被清空),另一个survivor里不能被GC回收的对象也会被放入这个survivor,始终保证一个survivor是空的4、当做第3步的时候,如果发现survivor满了,则这些对象被copy到old区,或者survivor并没有满,但是有些对象已经足够Old,也被放入Old区 XX:MaxTenuringThreshold5、当Old区被放满的之后,进行fullGC补充: MinorGC:年轻代所进行的垃圾回收,非常频繁,一般回收速度也比较快。 MajorGC:老年代进行的垃圾回收,发生一次MajorGC至少伴随一次MinorGC,一般比MinorGC速度慢十倍以上。 FullGC:整个堆内存进行的垃圾回收,很多时候是MajorGC 以后就是堆内存结构已经大致的垃圾回收过程。三、对象分配原则1.对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC。2.大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。3.长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,知道达到阀值对象进入老年区。4.动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。5.空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于检查HandlePromotionFailure设置,如果true则只进行Monitor GC,如果false则进行Full GC。四、垃圾收集器作为JVM中的核心之一垃圾收集器,主要完成的功能包括:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。所以说我们在实现垃圾收集器的同时就要实现两个算法一个是发现无用的对象第二就是回收该对象的内存。收集器主要分为引用计数器和跟踪收集器两种,Sun JDK中采用跟踪收集器作为GC实现策略。发现无用对象只要的实现算法包括引用计数法和根搜索算法,引用计数法主要是JVM的早期实现方法,因为引用计数无法解决循环引用的问题,所以现在JVM实现的主要是根搜索算法,引用计数法:堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器每次加1当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就不可用从而可以被回收。 根搜索算法:通过一系列的名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。目前的收集器主要有三种:串行收集器:使用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高并行收集器:对年轻代进行并行垃圾回收,因此可以减少垃圾回收时间。一般在多线程多处理器机器上使用并发收集器:可以保证大部分工作都并发进行(应用不停止),垃圾回收只暂停很少的时间,此收集器适合对响应时间要求比较高的中、大规模应用五、垃圾收集器的回收算法Copying算法:算法:复制采用的方式为从根集合扫描出存活的对象,并将找到的存活对象复制到一块新的完全未使用的空间中。 过程: 此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不过出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。Mark-Sweep算法: 算法:标记-清除采用的方式为从根集合开始扫描,对存活的对象进行标记,标记完毕后,再扫描整个空间中未标记的对象,并进行回收。 过程: 第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。它停止所有工作,收集器从根开始访问每一个活跃的节点,标记它所访问的每一个节点。走过所有引用后,收集就完成了,然后就对堆进行清除(即对堆中的每一个对象进行检查),所有没有标记的对象都作为垃圾回收并返回空闲列表。Mark-Compact算法: 算法:标记阶段与“Mark-Sweep”算法相同,但在清除阶段有所不同。在回收不存活对象所占用的内存空间后,会将其他所有存活对象都往左端空闲的空间进行移动,并更新引用其对象指针。过程:此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。Sun JDK GC策略:新生代算法实现:Copying,Copying,Copying旧生代算发实现:Mark-Sweep-Compact,Mark –Compact,Mark –Sweep!!六、JvisuaVM 工具如果我们想优化自己的程序,那么我们就必须清楚的了解不同代码程序所消耗的性能多少,作为JDK的一部分,这个工具给我们提供了很大的帮助。这个工具可以在JDK的bin目录下找到,功能很强大,可以注意利用

auto_answer 2019-12-02 01:56:35 0 浏览量 回答数 0

问题

后端服务器ECS常见问题

行者武松 2019-12-01 21:43:14 3357 浏览量 回答数 0

回答

1.阻塞与同步2.BIO与NIO对比3.NIO简介4.缓冲区Buffer5.通道Channel6.反应堆7.选择器8.NIO源码分析9.AIO1.阻塞与同步1)阻塞(Block)和非租塞(NonBlock):阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,当数据没有准备的时候阻塞:往往需要等待缞冲区中的数据准备好过后才处理其他的事情,否則一直等待在那里。非阻塞:当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,不会等待。如果数据已经准备好,也直接返回2)同步(Synchronization)和异步(Async)的方式:同步和异步都是基于应用程序私操作系统处理IO事件所采用的方式,比如同步:是应用程序要直接参与IO读写的操作。异步:所有的IO读写交给搡作系统去处理,应用程序只需要等待通知。同步方式在处理IO事件的时候,必须阻塞在某个方法上靣等待我们的IO事件完成(阻塞IO事件或者通过轮询IO事件的方式).对于异步来说,所有的IO读写都交给了搡作系统。这个时候,我们可以去做其他的事情,并不拓要去完成真正的IO搡作,当搡作完成IO后.会给我们的应用程序一个通知同步:阻塞到IO事件,阻塞到read成则write。这个时候我们就完全不能做自己的事情,让读写方法加入到线程里面,然后阻塞线程来实现,对线程的性能开销比较大,参考:https://blog.csdn.net/CharJay_Lin/article/details/812598802.BIO与NIO对比block IO与Non-block IO1)区别IO模型 IO NIO方式 从硬盘到内存 从内存到硬盘通信 面向流(乡村公路) 面向缓存(高速公路,多路复用技术)处理 阻塞IO(多线程) 非阻塞IO(反应堆Reactor)触发 无 选择器(轮询机制)2)面向流与面向缓冲Java NIO和IO之间第一个最大的区别是,IO是面向流的.NIO是面向缓冲区的。Java IO面向流意味着毎次从流中读一个成多个字节,直至读取所有字节,它们没有被缓存在任何地方,此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的教据,需要先将它缓存到一个缓冲区。Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,霱要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数裾。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。3)阻塞与非阻塞Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。4)选择器(Selector)Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择"通道:这些通里已经有可以处理的褕入,或者选择已准备写入的通道。这选怿机制,使得一个单独的线程很容易来管理多个通道。5)NIO和BIO读取文件BIO读取文件:链接BIO从一个阻塞的流中一行一行的读取数据image | left | 469x426NIO读取文件:链接通道是数据的载体,buffer是存储数据的地方,线程每次从buffer检查数据通知给通道image | left | 559x3946)处理数据的线程数NIO:一个线程管理多个连接BIO:一个线程管理一个连接3.NIO简介在Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据,面向流的I/O速度非常慢,而在Java 1.4中推出了NIO,这是一个面向块的I/O系统,系统以块的方式处理处理,每一个操作在一步中产生或者消费一个数据库,按块处理要比按字节处理数据快的多。在NIO中有几个核心对象需要掌握:缓冲区(Buffer)、通道(Channel)、选择器(Selector)。参考:链接image2.png | center | 851x3834.缓冲区Buffer缓冲区实际上是一个容器对象,更直接的说,其实就是一个数组,在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的; 在写入数据时,它也是写入到缓冲区中的;任何时候访问 NIO 中的数据,都是将它放到缓冲区中。而在面向流I/O系统中,所有数据都是直接写入或者直接将数据读取到Stream对象中。在NIO中,所有的缓冲区类型都继承于抽象类Buffer,最常用的就是ByteBuffer,对于Java中的基本类型,基本都有一个具体Buffer类型与之相对应,它们之间的继承关系如下图所示:image3.png | center | 650x3681)其中的四个属性的含义分别如下:容量(Capacity):缓冲区能够容纳的数据元素的最大数量。这一个容量在缓冲区创建时被设定,并且永远不能改变。上界(Limit):缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。位置(Position):下一个要被读或写的元素的索引。位置会自动由相应的 get( )和 put( )函数更新。标记(Mark):下一个要被读或写的元素的索引。位置会自动由相应的 get( )和 put( )函数更新。2)Buffer的常见方法如下所示:flip(): 写模式转换成读模式rewind():将 position 重置为 0 ,一般用于重复读。clear() :compact(): 将未读取的数据拷贝到 buffer 的头部位。mark(): reset():mark 可以标记一个位置, reset 可以重置到该位置。Buffer 常见类型: ByteBuffer 、 MappedByteBuffer 、 CharBuffer 、 DoubleBuffer 、 FloatBuffer 、 IntBuffer 、 LongBuffer 、 ShortBuffer 。3)基本操作Buffer基础操作: 链接缓冲区分片,缓冲区分配,直接缓存区,缓存区映射,缓存区只读:链接4)缓冲区存取数据流程存数据时position会++,当停止数据读取的时候调用flip(),此时limit=position,position=0读取数据时position++,一直读取到limitclear() 清空 buffer ,准备再次被写入 (position 变成 0 , limit 变成 capacity) 。5.通道Channel通道是一个对象,通过它可以读取和写入数据,当然了所有数据都通过Buffer对象来处理。我们永远不会将字节直接写入通道中,相反是将数据写入包含一个或者多个字节的缓冲区。同样不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。image4.png | center | 368x191在NIO中,提供了多种通道对象,而所有的通道对象都实现了Channel接口。它们之间的继承关系如下图所示:image5.png | center | 650x5171)使用NIO读取数据在前面我们说过,任何时候读取数据,都不是直接从通道读取,而是从通道读取到缓冲区。所以使用NIO读取数据可以分为下面三个步骤:从FileInputStream获取Channel 创建Buffer 将数据从Channel读取到Buffer中 例子:链接 2)使用NIO写入数据使用NIO写入数据与读取数据的过程类似,同样数据不是直接写入通道,而是写入缓冲区,可以分为下面三个步骤:从FileInputStream获取Channel 创建Buffer 将数据从Channel写入到Buffer中 例子:链接 6.反应堆1)阻塞IO模型在老的IO包中,serverSocket和socket都是阻塞式的,因此一旦有大规模的并发行为,而每一个访问都会开启一个新线程。这时会有大规模的线程上下文切换操作(因为都在等待,所以资源全都被已有的线程吃掉了),这时无论是等待的线程还是正在处理的线程,响应率都会下降,并且会影响新的线程。image6.png | center | 739x3362)NIOJava NIO是在jdk1.4开始使用的,它既可以说成“新IO”,也可以说成非阻塞式I/O。下面是java NIO的工作原理:1.由一个专门的线程来处理所有的IO事件,并负责分发。2.事件驱动机制:事件到的时候触发,而不是同步的去监视事件。3.线程通讯:线程之间通过wait,notify等方式通讯。保证每次上下文切换都是有意义的。减少无谓的线程切换。image7.png | center | 689x251注:每个线程的处理流程大概都是读取数据,解码,计算处理,编码,发送响应。7.选择器传统的 server / client 模式会基于 TPR ( Thread per Request ) .服务器会为每个客户端请求建立一个线程.由该线程单独负贵处理一个客户请求。这种模式带未的一个问题就是线程数是的剧增.大量的线程会增大服务器的开销,大多数的实现为了避免这个问题,都采用了线程池模型,并设置线程池线程的最大数量,这又带来了新的问题,如果线程池中有 200 个线程,而有 200 个用户都在进行大文件下载,会导致第 201 个用户的请求无法及时处理,即便第 201 个用户只想请求一个几 KB 大小的页面。传统的 Sorvor / Client 模式如下围所示:image8.png | center | 597x286NIO 中非阻塞IO采用了基于Reactor模式的工作方式,IO调用不会被阻塞,相反是注册感兴趣的特点IO事件,如可读数据到达,新的套接字等等,在发生持定率件时,系统再通知我们。 NlO中实现非阻塞IO的核心设计Selector,Selector就是注册各种IO事件的地方,而且当那些事件发生时,就是这个对象告诉我们所发生的事件。image9.png | center | 462x408当有读或者写等任何注册的事件发生时,可以从Selector中获得相应的SelectionKey,同时从SelectionKey中可以找到发生的事件和该事件所发生的具体的SelectableChannel,以获得客户端发送过来的数据。使用NIO中非阻塞IO编写服务器处理程序,有三个步骤1.向Selector对象注册感兴趣的事件2.从Selector中获取感兴趣的事件3.根据不同事件进行相应的处理8.NIO源码分析Selector是NIO的核心epool模型1)SelectorSelector的open()方法:链接2)ServerSocketChannelServerSocketChannel.open() 链接9.AIOAsynchronous IO异步非阻塞IOBIO ServerSocketNIO ServerSocketChannelAIO AsynchronousServerSocketChannel

wangccsy 2019-12-02 01:46:51 0 浏览量 回答数 0

回答

MongoDB ACID事务支持 这里要有一定的关系型数据库的事务的概念,不然不一定能理解的了这里说的事务概念。 下面说一说MongoDB的事务支持,这里可能会有疑惑,前面我们在介绍MongoDB时,说MongoDB是一个NoSQL数据库,不支持事务。这里又介绍MongoDB的事务。这里要说明一下MongoDB的事务支持跟关系型数据库的事务支持是两码事,如果你已经非常了解关系型数据库的事务,通过下面一副图对比MongoDB事务跟MySQL事务的不同之处。 MongoDB是如何实现事务的ACID? 1)MongoDB对原子性(Atomicity)的支持 原子性在Mongodb中到底是一个什么概念呢?为什么说支持但又说Mongodb的原子性是单行/文档级原子性,这里提供了一个MongoDB更新语句样例,如下图: MongoDB是如何实现事务的ACID? 更新“username”等于“tj.tang”的文档,更新salary、jobs、hours字段。这里对于这三个字段Mongodb在执行时要么都更新要么都不更新,这个概念在MySQL中可能你没有考虑过,但在MongoDB中由于文档可以嵌套子文档可以很复杂,所以Mongodb的原子性叫单行/文档级原子性。 对于关系型数据库的多行、多文档、多语句原子性目前Mongodb是不支持的,如下情况: MongoDB是如何实现事务的ACID? MongoDB更新条件为工资小于50万的人都把工资调整为50万,这就会牵扯到多文档更新原子性。如果当更新到Frank这个文档时,出现宕机,服务器重启之后是无法像关系型数据库那样做到数据回滚的,也就是说处理这种多文档关系型数据库事务的支持,但MongoDB不支持。那么怎么解决Mongodb这个问题呢?可以通过建模,MongoDB不是范式而是反范式的设计,通过大表和小表可以把相关的数据放到同一个文档中去。然后通过一条语句来执行操作。 2)MongoDB对一致性(consistency)的支持 对于数据一致性来说,传统数据库(单机)跟分布式数据库(MongoDB)对于数据一致性是不太一样的,怎么理解呢?如下图: MongoDB是如何实现事务的ACID? 对于传统型数据库来说,数据一致性主要是在单机上,单机的问题主要是数据进来时的规则检验,数据不能被破坏掉。而在分布式数据库上,因为他们都是多节点分布式的,我们讲的一致性往往就是讲的各个节点之间的数据是否一致。而MongoDB在这点上做的还是不错的,MongoDB支持强一致性或最终一致性(弱一致性),MongoDB的数据一致性也叫可调一致性,什么意思呢?如下图: MongoDB是如何实现事务的ACID? MongoDB的可调一致性,也就是可以自由选择强一致性或最终一致性,如果你的应用场景是前台的方式可以选择强一致性,如果你的应用场景是后台的方式(如报表)可以选择弱一致性。 一致性 上面我们讲到了通过将数据冗余存储到不同的节点来保证数据安全和减轻负载,下面我们来看看这样做引发的一个问题:保证数据在多个节点间的一致性是非常困难的。在实际应用中我们会遇到很多困难,同步节点可能会故障,甚至会无法恢复,网络可能会有延迟或者丢包,网络原因导致集群中的机器被分隔成两个不能互通的子域等等。在NoSQL中,通常有两个层次的一致性:第一种是强一致性,既集群中的所有机器状态同步保持一致。第二种是最终一致性,既可以允许短暂的数据不一致,但数据最终会保持一致。我们先来讲一下,在分布式集群中,为什么最终一致性通常是更合理的选择,然后再来讨论两种一致性的具体实现结节。 关于CAP理论 为什么我们会考虑削弱数据的一致性呢?其实这背后有一个关于分布式系统的理论依据。这个理论最早被Eric Brewer提出,称为CAP理论,尔后Gilbert和Lynch对CAP进行了理论证明。这一理论首先把分布式系统中的三个特性进行了如下归纳: 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。 分区容忍性(P):集群中的某些节点在无法联系后,集群整体是否还能继续进行服务。 而CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。 要保证数据强一致性,最简单的方法是令写操作在所有数据节点上都执行成功才能返回成功,也就是同步概念。而这时如果某个结点出现故障,那么写操作就成功不了了,需要一直等到这个节点恢复。也就是说,如果要保证强一致性,那么就无法提供7×24的高可用性。 而要保证可用性的话,就意味着节点在响应请求时,不用完全考虑整个集群中的数据是否一致。只需要以自己当前的状态进行请求响应。由于并不保证写操作在所有节点都写成功,这可能会导致各个节点的数据状态不一致。 CAP理论导致了最终一致性和强一致性两种选择。当然,事实上还有其它的选择,比如在Yahoo的PNUTS中,采用的就是松散的一致性和弱可用性结合的方法。但是我们讨论的NoSQL系统没有类似的实现,所以我们在后续不会对其进行讨论。 强一致性 强一致性的保证,要求所有数据节点对同一个key值在同一时刻有同样的value值。虽然实际上可能某些节点存储的值是不一样的,但是作为一个整体,当客户端发起对某个key的数据请求时,整个集群对这个key对应的数据会达成一致。下面就举例说明这种一致性是如何实现的。 假设在我们的集群中,一个数据会被备份到N个结点。这N个节点中的某一个可能会扮演协调器的作用。它会保证每一个数据写操作会在成功同步到W个节点后才向客户端返回成功。而当客户端读取数据时,需要至少R个节点返回同样的数据才能返回读操作成功。而NWR之间必须要满足下面关系:R+W>N 下面举个实在的例子。比如我们设定N=3(数据会备份到A、B、C三个结点)。比如值 employee30:salary 当前的值是20000,我们想将其修改为30000。我们设定W=2,下面我们会对A、B、C三个节点发起写操作(employee30:salary, 30000),当A、B两个节点返回写成功后,协调器就会返回给客户端说写成功了。至于节点C,我们可以假设它从来没有收到这个写请求,他保存的依然是20000那个值。之后,当一个协调器执行一个对employee30:salary的读操作时,他还是会发三个请求给A、B、C三个节点: 如果设定R=1,那么当C节点先返回了20000这个值时,那我们客户端实际得到了一个错误的值。 如果设定R=2,则当协调器收到20000和30000两个值时,它会发现数据不太正确,并且会在收到第三个节点的30000的值后判断20000这个值是错误的。 所以如果要保证强一致性,在上面的应用场景中,我们需要设定R=2,W=2 如果写操作不能收到W个节点的成功返回,或者写操作不能得到R个一致的结果。那么协调器可能会在某个设定的过期时间之后向客户端返回操作失败,或者是等到系统慢慢调整到一致。这可能就导致系统暂时处于不可用状态。 对于R和W的不同设定,会导致系统在进行不同操作时需要不同数量的机器节点可用。比如你设定在所有备份节点上都写入才算写成功,既W=N,那么只要有一个备份节点故障,写操作就失败了。一般设定是R+W = N+1,这是保证强一致性的最小设定了。一些强一致性的系统设定W=N,R=1,这样就根本不用考虑各个节点数据可能不一致的情况了。 HBase是借助其底层的HDFS来实现其数据冗余备份的。HDFS采用的就是强一致性保证。在数据没有完全同步到N个节点前,写操作是不会返回成功的。也就是说它的W=N,而读操作只需要读到一个值即可,也就是说它R=1。为了不至于让写操作太慢,对多个节点的写操作是并发异步进行的。在直到所有的节点都收到了新的数据后,会自动执行一个swap操作将新数据写入。这个操作是原子性和一致性的。保证了数据在所有节点有一致的值。 最终一致性 像Voldemort,Cassandra和Riak这些类Dynamo的系统,通常都允许用户按需要设置N,R,W三个值,即使是设置成W+R<= N也是可以的。也就是说他允许用户在强一致性和最终一致性之间自由选择。而在用户选择了最终一致性,或者是W 3)MongoDB对隔离性(isolation)的支持 在关系型数据库中,SQL2定义了四种隔离级别,分别是READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。但是很少有数据库厂商遵循这些标准,比如Oracle数据库就不支持READ UNCOMMITTED和REPEATABLE READ隔离级别。而MySQL支持这全部4种隔离级别。每一种级别都规定了一个事务中所做的修改,哪些在事务内核事务外是可见的,哪些是不可见的。为了尽可能减少事务间的影响,事务隔离级别越高安全性越好但是并发就越差;事务隔离级别越低,事务请求的锁越少,或者保持锁的时间就越短,这也就是为什么绝大多数数据库系统默认的事务隔离级别是RC。 下图展示了几家不同的数据库厂商的不同事物隔离级别。 MongoDB是如何实现事务的ACID? MongoDB在3.2之前使用的是“读未提交”,这种情况下会出现“脏读”。但在MongoDB 3.2开始已经调整为“读已提交”。 下面说说每种隔离级别带来的问题: READ-UNCOMMITTED(读尚未提交的数据) 在这个级别,一个事务的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为“脏读(dirty read)”。这个级别会导致很多问题,从性能上来说,READ UNCOMMITTED不会比其他的级别好太多,但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用。 READ-COMMITTED(读已提交的数据) 在这个级别,能满足前面提到的隔离性的简单定义:一个事务开始时,只能“看见”已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫“不可重复读(non-repeatable read)”,因为两次执行同样的查询,可能会得到不一样的结果。 REPEATABLE-READ(可重复读) 在这个级别,保证了在同一个事务中多次读取统一记录的结果是一致的。MySQL默认使用这个级别。InnoDB和XtraDB存储引擎通过多版本并发控制MVCC(multiversion concurrency control)解决了“幻读”和“不可重复读”的问题。通过前面的学习我们知道RR级别总是读取事务开始那一刻的快照信息,也就是说这些数据数据库当前状态,这在一些对于数据的时效特别敏感的业务中,就很可能会出问题。 SERIALIZABLE(串行化) 在这个级别,它通过强制事务串行执行,避免了前面说的一系列问题。简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少在本地事务中使用SERIALIABLE隔离级别,主要应用在InnoDB存储引擎的分布式事务中。 4)MongoDB对持久性(durability)的支持 对于数据持久性来说,在传统数据库中(单机)的表现为服务器任何时候发生宕机都不需要担心数据丢失的问题,因为有方式可以把数据永久保存起来了。一般都是通过日志来保证数据的持久性。通过下图来看一下传统数据库跟MongoDB对于数据持久性各自所使用的方式。 MongoDB是如何实现事务的ACID? 从上图可以看出,MongoDB同样是使用数据进来先写日志(日志刷盘的速度是非常快)然后在写入到数据库中的这种方式来保证数据的持久性,如果出现服务器宕机,当启动服务器时会从日志中读取数据。不同的是传统数据库这种方式叫做“WAL” Write-Ahead Logging(预写日志系统),而MongoDB叫做“journal”。此外MongoDB在数据持久性上这点可能做的更好,MongoDB的复制默认节点就是三节点以上的复制集群,当数据到达主节点之后会马上同步到从节点上去。

景凌凯 2019-12-02 02:05:12 0 浏览量 回答数 0

回答

一、内存溢出类型 1、java.lang.OutOfMemoryError: PermGen space JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。 PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。 一个最佳的配置例子:(经过本人验证,自从用此配置之后,再未出现过tomcat死掉的情况) set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m 2、java.lang.OutOfMemoryError: Java heap space 第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小。假设物理内存无限大,那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了。 注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。 垃圾回收GC的角色 JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收: 当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时,就会报out of memory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。 根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。 为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收, 一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。 二、JVM内存区域组成 简单的说java中的堆和栈 java把内存分两种:一种是栈内存,另一种是堆内存 1。在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配; 2。堆内存用来存放由new创建的对象和数组 在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理 堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢; 栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。 java堆分为三个区:New、Old和Permanent GC有两个线程: 新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn java栈存放 栈调整:参数有+UseDefaultStackSize -Xss256K,表示每个线程可申请256k的栈空间 每个线程都有他自己的Stack 三、JVM如何设置虚拟内存 提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。 提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 提示:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。 默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。 提示:假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。 简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制, 这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了 提示:注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。 提示:设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old"的一半,原因是old区如果不够大会频繁的触发"主" GC ,大大降低了性能 JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64; 由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 解决方法:手动设置Heap size 修改TOMCAT_HOME/bin/catalina.bat 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m" 四、性能检查工具使用 定位内存泄漏: JProfiler工具主要用于检查和跟踪系统(限于Java开发的)的性能。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能。 1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位; 2. 应用服务器极为不稳定,几乎每两天重新启动一次,有时甚至每天重新启动一次; 3. 应用服务器经常做Full GC(Garbage Collection),而且时间很长,大约需要30-40秒,应用服务器在做Full GC的时候是不响应客户的交易请求的,非常影响系统性能。 因为开发环境和产品环境会有不同,导致该问题发生有时会在产品环境中发生,通常可以使用工具跟踪系统的内存使用情况,在有些个别情况下或许某个时刻确实是使用了大量内存导致out of memory,这时应继续跟踪看接下来是否会有下降, 如果一直居高不下这肯定就因为程序的原因导致内存泄漏。 五、不健壮代码的特征及解决办法 1、尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。 对于仍然有指针指向的实例,jvm就不会回收该资源,因为垃圾回收会将值为null的对象作为垃圾,提高GC回收机制效率; 2、我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域; String str = "aaa"; String str2 = "bbb"; String str3 = str + str2;//假如执行此次之后str ,str2以后再不被调用,那它就会被放在内存中等待Java的gc去回收,程序内过多的出现这样的情况就会报上面的那个错误,建议在使用字符串时能使用StringBuffer就不要用String,这样可以省不少开销; 3、尽量少用静态变量,因为静态变量是全局的,GC不会回收的; 4、避免集中创建对象尤其是大对象,JVM会突然需要大量内存,这时必然会触发GC优化系统内存环境;显示的声明数组空间,而且申请数量还极大。 这是一个案例想定供大家警戒 使用jspsmartUpload作文件上传,运行过程中经常出现java.outofMemoryError的错误, 检查之后发现问题:组件里的代码 m_totalBytes = m_request.getContentLength(); m_binArray = new byte[m_totalBytes]; 问题原因是totalBytes这个变量得到的数极大,导致该数组分配了很多内存空间,而且该数组不能及时释放。解决办法只能换一种更合适的办法,至少是不会引发outofMemoryError的方式解决。 5、尽量运用对象池技术以提高系统性能;生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。 6、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃 7、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error 的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。 “答案来源于网络,供您参考” 希望以上信息可以帮到您!

牧明 2019-12-02 02:16:21 0 浏览量 回答数 0

问题

怎样实现数据存储的管理维护

elinks 2019-12-01 21:14:17 9098 浏览量 回答数 0

回答

更换服务器~100个是单服务器最大的负荷了你用的是镶嵌式的,要选择服务器机组的那种~刀片式服务器~然后oracl数据库支持分开安装。同步处理~ 你肯定买的是架式服务器~######装ORACLE服务器是刀片式的,6核至强 24G的内存 应该不是服务器瓶颈######oracl装在独立的一台服务器上的话,只支持小形企业和地、市级企业运行 你说的情况,可以理解你的数据量非常庞大,,有可能是省、国家级的数据量了~~ 让你单位给你单独开个服务器房间,更换服务器机柜然后购买刀片式服务器做服务器阵列机组~######数据量倒不会太大,一天1G不到,问题是很多存储过程的逻辑很复杂,一条线程调用存储过程,要等待很久才会返回,直接导致工作线程速度很慢,数据进入速度太快,工作异常状态频繁出现。######必须要实时的存入数据库吗?不能先缓存到服务器,然后让服务器慢慢去处理吗?或者直接将数据记入日志,然后sqlload?######回复 @xinzaibing : 我想到一个蛋疼的方式:数据写文件,文件内容定期入库,程序定期读取数据库计算的结果缓存到内存中。不知道你具体需求,瞎琢磨一个。######回复 @asdfsx : 公司领导一致认为内存不可靠,断电、程序异常什么的...存在内存的数据就没了...真是蛋疼啊######回复 @xinzaibing : 如果数据量不大的话,还有一个方案就是都保存在内存里,然后定时把内存里的结果同步到数据库里。数据库的逻辑挪到程序里..........这个方案比较累啊。另外就是缓存可以加个优先级高低的判断。######目前要求是必须要实时入库,采取写日志文件的方法也可以。 这些数据有一个特点,在某一个时刻会有一个突然出现的峰值,然后又慢慢变少,但是这个时间是不固定的,由于只实用了一条双缓冲队列,所有需要紧急处理的数据和非紧急处理的数据都在队列里,而如果遇到非紧急数据,处理了很长的时间,就直接导致后面的紧急数据失效了...或者导致嵌入式程序判断服务端未收到数据,进而采取重发,导致一条队列里有非常多重复的数据。######我可能会使用数据写入日志文件,然后定时将日志入库的办法操作######大概意思可能是多线程对数据库表的操作导致数据表锁定,性能损失在内耗上了。。那数据表采用行级锁呢?(这样会增大系统开销)我是菜鸟,求教  ######回复 @xinzaibing : 这个应该是属于最初的设计问题,hohoho######回复 @asdfsx : 目前我也在往这方面考虑,如果数据分类处理。那就得大改结构了...唉######回复 @xinzaibing : 建议根据上传的不同数据进行不同的处理,不要一股脑的都放在缓存中,如果是心跳的话,应该立即响应,如果是要处理的数据的话,才需要进行缓存等待处理######ORACLE默认就是行级锁的应该.. 主要是数据的写入速度远远小于数据上传的速度,导致了缓存溢出,紧急数据不能得到及时处理,大量数据出现超时失效,无法对嵌入式的采集器程序作出及时的心跳相应和其他回复(因为都在队列中,无法处理,无心跳的话嵌入式采集器会误认为服务器断线)。最终导致单台服务器接入数据的嵌入式设备的数量太少,不满足需求。######去年刚毕业,由于公司小,一个人搞后台,压力太大啊...大家指指招呗~ @中山野鬼######今天到图书馆看了一本书《让Orcale跑的更快点》,上面说可以从如下几个方面优化: 数据库方面:建适当的索引,固定长度;查询条件比较尽量简化;不同的表放在不同的磁盘里…… 服务层:增大缓存,(有没有数据库连接池不知道你能用上不) 软件层:对Java使用PaperStatement 囫囵吞枣就记得这么多了。。。哭~~######非常感谢...我去看看这本书 :)######我不清楚你的数据采集的内容是什么。不过看的出,对实时性要求高。换我,基本上就一个思路。 1、做个前段服务器,什么事情都不干,只进行数据的压缩。然后所有数据库和计算操作,放到后端。 至于并发,你这种 1W=100台服务器的方式治标不治本。######@中山野鬼 是说对数据进行预处理,提取有效内容?还是就是zip?######回复 @asdfsx : 不一样的。而是数据压缩。采样数据中间,信息密度不会太大的。######老鬼的思路有点像我说的那个数据写日志文件,或者内存缓存定时入库...........都被否定了啊######@xinzaibing 还有一个建议,上传的数据加一个验证,如果上传的数据已经插入缓存,就不要再次插入了。无脑插入插到崩也不是什么好主意啊######回复 @asdfsx : 要回复的,要处理成功后才回复,存库失败或者某些异常导致服务端崩溃重启,就不进行回复,客户端会持续地进行重发,重发到一定次数后,存本地,等恢复正常后发送存本地的数据

kun坤 2020-06-09 11:56:38 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 SQL审核 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 人工智能 阿里云云栖号 云栖号案例 云栖号直播