看今年二月份的go语言占比,go语言还是在缓慢上升。这门语言目前看还是比较有前景的,如果你对go语言感兴趣,你可以转。
成都创新互联公司是专业的太谷网站建设公司,太谷接单;提供成都网站建设、成都做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行太谷网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
现代化编程应该是:不强制用相同的 IDE,统一的代码风格,方便的依赖管理,持续集成,版本控制等。
在我的青少年时期,我涉猎了编程基础和一些汇编。当我学习了 Turbo Pascal 之后这事更进了一步,它提供了一种最早期的集成开发环境(IDE)。我觉得这下合我心意了。实际上,IDE 是一种让你在一个友好的环境内,方便地编写、编译、调试和运行代码的程序。Turbo Pascal 没有太多的图形界面(它基于文本),但它有菜单和窗口。你可以进入调试模式,跟踪变量的值等等。
然后我转到了 Delphi (一种图形化的 Turbo Pascal),它拥有到今天看来仍然不错的出色 IDE。我用 Visual Basic 设计了一个“会报时的钟”,当时发表在 Bulletin Board Systems(使用 Windows 3.1 的一个系统)。那之后我发现了 Visual Studio。有好几年我的 C++ 编程都是借用的 Visual Studio。以上就是我一直使用的所有 IDE。
早在八十年代初,Smalltalk 就有了著名的强大图形化 IDE(Youtube 视频)。
我认为,使用 IDE 并不代表着“现代化”。现在的 IDE 和过去的 IDE 非常相像。虽然我们编程的内容改变了,但在很多情况下,我们如何编程却没有改变。在我的 Dell 笔记本电脑里装着最新版 Visual Studio。换做 20 年前的我,也能完美地轻松上手它。调试、代码补全、远程代码执行,它和以前很像。事实上,Visual Studio 从未与 Turbo Pascal 相差很大过。而我发现这非常令人沮丧。我以为我们应该取得比这更快的进步。
我提出了现代化编程在桌面外观上难有作为的观点。图形化用户界面(GUI)只是表层。现代化编程技术都是关于流程和实际工具的,而不是它们之上的表层。我不在乎你是否使用 Eclipse 或 Emacs,这和你如何现代化毫不相关。
那么,什么是“现代化”?
编码是社会化的
在 20 年前,要求你公司里的每个人都使用相同的 IDE,并且要唯一依赖于这种 IDE 来构建、测试和部署代码,这是很明智的。但在你公司外有很多聪明的人,他们往往不使用你这种 IDE。如今,你可以触及他们了。这意味着对于所采用的工具和流程你必须明智。
如果你嘲弄使用 Atom 文本编辑器、Visual Studio 或者 Emacs 编程的人,那你就不是社会化的。你需要尽可能的包容,否则就会付出代价。
Go 语言有自己的格式化工具
我不在乎在你保存的时候,是不是自动重新格式化代码,或者有没有点击重新格式化按钮,或者是不是输入 go fmt,这些都一样。但它无疑是一个卓越的现代化的想法。这就是进步。所有的编程语言都应该为用户强加一个唯一的代码格式。别再 bikeshedding(过于关心旁枝末节,而忽视主要问题)。
我们很清楚 Java 拥有规范,但规范是不够的。我们需要一个工具,能把代码作为输入,并生成一个唯一定义了的输出,它能处理从行长度到空格的所有问题。
这个工具的目标是对于应该如何格式化代码,不再有任何可能有的争议,而且产生正确的格式不费吹灰之力。我简直无法告诉你这是多么的重要。
像 Rust、Go、Swift 这样的编程语言有自己的程序包管理系统
因此,例如在 Swift 中,我可以创建一个名为 Package.swift 的小文本文件,并把它放入我项目的根文件,在那里声明我的依赖。
importPackageDescription
letpackage = Package(
name: "SwiftBitsetBenchmark",
dependencies: [
.Package(url: "",
majorVersion: 0),
.Package(url: "",
majorVersion: 0)
]
)
然后我可以输入 swift build,软件会自动抓取依赖代码,并构建我的程序。这在 Swift 运行的所有地方通用。你使用哪种文本编辑器和 IDE 都没关系。
你不想使用文本编辑器,而更喜欢图形界面?可以。都没有区别。
为什么那样显得现代化?因为自动地解决依赖关系而不费吹灰之力,对于 20 年前的我来说就像魔术。并且自动地、系统地解决依赖关系是极其重要的。我不想永远都不得不手动安装和部署一个依赖项。我希望其他人能够在几秒内把我的库添加到他们项目中,而不是几分钟或是几小时。
是的,你可以将它添加到现有的语言(如:Java 的 Maven 或是 IED)但需要有一个唯一的方法让它起效。
像 Rust、Go、Swift 这样的编程语言,在一开始就支持单元测试。
比如在 Go 里,创建一个 filemyproject_test.go,然后添加 func TestMyStuff(t * testing.T)这样的函数,然后输入 go test 既可。
在 20 年前,几乎没有人测试他们的代码,而今天已经是一个必要要求,您和它需要以一种唯一的方式来做,这样你就可以在项目之间移动,还总是知道如何测试了。
如果不能在你的代码中立刻认出健全的单元测试,我会设想你的代码严重损坏了。
持续集成
代码更改时,你想要一个远程工具来获取新代码,并测试它,以便可以提前停止回归。人们可以在你的代码上运行测试还不够,他们还需要看到自动化测试的结果,自行检查最终的故障。
持续集成是较大规模计划的一部分:你必须在你编程的时候疯狂地自动化程序。体力劳动应该最小化。有时候这意味着你真的应该只是点击一个按钮,无论是通过一个图形化用户界面,还是命令窗口,但它不意味着需要反复地遵循一系列复杂的命令。
版本控制
20 年前,你在桌面上编写代码,并通过电子邮件发送新代码(作为补丁)是讲得通的。但这只在缓慢的合作节奏中有意义。如今,这么做是愚蠢的。任何差于 Git 的都是落后的。注意,如今甚至微软构建 Windows 也使用 Git。
那么,当你共事于从来没有听过现代编程的聪明学生会发生什么呢?他们看一个类似 go get 的命令,只看得到表层(一个命令行)。他们认为这是落后的。漂亮的图形在哪?
他们使用一个好看的 IDE 工作,像是 Visual Studio 或 Eclipse,并确信自己是现代化的,完全无视 IDE 可以追溯到几十年前的事实。然后并没有使用 IDE 的优势,比如更好的功能可见性和更快的操作,而是在其他地方使用现代化编程技术。他们坚持守旧派编程:
没有测试。至少,没有自动化和系统化的测试。
在一个具体的设置上难以处理依赖关系。
没有自动化。没有持续集成,没有自动化部署。
他们编程就像我几十年前使用 Turbo Pascal 入门的时候。尽管 Turbo Pascal 有图形化用户界面(GUI),但它是非常古老的学校。
网关=反向代理+负载均衡+各种策略,技术实现也有多种多样,有基于 nginx 使用 lua 的实现,比如 openresty、kong;也有基于 zuul 的通用网关;还有就是 golang 的网关,比如 tyk。
这篇文章主要是讲如何基于 golang 实现一个简单的网关。
转自: troy.wang/docs/golang/posts/golang-gateway/
整理:go语言钟文文档:
启动两个后端 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 计数;一种是链式调用。
具体代码
智能合约调用是实现一个 DApp 的关键,一个完整的 DApp 包括前端、后端、智能合约及区块 链系统,智能合约的调用是连接区块链与前后端的关键。
我们先来了解一下智能合约调用的基础原理。智能合约运行在以太坊节点的 EVM 中。因此要 想调用合约必须要访问某个节点。
以后端程序为例,后端服务若想连接节点有两种可能,一种是双 方在同一主机,此时后端连接节点可以采用 本地 IPC(Inter-Process Communication,进 程间通信)机制,也可以采用 RPC(Remote Procedure Call,远程过程调用)机制;另 一种情况是双方不在同一台主机,此时只能采用 RPC 机制进行通信。
提到 RPC, 读者应该对 Geth 启动参数有点印象,Geth 启动时可以选择开启 RPC 服务,对应的 默认服务端口是 8545。。
接着,我们来了解一下智能合约运行的过程。
智能合约的运行过程是后端服务连接某节点,将 智能合约的调用(交易)发送给节点,节点在验证了交易的合法性后进行全网广播,被矿工打包到 区块中代表此交易得到确认,至此交易才算完成。
就像数据库一样,每个区块链平台都会提供主流 开发语言的 SDK(Software Development Kit,软件开发工具包),由于 Geth 本身就是用 Go 语言 编写的,因此若想使用 Go 语言连接节点、发交易,直接在工程内导入 go-ethereum(Geth 源码) 包就可以了,剩下的问题就是流程和 API 的事情了。
总结一下,智能合约被调用的两个关键点是节点和 SDK。
由于 IPC 要求后端与节点必须在同一主机,所以很多时候开发者都会采用 RPC 模式。除了 RPC,以太坊也为开发者提供了 json- rpc 接口,本文就不展开讨论了。
接下来介绍如何使用 Go 语言,借助 go-ethereum 源码库来实现智能合约的调用。这是有固定 步骤的,我们先来说一下总体步骤,以下面的合约为例。
步骤 01:编译合约,获取合约 ABI(Application Binary Interface,应用二进制接口)。 单击【ABI】按钮拷贝合约 ABI 信息,将其粘贴到文件 calldemo.abi 中(可使用 Go 语言IDE 创建该文件,文件名可自定义,后缀最好使用 abi)。
最好能将 calldemo.abi 单独保存在一个目录下,输入“ls”命令只能看到 calldemo.abi 文件,参 考效果如下:
步骤 02:获得合约地址。注意要将合约部署到 Geth 节点。因此 Environment 选择为 Web3 Provider。
在【Environment】选项框中选择“Web3 Provider”,然后单击【Deploy】按钮。
部署后,获得合约地址为:0xa09209c28AEf59a4653b905792a9a910E78E7407。
步骤 03:利用 abigen 工具(Geth 工具包内的可执行程序)编译智能合约为 Go 代码。abigen 工具的作用是将 abi 文件转换为 Go 代码,命令如下:
其中各参数的含义如下。 (1)abi:是指定传入的 abi 文件。 (2)type:是指定输出文件中的基本结构类型。 (3)pkg:指定输出文件 package 名称。 (4)out:指定输出文件名。 执行后,将在代码目录下看到 funcdemo.go 文件,读者可以打开该文件欣赏一下,注意不要修改它。
步骤 04:创建 main.go,填入如下代码。 注意代码中 HexToAddress 函数内要传入该合约部署后的地址,此地址在步骤 01 中获得。
步骤 04:设置 go mod,以便工程自动识别。
前面有所提及,若要使用 Go 语言调用智能合约,需要下载 go-ethereum 工程,可以使用下面 的指令:
该指令会自动将 go-ethereum 下载到“$GOPATH/src/github点抗 /ethereum/go-ethereum”,这样还算 不错。不过,Go 语言自 1.11 版本后,增加了 module 管理工程的模式。只要设置好了 go mod,下载 依赖工程的事情就不必关心了。
接下来设置 module 生效和 GOPROXY,命令如下:
在项目工程内,执行初始化,calldemo 可以自定义名称。
步骤 05:运行代码。执行代码,将看到下面的效果,以及最终输出的 2020。
上述输出信息中,可以看到 Go 语言会自动下载依赖文件,这就是 go mod 的神奇之处。看到 2020,相信读者也知道运行结果是正确的了。