⏳ 约5分钟 · 1760汉字+136词

初学 Go 语言是在去年 11 月 20 日。到今年 2022 年的 2 月 3 日,我写了一个小 bot 连续运行成功,发布到了 github 上开源。花了两个多月时间。我感觉效率还是不错的。于是我这就来记录这段学习经历:目的一是让同样正在跨编程入门这道薛定谔之忽高忽低门槛的小白同学一些参考,更顺利的入门编程;目的二是回顾并巩固自己过去的学习,为下一步继续学习打好基础;目的三是让更多的人能够对 Rum 这个新的东西感兴趣。希望能成功达成目的:

Rum 是一款建立在区块链上的去中心化的内容平台。

这个定义不一定准确,因为 Rum 现在还是非常初级的阶段,想象空间非常大,提前下定义只会限制想象。这也是我选择 Rum 来学习 Go的原因吧。前面三篇我们做好了一个可以持续运行并给 Rum 发送内容的 bot。我们自己的电脑不一定会长期在线和联网。于是我们可以在服务器上去运行 Rum,同时再运行我们写好的 bot。

我自己搭建了一个运行 Rum 服务端(Rum 服务端我们称为 quorum)的服务器环境,再用我本地的电脑去连接,以便我后续在本地写 Go 程序能够更容易地在服务器环境上去测试。这个过程我也总结了一篇文章:从零开始在 Ubuntu 20.04 上Build Quorum 并用本地 Rum App 进行连接

从零开始在 Ubuntu 20.04 上Build Quorum 并用本地 Rum App 进行连接

上面提到的文章也是写给我这样的新手小白看的,目的都是帮助新手避免踩坑,与帮助自己巩固基础并进行下一步的学习。搭建好环境之后,像我们自己在电脑上测试 bot 一样,把我们的代码放到服务器上运行就可以了。

既然到了服务器上去运行就不得不用命令行进行操作。命令行对我这个小白来说,用起来即使不方便,感觉上很酷,就够了。我们自己写的程序要是也需要输入一个带参数的命令才能运行,岂不是酷毙了。

也是一番搜索,查到我们要带参数运行命令,需要一个包叫做 flag。是的,在命令行里带参数,就是立 flag。我们 import 这个包:

然后在 main 函数里立起一个新的 flag

调用 flag.String 方法,需要三个参数,第一个是 flag 名,这里我写的 gid,group ID 的简写;第二个是默认值,我用了“Go语言学习小组”的 ID;第三个是一个说明文档,用户用了 -h 的 flag,可以告诉用户怎么使用。填完了该填的参数,需要用 flag.Parse() 来解析用户传递的 flag。最后需要注意的一点是, flag.String 返回的是一个地址,要用上 flag 的值需要加上 * 这个符号,于是 postToRum 这个函数的第三个参数现在写成这样:

要正式运行这个代码了,会有好多测试,每次都输入一长串的 ID 感觉很麻烦而且一点都不酷。看了大佬们的代码,经常都会有一个配置文件,把很多东西写好在配置文件上,再来运行。酷!我们也来搞这个。

先设计一下我们配置文件的结构,之前学过一点 Json 的数据结构,所以也没多想,就用 Json 来作为配置文件的格式吧。然后画图进行一个简单的框架设计:

这里面计划的功能冗余了一些,很多都没用上,比如可以选择不同的发送方法什么的,可以留给读者来加工(嗯,并不是我偷懒了),按照设计写出来的 Json 文件如下:

下一步是解析并读取配置文件,把刚刚的一段 Json 保存到 config.json 文件中,和代码放在一个根目录下。读取 Json 文件:

这个时候变量 rawData 储存的是 config.json 里面的字符串,也就是 String 格式。我们还需要解析到一个 struct 中,按照我们自己设定的格式来写 struct:

这样我们就可以把 rawData 里面的字符串存到 Configs 这个我们新建的 struct 里,这次我们直接写一个读取 config 文档的函数好了:

