阿小信大人的头像
做你说过的,说你能做的 阿小信大人

2019年记录的etcd相关调研2021-01-20 22:03

## etcd 是什么?

键值存储仓库,用于配置共享和服务发现。

> A highly-available key value store for shared configuration and service discovery.

使用 etcd 的场景默认处理的数据都是控制数据,对于应用数据,只推荐数据量很小,但是更新访问频繁的情况。

## 为什么不用zookeeper?

etcd 实现的这些功能, ZooKeeper都能实现。

ZooKeeper缺点:

1. 复杂。ZooKeeper的部署维护复杂
2. Java 编写。引入大量的依赖
3

......
#数据库#   [0]阅读全文[151]

goroutine 中的 panic 处理小结2021-01-08 22:34

在 go 的函数中使用 defer + recover 不能捕获在当前函数里面新开的 goroutine 的 panic。
在新的 goroutine 里面 panic 了即使上层有 recover 也会导致进程退出。

原因在于 panic 仅保证当前 goroutine 下的 defer 都会被调到,但不保证其他协程的defer也会调到。
panic 发生时会先处理完当前goroutine已经defer挂上去的任务,执行完毕后再退出整个程序(注意是退出进程而不只是协程)。

因此在开新的 goroutine 的时候,一定要要注意这里,不要以为最外层有了 recover 程序就一

......
#Golang#   [0]阅读全文[263]

lua 获取 nginx get 请求中的数组参数的坑2021-01-08 22:34

lua 在 nginx 里面获取 http get 请求的 url 数组参数时有个小坑需要特别注意。

线上的 get 请求传数组参数的形式让人眼花缭乱:

?p=v1&p;=v2
?p[]=v1&p;[]=v2
?p[0]=v1&p;[1]=v2

三种形式都有,然后 lua 的坑在于获取没有数组下标的数组参数的时候,数据格式可能不一样...导致程序异常。

lua 在 nginx 里面获取到的是:

raw: ?p=v1&p;=v2 -> {"p":["v1","v2"]}
-------------
ra

......
#Linux/Mac#   #nginx [0]阅读全文[218]

实现自定义的 gin Logger 中间件2021-01-08 22:33

image

### gin 的中间件原理解析
在 gin 中,中间件是一系列 `gin.HandlerFunc`链,它的函数签名类型和我们业务中写的URL对应的 handler 是一样的,都是`gin.HandlerFunc`。

gin 创建实例时返回一个 `Engine`,该`Engine`包含一个`RouterGroup`,而`RouterGroup`是一个`IRoutes`接口的实现,实现了路由注册的各种方法。

使用 `engine.Use` 方法可以全局注册多个中间件,也可以在注册URL handler 时局部添加中间件。

gin 在处理请求时,按顺序调用这条`gin.Hand

......
#Golang#   [0]阅读全文[242]

php-fpm 超时原因分析2021-01-08 22:32

### 背景

线上PHP服务,同一台机器上部有AB两个服务,A接收外部请求后再通过本地nginx请求部署在本地的B服务获取数据,同时也有大量的请求直接请求B服务获取数据,偶发会在一段时间内Nginx大量返回504请求超时和少量502连接被断开。

超时期间机器的CPU、内存、IO等负载都正常,请求量相对有增加但QPS不到100,比起高峰时间的请求量(QPS差不多2800)这点起伏几乎可以忽略不计,高峰时期服务却没有任何异常。通过日志中的requestid分析,发现从A服务到B服务之间的日志打印时间间隔很长,请求链路从A服务的最后一条日志到B服务的第一条日志之间间隔有10多秒之长。

......
#Linux/Mac#   [0]阅读全文[189]

Nginx + Lua + Redis 实现基础的令牌桶算法限流2020-06-16 17:30

image

## 关于令牌桶( token bucket )

令牌桶限流的原理是系统以一个恒定的速度往固定容量的桶里放入令牌,当有请求进来时,需要先从桶里获取并消耗一个令牌,当桶里没有令牌可取时,则拒绝服务或让请求等待。

如图:

![image](https://user-images.githubusercontent.com/2876405/84757479-cb8c3300-aff6-11ea-9be7-7d941ce1a2df.png)

每隔 1/r 秒向 bucket 中填充一个 token ;
bucket 最多只能存放 b 个 token ,如果填充 token 时

......
#数据库#   #redis #nginx [0]阅读全文[812]

gostub 打桩学习笔记2020-06-02 18:22

golang 单元测试中常用以下 4 个库方便测试代码的编写:

[gostub](https://github.com/prashantv/gostub) 主要用来给变量、函数、过程打桩 但是给函数打桩时,需要做侵入式修改

[convey](http://goconvey.co) 主要用途是用来组织测试用例的,提供了很多断言,兼容`go test`,有 web ui ,保存代码可自动跑测试

[gomock](https://github.com/golang/mock) 主要用来给接口打桩的。 mockgen 可以生成对应的接口测试文件。

[monkey](https:

......
#Golang#   [0]阅读全文[1313]

在zap中集成Sentry自动上报Error事件2020-03-15 17:59

截屏2020-03-15 17 48 56

在项目中发生了错误时我们都会打印Error级别的日志,但是即使有日志采集,在对发生Error时的告警通知和信息采集都不一定能快速且完善,目前对日志的告警也只是限于一些指标上的阈值告警,对于一些偶发或者非必现的Error其实我们还是很难及时发现,使用[Sentry](https://sentry.io)可以解决这类痛点,在可能产生Error的地方我们除了打印Error日志,同时还会对Error事件进行Sentry上报,Sentry会记录详细的相关issue并告警通知。

在golang的项目中我对易用性和性能及流行程度的综合考虑下选择使用[zap](https://godoc.org/go.

......
#Golang#   [0]阅读全文[1514]