标签:
OCS简介
OCS( Open Cache Service)为分布式高速缓存服务,主要实现热点数据的快速响应; OCS支持Key/Value的数据结构,兼容memcachebinary protocol且支持SASL的客户端都可与服务端通信。
OCS 支持即开即用的方式快速部署;业务系统的时延和吞吐量受限于数据的更新和获取,常见的解决方案是在业务层和持久化层之间增加缓存层,从而降低持久化层的压力,提高系统整体的反应速度。
与自建memcached相同之处在于OCS兼容memcached协议,与用户环境兼容,可直接用于OCS服务。
不同之处在于硬件和数据部署在云端,有完善的基础设施、网络安全保障、系统维护服务。所有的这些服务,都不需要投入额外运维资源和成本,只需根据使用量进行付费即可。
产品特点
1. 性能优越。采用内存 SSD的部署方案,通过内存为用户提供数据访问,响应时间大为缩短;
2. 服务可靠。当某台服务器宕机时,集群将在10s内恢复服务,用户当前的客户端自动重连后即可恢复服务;
3. 数据持久。用户所有KV键值都会分散到集群中保存2份数据,单一服务器损毁不会丢失数据;
4. 安全保障。OCS仅提供内网访问,为ECS和RDS的用户提供高速缓存服务,可以避免外部攻击;
5. 弹性部署。用户可根据需要在线购买OCS实例,并即时开通服务,无需购买硬件;当业务规模发生变化时,又可在线变更实例快速部署;
6. 管理透明。阿云的OCS团队负责OCS产品的管理,包括日常维护、软硬件故障处理、补丁更新等工作,保障服务的健康有效;
7. 兼容性。兼容memcache binaryprotocol,符合该协议的客户端(binary SASL)都可使用OCS。
其它
1. 本文重在说明如何使用OCS作出高质量的设计,也作了一些OCS原理介绍。但有关开发技术相关的内容,开发者还需要参考具体memcached client的API规范。
2. 因为memcached client众多,为方便理解,使用memcached协议元操作名称指代客户端方法名称,实际可能会被客户端增减或修改。
3. OCS实际上是以memcached协议封装的Tair,但本文不要求读者具有memcached和Tair的基础。
4. 除另有说明外,本文中的“缓存对象”包含Key和Value两部分。
技术分析
基本架构
OCS是通过在Tair系统上封装memcached协议而成。以一次访问为例:首先云服务器发起memcached请求到OCS,其次负载均衡(LVS)到某台memcached的代理服务器(Proxy)上,再次Proxy把memcached请求转换为Tair请求,最后由Tair集群完成实际的高速存取功能。架构如下图:
名词说明
1. Tair:是一个高性能、分布式、可扩展、高可靠的Key/Value结构存储系统。该项目由阿里巴巴开发并在集团内部广泛使用的缓存服务,也是淘宝的开源项目之一。
http://tair.taobao.org/。
2. Memcached:是一个高性能的分布式内存对象的Key/Value缓存系统,用于应用以减轻数据库负载,现在也有很多人将它作为内存式数据库在使用,memcached通过它的自定义协议与客户端交互,而有众多的各种常见语言的客户端实现。
http://www.memcached.org/
3. 负载均衡集群,是OCS服务的入口;
4. Proxy:Tair客户端,同时把memcached转变为Tair的代理服务;
对业务方来说,可以直接购买OCS服务,也可以自建缓存集群。两者对比如下:
项目 | 自建(memcached) | OCS |
安全性 | 安全性高 可利用安全组等ECS安全机制 |
安全性高 提供源IP地址白名单、密码等安全机制,各项安全加固和检查。 |
容量 | 专用空间:内存 受限于ECS规格和台数 |
最小128M,最大10G |
带宽 | 免费、内网带宽 | 免费,实例额定带宽。 OCS服务总带宽受限于OCS集群规模,由阿里云根据运行负载动态扩展。 |
高可用性 | 内存,高易失性 | 可用性高、冗余双份存储 |
综合对比 | 额外做的工作有: 1. 集群搭建和升级; 2. 软件安装和升级; 3. 安全加固和问题响应; 4. 开发复杂性高 优点:专用集群,没有容量和带宽的限制,隔离性、扩展性、灵活性好,只要有足够的投入,可以满足任何场景的需求; 缺点:技术要求高,成本高 |
分布式和高可用功能由OCS内部实现,通过memcached接口提供标准缓存服务,极大简化了开发难度,从而提高了系统稳定性,增强了易用性。 优点:标准缓存服务,空间和带宽弹性升级,稳定性好,易用性高,价格便宜; 缺点:无法灵活自定义某些特性,可能不满足某些特殊场景的需求; |
功能特性
配额
OCS服务按实例为单位进行计费,目前只支持预付费。实例规格以空间大小区分,最小为128M,最大为10G,中间划分若干档。说明如下:
1. 缓存空间指的是Key和Value的总占用空间,以Byte为单位。
2. 每用户可最大购买的实例个数不限。每个实例的属性是空间大小,OCS会对每个空间大小有固定对应的连接数、QPS和带宽限定。
3. 云服务器和OCS之间是内网流量,且多用户共享。为减少用户间的互相影响,带宽与空间绑定,但不作为计费项。
4. Key最大为1K,Key Value最大为1M;缓存对象越小,业务系统的并发度越高,最好小于10K。过大的缓存对象会影响对业务系统的并发度(会占用较大带宽,导致降低QPS上限),也是设计需要优化的征兆。
5. 缓存空间的配额检查频率是分钟级,所以实际使用在短时间内可能会超出购买空间。当超过购买空间后,OCS会按非严格的LRU(LeastRecently Used)算法释放部分数据项。
数据过期和释放
缓存中的数据不会永久保存在OCS中。从技术层面来说,OCS对象有三种失效方式:
1. Delete。如果要立即删除缓存对象,可以显式调用delete方法。
2. LazyExpiration。OCS内部不会扫描缓存对象是否过期,而是在Get时查看缓存对象的时间戳,检查记录是否过期,这种技术被称为Lazy(惰性)Expiration。LRU(Least Recently Used)。OCS会优先使用已超时的对象的空间,但也会发生添加新对象时空间不足的情况,此时就会自动触发名为 LRU机制来分配空间。为了性能高效,OCS的LRU算法,能够做到相对准确,但不是十分严格。
数据过期是OCS的自动删除缓存对象的机制,它既确保了数据的新鲜度,又保证了开发模型的简单化。当更新缓存数据(Set、Add、Replace)时,可针对每个缓存对象设置超时时间(expire),以指定这个对象在OCS中存活多长时间。如果没有提供超时时间,expire默认为0,即永不过期,也可指定为相对时间和绝对时间。
在某些场景下,单独更新对象的超时时间(Touch)或读对象的同时也更新超时时间(GetAndTouch)可能是需要的。
expire参数规则(Set、Add、Replace、Touch、GetAndTouch):
expire参数 | 说明 |
0 | 永不过期 |
<=2592000秒(30天) | 以当前时间为起点的相对时间 |
>2592000 | 从1970-01-0100:00:00开始的秒数表示的绝对时间 |
注意:GetAndTouch暂未开放
设置显式过期时间
仔细斟酌/调试OCS缓存中的到期时间设置十分重要。较长的过期时间具有若干潜在缺点。首先,如果缓存的源对象更改很频繁,则缓存的版本可能会变得陈旧。通过将过期时间设置为更短的值,您可以强制应用程序按适当的间隔刷新缓存的对象。此外,较长的过期时间可能会导致用不再使用的项填充缓存。在典型情况下,最近最少使用 (LRU) 的项将被逐出,以便为新缓存的对象腾出空间。如果过期时间太长,则始终满的缓存会导致很难了解您实际需要的内存量。因此,很难确定缓存空间大小是否满足业务的需要。
但是,如果设置太短的过期时间,则可能会让缓存所带来的好处大打折扣。因此,考虑正确的过期时间值很重要。实际上,过期时间的选择跟具体业务和缓存数据类型有很大关系。
除非特殊场景,把过期时间指定为永不过期不是一种好的做法。
高可用性
服务总体可用性为99.9%。Tair集群的数据引擎为ldb,持久存储采用SSD。
1. 保证被缓存对象的持久性,内存和SSD两级存储机制;
2. 不同物理机上的双份冗余存储;
a) 一台机器失效后,自动由集群中其它机器接管服务;
b) 一份数据丢失后,可由另一份自动恢复到故障前的数据状态;
3. 同一地区内共用一个OCS集群,目前不支持跨地域的冗余。
虽然OCS提供高可性保证,但需要认识到在缓存数据存在过期、或被LRU逐出的可能性。另外,极端情况下,甚至OCS整体不可用或缓存数据全部丢失是可能发生的。Caching只是提升性能和可扩展性的手段之一,系统应能够独立于OCS运行,把OCS当做持久化存储也是不明智的。
OCS是业务系统中进行合适的错误处理,对系统的高可用有很大帮助。参见本文“错误处理”章节。
并发性
和memcached一样,OCS提供两种同步模式:
1. 原子递增或者递减(incr/decr),适用于32位无符号整数的更新;
2. CAS操作,适用于任意对象的操作。
CAS协议通过compare and set来实现原子更新,是一种“乐观同步模型”。OCS基于Tair,其中存储的每个数据都有版本号(cas值,2字节无符号整数),版本号在每次更新后都会递增。每次存储数据同时要附带一个版本号,OCS比对这个版本号与当前存储数据的版本号是否相等,如果相等就让新的数据覆盖老的数据,如果不相等就认为更新失败,这在并发环境下特别有用。CAS更新其实是分为两个步骤:获取CAS值和尝试更新。在一般的客户端实现中都支持CAS协议,使用方法参见相应客户端的使用说明。
OCS的版本号(cas值)的改变逻辑如下:
1. 如果增加新数据且没有指定版本号,会自动将版本设置成1;
2. 如果是更新老数据且没有指定版本号,或者与传入版本号与当前版本一致,版本号自增1;
3. 如果是更新老数据且传入版本号与当前版本不一致,更新失败,返回错误。
4. 如果是传入版本号参数为0,表示强制更新,版本号自增1。
OCS使用注意事项:
1. 在同步的场景,增加新数据时,传入的版本号必须是大于客户端的个数(例如1000),且要保证所有客户端是相同逻辑。因为传入0,会被认为是强制覆盖;而传入1,则与第1个客户端写成功的版本号冲突,以此类推。
2. 对于多数不需要同步的场景,直接使用非cas方法;或传入0,直接进行强制更新。
3. 同步错误返回中包含错误码0×0005( Item notstored)和CAS值。0×0005是memcachebinary protocol的约定,具体的客户端可能会有自己独特的错误码或异常。
安全性
由于OCS的多租户共享特性,它采用SASL和访问主体限制两方面的安全机制来保证OCS的数据安全。只有来源于特定云服务器,且通过密码验证的用户才能获得对特定实例的访问授权。分别说明如下:
1. SASL。SASL全称SimpleAuthentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。memcached从1.4.3版本开始,支持SASL认证。由于OCS的多租户共享特性,也采用SASL作为鉴权机制。SASL本质上是使用密码保证的缓存数据安全,建议采用强密码和定期修改密码的策略;
2. 访问源限制。包含两方面:
a) 访问源必须来源于是阿里云内网的云服务器;
b) 访问源IP地址白名单。(目前未支持)
错误处理
虽然OCS错误码与memcached兼容,但因为网络错误和OCS的错误会被memcachedclient封装或转换为自身独特的错误码或异常,所以开发者需要学习具体客户端的开发技术。
OCS封装了memcachedclient的分布式管理功能,是一个完整的分布式缓存系统,所以针对内部的可恢复错误,会自动进行恢复,不会传播到OCS之外(例如Tair中某节点失效时,与OCS的网络连接也不会受影响)。除了连接OCS服务时可能发生的网络异常外,OCS服务可能会给memcachedclient返回下表所列错误:
错误码 | 说明 | 备注 |
0×0000 | Noerror | 成功 |
0×0001 | Keynot found | 对象不存在或已经过期 |
0×0002 | Keyexists | add对象时,对象已经存在 |
0×0003 | Valuetoo large | Key Value长度超限 |
0×0004 | Invalidarguments | 参数无效 |
0×0005 | Itemnot stored | 数据更新时,cas值不匹配 |
0×0006 | Incr/Decron non-numeric value | Incr/Decr数据类型错误 |
0×0081 | Unknowncommand | 不支持的命令 |
0×0082 | Outof memory | 内存不足等服务内部错误 |
注:随着memcached的发展,错误码也会有调整,以上仅供参考。
一般情况下,OCS的返回错误是持久性的故障,错误处理一般是中止当前逻辑、记录错误日志等操作,而不应该反复重试。因为网络或自身软件故障等原因,OCS也存在失效的可能,所以全面的故障处理对业务整体可用性至关重要。
但OCS也可能会返回暂时性错误,此时的重试逻辑对于健壮性就十分重要。如果重试反复失败,还是需要执行其它故障排除操作。
下表列出了部分错误的建议处理方式:
类型 | 错误码 | 建议错误处理方式 |
网络 | 连接失败 | 使用域名访问OCS,如果连接异常,通常是持久性故障,错误处理中也可包含重试逻辑。 |
网络超时 | 建议进行有限次的重试,但意识到该操作在服务器上可能已经成功也十分重要。在某些情况下,这种用法可能会使重试逻辑复杂化。例如,以cas方式更新对象,虽然返回了 Timeout 错误,但更新操作可能已经成功,此时仅仅重试该调用一定会失败,因为服务器上有了更新的版本。正确的做法可能是重新获取该对象的新版本,然后重试更新操作。 | |
其它网络错误 | 按通常的网络错误处理逻辑进行相应处理。OCS会在连接空闲90s后主动断开与客户端的连接。 | |
OCS | 0×0005 | 同步错误。建议使用新cas值重试,新cas值也在返回中。 |
其它错误 | 建议直接进行相应错误处理,不必重试。 | |
整体 | 多种网络或OCS错误 | OCS服务不可用的表现形式可能是网络异常或OCS服务本身异常。反复重试的失败,可能原因之一是OCS服务不可用。业务应有处理服务不可用的处理逻辑,例如服务降级等。 |
本地缓存(LocalCache)
1. 本地缓存能够避免因为频繁访问的对象而对OCS进行反复的网络请求。(带宽、网络IO、Socket连接)。
2. 本地缓存能够避免与此传输相关联的反序列化成本。
在将本地缓存用于所有类型的数据前,应该明确一点,本地缓存中的项在本地失效前不更新。如果该对象在OCS上更改或失效,则应用程序将继续使用较旧的值,直到本地存储的对象失效。
连接池
对很多memcached客户端来说,内置连接池功能(与OCS服务的并发连接)。对同一个memcached可以创建N个连接组成连接池来提高客户端在高并发环境下的表现,而这一切对使用者来说却是透明的。启用连接池的前提条件是保证数据之间的独立性或者数据更新的同步,对OCS来说的各个连接之间是没有做更新同步的,因此应用需要保证数据之间是相互独立的或者全部采用CAS更新来保证原子性。
OCS会在连接空闲90s后主动断开与客户端的连接。虽然如此,为了降低系统开销,通常不建议开启客户端的心跳检测功能。
连接池通常不建议设置太大,一般来说,推荐在1~5之间为好,太大则浪费系统资源,太小无法达到提升性能的目的。
memcached兼容性
1. OCS(同memcached)不支持命名空间(namespace),但可以通过实例或memcached的其它技术手段模拟(例如在真实的键之前加入有意义的前缀);
2. OCS不支持memcachetextual protocol,支持memcache binary protocol,且命令语义和返回值保持兼容。memcached二进制协议规范参见:
https://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol。
以下为OCS支持的元操作,不同客户端封装后会有增减或修改。编程实现时,请以相应客户端操作的定义为准。
分类 | 元操作 | 说明 |
OCS支持 | Add | 表示如果服务器没有保存该关键字的情况下,存储该数据 |
Replace | 表示在服务器已经拥有该关键字的情况下,替换原有内容 | |
Set | 表示存储该数据,不论数据项是否已经存在 | |
Get | 获取Key的Value | |
Delete | 直接删除缓存对象 | |
Increment Decrement |
命令用来修改以及存在的数据项的内容,增加或者减少它。该数据被当作32位无符号整数处理 | |
Version | 获取服务器版本信息 | |
Append | 在value后追加字符 | |
Prepend | 在value前追加字符 | |
No-op | 无操作,用于保活或清空q命令的返回 | |
Quit | 当服务器接受到此命令后,就关闭与该客户端的连接 | |
OCS不支持 | mget | 批量获取value |
mset | 批量更新value | |
mdelete | 批量删除value | |
Flush | 删除所有缓存对象,在更换数据库等场景下需要 | |
Stat | 获得各种监控数据,OCS本身提供各种监控数据和UI展示 |
注意:所有Q命令,在当前版本中与不带Q版本相同
适用场景
1. 适合于大量的热点数据缓存(KB级别),能够显著提高系统反应速度,降低数据库或文件系统负载;
2. 分布式非持久化共享数据,例如WebServer的Session数据、用户的Token、权限信息等;
3. 任何频繁更新或读取的临时数据的场景;
4. 通常是使用缓存读场合,减轻后端持久化存储的读压力;在某些场景下,缓存写也是适合的,虽然OCS提供双份冗余存储(SSD),但也需要认识到在极端情况下数据丢失是可能发生的;
5. 如果对数据实时变化不敏感,允许适度延迟更新,则直接使用数据过期设置即可;如果敏感,则需要更新持久化时存储时,同时也更新OCS。
不适用场景
1. 单条缓存数据不宜过大,例如超过100K;
2. 事务性数据不适合缓存写,而应直接写数据库;
3. 有强一致性要求的数据;
4. 非热点数据;
5. 不能够适应Key/Value的形式数据。
产品使用
OCS带来了性能、扩展性和更低成本等好处的同时,同时也使得设计和系统更复杂,所以在使用之前,应该进行认真的考察和评估。
管理
空间预估
所需最大空间计算公式是:缓存对象平均字节数(Key Value)×缓存对象个数。缓存对象个数是个估计值,它受以下因素影响:
1. 热点数据量
2. 预期的命中率
3. 数据过期时间
实例
有两种方式对实例进行管理:官网和API。包含实例的创建、删除、查询、修改、启用、禁用、监控等。
阿里云官网链接:http://www.aliyun.com/product/ocs
SDK文档下载链接:http://help.aliyun.com/manual?lastSortId=495
监控
OCS提供丰富的监控项,例如:已用空间、命中率/次数、读取速率/次数、写入速率/次数、当前连接数、当前QPS、当前每秒逐出个数等。
当发现命中率过低或抖动时,可通过增大缓存空间,调长过期时间等措施来改进。
客户端选择
每一个memcached客户端都有自己的特点,可以根据应用特点选用支持SASL和memcachedbinary protocol的任何一款memcached客户端。开发者须自行保证客户端的质量。因客户端直接或间接导致的故障或损失,阿里云概不负责。以下介绍几种见客户端,更多选择请参考
https://code.google.com/p/memcached/wiki/Clients。
语言 | 客户端 | 说明 |
Java | gwhalin_memcached | 优点:memcached官方提供的java客户端,应用最为广泛,性能稳定; 缺点:基于传统阻塞io,不具备memcached之间数据热备功能,客户端访问memcached服务端不命中直接请求数据源。 https://github.com/gwhalin/Memcached-Java-Client/wiki/ |
alisoft_memcached | 优点:支持错误转移和数据备份,支持本地缓存等; 缺点:测试性能不是最优。 http://code.google.com/p/memcache-client-forjava/ |
|
XMemcached | 优点:高性能、支持完整的协议、支持客户端分布、允许设置节点权重、动态增删节点、支持JMX、与Spring框架和Hibernate-memcached的集 成、客户端连接池、可扩展性好; 缺点:不具备memcached之间数据热备功能。 http://code.google.com/p/xmemcached/ |
|
PHP | memcached | 建立在libmemcached基础上,功能相比memcache更全一些。 优点:高性能、功能丰富、支持BinaryProtocol; 缺点:不支持长连接,不支持非OO接口。 http://pecl.php.net/package/memcached |
.NET | EnyimMemcached | 优点:成熟、稳定。 http://www.codeplex.com/EnyimMemcached/ |
C/C Python Perl Ruby |
libmemcached | libmemcached 是一个 memcached 的库,客户端库,C 和C 语言实现的客户端库,具有低内存占用率、线程安全、并提供对memcached功能的全面支持。 优点:低内存占用率、线程安全、功能全面。 http://www.libmemcached.org |
注意:第三方开源客户端,非阿里云官方提供,可能存在潜在bug。开发者须自行保证客户端的质量。因客户端直接或间接导致的故障或损失,阿里云概不负责。
缓存策略
正确的缓存策略可以在有限的成本内,大幅提高吞吐量和降低延迟时间。在业务系统的设计阶段,需要进行缓存策略整体设计。这可能会包含如下方面:
1. 数据分类。根据业务数据特点(例如大小、访问时延要求、频繁程度、更新频率,读写比例、一致性要求等)进行类别划分;
2. 识别需要缓存(性能瓶颈)的数据类型;
3. 缓存更新策略。根据对数据的实时性要求不同,在OCS中有两个选择:
a) 显式更新缓存内容,新内容即时生效;
b) 设置失效时间,过期后自动失效;
4. 直接使用OCS服务还是在ECS上搭建专用的分布式缓存服务;
5. 对象压缩。最明显的好处是,用于占用更少的存储空间。但还有其他潜在的好处,例如更快的传输效率、更小的带宽占用。缺点是压缩和解压需要占用额外的处理器时间。在使用压缩前,应考虑对象的类型。例如,.jpg 、.wav、 .mp4 等图片/音频/视频文件已经进行了压缩。进一步的压缩需要处理时间,但不会显著降低文件大小。应该在评估和测试后,再决定是否应该采用压缩处理;
6. 本地缓存。多数情况下,多级缓存会产生的良好的效果。
迁移到OCS
OCS是一个KV分布式缓存服务,类似的缓存服务也有很多,它们的开发技术和经验基本是类似的。再加上OCS兼容memcached协议,这使得开发者能够找到大量的学习资料,更容易地使用OCS服务。
1. 如果业务系统原来已经使用memcached作为缓存,则迁移到OCS是一个比较简单的事情。因为OCS兼容memcached,所以代码不需要改变,只需要作必要的配置更改和测试即可;
2. 如果业务系统原来使用的是其它缓存,则设计保持不变,只需要做相关的代码修改和测试。
3. 如果业务系统原来没有使用缓存,计算采用OCS提高系统反应速度和降低数据库压力,因为OCS封装了分布式管理、高可用等功能,所以开发难度小于memcached。
FAQ
1. 是否可以使用自己的客户端?
可以,只要满足memcachedsasl和binary协议的客户端都可以支持。
2. OCS与memcached完全相同吗?如果不是,有哪些差别?
OCS内部使用Tair,并以memcached接口提供服务,各命令的语义和错误返回值保持兼容,基本可以做到无缝切换。但也有一些差别:
a) 不支持memcached的Flush、Stat命令;另外也不支持Tair本身的mget、mset、mdelete命令;
b) Q命令与对应的正常命令一样,能被调用和像正常命令一样执行和返回结果,但暂时没有实现Q功能;
c) Increment和Decrement的操作数在memcached中是64位无符号整数,在OCS中是32位无符号整数;另外,对字符串数据的操作结果也有不同;
d) CAS值在memcached中是32位无符号整数,在OCS中是16位无符号整数。这对开发都而言,没有任何影响;
3. SASL是什么?
SASL全称SimpleAuthentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。memcached从1.4.3版本开始,支持SASL认证。由于OCS的多租户共享特性,也采用SASL作为鉴权机制。SASL本质上是使用密码保证的缓存数据安全,建议采用强密码和定期修改密码的策略。
4. 为何有时候客户端操作会异常?
由于存在网络传输,网络的抖动有可能会有操作失败。客户端所在服务器负载过高时,可能会造成处理缓慢,最终造成超时。90s之内客户端没有请求,OCS会自动断开连接,请确保使用的客户端具有重连功能
5. 系统是PHP语言,使用哪个客户端比较好?
memcached客户端很多,开发者可根据自己的需要自行选择,并确保它的高效和稳定。因客户端直接或间接导致的故障或损失,阿里云概不负责。
6. SpyMemcached无故出现异常?
目前SpyMemcached版本不支持并发访问,如果并发访问,有可能造成协议包错乱,导致异常。
7. 多大的数据最适合存储在OCS上?
Key最大为1K,Key Value最大为1M。但太大的对象,会占用较大带宽,导致较小的QPS,建议Key Value大小最好10K以下。
8. 对OCS的访问是否需要负载均衡?
无需,OCS是分布式服务,负载均衡自动进行。
9. 客户端连接OCS是长连接还是短连接?
长连接。若业务并发量大,为性能考虑,可以开启连接池功能。
标签:
原文地址:http://www.cnblogs.com/xiaosongluffy/p/4462548.html