注意到我们的 ReadConfig 函数是用的大写字母开头,因为我把 ReadConfig 函数写进了一个自定义包里。所以 ReadConfig 函数是一个公共的函数,就是说我 import 了 ReadConfig 所在的包,就可以调用这个函数。下面就讲怎么做一个自定义包,非常简单,包名就是文件夹名,把文件夹放到根目录里。比如,我的包名就叫 readconfig,于是文件夹也叫 readconfig,文件夹里面的代码源文件名可以随便写,我就写 readconfig.go 了。readconfig.go 的第一行不能随便写,要写成:

于是我们就成功自定义了一个叫 readconfig 的包。接下来把上一步写好的 ReadConfig 函数以及 Configs 的 struct,放置于 readconfig.go 里就好了。

回到根目录的 main.go,这个时候有个特别需要注意的是,因为是自定义包,我们需要在 readconfig 前面加上主包名,我这里自定义的是 yearprogress。如下:

主包名 yearprogress 又是在 go.mod 文件里定义的。要生成 go.mod 需要我们在命令行里输入这样的命令:

Go 语言会根据我们引用的各种包自动帮我们生成一个 go.mod 文件,用来进行包管理。

这样就算完结了,很快是不是?因为我就是这样学习的,会跳过很多知识点,直接去找能帮助我完成这个小项目的积木块。这是我自己总结的学习方法,我称之为敏捷学习法。这里贴一个我之前写的文章叫做:【浅尝则止是正义!逃避困难也可以!论敏捷学习方法在编程学习上的应用。】是微信公众号链接,以后考虑逐步都转移到 github 吧:https://mp.weixin.qq.com/s/ZmOaU_VPwSJICqGpefiwaQ是去年5月份写的文章,年底就成功实践学了 Go 语言,说明这个学习方法还是有效果的。

https://mp.weixin.qq.com/s/ZmOaU_VPwSJICqGpefiwaQ

按照惯例,我把代码的全貌展示在 github 上。作为小白本白,我经常复制粘贴了别人的代码再修修补补一下就没法成功运行了,所以我这里提供一个完整的可以执行的代码,修修补补出了问题可以回滚:

https://github.com/hawken-im/yearprogress/tree/main/Step3

https://github.com/hawken-im/yearprogress/tree/main/Step3

我通过这个小项目入门了 Go 语言,下一步打算做个稍微复杂一点的项目,具体还没有想好,当然还是会和 Rum 结合起来。至于这个进度条小项目,我的计划是升级一个小功能,就是年末的时候可以按每 0.1% 来发布。还有就是研究 JWT,看看怎么才能稳定的远程接入 quorum(Rum 的服务器端)。希望能帮助到读者!

初学 Go 语言是在去年 11 月 20 日。到今年 2022 年的 2 月 3 日,我写了一个小 bot 连续运行成功,发布到了 github 上开源。花了两个多月时间。我感觉效率还是不错的。于是我这就来记录这段学习经历:目的一是让同样正在跨编程入门这道薛定谔之忽高忽低门槛的小白同学一些参考,更顺利的入门编程;目的二是回顾并巩固自己过去的学习,为下一步继续学习打好基础;目的三是让更多的人能够对 Rum 这个新的东西感兴趣。希望能成功达成目的:

到现在,我们已经可以给 Rum 发送进度条了。当时我本人,在写到这一步的时候已经偷偷自调闹钟,在整点向 Rum 的“去中心微博”那个种子网络发了两三次了。但是自己调闹钟来发内容,这根本不 bot!根本都不酷!这一步我们要加入定时任务这个 new feature。

经过多番研究

(踩了不少坑,关于 cron job 的繁琐本人在 Rum 上的朋友圈里吐槽了一番)

还是确定了引用这个包:

选定了这个包,就通过阅读官方文档,找到新建计划任务的方法:

cron.New() 可以新建一个实例,里面的参数是指定时区,我们这里就用 UTC 时间。接着应用实例 c 的方法 AddFunc 就好,如下:

[计划任务时间]采用的是 linux 著名的 crontab 计划任务常用的格式,这个具体怎么弄除了自己去查询,还有个神奇的网站帮我们去做计划任务的时间:https://crontab.guru/

https://crontab.guru/

AddFunc 方法可以使用多次,也就是添加多个计划,之后再用:

才可以开始计划好的任务。

