LJ的Blog

学海无涯苦做舟

0%

前言

在项目中某些场景需要先读取值,然后修改再保存,在这个过程中如果有并发请求,可能会突破程序设置的边界:在库存为 1 的情况下,同时有两个请求下单购买,如果不加处理,库存和订单总要异常一个。在单体服务中使用语言提供的锁就可以解决这一问题,但是在集群环境下,多节点的无状态服务,并发请求可能会通过负载均衡分发到不同的节点上,这时候就需要一个能在这种环境下也能生效的分布式锁了。

阅读全文 »

Working with Errors in Go 1.13

Damien Neil and Jonathan Amsterdam
17 October 2019

介绍

Go 将 error 作为 values 已经很好的为我们服务了数十年。尽管标准库对 errors 的支持很少——只有errors.Newfmt.Errorf函数,会产生只包含消息的 errors——内置的 error interface 允许 Go 程序猿添加他们想要的任何信息。它所需要的只是实现一个Error方法:

1
2
3
4
5
6
type QueryError struct {
Query string
Err error
}

func (e *QueryError) Error() string { return e.Query + ": " + e.Err.Error() }

像这样的 Error 类型无处不在,而且他们存储的信息千差万别,从时间戳到文件名到服务器地址。通常,该信息包括另一个较低级的 error 以提供额外的上下文。

阅读全文 »

原文:https://go.dev/blog/error-handling-and-go

错误处理与 Go

Andrew Gerrand

2011 年 7 月 12 日

介绍

如果你写过任何 Go 代码,你可能会遇到内置的 error 类型。Go 代码使用 error 值来表明不正常的状态。例如:os.Open 函数在他打开文件失败时会返回非空的 error。

1
func Open(name string) (file *File, err error)

以下代码使用 os.Open 去打开一个文件。如果发生了错误他会调用log.Fatal去打印错误消息和停止。(log.Fatal 会调用 os.Exit())

1
2
3
4
5
f, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}
// do something with the open *File f

你可以在 Go 中用知道的关于这个 error 类型来完成很多工作,但是本文我们会仔细看看 error 和讨论在 Go 中错误处理的一些良好实践。

阅读全文 »

Raft(可理解的分布式共识)

所以,什么是分布式共识?

让我们以一个栗子开始…

假设我们有一个单节点系统,在这个栗子中,你可以认为我们的节点是一个存储单个值的数据库,我们还有一个可以向服务端发送值的客户端,在单节点上很容易就这个值达成一致或共识。

但是我们如何在多节点上达成共识?

这就是分布式共识的问题

阅读全文 »

如今一般的编程资料都会有中文版本,特别是出了一段时间且普及程度比较广泛的资料,几乎一定会有中文版本,那么我们为什么要自己去读英文原文,自己翻译呢?我自己思考如下:

  • 翻译质量参差不齐,无法保证全篇都是高质量的翻译,难免会有错漏之处,阅读原文可以更好的理解作者的意思
  • 第一时间没有中文资料的时候,一定是会去读英文原文的文档的
  • 日积月累,提升自己的阅读能力

即使译者可以保证通篇都是高质量的译文,但是在实际工作中还是难免需要阅读英文文档,需要一定的阅读能力,在平时自己翻译一些文档刚好可以提升一下自己的阅读能力。

以上。

原文:The Go Memory Model

约定:

  • 普通的小括号是我认为原文应该要加入括号中翻译的,属于原文的一部分,也有部分我觉得可能翻译的不够准确会放入英文原文
  • 小括号中带 ta(translator add) 的表示译者认为应该添加可以帮助更好的理解的
  • 某些单词可能不翻译更有原来的味道,比如 channel,也没必要一定要翻译成中文通道

The Go Memory Model

2014年3月的版本

介绍

Go 内存模型指定了以下情形可以被保证:在一个协程中读取一个变量可以观察到由不同协程写入同一个变量所产生的值。

建议

由多个协程同时修改数据的程序必须串行(ta:serialize,个人理解应该是串行而不是序列化)这种访问。

为了串行访问,使用 channel 操作或者其他同步原语(例如在 sync 和 sync/atomic 包中的)保护数据。

如果您为了理解您的程序行为(ta: 协程并发行为)一定要阅读此文档的剩余部分,那您真的是太明智了。

不要耍小聪明(Don’t be clever)。

阅读全文 »

前言

不全的记录,只是有一些命令还不是很熟,记录下来备查

k8s 快捷键

  • 将本地端口映射到 k8s 对应 pod:kubectl -n namespace port-forward authsv-7cfc56d85d-v24pb 9999:9090,-n 命名空间,9999 本地端口,9090 远程端口

  • 实时打印 pod 日志:

    1
    kubectl -n namespace logs authsv-6f5f544d75-qgw6g authsv --tail 10 -f
  • 获取定时任务列表:kubectl -n namespace get cronjob

  • 删除节点:kubectl -n namespace delete xxx

  • 进入容器执行 shell 命令:kubectl -n namespace exec pod -it sh

  • k8s 定时任务,没有秒

1
2
3
4
5
6
7
8
9
# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6) (周日到周一;在某些系统上,7 也是星期日)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
阅读全文 »

同事用的是 emacs 开发,每次使用 ec 命令时都会弹出一首唐诗,觉得挺有意思的。于是咨询了一下,使用的是 fortune 和阮一峰大神整理的两个 tang300 的数据文件。

于是在 .zshrc 中编写了一个 vim 代码,让 vim 在启动时也会弹出一首唐诗:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
alias v=av
alias nv=av
alias vim=av

function av() {
# res=`curl --connect-timeout 2 https://v1.jinrishici.com/rensheng.txt`
# echo -e "\033[31m $res"
fortune -e tang300
sleep 0.7
if [[ $1 == *.java ]]
then /opt/homebrew/bin/vim $1
else nvim $1
fi
}
阅读全文 »

很久没写过技术类的文章了,最近打算重新拾起来,以前写的虽然比较浅,但是毕竟也记录了自己成长的过程,所以还是都放到这个博客上。后续写的可能更多的会和 go、java 相关,以上。

2021-10-28 09:05:05