go语言实现一个简单的简单网关

Python020

go语言实现一个简单的简单网关,第1张

网关=反向代理+负载均衡+各种策略,技术实现也有多种多样,有基于 nginx 使用 lua 的实现,比如 openresty、kong;也有基于 zuul 的通用网关;还有就是 golang 的网关,比如 tyk。

这篇文章主要是讲如何基于 golang 实现一个简单的网关。

转自: troy.wang/docs/golang/posts/golang-gateway/

整理:go语言钟文文档:www.topgoer.cn

启动两个后端 web 服务(代码)

这里使用命令行工具进行测试

具体代码

直接使用基础库 httputil 提供的NewSingleHostReverseProxy即可,返回的reverseProxy对象实现了serveHttp方法,因此可以直接作为 handler。

具体代码

director中定义回调函数,入参为*http.Request,决定如何构造向后端的请求,比如 host 是否向后传递,是否进行 url 重写,对于 header 的处理,后端 target 的选择等,都可以在这里完成。

director在这里具体做了:

modifyResponse中定义回调函数,入参为*http.Response,用于修改响应的信息,比如响应的 Body,响应的 Header 等信息。

最终依旧是返回一个ReverseProxy,然后将这个对象作为 handler 传入即可。

参考 2.2 中的NewSingleHostReverseProxy,只需要实现一个类似的、支持多 targets 的方法即可,具体实现见后面。

作为一个网关服务,在上面 2.3 的基础上,需要支持必要的负载均衡策略,比如:

随便 random 一个整数作为索引,然后取对应的地址即可,实现比较简单。

具体代码

使用curIndex进行累加计数,一旦超过 rss 数组的长度,则重置。

具体代码

轮询带权重,如果使用计数递减的方式,如果权重是5,1,1那么后端 rs 依次为a,a,a,a,a,b,c,a,a,a,a…,其中 a 后端会瞬间压力过大;参考 nginx 内部的加权轮询,或者应该称之为平滑加权轮询,思路是:

后端真实节点包含三个权重:

操作步骤:

具体代码

一致性 hash 算法,主要是用于分布式 cache 热点/命中问题;这里用于基于某 key 的 hash 值,路由到固定后端,但是只能是基本满足流量绑定,一旦后端目标节点故障,会自动平移到环上最近的那么个节点。

实现:

具体代码

每一种不同的负载均衡算法,只需要实现添加以及获取的接口即可。

然后使用工厂方法,根据传入的参数,决定使用哪种负载均衡策略。

具体代码

作为网关,中间件必不可少,这类包括请求响应的模式,一般称作洋葱模式,每一层都是中间件,一层层进去,然后一层层出来。

中间件的实现一般有两种,一种是使用数组,然后配合 index 计数;一种是链式调用。

具体代码

