golang实现mysql代理读写分离示例代码

代码语言:golang

所属分类:其他

代码描述:golang实现mysql代理读写分离示例代码,后端mysql数据库集群是一主多从。

代码标签: golang mysql 代理 读写 分离 示例 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

package main

import (
    "fmt"
    "log"
    "net"
    "strings"
    "sync"

    "github.com/go-mysql-org/go-mysql/client"
    "github.com/go-mysql-org/go-mysql/mysql"
    "github.com/go-mysql-org/go-mysql/server"
)

const (
    readHost  = "127.0.0.1:3306" // 只读副本 MySQL 服务器地址
    writeHost = "127.0.0.1:3306" // 主 MySQL 服务器地址
)

func main() {
    // 启动代理服务器
    l, err := net.Listen("tcp", "127.0.0.1:3307")
    if err != nil {
        log.Fatal(err)
    }
    defer l.Close()
    log.Println("Proxy server is listening on 127.0.0.1:3307")

    for {
        conn, err := l.Accept()
        if err != nil {
            log.Println(err)
            continue
        }

        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    // 确保连接在所有情况下都被关闭
    defer conn.Close()

    // 创建一个新的MySQL连接
    c, err := server.NewConn(conn, "root", "passwd", &MySQLHandler{})
    if err != nil {
        log.Println("Failed to create MySQL connection:", err)
        return
    }

    for {
        if err := c.HandleCommand(); err != nil {
            log.Println("Connection closed:", err)
            return
        }
    }
}

type MySQLHandler struct {
    readConn  *client.Conn
    writeConn *client.Conn
    mu        sync.Mutex
}

func (h *MySQLHandler) UseDB(dbName string) error {
    fmt.Printf("Use database: %s\n", dbName)
    return nil
}

func (h *MySQLHandler) HandleQuery(query string) (*mysql.Result, error) {
    fmt.Printf("SQL Query: %s\n", query)

    // 确定是读操作还是写操作
    isRead := isReadQuery(query)

    // 获取相应的连接
    conn, err := h.getConn(isRead)
    if err != nil {
        return nil, err
    }
    //defer h.closeConn(conn)

    result, err := conn.Execute(query)
    if err != nil {
        return nil, err
    }

    // 调试信息
    fmt.Printf("Result: %v\n", result)
    fmt.Printf("Affected Rows: %d\n", result.AffectedRows)
    fmt.Printf("Insert ID: %d\n", result.InsertId)
    fmt.Printf("Result Set: %v\n", result.Resultset)
    if result.Resultset != nil {
        fmt.Printf("Fields: %v\n", result.Resultset.Fields)
        for i, row := range result.Resultset.RowDatas {
            fmt.Printf("Row %d: %v\n", i, row)
        }
    }

    return result, nil
}

func (h *MySQLHandler) HandleFieldList(table string, fieldWildcard string) ([]*mysql.Field, error) {
    fmt.Printf("SQL table: %s\n", table)
    fmt.Printf("SQL field: %s\n", fieldWildcard)

    conn, err := h.getConn(true) // FieldList 通常是读操作
    if err != nil {
        return nil, err
    }
    defer h.closeConn(conn)

    fields, err := conn.FieldList(table, fieldWildcard).........完整代码请登录后点击上方下载按钮下载查看

网友评论0