一开始我是每 24 小时发送一次,感觉有些打扰别人的时间线,经过一番折腾,最终把发送进度条的频率设置为每 1% 发送一次。

这个的算法是这样思考的:在接近一个整数百分比的时间前,每分钟一个百分比,算出 15 分钟 15 个百分比,每个百分比作一次被减数,去减下一个整数百分比的时间。直到整数百分比减去算出来的百分比小于 0.00001。那么就设定一个计划任务,在算出来的那个时间发布进度条。然后,休眠 85 个小时,因为一年的 1% 差不多是 87个小时。如果这 15 分钟内没有一个百分比达成这个条件,则休眠 15 分钟,在下一个 15 分钟唤醒程序,再算一次。打太多字读者也许会有点难读,我们放代码吧,代码配合注释可能更容易理解:

上面的 for 循环是放在 main 里,是一个死循环,我的理想情况是这个代码能够一年都不停地运行不会出错。写这篇文章的时候已经稳定运行了 3 个百分点。这里的变量 startTime 是每一个 15 分钟判断开始的时间。设定的是整秒数。然后嵌套一个运行 15 次的 for 循环,每次循环都会在 startTime 的基础上增加一分钟并判断这个时间和整百分点时间差多少百分比。直到相差小于 0.00001。再嵌套的一个 for 循环会遍历我的 config 文件里的 Rum 种子网络 ID。

最终实现自己的目标前,会出不少问题,要定位这些问题,最好的方法就是每一步都输出一个结果。特别是我们上一步那种循环套循环,还要长期运行的代码,没有日志很难定位问题出在哪里。于是我引入了日志。也是老办法,查了下有哪些好用的包。试水了两三个,最后选到了这个:

非常不好意思的告诉读者们,我作为小白一开始连前面的 log 是别名都不懂,有了别名,以后要引用这个包就不需要写全名,而只需要写 log 这个小短词了。

阅读文档得知,将 log 输出到文件的语句如下:

先用 os.OpenFile 新建或打开一个文档,我这里取名叫 “YP.log”,将文档赋值给变量 f,然后调用 log.SetOutput(f) 就可以将日志统统输出到文档 YP.log 里了。在需要记录日志的地方,调用 log.Info([日志内容]) 就可以了。于是我在主循环中加入了一些日志,好让我可以观察程序的运行:

按照惯例,我把代码的全貌展示在 github 上。作为小白本白,我经常复制粘贴了别人的代码再修修补补一下就没法成功运行了,所以我这里提供一个完整的可以执行的代码,修修补补出了问题可以回滚:

https://github.com/hawken-im/yearprogress/tree/main/Step2

https://github.com/hawken-im/yearprogress/tree/main/Step2

⏳ 约3分钟 · 918汉字+67词

初学 Go 语言是在去年 11 月 20 日。到今年 2022 年的 2 月 3 日,我写了一个小 bot 连续运行成功,发布到了 github 上开源。花了两个多月时间。我感觉效率还是不错的。于是我这就来记录这段学习经历:目的一是让同样正在跨编程入门这道薛定谔之忽高忽低门槛的小白同学一些参考,更顺利的入门编程;目的二是回顾并巩固自己过去的学习,为下一步继续学习打好基础;目的三是让更多的人能够对 Rum 这个新的东西感兴趣。希望能成功达成目的:

上一篇我们写了函数,可以用 HTTP Post 方法向 Rum 发送内容,我们这一篇就来发送焦虑内容之年度进度条吧。进度条采用文本形式,我在 Unicode 的列表里找到了一些方块:

这个找 Unicode 的地方我提供给读者:https://unicode-table.com/

https://unicode-table.com/

进度条的算法我是这样规定的:整个进度条长度是30个块,把百分比换算成三十分之 N。N 是一个整数。那么把百分之几换算成三十分之几感觉掉了很多精度,这个丢掉的精度我用一些不完整的方块来表示。我找了 quarter block 表示四分之一块,找了 half block 表示一半,three quarter block 表示四分之三块,这样至少视觉上不会感觉太“不精确”了。照着这样的算法思路我写了生成进度条的代码如下:

