music unfamous original game design efficient software wtf
life ui algorithm fix programming

Golang Web 从头开发 P1-概论

作者:trinity  Golang    2016-12-20  标签:  programming 

Golang的优势

在Quaro上看到一个问题,里面谈到 Golang 在中国大陆拥有极大的粉丝群体.这是一个值得令人欣慰的事实.想想大陆程序员的竞争压力从而对新技术骨折似的敏感态度,是很容易理解的.另外 Python 已成功的让一部分程序员减少了加班时间,Golang 则可能会带来其他新机遇;云计算,虚拟化已提前占领了未来十年的趋势以及大陆程序员对于彼岸 Google 公司的神圣态度,一切都是这么的容易理解.

其实,PHP,Python程序员使用Golang的感受和C程序员是有相当明显的差异的.Google 宣称的"Golang是更好的C"已经昭示了这一点.从之前我的一篇文章是一个国外Python程序员对Golang的吐槽.可以看到在这之间的某种隔膜.这个前提重要的地方在于,在谈到Golang的优势的时候,C程序员恐怕会感受更强烈.

大面上来说,开源,跨平台支持,类似C的简单有效的语言表达能力,编译型的native执行,原生协程支持,必要的支持库,调用C--你找不到第二款对于C程序员来说这么理想的语言,招招切中要害.

if err !=nil {} 或者 checkErr(err)

这是很多程序员除了吐槽import多余包引发编译错误之外吐槽率也很高的一个点.

"我放弃Golang没别的高深的说法,就是受不了check error"--你可能也见过类似的评论.

//Java or C# 'all-in-one' try-catch
public static void main(string args){
    try{
        ....(all code here)
    }catch(Exception e){
        ....
    }
}
Java,以及C#程序员这样的大局观每每让我叹为观止,诚然,这是一个方案.被喷的多了,就不得不分门别类的 try...catch,这也是包括C++在内的很多语言的做法.如果一层try...catch仅仅影响代码阅读的话,嵌套的try...catch以及try内部函数内部的try...catch等等会让代码逻辑打乱.不否认的两点:其一,相当一部分软件从业人员没有深度接触过C;其二,长期使用自带GC的语言让程序员对错误检查这件事的敏感度有所降低.


这让我想起了zeromq库的作者之一对于这个问题的看法(原文链接).他放弃了C++,采用了C来实现一个C版本的nanomsg.其实C++编程对我而言所有原则里面包含两条: 不在构造函数里写可能引起错误的代码,比如只给简单成员变量初始化避免打开文件等;如果可能,不使用 try...catch (有时候第三方库会用try...catch的错误检查方式)。

这不代表try...catch一无是处,但如果依赖这种错误检查手段,是很难愉快的.

/******C++ try catch version*******/
int func(const char* a,const char* b){
	try{
		...
	}catch(xxexception e){
		throw yyexception;
	}

	try{
		...
	}catch(yyexception e){
		return -2;
	}

	try{
		...
	}catch(zzexception e){

	}

	...

	return 0
}

/******C++ C-style version*******/

#define CHKERR(errcode) if(0 != (errcode)) return (errcode)

int func(const char* a,const char* b){
	int errcode=0

	...
	CHKERR(errcode);
	...
	CHKERR(errcode);
	...
	CHKERR(errcode);

	return errcode;
}
高下立判.

Web开发新领地

不知道有多少C/C++程序员为了做个网站学习了3P(PHP/Perl/Python)?

百度知道最早是C开发的.这尽管很违和,也不见得总体性能会好,但至少C是可行的.那些早期的CGI以及没有Apache的时代,很难想象用C去开发一个Web系统(尽管偶尔会吐,但并不难)

Golang出现之后,突然就好像回到了那个时代.而且有人测试,直接调用net/http,性能直接接近OpenResty(Nginx+Lua)的性能!尽管脱离实际应用架构的测试代码能代表的东西不多,至少反映了并发性能.这是比PHP的Yaf,Phalcon,以及Python的Nginx+uwsgi+Flask,tornado要好的.

Golang Web Framework

对于Golang,这一点很不同于PHP,Python--PHP给人留下只能运行在Apache或者fpm下的印象,默认支持似乎是在鼓励PHP,Html代码混合,这意味着你不得不用个框架,至少也得有个模板引擎吧.而Python是比PHP舒服的多的,当然这种舒服往往建立在大量优秀包的基础上.Golang自带net/http,html/template.有re,url,轻易的动静分离了,性能出来了,部署简单到难以置信,不完美么?

然而Web框架是一种思维惯性.就像C#的会基于.net framework封装出来一些xx framework.

于是有了beego,revel这种大一统的作品,也有martini这种较之较小的.这次的Web开发并没有使用这种大一统的作品框架.因为我对陷入框架一直怀着一种恐惧.需要的可能是一个router库(Golang的自带路由也还好),较薄的存储接口(ORM也很可怕,除了SQLAlchemy),一个redis,一个queue,Python脚本消费queue,做cron等,前面挡一个Nginx做反向代理和静态缓存Gzip,后面Go实例启动在supervisor里.在这里beego实现的很好的一点是session,router这些做成了可独立使用的包.