2021-11-19 17:55:19
619
0
0
## 1 背景
> 保护服务节点或者数据节点,防止瞬时流量过大造成服务和数据崩溃,导致服务不可用
## 2 主流限流算法
### 2.1 固定/滑动窗口限流算法
#### 2.1.1 固定窗口限流
实现过程:
也叫计数器算法,顾名思义就是固定一个窗口,在这个时间窗口下维护一个累加的计数器,每来一个请求计数器+1,并判断计数是否超过阈值,
超过阈值则拒绝请求直到下一个时间窗口将计数器清零再继
2021-07-22 14:23:20
322
0
0
订阅subscribe
package main
import (
"fmt"
"github.com/go-redis/redis"
)
func main() {
client := redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
})
pubsub := client.Subscribe("chat")
defer pubsub.Close()
for msg := range pubsub.Channel() {
fmt.Printf("channel=%s message=%s\n", msg.Channel, msg.Payload)
}
}
订阅psubscribe
package main
import (
"fmt"
"github.com/go-redis/redis"
)
func main() {
client := redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
})
pubsub := client.PSubscribe("*")
defer pubsub.Close()
for msg := range pubsub.Channel() {
fmt.Printf("channel=%s message=%s\n", msg.Channel, msg.Payload)
}
}
发布publish
package main
import (
"fmt"
"github.com/go-redis/redis"
)
func main() {
client := redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
})
n, err := client.Publish("chat", "hello").Result()
if err != nil{
fmt.Printf(err.Error())
return
}
fmt.Printf("%d clients received the message\n", n)
}
2021-07-16 13:31:44
353
0
0
```go
package main
import (
"fmt"
"log"
"os"
"path"
"path/filepath"
"runtime"
"strings"
)
func main() {
fmt.Println("getTmpDir(当前系统临时目录) = ", getTmpDir())
fmt.Println("getCurrentAbPathByEx
2021-05-28 12:10:25
316
0
0
##【模板标签】
模板标签用`{{`和`}}`括起来
##【注释】
`{{/* a comment */}}`
使用`{{/*`和`*/}}`来包含注释内容
##【去掉空白】
`{{- . -}}`
可以使用`{{- `和` -}}`来分别去掉标签左右两边的空白。
可以单独使用,例如:
```
{{- 2 }}
{{ 3 -}}
```
##【变量】
* `{{.}}`
此标签输出当前对
2021-05-05 22:27:48
406
0
0
有时候,我们使用go语言开发一些程序的时候,往往出现多个进程同时操作同一份文件的情况,这很容易导致文件中的数据混乱。 我们需要采用一些手段来平衡这些冲突:需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock。
对于flock,我们最常见的例子就是nginx,进程起来后就会把当前的PID写入这个文件,当然如果这个文件已经存在了,也就是前一个进程还没有退出,那么Ngi
2021-05-05 22:23:20
349
0
0
前言
题目是golang下文件锁的使用,但本文的目的其实是通过golang下的文件锁的使用方法,来一窥文件锁背后的机制。
为什么需要文件锁
> 只有多线程/多进程这种并发场景下读写文件,才需要加锁
- 场景1-读写并发
读写并发场景下,如果不加锁,就会出现读到脏数据的情况。想象一下,读文件的进程,读到第500字节,有其它进程以覆盖写的方式向文件中写入1000字节,那读进程读到的后500字
2021-04-28 15:23:03
694
0
0
下面这个demo,在32位系统(我测试的运行环境:32位arm linux)会崩溃。
```
package main
import (
"sync/atomic"
)
type Foo struct {
a int64
b int32
c int64
}
func main() {
var f Foo
atomic.AddInt64(&f.a, 1) // 这里不会崩溃
atomic.AddInt64(&f.c, 1) // 这里会崩溃
}
```
崩溃信息如下:
```
panic: unaligned 64-bit atomic operation
goroutine 1 [running]:
runtime/internal/atomic.panicUnaligned()
/usr/local/go/src/runtime/internal/atomic/unaligned.go:8 +0x24
runtime/internal/atomic.Xadd64(0x1416084, 0x1, 0x0, 0x75fd8, 0x14000e0)
/usr/local/go/src/runtime/internal/atomic/asm_arm.s:233 +0x14
main.main()
/tmp/test.go:16 +0x3c
```
在Go源码go/src/sync/atomic/doc.go的注释中,有如下描述:
```
// BUG(rsc): On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX.
//
// On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.
//
// On ARM, x86-32, and 32-bit MIPS,
// it is the caller's responsibility to arrange for 64-bit
// alignment of 64-bit words accessed atomically. The first word in a
// variable or in an allocated struct, array, or slice can be relied upon to be
// 64-bit aligned.
```
大致意思是,在一些32位的环境(包括x86和arm),标准库sync/atomic中操作int64的函数存在bug,调用者需自行保证,被操作的int64是按64位对齐的。。否则给你来个panic。惊不惊喜意不意外。。
这里简单说一下64位对齐是啥意思,拿上面那个demo来说:
```
type Foo struct {
a int64 // 位置从0开始,满足64位对齐
b int32
c int64 // 位置`size(a)+sizeof(b)=96`,不是64的倍数,就不满足了
}
```
所以,atomic.AddInt64(&f.a, 1)不会崩溃,atomic.AddInt64(&f.c, 1)会崩溃。
值得一提的有几点:
64位系统原子操作int64没这个问题
32位系统原子操作int32也没问题
32位系统原子操作int64有问题,注意,是原子操作有问题,并不是说int64不能用
uint64和int64是一样,也即这个问题只关心整型位数,不关心符号
以上说的原子操作,特指Go标准库sync/atomic中的函数
解决方法有两种:
1. 一种是保证结构体中的需要使用atomic的int64按64位对齐,比如最简单的就是把这些变量的声明写在结构体的最前面。同时,还需要保证这种结构体被其他结构体嵌套时,也要64位对齐。缺点是编写和维护代码的心智负担比较大。
2. 另一种就是把int64变量的原子操作改成mutex互斥锁保护。缺点是mutex比atomic的开销大。
2021-04-21 13:57:57
533
0
0
## 一、添加免密认证
```
# cat ~/.ssh/config
# gitlab
Host gitlab.xxx.com
Port 22
HostName gitlab.xxx.com
PreferredAuthentications publickey
IdentityFile your_private_key_path
User wangruixing
############
2021-04-18 14:54:49
200
0
0
## 背景
在使用缓存时,容易发生缓存击穿。
**缓存击穿**:一个存在的key,在缓存过期的瞬间,同时有大量的请求过来,造成所有请求都去读数据库,这些请求都会击穿到数据库,造成瞬时请求量大、压力骤增。
## singleflight
**介绍**
`import "golang.org/x/sync/singleflight"`
singleflight类的使用方法:
新建一个singl
2021-01-30 19:16:55
1183
0
0
包下载:go get github.com/go-playground/validator/v10
一、概述
在接口开发经常会遇到一个问题是后端需要写大量的繁琐代码进行数据校验,所以就想着有没有像前端校验一样写规则进行匹配校验,然后就发现了validator包,一个比较强大的校验工具包下面是一些学习总结,详细内容可以查看validator
二、操作符说明
1/2