存档

‘Go’ 分类的存档

多机房数据同步(一致性读写)视频 @Qcon

2015年1月20日 谭俊青 2 条评论

http://www.infoq.com/cn/presentations/tuniu-multiple-data-centers-distributed-database-synchronization

解决跨数据中心的数据同步和一致性问题,实现跨机房的高可用访问(比如中国特殊网络状况,提供多个数据中心的情况下,解决数据的可用性、一致性)。

分类: Go, MySQL Replication, database 标签: ,

Golang 实现的 mysql-proxy

2013年5月15日 谭俊青 10 条评论

Golang1.1昨天发布,性能提升不少。让我想起去年写的mysql-proxy,于是拿出来又改了一下调用最为频繁的一个函数,发现性能已经非常理想。这里放出来给有兴趣的朋友试用。
目前支持的功能是读写分离(非事务,如果用事务的话不会分发到slave上)和slave的负载均衡,未做失效检查。另外prepare可能会有问题。
如果有什么需求可以后续添加,golang改起来非常方便,当初这个proxy我也就1个礼拜完成的。

下载地址:http://www.mysqlab.net/products/mysql-proxy/lbproxy64.tar.gz (linux 64位)
(有需要win版本的可以密我)

配置:
1. 需要配置用于连接proxy的用户名和密码(sha1(plain password))
2. 需要配置连接后端master和slave的用户和密码(sha1(plain password))
3. slaves需要按照proxy.ini 格式写,因为解析ini文件的目前还没有容错
(本来是打算配置用web界面来做的,被其他事情给耽搁了)

启动:
目前启动方式很山寨
cd /path/to/proxy && ./proxy
(这个容易改,我已经有现成的python manager,套用过来就行)

大家有什么反馈可以q我或者这里留言(第一次需要审核,防止垃圾广告。)

分类: Go, MySQL 标签:

Go(golang) FastCGI Client

2012年6月1日 谭俊青 2 条评论

最近用Go语言写给legendbase.com写网站的时候实现了个MVC框架,原理是根据uri请求,用reflect方法找到相应的controller跟method,然后执行之.当没有找到就根据uri后缀是否是php,如果是则调用fastcig-client执行配置目录下的php文件.如果再没有就写404错误. Go语言官方package没有client的实现,于是花了点功夫实现了个,开源出来,给需要的朋友节省点时间.

地址: http://code.google.com/p/go-fastcgi-client/

使用示例: 

func main() {

        reqParams := "name=value"

        env := make(map[string]string)
        env["REQUEST_METHOD"] = "GET"
        env["SCRIPT_FILENAME"] = "/Users/ivan/work/test/fcgi/test.php"
        env["SERVER_SOFTWARE"] = "go / fcgiclient "
        env["REMOTE_ADDR"] = "127.0.0.1"
        env["SERVER_PROTOCOL"] = "HTTP/1.1"
        env["QUERY_STRING"] = reqParams

        fcgi, err := fcgiclient.New("127.0.0.1", 9000)
        if err != nil {
                fmt.Printf("err: %v", err)
        }

        content, err := fcgi.Request(env, reqParams)
        if err != nil {
                fmt.Printf("err: %v", err)
        }

        fmt.Printf("content: %s", content)
}
 

分类: Go 标签: ,

MySQL driver(驱动) liblbmysql for Go1

2012年5月24日 谭俊青 1 条评论

Go语言1.0出来之后,原来可用的MySQL驱动在新版本上基本不可用了,于是这几天自己写了个简单的MySQL的驱动,暂不支持prepare,没有implement sql/driver. 或许有能用的上的朋友,所以分享出来. 先介绍用法,后面提供下载链接.
先直接上例子

package main

import (
        "log"
        "liblbmysql"
)

func main() {
        settings := make(map[string]interface{})

        settings["host"] = "localhost"
        settings["port"] = 3306
        settings["uname"] = "ivan"
        settings["pass"] = "******"
        settings["dbname"] = "test"
        settings["charset"] = "utf8"
       
        conn, err := liblbmysql.Connect(settings)
        if err != nil {
                log.Fatal("Connect to MySQL error: %v", err)
        }

        var qr *liblbmysql.QueryResult

        qr, err = conn.ExecuteFetch("select * from ivan")
        if err != nil {
                log.Printf("query error: %v", err)
        } else {
                for {
                        m := qr.FetchMap()
                        if m != nil {
                                log.Printf("row map: %v\n", m)
                        } else {
                                break
                        }
                }
        }
        qr.Free()
        conn.Close()
}
 

【阅读全文·MySQL实验室】

分类: Go, MySQL 标签: ,

daemon function for Go language(golang)(fixed for mac/darwin)

2011年12月1日 谭俊青 2 条评论
/* ivan(a.t)mysqlab.net */

package main

import (
        "syscall"
        "os"
        "log"
)

func daemon(nochdir, noclose int) int {
        var ret, ret2 uintptr
        var err uintptr

        darwin := syscall.OS == "darwin"

        // already a daemon
        if syscall.Getppid() == 1 {
                return 0
        }

        // fork off the parent process
        ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
        if err != 0 {
                return -1
        }

        // failure
        if ret2 < 0 {
                os.Exit(-1)
        }

        // handle exception for darwin
        if darwin && ret2 == 1 {
                ret = 0
        }

        // if we got a good PID, then we call exit the parent process.
        if ret > 0 {
                os.Exit(0)
        }

        /* Change the file mode mask */
        _ = syscall.Umask(0)

        // create a new SID for the child process
        s_ret, s_errno := syscall.Setsid()
        if s_errno != 0 {
                log.Printf("Error: syscall.Setsid errno: %d", s_errno)
        }
        if s_ret < 0 {
                return -1
        }

        if nochdir == 0 {
                os.Chdir("/")
        }

        if noclose == 0 {
                f, e := os.OpenFile("/dev/null", os.O_RDWR, 0)
                if e == nil {
                        fd := f.Fd()
                        syscall.Dup2(fd, os.Stdin.Fd())
                        syscall.Dup2(fd, os.Stdout.Fd())
                        syscall.Dup2(fd, os.Stderr.Fd())
                }
        }

        return 0
}
// usage example: daemon(0, 0)
 

参考:http://code.google.com/p/go/issues/detail?id=227

分类: Go 标签: , ,