变量 bar 是函数要返回的值,也是要发送给 Rum 的全部内容。经过前面的计算,生成进度条之后,干脆在这个函数里把标题和时间戳也加上,成了最后的内容。这个函数的一个参数是 perc,也即percentage,百分比,顺理成章的,我们需要根据时间来计算百分比了。

计算时间的百分比很简单,输入一个时间,计算从 2022 年 1 月 1 日零点,到这个时间的时间长度,再比上整个 2022 年的时间长度就好了。代码如下:

代码设置了变量 initialTime ,初始的时间,即是 2022 年 1 月 1 日零点。参数是 nextPost,类型是一个时间类型。变量 duration 就是用 nextPost 减去 initialTime 得出的时长了。精确到了小时,因为我最终输出的百分比只保留了 1 位小数点,精确到小时足够了。

到这里我们基础的功能都已经有了,再做更进一步的优化调整前我们做一次整合。手上现在有三个函数:

输入参数 content,也即要发布的内容,参数 group 是指定要发到 Rum 的哪一个种子网络(群组)。

参数 perc 是百分比,根据百分比生成内容 bar,并返回。

参数 nextPost 是一个时间,输入时间,返回 perc 这个百分比。

把三个函数整合到 main 函数中:

这里采用了当前的 UTC 时间,传递给 timePerc 函数,生成了百分比,把百分比传递给 printBar 函数,生成要发送的内容,赋值给变量 progressBar。接下来把内容传递给上一篇写的函数,postToRum,礼成!

按照惯例,我把代码的全貌展示在 github 上。作为小白本白,我经常复制粘贴了别人的代码再修修补补一下就没法成功运行了,所以我这里提供一个完整的可以执行的代码,修修补补出了问题可以回滚:

https://github.com/hawken-im/yearprogress/tree/main/Step1

https://github.com/hawken-im/yearprogress/tree/main/Step1

另外,最终实现自己的目标前,会出不少问题,要定位这些问题,最好的方法就是每一步都输出一个结果。这里我用了 fmt.Println()。

初学 Go 语言是在去年 11 月 20 日。到今年 2022 年的 2 月 3 日,我写了一个小 bot 连续运行成功,发布到了 github 上开源。花了两个多月时间。我感觉效率还是不错的。于是我这就来记录这段学习经历:目的一是让同样正在跨编程入门这道薛定谔之忽高忽低门槛的小白同学一些参考,更顺利的入门编程;目的二是回顾并巩固自己过去的学习,为下一步继续学习打好基础;目的三是让更多的人能够对 Rum 这个新的东西感兴趣。希望能成功达成目的:

学 Go 的出发点是因为大佬们都用 Go 语言来写链上应用。看着他们在群里交流的非常欢乐,文字我都认识,但就不懂他们在讲什么。这种感觉太难受,就像小矮人身在片场却眼巴巴看高等精灵们讲精灵语,脸上还是挂着围笑假装在参与对话。

然后呢,因为自己喜欢游戏,找了本书叫:Pac Go: A Pac Man clone written in Go
就是用 Go 语言写吃豆人游戏。好,从这本书开始入门 Go。并不是因为作者是美丽的女程序员我才选择的这本书。

Pac Go: A Pac Man clone written in Go

并不是

P.S. 这本书的链接是链到 xue.cn 的,是一个可以一边阅读编程教程一边在当前书页运行代码的学习网站。

一边做实例,一边学编程,也非常符合我自己的学习理念。很快我从 xue.cn 转移到了 github 去学习,上面有 Pac Go 的开源代码。自己 clone 了一份到电脑上,然后通过读 readme 继续学习。

xue.cn

老实说 Pac Go 的前 5 章我认真跟着学了,后面就没有认真学,而是略读之后,感觉基础语法已经掌握差不多了,就开始用 Go 做自己的项目。因为新的一年快要到了,如何让人即便是年初,也要焦虑起来呢?想到了在 Twitter 上见过的 year progress。把人习以为常的日期,转变成百分比的进度条,会发现,时间怎么这么不经用?这么不经意的流逝掉了?这会让人产生巨大的焦虑感。于是我打算做一个这样的 bot 并到 Rum 上去运行。

