开发者社区> 问答> 正文

通过自动重连方式解决RDS闪断问题

RDS闪断解决方案

一RDS闪断的原因和影响:
1、    什么是闪断?
是指游戏APP与RDS之间的网络链路在短时间内(一般不超过三十秒) 发生了的中断。


2、    出现闪断的原因和影响。
说道闪断原因,先要解释下阿里云的RDS产品的工作原理。
阿里云RDS数据库是采用主从热备的方式进行数据存备份。一旦RDS的主库出现问题,系统为保证数据库高可用性,RDS会在30秒钟之内切换到备库。这个过程有可能会造成用户游戏不可用,出现断开或游戏退出的现象。


3、    如何将RDS闪断带来的影响降到最小?
接下来我们介绍三种解决方案,帮助大家减少RDS闪断对于游戏的影响。


二、RDS闪断的解决方案


方案1、配置连接池设置重连机制解决闪断问题
1.1、 解决方案原理:


    大多数连接池均包含链接有效性探测,适当配置后即可消除连接闪断对应用的影响。
例如当前游戏的主要开发语言是Java和C++,以JAVA语言的CP30、DBCP、Druid等连接池为例,可以通过以下几个参数设置连接池(需要充分测试以确定可能的性能开销):
<property value=”SELECT 1″ name=”validationQuery”></property><property value=”true” name=”testWhileIdle”></property>
<property value=”true” name=”testOnBorrow”></property>
<property value=”true” name=”testOnReturn”></property>
(C++一般需要自己写连接池这里不做举例)。
下面我们针对于常用游戏开发语言和连接池配置做简答的介绍。


1.2、JAVA、PHP、C 、C++、Python、连接池的设置介绍


1.2.1 JAVA连接池介绍与配置
√     C3P0:C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate[1] 一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
√    Proxool:这是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能。
√    Jakarta DBCP:DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序中使用。
√    DDConnectionBroker:DDConnectionBroker是一个简单,轻量级的数据库连接池。
√    DBPool DBPool:DBPool是一个高效的易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池使你能够开发一个满足自已需求的数据库连接池。
√    XAPool:XAPool是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。
√    Primrose:Primrose是一个Java开发的数据库连接池。当前支持的容器包括Tomcat4&5,Resin3与JBoss3.它同样也有一个独立的版本可以在应用程序中使用而不必运行在容器中。Primrose通过一个web接口来控制SQL处理的追踪,配置,动态池管理。在重负荷的情况下可进行连接请求队列处理。
√    SmartPool :SmartPool是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks),连接阻塞,打开的JDBC对象如Statements,PreparedStatements等. SmartPool的特性包括支持多个pools,自动关闭相关联的JDBC对象, 在所设定time-outs之后察觉连接泄漏,追踪连接使用情况,强制启用最近最少用到的连接,把SmartPool"包装"成现存的一个pool等。
√    MiniConnectionPoolManager:是一个轻量级JDBC数据库连接池。它只需要Java1.5(或更高)并且没有依赖第三方包。
√    BoneCP :BoneCP是一个快速,开源的数据库连接池。帮你管理数据连接让你的应用程序能更快速地访问数据库。比C3P0/DBCP连接池快25倍。
√    Druid:但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。Druid针对Oracle和MySql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。简单SQL语句用时10微秒以内,复杂SQL用时30微秒。通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter就是通过Druid的SQL Parser分析语义实现的。
请参考:http://blog.csdn.net/zhanyuanlin/article/details/9983171


1.2.2PHP连接池介绍及配置
A、连接池介绍
Php一般用作网页游戏,由于php没有连接池,自身也不能实现连接池。 因为php在解释执行完毕后会释放所有内存资源,当然其中用到的数据库连接也会被释放,所以不能做连接池。
B、我们可以通过以下三种方式解决:
√    通过中间件实现,如PDO。
<?php
$user='root';
$pass='123456';
$dsn="mysql:host=127.0.0.1;dbname=test";


