【每日笔记】【Go学习笔记】2019-01-04 Codis笔记

栏目: Go · 发布时间: 7年前

内容简介:作者:谭淼dlv是调试go语言的工具,与gdb类似。下面是一些dlv的常用命令:调试命令(常用的为break,continue,next,print):

作者:谭淼

1、dlv的使用

dlv是调试 go 语言的工具,与gdb类似。下面是一些dlv的常用命令:

  • (1)dlv attach pid:类似与gdb attach pid,可以对正在运行的进程直接进行调试(pid为进程号)。
  • (2)dlv debug:运行dlv debug test.go会先编译go源文件,同时执行attach命令进入调试模式,该命令会在当前目录下生成一个名为debug的可执行二进制文件,退出调试模式会自动被删除。
  • (3)dlv exec executable_file:直接从二进制文件启动调试模式。

调试命令(常用的为break,continue,next,print):

【每日笔记】【Go学习笔记】2019-01-04 Codis笔记

注意:dlv可以通过goroutines查看所有的协程,并通过“goroutine 协程号”来切换协程。

2、martini框架

github地址: https://github.com/go-martini...

Martini是一个为了编写模块化Web应用而生的强大的GO语言框架。其使用参考: https://github.com/go-martini...

3、codis-fe的启动

codis-fe启动首先要解析参数,然后启动martini。

m := martini.New()
m.Use(martini.Recovery())
m.Use(render.Renderer())
m.Use(martini.Static(assets, martini.StaticOptions{SkipLogging: true}))

首先调用martini.New()方法创建一个Martini结构体,然后在调用该结构体的Use方法注册中间件。

中间件的注册比较简单,就是向handlers切片添加方法。

func (m *Martini) Use(handler Handler) {
   //校验方法
   validateHandler(handler)

   m.handlers = append(m.handlers, handler)
}

在处理请求时,会遍历注册的处理函数执行。

func (c *context) run() {
   for c.index <= len(c.handlers) {
      _, err := c.Invoke(c.handler())
      if err != nil {
         panic(err)
      }
      c.index += 1

      if c.Written() {
         return
      }
   }
}

除此之外,还有一个疑问,对于静态资源,是在哪里决定Content-Type的呢?

func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker) {
    ......
    // If Content-Type isn't set, use the file's extension to find it, but
    // if the Content-Type is unset explicitly, do not sniff the type.
    ctypes, haveType := w.Header()["Content-Type"]
    var ctype string
    if !haveType {
        ctype = mime.TypeByExtension(filepath.Ext(name))
        if ctype == "" {
           // read a chunk to decide between utf-8 text and binary
           var buf [sniffLen]byte
           n, _ := io.ReadFull(content, buf[:])
           ctype = DetectContentType(buf[:n])
           _, err := content.Seek(0, io.SeekStart) // rewind to output whole file
           if err != nil {
              Error(w, "seeker can't seek", StatusInternalServerError)
              return
           }
        }
        w.Header().Set("Content-Type", ctype)
    } else if len(ctypes) > 0 {
       ctype = ctypes[0]
    }
    ......
}

从代码可以看出,是根据后缀名来决定的。

后面将会新建一个路由实例,并添加路由。

r := martini.NewRouter()
r.Get("/list", func() (int, string) {
   names := router.GetNames()
   sort.Sort(sort.StringSlice(names))
   return rpc.ApiResponseJson(names)
})

r.Any("/**", func(w http.ResponseWriter, req *http.Request) {
   name := req.URL.Query().Get("forward")
   if p := router.GetProxy(name); p != nil {
      p.ServeHTTP(w, req)
   } else {
      w.WriteHeader(http.StatusForbidden)
   }
})

注册路由后便开启服务。

hs := &http.Server{Handler: h}
if err := hs.Serve(l); err != nil {
   log.PanicErrorf(err, "serve %s failed", listen)
}

Serve函数的实现也很简单,就是循环进行accept,每收到请求便创建一个协程进行处理。

func (srv *Server) Serve(l net.Listener) error {
   ......
   for {
      rw, e := l.Accept()
      ......
      tempDelay = 0
      c := srv.newConn(rw)
      c.setState(c.rwc, StateNew) // before Serve can return
      go c.serve(ctx)
   }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Responsive Web Design

Responsive Web Design

Ethan Marcotte / Happy Cog / 2011-6 / USD 18.00

From mobile browsers to netbooks and tablets, users are visiting your sites from an increasing array of devices and browsers. Are your designs ready? Learn how to think beyond the desktop and craft be......一起来看看 《Responsive Web Design》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具