理性的角度出发我应该规划一下这个程序的各个功能零件,以及工作流程,然后从生成进度条这一步开始,最后再做发布到 Rum 的 HTTP 请求。但我是小白啊,我野路子啊!我有搞着玩的特权啊!先试着用 Go 写 HTTP 的 Post 请求,发布到 Rum 上看看再说。

导入Go 语言的 HTTP 包:

有了这个包,就可以调用 Go 语言的 HTTP 方法了,这里我是随便 google 了一下,了解到 HTTP 到底是个什么东西,HTTP 请求又是怎么发送的。在此建议像我一样的新手小白也自己去研究 HTTP,这个并不难。本文不再花篇幅来讲 HTTP。当然深入研究也会花大量时间,这里用不到那么深入的知识,单独看看 Post 和 Get 两种最常用的 HTTP 请求就好了。

简单理解了 HTTP 请求,回来继续写自己的代码。

建立一个 client 用来发送 request。代码是:

上面这一段代码简单的解释是这样的:变量 client 是一个地址,指向了 http 包内的 struct,名为 Client。而这个 Client 里的一个值,也是一个 struct,名为 Transport。将 Transport 里的一个 TLSClientConfig 写入一个 tls 设置,把 InsecureSkipVerify 设置为 true。这里的 tls 是把 HTTP 变成 HTTPS 的一层协议。我们这个设置是为了跳过一个 tls 的验证。因为这个 HTTP 请求的地址就在本地,我们可以不用进行验证。

client 建立之后我们需要用 client 来发送请求。这段代码是:

变量 req 就是我们要发送请求的一个实例了。通过 http.NewRequest 来建立,有三个参数,分别是:“POST”,表示我们的请求是 POST 方法;第二个参数是 URL,端口号可以在 Rum 客户端的“节点与网络”菜单中的“节点参数”中找到;

第三个 body 变量是要 Post 给 Rum 的具体内容。

接下来设置一个 header,把 header 设置为一个 json 的内容。这是因为 Rum 需要我们发送 json 内容。最后就通过 client.Do(req) 来执行我们设置好的一切,并将请求到的返回值赋值给 resp 变量。这样就通过 Go 完成了一个完整的 HTTP request。

我把这个完整的 HTTP request 提供如下,整个 request 写成了一个叫 postToRum 的函数,请注意函数里面定义的叫 Payload 的 struct 数据结构是按照 quorum 的格式要求来声明的,内容格式可以自定义的是标题,正文,然后目标种子网络的ID,其他的不用修改:

函数的四个参数分别是 title 表示标题,content 表示内容,group 用于指定要发布内容的种子网络 ID,最后 url 是要发 POST 请求的目标 url,这里的地址是根据 Rum 的 api 要求来的,读者感兴趣可以自己在 Rum 的 github 主页去看看,这里的话可以直接用我提供的地址。

值得注意的是,请求的内容主体:body 变量,经过了两次加工:最初是一个 struct,这个 struct 要符合 Rum 的格式要求,我们取名叫 Payload。然后用 Payload 来创建一个叫 data 的实例,给 data 填入了具体的内容。再接下来,用 json.Marshal(data) 方法,把 data 解析成了 json 格式,并赋值给变量 payloadBytes。最后再把 payloadBytes 通过 bytes 包的 bytes.NewReader(payloadBytes) 方法,转变成了能够通过 HTTP POST 方法发送给 Rum 的字符。

既然写好了这个函数,我也迫不及待的往 Rum 上发了一个 Hello Rum 的消息。于是在 mian 函数里写下如下代码:

目标种子网络的 ID 可以在种子网络的详情处获取到,比如“Go语言学习小组”的 ID 是

fe2842cb-db6b-4e8a-b007-e83e5603131c

我们填入 ID 就可以往“Go语言学习小组”发送 Hello Rum 了。以上代码的片段忽略掉了一些 Go 语言的一些前置语句,比如包管理的 package 语句,比如引入依赖的包的 import 语句。这里我把代码完整的提供到了 github 仓库里。本系列文章的第一步骤放在了 Step0 文件夹里(因为我们程序员要习惯从零开始):

https://github.com/hawken-im/yearprogress/tree/main/Step0

https://github.com/hawken-im/yearprogress/tree/main/Step0

clone 完整代码或者复制粘贴也行,之后在 Step0 目录下执行:

