分类目录归档:go语言

Go 一段典型的请求超时退出代码

下面的代码实现了golang中请求超时退出的机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func DoSomething() {
   done := make(chan error)
   go func() {
      done <- DoThing()
   }()

   select {
   case <-time.After(time.Second*10):
      Close()//中止DoThing()的执行,比如关闭网络连接
      return fmt.Errorf("Timeout")
   case err := <-done:
      if err != nil {
         err = fmt.Errorf("call failed, err %v", err)
      }
      return err
   }
}

golang 反射

本文简单要介绍反射。

什么是反射
一般我们定认了变量,类,就可以使用它。而反射,可能让我们反向的了解这些变量、类里面的包含了什么东西。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
"fmt"
"reflect"
)

func main() {
   x := 3.14
   fmt.Println("type:", reflect.TypeOf(x))
   fmt.Println("value:", reflect.ValueOf(x))
}

输出:
type: float64
value: 3.14

可以看出,定义了x变量以后,通过反射可以获取到变量的类型、值等等,也就是说我们不再只有使用这个变量,而是打入了它的内部,反射大体就是这么个意思了,呵呵~~

go session使用

Go官方没有提供session支持,需要使用第三方库,这里介绍github.com/gorilla/sessions的使用。
这个库本身只支持cookie和文件存储,但有基于这个库的扩展,可以支持mysql redis等等。

使用方式:
存值:

1
2
3
4
5
6
7
8
var store=sessions.NewCookieStore([]byte("10df6669f6414d0ce82dbf46aaae0741"))
var sessionName = "golang_everyday"

func store(w http.ResponseWriter, r *http.Request,k string,v string) {
   session,_:=store.Get(r,sessionName)
   session.Values[k] = v
   session.Save(r,w)
}

取值:

1
2
3
4
5
func get(w http.ResponseWriter, r *http.Request,k string) (string,error){
   session,_:=store.Get(r,sessionName)
   v,err :=session.Values[k].(string)
   return v,err
}

删除go get下载到的第三方包

通过go get方式下载了第三方的包以后,官方命令并没有提供删除命令。需要手动找到包所在的目录然后删除文件。

由于go get在下载指定包的同时,也会把包所有的依赖包下载下来,如果要删除依赖包,只能一个个的找到,然后删掉,比较麻烦了。

如果已下载的包比较旧,想要升级到最新版本,直接go get -u github.com/xxx/xxx就可以了。

Go一致性哈希库consistent

stathat.com/c/consistent是一个一致性哈希库。
一致性哈希是为了解决在分布式系统中,数据存取时选择哪一个具体节点的问题。
比如,系统中有五个节点,大量用户信息分别存在不同的节点上,具体到某一个用户,其信息应该确定的存在一个节点上,不能两次请求,分别去不同的节点上取数据。最简单的思路,可以拿用户ID和节点数求余数,
比如用户ID是 1、6、11、16的在第一个节点上,2、7、12、17的在第二个节点上,依此类推。

但是,如果系统中某一个节点坏掉了,变成4个了。如果再按4求余的话,会导致大量数据需要重新初始化。比如用户6,原来在第1个节点上,坏掉一个以后6%4=2,用户数据跑到第2个节点上去了。
如果系统中增加了新的节点,同样也会导致这个问题。

一致性哈希就是为了解决这个冲突的。关于其介绍,可参考:
http://blog.csdn.net/cywosp/article/details/23397179
http://www.cnblogs.com/haippy/archive/2011/12/10/2282943.html

下面介绍consistent库的使用
代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
    "fmt"
    "stathat.com/c/consistent"
)

func main() {
    cons := consistent.New()
    cons.Add("cacheA")
    cons.Add("cacheB")
    cons.Add("cacheC")

    server1, err := cons.Get("user_1")
    server2, err := cons.Get("user_2")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("server1:", server1) //输出 server1: cacheC
    fmt.Println("server2:", server2) //输出 server2: cacheA

    fmt.Println()

    //user_1在cacheA上,把cacheA删掉后看下效果
    cons.Remove("cacheA")
    server1, err = cons.Get("user_1")
    server2, err = cons.Get("user_2")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("server1:", server1) //输出 server1: cacheC,和删除之前一样,在同一个server上
    fmt.Println("server2:", server2) //输出 server2: cacheB,换到另一个server了
}

输出结果:
server1: cacheC
server2: cacheA

server1: cacheC
server2: cacheB

可以看到删除chcheA以后,user_2对应的server由cacheA换到cacheB了,而server1没有改变。