Go实现FastCgi Proxy Client 系列(三)优化篇


声明:本文转载自https://my.oschina.net/lwl1989/blog/1813102,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

墨迹一点

个人琐碎

最近比较忙,以致于很久都没有写blog了,但是,golang的水平自认为是总算入门了。

协程的个人理解

网上的说法一般都是协程是轻量级线程。

我个人认为协程的好处

  1. 无需在用户态和内核态切换(完全在用户态)
  2. 无需线程上下文切换的开销(因为之上的好处)
  3. 编码简单(原子操作,锁都没有了)

httpHandler优化

利用协程优化请求

这是我们原本的handler(就是监听http请求的一个对象,实现了ServeHTTP)

type HttpHandler struct {        Vhosts     Vhosts     HandlerMap map[string]*http.ServeMux } 

很明显,这里就已经是入口了,我们将其修改成

type HttpHandler struct {        Vhosts            Vhosts     HandlerMap        map[string]*http.ServeMux     Response          chan *Response     StaticFile        chan *StaticFileHandler     serverEnvironment map[string]string } 

当我们遇到请求的实行,我们直接开启协程

go Run(w,r) 

在Run方法中,将实现部分写入协程(即IO、计算部分),在大部分代码不变的情况下(请看1和2的分析)我们将几种错误的情况抛出一个Response对象,比如请求的是/favicon.ico

if r.RequestURI == "/favicon.ico" { 		httpHandler.Response <- &Response{200, map[string]string{}, nil, ""} 		return } 

具体的伪代码应如下:

if something wrong {      gerWrongCode      res := generate WrongResponse     httpHandler.Response <- res     return  }   res := do proxy httpHandler.Response <- res 

另外,关于静态文件,我们并不需要proxy,所以我们要告知上面,这个是静态文件,go直接处理

        fileCode,filename := httpHandler.buildServerHttp(r, env, hm)  		switch fileCode { 		case FileCodeStatic: 			httpHandler.StaticFile <- &StaticFileHandler{ 				name, 				port, 				filename, 			} 			return             case ......         } 

处理协程回调

那么确定我们已经将各种IO和逻辑处理写入了协程了,这个时候,我们回到ServeHTTP方法

    go Run(w,r)     for { 		select {    //进行协程的处理 		case response := <-httpHandler.Response:  //当遇到response的时候 送出结果 			response.send(w, r) 		case hand := <-httpHandler.StaticFile:    //当遇到是静态文件的时候 直接走本身go原本的handler 			staticHandler := httpHandler.HandlerMap[hand.Host+hand.Port] 			staticHandler.ServeHTTP(w, r)  		default: 			respond(w, "<h1>404</h1>", 404, map[string]string{}) 		} 	} 

添加日志

像nginx之类的,都可以写日志,那这个功能我也不能少

只需要在HttpHandler对象注入的时候加入一个log即可

type HttpHandler struct {    	Vhosts            Vhosts 	HandlerMap        map[string]*http.ServeMux 	Response          chan *Response 	StaticFile        chan *StaticFileHandler 	serverEnvironment map[string]string 	log               *log.Logger }  func (httpHandler *HttpHandler) SetLogger(log *log.Logger) { 	httpHandler.log = log }  func (httpHandler *HttpHandler)  GetLogger() *log.Logger { 	return httpHandler.log } 

然后,代码中可以放心大胆的使用 log.*方法

至于log写文件 ,百度谷歌谢谢,他本身就带了异步IO,就不用操心了。

其他

本文源码

Go实现FastCgi Proxy Client 系列(一)

Go实现FastCgi Proxy Client 系列(二)

一个FCM的消息代理服务器

一个秒级定时任务(非crontab)

本文发表于2018年05月15日 20:00
(c)注:本文转载自https://my.oschina.net/lwl1989/blog/1813102,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 611 讨论 1 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

行业标准总是平庸的

一直到现在我才突然明白,我梦寐以求,是真爱和自由。

把爱情留给我身边最真心的姑娘,你陪我歌唱陪我流浪,陪我两败俱伤。

把青春献给身后那座辉煌的都市,为了这个美梦,我们付出着代价。

又是一年五一,祝我们工人阶级劳动节快乐! 今年被困在北京了,离境再入境需要隔离十五天。只能京津冀周边走一走了,想出去玩啊啊啊啊啊~

快捷链接
网站地图
提交友链
Copyright © 2016 - 2020 Cion.
All Rights Reserved.
ICP备案:鲁ICP备19012333号-4.

鲁公网安备 37061302000383号.