就能看到结果了。

非常欢迎读者们发送 Hello Rum 到“Go语言学习小组”,小组的种子提供于此:

在度假,网不好,因此没法翻墙,断断续续 baidu 了好几天,被弄到 CSDN 里兜兜转转了好几天!鬼打墙一样。今天好不容易找了个咖啡店,翻出去了,立刻!马上!看到了这句话:

“In the most basic terms, A package is nothing but a directory inside your Go workspace containing one or more Go source files, or other Go packages.”划重点是”is nothing but”

这个太关键了中文文章要么就是高深莫测,搞得小白不知道他们是不是在故弄玄虚,要么就觉得包管理是不是太习以为常就干脆跳过。这篇文章就叫深入浅出。即便是可能会很高深,但是文章也说了, “In the most basic terms”。 对,可以很难,但是本小白要的就是”most basic terms”。 文章链接在此: https://www.callicoder.com/golang-packages/

https://www.callicoder.com/golang-packages/

继续学了 flag 和 arguement,这样就可以在命令行输入酷酷的命令了。go 的两个包分别是:

昨天跑通了 json 的解析,今天开始系统的学习 struct 以及指针,这样就能在函数中读取 struct 并返回一整个 struct今天主要看的书是 Head First Go下一步应该要把包管理学了,不然现在所有的代码都是堆在一个文件里面学完小半本 Head First Go 之前应该暂时不会更新 Year Progress 2022 代码了

今天学 go 语言解析 json,这两个教程解答了我很多问题:https://eager.io/blog/go-and-json/https://golangbyexample.com/struct-json-golang/

https://eager.io/blog/go-and-json/

https://golangbyexample.com/struct-json-golang/

新版 quorum 里 jwt token 是可选项,如果留空的话系统会自动生成一个。

Rum App 发布后我搭建了一个 windows server 运行,但一直感觉不够炫酷,于是折腾了一台 Ubuntu 主机。在主机上自己 Build Quorum,并运行,并在两位大佬轮番指导下才通过本地 Rum App 连接成功。两位大佬一位是 samson 一位是 wanming,这篇文章圈不出来他们本人。但是真的很感谢他们的热心帮助。如果大佬看到希望可以在评论区留言认领我的感谢。

正文开始

这一步我们会通过 git 命令从 github 上直接克隆一个 Rum System 到我们的服务器上。所以你需要先在服务器上安装 git:

安装完成输入命令:

检查一下是否安装成功。接下来就是从 github 上通过 git clone 命令来克隆 Rum System。Rum System 在 github 上的地址是:https://github.com/rumsystem/quorum

https://github.com/rumsystem/quorum

点击“Code”按钮会出现下拉菜单,菜单中选择“SSH”这一栏,就会出现仓库地址了。

将仓库地址放到克隆命令后,回车执行命令行:

如果发现系统提示我们无法连接,是因为 git clone 命令是通过 SSH 进行连接的,我们需要在自己的 github 账号里加入我们的 SSH 公钥。

步骤可以参考 github 的官方教程,链接如下:https://docs.github.com/en/authentication/connecting-to-github-with-ssh

https://docs.github.com/en/authentication/connecting-to-github-with-ssh

克隆完成后可以“ls”一下看看是不是有了“quorum”这个文件夹。

现在可以进入文件夹去 build 我们的 Rum System。

在根目录里执行开发人员准备好的脚本文件就好:

这个时候有可能会报错,是说我们还没有安装 go 语言。那我们就安装一下好了。go 语言的官方下载页面在这里:https://go.dev/dl/

https://go.dev/dl/

进去后下载 linux 的版本就好:

你可以通过 scp 命令上传到服务器,也可以在服务器上用 curl 命令把这个文件下载下来。我这里是在本地用的 scp 命令:

上传成功后,到文件所在位置输入如下命令:

然后把 go/bin 输入到环境变量中,只需要把下面的语句放到 /etc/profile 文件内:

确认一下是否安装成功:

go 语言的官方安装教程在这里:https://go.dev/doc/install

https://go.dev/doc/install

再次 Build 成功,进入下一步。

