rds proxy 数据库代理 简介

目录

RDS Proxy定义

RDS Proxy实用功能

连接转发功能

连接池功能

IAM功能

故障转移功能

连接转发功能实现

场景1

场景2


RDS Proxy定义

RDS Proxy,定义为RDS的中间代理,致力于实现一些RDS当前不具备的功能或者解决RDS当前不易解决的问题。例如,在MySQL中,不易管控连接突增问题,不易按特定需求 (如:只审计DELETE操作) 定制审计功能。

RDS Proxy实用功能

我罗列了几个实用、不需要过多编码即可实现的功能:

连接转发功能

    连接转发,做的事情很简单,将客户端的连接通过Proxy转发的DB   Server。该功能在做拆库,做设备裁撤很有用处。

连接池功能

    连接池,可控制透传到DB Server的连接数,减轻DB连接压力。

IAM功能

    IAM, 全称Identify and Access Manangement, 身份认证管理。通过Proxy,     可实现一种常用场景: 

    DBA/研发通过企业个人账号,通过Proxy,Proxy与公司IAM互通,

    自动校验账户的身份,来决定是否转发请求到DB Server。

    这样,就不用在每个DB上去管理单独的个人账户,减少因人员更替带来的      账号管理不善风险。

故障转移功能

     故障转移,也就是通过Proxy实现DB Server的HA能力,对应用透明。

连接转发功能实现

本文主要介绍连接转发功能,其他功能后续序列中介绍。

先说说为什么需要这个功能。

场景1

在遇到机房裁撤或者DB Server机器跨机房搬迁时,如没有内部DNS服务,会涉及到DB地址的变更。DB地址变更后,需要业务配置做变更。为保证安全性,需要客户端业务侧一次性全部正确更改,如涉及多个业务,需要多个业务协同更改,难度极大。此时,。

 

参考上图,使用RDS Proxy, 可以更安全地实现APP搬迁请求至新DB,步骤:

1. 使用RDS Proxy,Proxy请求转发至old DB。APP侧可以逐步更改DB配置文件,将DB请求转至Proxy。

2. 等待应用侧全部更改请求至RDS Proxy。(如何判断? 下图中,如果old DB还有非 10.11.1.2的连接,代表未改完。可以通过设置long_query_time=0, 开慢查询日志检测)。

3. 同步完成,校验完数据后,将RDS Proxy指向新DB。

4. APP侧可以逐步将DB配置文件,改回新DB。

场景2

接下来看看如何实现DB Proxy的转发功能,此处使用golang作为编程语言,mysql作为后端RDS。

关键流程为:

1. 在Proxy上监听1个端口,用来接收客户端请求。

// listener为监听的对象,可读取客户端发送的数据,也可响应给客户端。
// 假设Proxy监听端口在 8080上。客户端直接访问Proxy IP+该端口,即可连接到Proxy
listener, err := net.Listen("tcp", "0.0.0.0:8080")

2. 通过goroutine不断地获取监听到的数据,然后持续连接到目标DB。

// 伪代码示例
for {
  // 通过Accept不断读取客户端数据。
  conn,err := listener.Accept()
  if err != nil {
    continue
  }
  go connDestDB(conn)
}

// connDestDB:与目标DB交换数据包
func connDestDB(conn net.Conn) {
  dbConn,err := net.Dial("tcp", "10.11.1.1:3306")
  // 这里的readPackage,代表DB侧返回的初始认证包
  // 官方描述整个过程为 Initial Handshake: starts with server sending the Initial Handshake Packet.
  // and then client sends the Handshake Response Packet.
  
  // 这里面官方文档在Protocol::Handshake中没有体现出4字节包头,实际上存在
  header,handshake := readPackage(dbConn)
  // 发送给客户端,要求完成认证
  conn.Write(header)
  // handshake中为官方文档Protocol::HandshakeV10的内容。
  conn.Write(handshake)
}

// readPackage 读取DB交互过程中的数据包处理逻辑(伪代码)
func readPackage(conn net.Conn) ([]byte,[]byte,error)  {
  header := []byte{0, 0, 0, 0}
  rb := bufio.NewReaderSize(conn, 8*1024)
  // 4字节为mysql包头,前3字节代表包长度,后1字节为sequence ID.
  if _, err := io.ReadFull(rb, header); err != nil {
    return nil,nil,err
  }
  // 网络字节序,小端存储。
  length := int(uint32(header[0]) | uint32(header[1])<<8 | uint32(header[2])<<16)
  data := make([]byte, length)
  handshake := io.ReadFull(rb, data)
  return header, handshake,nil
}

3. 客户端数据包与DB进行交互,完成Handshake认证后,即可完成连接建立。

// 同样滴, 在我们将客户端的HandshakeResponse发送给服务端
header,data := readPackage(conn)
dbConn.Write(header)
dbConn.Write(data)

// 持续不断地获取MySQL Server返回的结果,Copy是指的从右到左复制
go func() {
  _, err = io.Copy(conn, dbConn)
  if err != nil { //客户端exit,则退出
      return
  }
}

