0%

No knowledge gap, no insecurity.

学习内容

阅读全文 »

最近在研究gRPC的客户端连接可用性的时候,测试了一个场景:gRPC的服务端主动断掉TCP连接之后,gRPC客户端持有的连接是否有效?步骤如下:

  1. 启动 gRPC 的客户端和服务端。
  2. gRPC 客户端向服务端发送一些数据(建立 TCP 连接,虽然 gRPC 是基于 http2,但是底层还是 TCP)。
  3. 杀死 gRPC 服务端,然后再快速成功拉起 gRPC 服务端。
  4. gRPC 客户端继续向 gRPC 服务端发送请求,是可以正常响应的(gRPC 客户端会自己维护连接的可用性)。

以上步骤,乍一看是没有问题的,但是想起 TCP 谁主动关闭连接,谁的连接状态就会变成 TIME_WAIT,TIME_WAIT 是需要 2MSL(linux 系统固定 60s)处于等待状态,期间服务端应该是不能使用同一个端口,也就是说应该不能立马拉起来的(与步骤 3 相矛盾)。

基于以上疑问,我对相关知识进行了一个梳理,一步步来解答上面的疑问。

阅读全文 »

前言

在 web 开发中,常常会遇到一个接口内依赖多个服务的情况,那必然会存在多次的接口调用,此时有串行调用和并发调用两种处理方式,来看下这两种方式的对比:

对比看出,并发调用的耗时取决于耗时最长的那个服务,整体耗时比串行调用减少了很多。熟悉 Go 的小伙伴立马会想到使用 goroutineWaitGroup 来解决。但是在实际业务场景中,多个依赖中任何一个出现错误,我们期望的是立即返回,而不是等待所有的依赖执行完在返回结果。要想实现以上功能需要编排好并发任务,并且做好并发协程中的错误传递,这并不是个简单的事情,有很多细节要处理。归纳几个重点:

  1. 控制协程数量,当任务数太多时,不能一个任务起一个协程。
  2. 错误取消,在并发过程中,出现错误则取消所有任务,返回失败(使用者可选择不取消)。
  3. 防止协程泄漏。

针对以上场景,go-zero 提供了 MapReduce 并发控制工具,能够很好地进行并发任务的编排,下面先应用场景进行介绍,知道它的使用才能更好的了解它的设计思想。

阅读全文 »

Go 语言中每种类型都自己的默认零值,int 的零值是 0,bool 的零值是 false,string 的零值是 “”,而 nil 作为 pointer、slice、map、channel、function、interface 的默认零值,在 Go 语言中有着非常重要的地位。本文就是对 nil 的使用进行深入的探究。

阅读全文 »

最近接触到微服务框架go-zero,大致翻看了下框架代码,感觉整个框架结构清晰、代码简洁,所以决定阅读源码学习下。

go-zeroSharedCalls的作用是:将并发请求合并成一个请求,以减少对下层服务的压力。

阅读全文 »