不会飞的章鱼

熟能生巧,勤能补拙;念念不忘,必有回响。

Go基础冲刺营_Day4_并发编程、文件操作与泛型

优雅退出

监听系统信号

服务器难免要遇到重启、升级的问题。那么当我们的服务器关闭的时候,我们需要考虑:

  1. 拒绝新的请求
  2. 等待当前的所有请求处理完毕
  3. 释放资源
  4. 关闭服务器
  5. 如果这中间超时了, 我们要强制关闭了

基础语法 —— goroutine

  • 一段异步执行的代码
  • 用关键字 go 启动

channel 与 select

基础语法—— channel

  • 使用 make 创建 channel
  • 带缓冲和不带缓冲的channel
  • 用 <- 符号来表达收发

基础语法 —— channel 带缓冲

  • 放满阻塞生产者
  • 空了阻塞消费者

基础语法—— channel 不带缓冲

  • 缺了任何一边都要阻塞另外一边

基础语法 —— select

  • 等待多个 channel
  • select 比较常见和 for 循环一起使用

基础语法 —— Go源文件命名与平台

  • 模式:name_platform_arch.go
  • 一般最多就是根据 OS 来分。因为到了区分架构那个地步,就太底层了

Hook(钩子函数)设计

Http Server —— 注册 Hook

  • 我们这 WaitForShutdown 啥都没干,而我们是期望它能够完成拒绝新请求,等待旧请求,然后再我们改造一下 WaitForShutdown 让它可以接收Hook。
  • 考虑到我们的 Hook 可能写出 BUG 无法退出,所以我们还需要超时机制。
  • 我们利用 context 包来达成目标

Http Server —— 关闭动作

按照我们的设计,我们需要:

  1. 拒绝新的请求:需要一个开关
  2. 等待当前的所有请求处理完毕:维持请求计数
  3. 释放资源:用户可能需要自己释放一些资源
  4. 关闭服务器:把所有启动的 Server 都关闭了
  5. 如果这中间超时了, 我们要强制关闭了

Http Server —— 拒绝请求并记录

我们这 WaitForShutdown 啥都没干,按照我们的设计,我们需要:

    1. 拒绝新的请求:需要一个开关
    1. 等待当前的所有请求处理完毕:需要维持请求计数

我们需要注册一个 Hook,在收到信号之后关闭开关,然后停下来等待

这是一个很典型的 AOP 场景,所以我们可以考虑使用 filter 来判断要不要拒绝请求,并且维持请求计数

context 与 atomic

基础语法 —— context 包

context.Context 是 Go 提供的线程安全工具,称为上下文。
方法:
• WithTimeout:一般用户控制超时
• WithCancel:用于取消整条链上的任务
• WithDeadline:控制时间
• WithValue:往里面塞入 key-value
• Backgroud:返回一个空的 context.Context
• ToDo:返回一个空的 context.Context,但是这个标记着你也不知道传什么

基础语法 —— context 与 thread-local

  • Go 官方没有支持 thread-local(或者说 goroutine-local)
  • 第三方有人搞出来了类似的东西,但是一般不建议使用,因为实现太奇诡,大部分人都没胆子用在自己的
    项目上
  • 因为缺乏 thread-local,所以很多时候我们要实现类似的功能,都只能依赖于 context 在方法直接传递。
    因此一般建议自己的方法签名,都把 context.Context 作为第一个参数

基础语法 —— atomic 包

方法分成这几类:
• AddXXX:操作一个数字类型,加上一个数字
• LoadXXX:读取一个值
• CompareAndSwapXXX:大名鼎鼎的 CAS 操作
• StoreXXX:写入一个值
• SwapXXX:写入一个值,并且返回旧的值。
它和 CompareAndSwap 的区别在于它不关心旧的值是什么

• unsafepointer 相关方法,不建议使用。
难写也难读,不到逼不得已不要去用。尤其是不要为了优化而故意用 unsafepoint

静态资源服务

server Context 复用

接口的实现的注册与发现

------ 本文结束------
如果本篇文章对你有帮助,可以给作者加个鸡腿~(*^__^*),感谢鼓励与支持!