原曲:东方幻想乡/BadApple!! Vocal:nomico サークル:AlstroemeriaRecords 社团:AlstroemeriaRecords アルバム:Lovelight 专辑:Lovelight Arranger:MasayoshiMinoshima na ga re te ku to ki no na ka de de mo ke da ru sa ga ho ra gu ru gu ru ma wa tte ながれてく ときのなかででも けだるさが ほらグルグルまわって 流 れてく 时 の中 ででも 气だるさが ほらグルグル回 って 就算在流逝的时间中仍能发现 你瞧,只在原地打转不停 wa da si ka ra ha na re ni ko ko ro mo mi e na i wa so u si ra na i わたしから はなれにこころも みえないわ そうしらない? 私 から 离 れに心 も 见えないわ そう知らない? 我那已失去的心也看不见 你能明白吗? ji bu n ka ra u go ku ko to mo na ku to ki no su ki ma ni na ga sa re tu du ke te じぶんから うごくこともなく ときのすきまに ながされつづけて 自分 から 动 く事 もなく 时 の隙 间に 流 され续 けて 就算自己什么都不做 时光仍渐渐消逝在缝隙中 si ra na i wa ma wa ri no ko ro na do wa da si wa wa da si so re da ke しらないわ まわりのことなど わたしはわたし それだけ 知らないわ 周 りの事 など 私 は私 それだけ 周遭的一切我一概不知 “我就是我” 所知的仅此而已 yu me mi te ru na ni mo ni te na i ka ta ru mo mu da na ji fu n no ko to ba ゆめみてる? なにもみてない? かたるもむだな じぶんのことば? 梦 见てる? 何 も见てない? 语 るも无驮な 自分 の言 叶? 在梦中发现了吗? 还是什么都没发现? 发现自己如何诉说也没用的真心话? ka na si mu na n te tu ka re ru da ke yo na ni mo ka n ji zu su go se ba i i no かなしむなんて つかれるだけよ なにもかんじず すごせばいいの 悲 しむなんて 疲 れるだけよ 何 も感 じず 过ごせばいいの 悲伤只会使自己更累 干脆什么都别多想 如此度日就好 to ma do u ko to ba a ta e ra re te mo ji fu n no ko ko ro ta da u e no so ra とまどうことば あたえられても じふんのこころ ただうえのそら 户惑 う言 叶 与 えられても 自分 の心 ただ上 の空 就算听到令人困惑的话语 我的心早已悬在半空 mo si wa da si ka ra u go ku no na ra ba su be te ka e ru no na ra ku ro ni su ru もしわたしから うごくのならば すべてかえるのなら くろにする もし私 から 动 くのならば すべて变えるのなら 黑 にする 若我试着改变这一切的话 这一切都将化为黑暗 ko n na ji fu n ni mi ra i wa a ru no ko n na se ka i ni wa da si wa i ru no こんなじふんに みらいはあるの? こんなせかいに わたしはいるの? こんな自分 に 未来 はあるの? こんな世界 に 私 はいるの? 这样的我能有未来吗? 这样的世界能有我吗? i ma se tu na i no i ma ka na si i no ji fu n no ko to mo wa ka ra na i ma ma いませつないの? いまかなしいの? じふんのことも わからないまま 今 切 ないの? 今 悲 しいの? 自分 の事 も わからないまま 现在我很难过吗? 现在我很悲伤吗? 就像这样连自己的事都不清楚 a yu mu ko to sa e tu ka re ru da ke yo hi to no ko to na do si ri mo si na i wa あゆむことさえ つかれるだけよ ひとのことなど しりもしないわ 步 む事 さえ 疲 れるだけよ 人 の事 など 知りもしないわ 就算继续走下去也只会感到更累 人际关系什么的 干脆也别去了解了 ko n na wa da si mo ka wa re ru mo na ra mo si ka wa re ru no na ra si ro ni na ru こんなわたしも かわれるもなら もしかわれるのなら しろになる? こんな私 も 变われるもなら もし变われるのなら 白 になる? 这样的我也能改变吗 如果真的改变的话 一切能回归虚无吗? na ga re te ku to ki no na ka de de mo ki da ru sa ga ho ra gu ru gu ru ma tte ながれてく ときのなかででも きだるさが ほらグルグルまって 流 れてく 时 の中 ででも 气だるさが ほらグルグル回って 就算在流逝的时间中仍能发现 你瞧,只在原地打转不停 wa da si ka ra ha na re ni ko ko ro mo mi e na i wa so u si ra na i わたしから はなれにこころも みえないわ そうしらない? 私 から 离 れに心 も 见えないわ そう知らない? 我那已失去的心也看不见 你能明白吗? ji fu n ka ra u go ku ko to mo na ku to ki no su ki ma ni na ga sa re tu du ke te じふんから うごくこともなく ときのすきまに ながされつづけて 自分 から 动 く事 もなく 时 の隙 间に 流 され续 けて 就算自己什么都不做 时光仍渐渐消逝在缝隙中 si ra na i wa ma wa ri no ko ro na do wa da si wa wa da si so re da ke しらないわ まわりのことなど わたしはわたし それだけ 知らないわ 周 りの事 など 私 は私 それだけ 周遭的一切我一概不知 “我就是我” 所知的仅此而已 yu me mi te ru na ni mo ni te na i ka ta ru mo mu da na ji fu n no ko to ba ゆめみてる? なにもみてない? かたるもむだな じふんのことば? 梦 见てる? 何 も见てない? 语 るも无驮な 自分 の言 叶? 在梦中发现了吗? 还是什么都没发现? 发现自己如何诉说也没用的真心话? ka na si mu na n te tu ka re ru da ke yo na ni mo ka n ji zu su go se ba i i no かなしむなんて つかれるだけよ なにもかんじず すごせばいいの 悲 しむなんて 疲 れるだけよ 何 も感 じず 过ごせばいいの 悲伤只会使自己更累 干脆什么都别多想 如此度日就好 to ma do u ko to ba a ta e ra re te mo ji fu n no ko ko ro ta da u e no so ra とまどうことば あたえられても じぶんのこころ ただうえのそら 户惑 う言 叶 与 えられても 自分 の心 ただ上 の空 就算听到令人困惑的话语 我的心早已悬在半空 mo si wa da si ka ra u go ku no na ra ba su be te ka e ru no na ra ku ro ni su ru もしわたしから うごくのならば すべてかえるのなら くろにする もし私 から 动 くのならば すべて变えるのなら 黑 にする 若我试着改变这一切的话 这一切就将化为黑暗 mu da na ji ka n ni mi ra i wa a ru no ko n na to ko ro ni wa da si wa i ru no むだなじかんに みらいはあるの? こんなところに わたしはいるの? 无驮な时间 に 未来 はあるの? こんな所 に 私 はいるの? 蹉跎的时光中还能拥有未来吗? 这样的地方还能让我存在吗? wa da si no ko to wo i i ta i na ra ba ko to ba ni su ru no na ra ro ku de na si わたしのことを いいたいならば ことばにするのなら “ろくでなし” 私 の事 を 言いたいならば 言 叶にするのなら “ろくでなし” 如果想要描述我这个人的话 以语言表达就是个“没用的废人” ko n na to ko ro ni wa da si wa i ru no ko n na ji ka n ni wa da si wa i ru no こんなところに わたしはいるの? こんなじかんに わたしはいるの? こんな所 に 私 はいるの? こんな时间 に 私 はいるの? 我能在这样的地方吗? 这样的时间能有我吗? ko n na wa da si mo ka wa re ru mo na ra mo si ka wa re ru no na ra si ro ni na ru こんなわたしも かわれるもなら もしかわれるのなら しろになる? こんな私 も 变われるもなら もし变われるのなら 白 になる? 这样的我也能改变吗 如果真的改变的话 一切能回归虚无吗? i ma yu me ni te ru na ni mo mi te na i ka ta ru mo mu da na ji fu n no ko to ba いまゆめみてる? なにもみてない? かたるもむだな じぶんのことば? 今 梦 见てる? 何 も见てない? 语 るも无驮な 自分 の言 叶? 今天在梦中发现了吗? 还是什么都没发现? 发现自己如何诉说也没用的真心话? ka na si mu na n te tu ka re ru da ke yo na ni mo ka n ji zu su go se ba i i no かなしむなんて つかれるだけよ なにもかんじず すごせばいいの 悲 しむなんて 疲 れるだけよ 何 も感 じず 过ごせばいいの 悲伤只会使自己更累 干脆什么都别多想 如此度日就好 to ma do u ko to ba a ta e ra re te mo ji fu n mo ko ko ro ta da u e no so ra とまどうことば あたえられても じぶんのこころ ただうえのそら 户惑 う言 叶 与 えられても 自分 の心 ただ上 の空 就算听到令人困惑的话语 我的心早已悬在半空 mo si wa da si ka ra u go ku no na ra ba su be te ka e ru no na ra ku ro ni su ru もしわたしから うごくのならば すべてかえるのなら くろにする もし私 から 动 くのならば すべて变えるのなら 黑 にする 若我试着改变这一切的话 这一切就将化为黑暗 u go ku no na ra ba u go ku no na ra ba su be te ko wa su wa su be te ko wa su wa うごくのならば うごくのならば すべてこわすわ すべてこわすわ 动 くのならば 动 くのならば すべて坏 すわ すべて坏 すわ 想要行动的话 想要改变的话 一切都会毁坏 一切都会崩溃 ka na si mu na ra ba ka na si mu na ra ba wa da si no ko ko ro si ro ku ka wa re ru かなしむならば かなしむならば わたしのこころ しろくかわれる? 悲 しむならば 悲 しむならば 私 の心 白 く变われる? 如果我感到伤心 如果我感到悲哀 我的心是否就能回归虚无呢? a na da no ko to mo wa da si no ko to mo su be te no ko to mo ma da si ra na i no あなたのことも わたしのことも すべてのことも まだしらないの 贵 方の事 も 私 の事 も 全 ての事 も まだ知らないの 不管是你的一切 或是我的一切 甚至是所有的一切 我还完全不清楚 o mo i me fu ta wo a ke ta no na ra ba su be te ko wa su no na ra ku ro ni na re おもいめふたを あけたのならば すべてこわすのなら くろになれ!! 重 い目盖 を 开けたのならば すべて坏 すのなら 黑 になれ!! 想张开这沉重的眼睛的话 想毁灭一切的话 就让黑暗吞噬掉这一切!! 曲谱 第一个:23456 2'1'62 6543 23456 54 3234 322b2323456 2'1'62 6543 23456 54 345623456 2'1'62 6543 23456 54 3234 322b2323456 2'1'62 6543 23456 54 34561'2'656 561'2'65656 654312 123456261'2'656 561'2'65656 654312 12345625 61'2'656 561'2'65656 654312 123456261'2'656 561'2'6562`3`4`3`2`1`6 565431261'2'656 561'2'65656 654312 123456261'2'656 561'2'65656 654312 123456261'2'656 561'2'65656 654312 123456261'2'656 561'2'6562`3`4`3`2`1`6 5654312 第二个:671'2'3' 6'5'3' 6 3'2'1'7 671'2'3' 2'1'7671'76(5#)7 671'2'3' 6'5'3' 6 3'2'1'7 671'2'3' 2'1'7 1' 2' 3' 671'2'3' 6'5'3' 6 3'2'1'7 671'2'3' 2'1'7671'76(5#)7 671'2'3' 6'5'3' 6 3'2'1'7 671'2'3' 2'1'7 1' 2' 3' 5'6'3'2'3' 2'3'5'6'3'2'3' 2'3' 2'1'756 5671'2'3'6 3'5' 5'6'3'2'3' 2'3'5'6'3'2'3' 2'3' 2'1'756 5671'2'3'6 3'5' 5'6'3'2'3' 2'3'5'6'3'2'3' 2'3' 2'1'756 5671'2'3'6 3'5' 5'6'3'2'3' 2'3'5'6'3'2'3' 6'7' 1''7'6'5'3' 2'3'2'1'756 3'5' 5'6'3'2'3' 2'3'5'6'3'2'3' 2'3' 2'1'756 5671'2'3'6 3'5' 5'6'3'2'3' 2'3'5'6'3'2'3' 2'3' 2'1'756 5671'2'3'6 3'5' 5'6'3'2'3' 2'3'5'6'3'2'3' 2'3' 2'1'756 5671'2'3'6 3'5' 5'6'3'2'3' 2'3'5'6'3'2'3' 6'7' 1''7'6'5'3' 2'3'2'1'756

