文章目录
1.微服务概览
2.微服务设计
可用性&兼容性设计
API Gateway (网关)
Microservice划分
Microservice安全
gRPC
第一课问题
- 微服务消息一致性: 分布式一致性, 本地事务+消息队列(二阶段提交),再利用消息传递 多个微服务
- 网关容灾:1. 基础设施,无状态,集群,权限验证等 不太容易挂 2.本身过载保护、限流,通常是大网关, 也可以以大业务线划分网关
- 服务拆分、聚合组装繁琐:目前没什么好的方法,业界有一个 faas
错误传递
按照我之前提到的原则,这是一个正确的错误处理方式:把错误返回到最上层。然后他会被打印到日志里。将错误收集反馈在 Web 服务层,只在一个地方处理错误。
但是这段代码有一个问题。不幸的是, Go 的内置错误没有提供错误栈跟踪。除此之外,这个错误是在外部依赖下生成的,我们需要知道项目中的哪段代码对这个错误负责。
github.com/pkg/errors
github.com/pkg/errors 拯救了这个问题。
通过wrap即可以包含底层被调用函数的上下文信息,又可以通过cause还原错误,对原错误类型进行判断,
我将上面的方法重写,添加堆栈跟踪,以及从数据层获取失败的信息,而且是在不改动原始的错误下:
import "github.com/pkg/errors"
// The repository uses an external depedency orm
func getFromRepository(id int) (Result, error) {
result := Result{ID: id}
err := orm.entity(&result)
if err != nil {
return Result{}, errors.Wrapf(err, "error getting the result with id %d", id);
}
return result, nil
}
// after the error wraping the result will be
// err.Error() -> error getting the result with id 10: whatever it comes from the orm
这个方法做的事儿是:在 ORM 返回的错误外面包装一层,在不影响原始错误的情况下,创建一个堆栈跟踪(译者注:wrap 的嵌套)。
让我们看下其他层是如何处理这个错误的。交互层:
func getInteractor(idString string) (Result, error) {
id, err := strconv.Atoi(idString)
if err != nil {
return Result{}, errors.Wrapf(err, "interactor converting id to int")
}
return repository.getFromRepository(id)
}
最顶层的 Web 服务层:
r := mux.NewRouter()
r.HandleFunc("/result/{id}", ResultHandler)
func ResultHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
result, err := interactor.getInteractor(vars["id"])
if err != nil {
handleError(w, err)
}
fmt.Fprintf(w, result)
}
func handleError(w http.ResponseWriter, err error) {
w.WriteHeader(http.StatusIntervalServerError)
log.Errorf(err)
fmt.Fprintf(w, err.Error())
}
错误返回 问题汇总
- error warp: 在跟第三方库、标准库交互的函数需要warp, 遇到错误 1.往上抛,2.降级
- log在哪里打比较好?如何记录完成上下文信息? 最外层打log,1. grpc将 request对象 用%v 全部打进去,2.http将form表单与错误写入error 3.将context传入log里面
- 自定义错误码:ddd思想,dao层就应该抛
错误信息才warp, 日志微乎其微
warp防止你在每一层都打日志,用errors.WithMessage
第四周 Go工程化实践
proto管理
https://www.bookstack.cn/read/API-design-guide/API-design-guide-README.md?wd=API-design-guide
配置
Unittest
评论系统架构设计
cache miss问题(回源)
comment-service核心店时处理Rpc请求,
cache miss(抖动)时,从mysql里面读数据,进行数据回源缓存。这是可利用kafka来做cache处理,避免内存中占用过大
comment-job开多线程,如何保证顺序性
kafka 按照comment_subject_id 来 使用一致的pattion去消费
两个服务相互调用,采用消息队列解耦
多个进程 单飞 如何回源问题 Kafka
单飞时设置 redis lock key,设置时间
CDN命中率
MAGLEV HASH
节省流量、安全考虑
cdn域名不能跟主域名一致