Codis源码解析——fe的启动

虽然dashboard负责对集群的实际操作,但是用户的最直观操作,都是来自于fe的。这一节我们就来讲fe的启动,没有proxy和dashboard那么复杂。

首先,启动的时候指定fe的监听端口,这个就是我们最后通过浏览器打开fe的端口

--listen=0.0.0.0:18090

然后根据系统参数找到assets文件夹目录,再在这个目录下寻找index.html,没错,就是浏览器中看到的html。如果在本地启动的时候这一步报错,assets目录下找不到index.html,就自己手动写死assets的地址即可。

indexFile := filepath.Join(assets, "index.html")
if _, err := os.Stat(indexFile); err != nil {
    log.PanicErrorf(err, "get stat of %s failed", indexFile)
}

接下来,找启动的时候配置的codis.json。通过codis.json连接到dashboard,fe就算是和集群关联起来了。

if d["--dashboard-list"] != nil {
    file := utils.ArgumentMust(d, "--dashboard-list")
    //只有一个字符串属性,指向codis.json的位置
    loader = &StaticLoader{file}
    log.Warnf("set --dashboard-list = %s", file)
} .....
//router是一个ReverseProxy结构,后面很多操作都是关于这个router的
router := NewReverseProxy(loader)
type ReverseProxy struct {
    sync.Mutex
    loadAt time.Time
    loader ConfigLoader
    //这个httputil.ReverseProxy,相当于一个请求的handler,收到客户端请求,将请求转发给另一个服务器,再将响应发回给客户端
    routes map[string]*httputil.ReverseProxy
}

func NewReverseProxy(loader ConfigLoader) *ReverseProxy {
    r := &ReverseProxy{}
    r.loader = loader
    //到目前为止只是把routes的结构初始化好,里面还是空的
    r.routes = make(map[string]*httputil.ReverseProxy)
    return r
}

使用martini框架,新建路由和handler

m := martini.New()
m.Use(martini.Recovery())
m.Use(render.Renderer())
m.Use(martini.Static(assets, martini.StaticOptions{SkipLogging: true}))
//新建一个路由实例
r := martini.NewRouter()
r.Get("/list", func() (int, string) {
    //遍历ReverseProxy的routes,将键值组成字符串切片
    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")
    //在router的routes属性中。取出name对应的ReverseProxy
    if p := router.GetProxy(name); p != nil {
        p.ServeHTTP(w, req)
    } else {
        w.WriteHeader(http.StatusForbidden)
    }
})

m.MapTo(r, (*martini.Routes)(nil))
m.Action(r.Handle)

最终我们得到了一个拥有完整规则的请求处理器handler,就是m。下一步,监听启动端口,新建路由表并将路由表指向刚才的martini框架的Router。最后一步,hs.Serve(l)这里,服务器接收指定监听器收到的请求,并为每个请求新建goroutine。goroutine负责读取并调用srv.Handler对请求进行相应

//监听10890端口,得到的l是一个Listener
l, err := net.Listen("tcp", listen)
//新建路由表
h := http.NewServeMux()
h.Handle("/", m)
hs := &http.Server{Handler: h}
if err := hs.Serve(l); err != nil {
    log.PanicErrorf(err, "serve %s failed", listen)
}

补充一下go语言路由表的知识,路由表实际就是一个map。这个map的键就是路径,比如本例的”/”,值就是对应的handler,比如本例中的m。

go语言web服务器的工作流程如下:

  1. 创建并循环监听listen socket。
  2. 监听器监听到新的请求,并创建网络连接conn,然后开启一个goroutine负责处理该链接。
  3. 从链接根据请求参数构造出http.Request对象,然后根据请求路径在路由表中查找,把请求转发给对应的应用层的处理函数。
  4. 处理函数进行处理,并将响应返回给用户
  5. 应用层处理完该链接请求后关闭该链接,如果是http alive则不关闭

到这里,fe也已经启动成功,后面只需要用户对fe进行操作即可。

这里写图片描述

如果你前面已经成功启动了dashboard和proxy,打开浏览器输入下图中的地址,就能看到完整的页面了

这里写图片描述

说明
如有转载,请注明出处
http://blog.csdn.net/antony9118/article/details/76071846

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值