这选择显然是因人而异的。。至于怎么选,要看你是初学者,还是老手?。。对性能有要求,还是没要求?

如果是完全没有基础,我建议哪个都不选,如果非要选一个,那就选PYTHON。。如果你是初学者,把网上的教程看个遍,再买上几本书。。。你所学会的也仅仅是语法,而根本不会编程。。。因为这些教程,也仅仅是教你语法,而没有教你编程。。你甚至把网上的教程看个精光,却连个最基本的OA系统都做不出来。。。只能在一个黑乎乎的控制台上,打印一堆破字符。。

-------网上的所有教程都会教你的:

怎么定义一个变量?怎么在控制台打印变量?

怎么写一个循环?怎么在控制台打印一堆变量?

怎么写一个函数?怎么在控制台打印返回值?

怎么创建一个对象?怎么在控制台打印对象属性?

------高级一点的教程,会教你的:

怎么用PYTHON的模块,写一个爬虫?

怎么用RUBY的ROR框架,获取一个表单?

怎么用GO的beego,写一个博客?

-------而这些的教程,从来不教你的:

面向对象有什么用? 委托是什么?事件是什么? 工厂模式,单例模式,观察者模式,这些都是啥?套接字是啥?UDP是啥?TCP/IP是啥?二叉树是什么玩意?状态机又是什么玩意?啥叫逆变?啥叫协变?啥叫异步?啥叫反射?

---------------------------------------------------------------------------------------------

如果一套教程,要把这些都讲明白。。。可能需要上千集。。。所以这些教程,都跳过了这些内容。。但如果你不明白这些,就根本学不会编程。。。如果你打算学一门语言,而手上只有几十集教程,外加三五本书。。。那你只能学会玩控制台。。。

所以初学者选择一门语言,首先要保证这门语言作为主要开发语言,常年被公司使用,这样才能真正学会编程。然而这三门语言都不具备这样的特点。它们通常都是被当成第二语言,做一些辅助开发的工作。其中Python只在极少数情况下,才被用来作为主要开发语言。至于Go与Ruby,我目前还没听说过它们有被当作主要开发语言的例子。我所推荐的是从C#和JAVA两者之间,二选一。。。学精其中一门之后,再来考虑PYTHON或GO作为第二语言。。。不然无论你选哪个,都几乎不可能靠一门语言找到工作。