Build 成功的可执行文件存在 dist 文件夹中。cd 进 dist 去,ls 看到 dist 里面的文件夹里有个 linux 文件夹,再次 cd 进去,就到了 linux 系统的可执行文件的所在地了。

直接 ./quorum 运行是不行的,需要加一些参数,我的带参数的运行命令是这样的:

这样就能运行成功了。运行成功的界面应该长这样:

会跳出一些 warning 什么的,可以暂时忽略掉。

这个时候可以输入一个 curl 命令检查一下是否连接成功:

成功的话会返回一个当前种子网络的状态的消息。

进入下一步之前再保存一个密钥,它位于 quorum 文件所在的文件夹里,cd 进 cert 文件夹,里面有两个文件分别是 server.key 和 server.crt。输入命令:

把返回的密钥复制保存在本地。

新版本里 jwt token 不是必须的,这里也可以去存一个备用,jwt 位于 quorum 运行根目录所在的 config 文件夹里,里面有个后缀为 .toml 的文件,cat 或 vi 打开就能找到 jwt。

这下万事俱备了,我们在本地打开 Rum APP,从菜单项“节点与网络”中选中“外部节点”。

到了填入节点信息的步骤,把我们在上一步收集到的 jwt 和 server.crt 填进去就好了:

顺利的话,应该可以看到“外部节点模式”亮绿灯了:

不顺利的话,比如我,踩到的坑我在下一个小节总结一下,看看读者能不能顺利回避:

  1. 如果是新手小白的话可能会在各种文件夹和目录之间反复横跳找不到方向。这个看仔细一点就好了。
  2. 防火墙可能会阻止本地 APP 连接服务器。解决办法是打开端口 433,7000,8002。
  3. 最坑我的是我的云主机买的内存太小,如果内存溢出 quorum 进程马上就会被杀死。这个问题我一直无法定位,走了好多弯路,最后是求助大佬帮我发现的。解决办法是加了 1G swap。
  4. 最后是一个很好用的工具 tmux,可以帮我们保持住 quorum 的运行的同时开启别的命令行界面进行测试。

Sun Nov 21今天的 Leetcode 练习是:把罗马数字转化成整数,很有趣的一个小练习(也许是简单容易理解才觉得有趣哈哈)。然后我对 Go 还不熟悉,还不知道 Go 里面也有类似 Json 的数据结构。最后看了solution。发现别人的解题思路很棒,很直接。最后采用了她的思路。

Sat Nov 20

今天打算开始每天一个 Leetcode。试着做了一个递归小函数,这种在以前初学编程的时候感觉好难好难,在 Leetcode 上居然是 easy 级别。程序员真厉害。https://github.com/hawken-im/GoLeetCode

https://github.com/hawken-im/GoLeetCode

Sat Nov 19

先是在 xue.cn 上找了书但是发现有bug,然后在github上找到了该repo的地址就干脆在 github 里学习了吧。https://github.com/danicat/pacgo/

https://github.com/danicat/pacgo/

函数中有个叫“defer”的东西,后来去研究了,是一个很方便的语句,可以记录当前的状态但是延迟到函数结束再执行。

然后还学了ansi escape code,一个很奇怪的控制命令行窗口的代码……掌握这个奇怪的知识有啥用吗,还是说这个知识点背后还有点别的有连续性的知识体系,暂时没有继续研究下去。

I followed these two instructions:

Remember to config “sites-available” seperately, try not to config the global config file, for two reasons:

  1. It’ll be easier to maintain.
  2. Certbot is not that clever, so we want to leave the global config file to Certbot.

Follow the official instructions to install Certbot correctly.Then we need to choose a command to call a plugin to get CA.After I finished reading, I found out many unofficial instructions online are outdated.If we install Certbot correctly, we only need to use command:

Then Certbot can do all for you. Even can create a cron job to renew certificate automatically.

Try to get into the shawdowsocks container created by docker.

Found this command:

docker exec -it bash

It didn’t work. And I found this:

https://mkyong.com/docker/docker-exec-bash-executable-file-not-found-in-path/

https://mkyong.com/docker/docker-exec-bash-executable-file-not-found-in-path/

Noticed not every image is using the bash shell.

Then tried this:

docker exec -it sh

It actually worked.

0%