// 可以继续接收客端后续的SQL请求
for {
  //正常会在连接成功后,客户端发送select @@version_comment limit 1
  _,_,err := readPackage(conn)
  //无法从客户端获取到数据,可能是账号认证失败了。
  if err != nil {
    return
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
奇虎360公司开源的Atlas是优秀的数据库中间件,美团点评DBA团队针对公司内部需求,在其上做了很多改进工作,形成了新的高可靠、高可用企业级数据库中间件DBProxy,已在公司内部生产环境广泛使用,较为成熟、稳定。 DBProxy的优点 支持多语言MySQL客户端 读写分离 负载均衡 Slave故障感知与摘除(Master需要MHA等其他联动) 后端连接池 自定义SQL拦截与过滤 流量分组与控制 丰富的监控状态 支持分表(分库版本正在内测中) Client IP限制 DBProxy对Atlas的改进 新增功能点 新增参数 backend-max-thread-running用于指定每个MySQL后台的最大thread running数 thread-running-sleep-delay用于指定在thread running数超过backend-max-thread-running时,客户端连接等待的时间 添加到黑名单中需要满足两个条件:SQL执行的时间和频率 提供了查看、修改、添加、删除黑名单的功能 黑名单管理提供了将黑名单保存到文件以及从文件中Load到内存中的功能 在手动添加黑名单时,只需要将用户的SQL语句输入,在内部自动转化成过滤条件,手动添加时是否生效由参数 manual-filter-flag 来控制,OFF:不生效,ON:立即生效 手动添加与自动添加两种情况下的过滤条件是否生效是分别由不同参数控制,这个要区分清楚。另外,也可以使用 admin 的命令来设置是否开启/关闭某个过滤条件 SQL执行的时间 由参数 query-filter-time-threshold 来指定,如果SQL执行时间超过此值,则满足条件 SQL执行频率 由参数 query-filter-frequent-threshold 来指定,如果SQL执行频率超过此值,则满足条件 频率就是在时间窗口内执行的次数。时间窗口则是由频率阈值和最小执行次数来计算出来的,当时间窗口小于60s时,扩展到60s 参数 access-num-per-time-window 用来指定在时间窗口内的最小执行次数,添加此参数是考虑到执行时间长的SQL在计算频率时同时参考其执行的次数,只有执行一定次数时才去计算其频率。当执行时间与执行频率都满足时条件时,会自动将查询作为过滤项放到黑名单中,加入到黑名单中是否生效由参数 auto-filter-flag 来控制,OFF:不生效,ON:立即生效 黑名单的管理 从库流量配置 指定查询发送到某个从库 参数动态设置(完善show proxy status/variables) 支持save config,动态增加、删除分表 响应时间percentile统计 统计最近时间段DBProxy的响应时间 kill session 支持DBProxy的admin接口kill session操作 backend平滑上下线 支持平滑的backend上下线 DBProxy非root用户启动 使用非root用户启动 admin账号的安全限制 admin账号密码的动态修改及host限制 增加异步刷日志的功能 增加日志线程、异步刷日志,提高响应时间 支持DBProxy平滑重启功能 支持SQL过滤的黑名单功能 支持对于MySQL后台的thread running限制功能 该功能通过在DBProxy内限制每个后台MySQL的并发查询,来控制对应MySQL的thread running数 当发向某个MySQL后台的的并发查询超过某个阈值时,会进行超时等待,直到有可用的连接,其中阈值与超时等待的时间都已经参数化,可以动态配置 set backend offline不再显示节点状态 支持set transaction isolation level 支持use db 支持set option语句 支持set session级系统变量 支持建立连接时指定连接属性 改进连接池的连接管理,增加超时释放机制。当连接池中的空闲连接闲置超过一定时
Spring Boot是一个快速开发框架,它支持各种类型的数据库连接。在应用程序中连接RDS数据库是很常见的,因为RDS是阿里云提供的一个高性价比的数据库解决方案。下面是连接RDS数据库的详细步骤。 1.创建RDS实例并获取连接字符串 首先,我们需要在阿里云控制台创建一个RDS实例。在创建过程中,我们需要生成一个用户名和密码,并选择一个数据库引擎类型。创建RDS实例后,我们需要获取连接字符串,该字符串由RDS实例的IP地址、端口号、用户名和密码组成。 2.配置Spring Boot的application.properties 打开Spring Boot应用程序的application.properties文件,添加以下配置信息: ``` spring.datasource.url=jdbc:mysql://[RDS实例的IP地址]:[端口号]/[要连接的数据库名]?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=10 spring.datasource.username=[用户名] spring.datasource.password=[密码] spring.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 注意,需要将URL中的“[RDS实例的IP地址]”替换为实际的IP地址,“[端口号]”替换为实际的端口号,“[要连接的数据库名]”替换为实际的数据库名。 3.测试数据库连接 在application.properties中配置好连接信息后,我们需要测试数据库连接是否有效。可以在代码中添加以下测试代码: ``` @Autowired private DataSource dataSource; @Bean public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { System.out.println("Datasource: " + dataSource); }; } ``` 此代码会在应用程序启动时测试数据库连接,并在控制台输出数据源信息。 4.进行数据库操作 完成测试后,我们可以使用Spring Boot的JPA、MyBatis等框架进行数据库操作了。使用这些框架可以大幅度提高开发效率,同时避免手动书写SQL语句的繁琐和易错。 总之,连接RDS数据库只需要简单的配置即可,Spring Boot的便利性和强大性使得应用程序的开发变得更加高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值