class WuMingFeng extends PDO {
public function __construct(){
  try {
   parent::__construct($GLOBALS['dsn'], $GLOBALS['user'], $GLOBALS['pass']);
  } catch (PDOException $e) {
   die("连接出错!"); //$e->__toString();
  }
}


public final function query($sql){
  try {
   return parent::query($this->setString($sql));
  }catch (PDOException $e){
   die("执行错误!");
  }
}
}
$db=new WuMingFeng(); //初始化
?>


√    Sqlrelay实现。
参考:http://blog.163.com/e4lich@126/blog/static/848106502011014103645812/


√    通过mysql_pconnect()检测实现
实现方式:永久的数据库连接是指在脚本结束运行时不关闭的连接。 当收到一个永久连接的请求时。PHP将检查是否已经存 在一个(前面已经开启的)相同的永久连接。如果存在 将直接使用这个连接;如果不存在,则建立一个新的连接,代码示例如下。
<?php $con = mysql_pconnect("localhost","mysql_user","mysql_pwd");
if (!$con)  {  die('Could not connect: ' . mysql_error());  } ?>


1.2.3、C++配置方式
直接通过写代码检测连接的有效性即可,代码 如下:
void __fastcall TfrmMain::tmr1Timer(TObject *Sender)
{
       bool bLian=False;
       try
        {
            qry1->Close();
            qry1->Open();
            bLian=True;
        }
        catch (Exception &exception)
        {
           dm->aConn->Close();
           bLian=False;
           Sleep(500);
        }
        if (!bLian)
        {
          try
        {
          dm->aConn->Open();
          dm->qryCreateTemp->ExecSQL();
          bLian=True;
        }
        catch (Exception &exception)
        {
        }
        }
}


1.2.4、Python配置方式
DBUtils模块的配置指令
import pgdb
from PooledDB import PooledDB
pool = PooledPg(pgdb, 5, database='mydb') db = pool.connection()


1.2.5、C语言配置方式
通过Libzdb 实现了一个小型、快速和易用的线程安全连接池数据库(API),即可连接多种数据库,进行配置配置。
或通过URL指定连接信息http://www.tildeslash.com/libzdb/即可配置。


方案2、使用短链接解决闪断问题
在游戏设计时,尽量使用“短连接”模式向数据库发起请求,降低前端在链接方面对于后端服务器的时效依赖。
短连接模式:是指程序调用时,前端程序与数据库建立会话后,只进行一次请求,完成后该会话即被关闭。这样做会减少程序本身对于服务器的链接请求时效,从而减少RDS闪断对于程序本身的影响。
这样做的缺点是:短连接非常消耗性能和资源。每个请求都需要 向数据库认证账号与密码,每个认证过程至少6次网络 交互,效率较低;
适用场景:适合于请求量较小的应用或网站采用。如某些休闲类的小游戏,和后台的交互相对较少的情况。
方案


方案3、使用缓存数据库解决闪断问题


3.1解决方案原理:
游戏架构中一般会使用缓存数据库,网络游戏的数据变动比较频繁,如果每次数据变动都刷往后端数据库,会导致数据库不负重荷。在游戏逻辑和数据库间提供一层缓冲服务,有利于减轻这重压力。提高性能的同时也可以降低由于RDS闪断带来的问题,即数据不在缓存中,直接和数据库连接,发生闪断的情况受影响。由于缓存的命中率一般较高,所以闪断的影响会大幅降低,但不能完全避免。


通过设置Memcache缓存解决
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
更多memcache介绍可登陆http://www.memcached.org/查看


通过设置redis缓存解决
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
http://www.redis.cn/
更多redis.介绍可登陆http://www.redis.cn/查看







展开
收起
nono20011908 2014-09-29 18:06:28 35231 0
1 条回答
写回答
取消 提交回答
  • Re通过自动重连方式解决RDS闪断问题
    感觉你写的正是我遇到是的现象,但我看不懂!能帮忙看看怎么解决吗?上线不到30秒就掉!!!

    -------------------------

    Re通过自动重连方式解决RDS闪断问题
    369513234@qq.com
    2016-11-10 22:31:05
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
搭建电商项目架构连接MySQL 立即下载
搭建4层电商项目架构,实战连接MySQL 立即下载
PolarDB MySQL引擎重磅功能及产品能力盛大发布 立即下载

相关镜像