CDC
change data capture
key 被更新的时候打印数据
开源框架选择合适的组件
e2e测试
责任链模式
不同的Handler 组成一条链,链条上的每一个环都有自己功能.一方面可以用责任链模式将复杂逻辑分成链条上的不同步骤
洋葱模式
拥有一个核心,这个核心一般是业务逻辑.而后在这个核心外层层面包裹,每一层就是一个middleware.一般用洋葱模式来无侵入式地增强核心功能,或者解决AOP问题
AOP
AOP是面向切面编程,用于解决横向关注点问题,如可观察性问题,安全问题等
sync Cond
使用场景
有一个协程正在接受数据,其它协程必须要等待这个协程接收数据完成,才能读取正确的协程
- 可以用一个全局变量标识第一个协程是否接收数据完成,剩下的协程反复检查该变量的值,直到读取到数据
- 也可以创建多个channel ,每个协程阻塞在一个channel上,由接收数据的协程在数据接收完毕后,挨个通知
哪些方法
NewCond 创建实例
Broadcast 广播唤醒所有
Signal 唤醒一个协程
Wait 等待
go context 应用
Context 解读
type Context interface {
Done() <-chan struct{}
Err() error
Deadline()(dealine time.Time,ok bool)
Value(key any) any
}
Context
是一个接口,定义了四个方法,他们都是幂等
Done()
返回一个channel 可以表示context 被取消的信号 当这个channel被关闭时 说明context被取消了,这是一个只读的channel 读一个关闭的channel会读出相应类的零值,并且源码里没有地方会向这个channel里面塞值,因此在子协程里读这个channel 除非被关闭否则读出不了任何东西.当子协程从channel读出了值后,就可以做出收尾工作,尽快退出
Err()
返回一个错误,表示channel 被关闭的原因 例如是被取消 或者超时
Dealine()
返回context的截止时间,通过此时间,函数就可以决定接下来的操作.如果时间太短,就可以不往下做了,浪费系统资源,也可以用这个dealine 来设置一个I/O
操作的超时时间
Value()
获取之前设置的key对应的值
canceler
type canceler interface{
cancel(removeFormParent bool,err error)
Done() <-chan struct
}
实现意思定义的两个方法,就表明该 Context是可以被取消的
请求requestId 链路
go channel 应用
停止信号
任务定时
与timer
结合
select {
case <-time.After(100*time.Millisecond)
case <- s.stopc:
return false
}
定时执行任务
package main
func worker() {
ticker := time.Tick(1*time.Secend)
for {
select {
case <-ticker:
fmt.Println("执行了1s ")
}
}
}
解耦生产方和消费方
控制并发 数
同时执行几百个任务 如何在任务执行过程中,对频率进行限制
package main
var limit = make(chan int,3)
func main(){
for _,w:=range work {
go func() {
// 超过三个为执行完成 一直等待
limit <-1
w()
<-limit
}()
}
}
构建缓冲型的channel,容量为3 接这遍历任务列表,每个任务启动一个goroutine去完成.真正执行任务,访问第三方的动作再w()中完成 在执行w()之前,先要从limit 中拿许可证,拿到许可证之后,才能执行w(),等任务完成后归还,
limit <-
在func 内部的原因
如果在外层,就是控制系统goroutine的数量,可能会阻塞for 循环,影响业务逻辑 limit 其实和逻辑无光,只是性能调优,放在内层和外层语义不一样
需要 defer
来保障