激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - golang實現基于channel的通用連接池詳解

golang實現基于channel的通用連接池詳解

2020-05-13 11:21xialeistudio Golang

這篇文章主要給大家介紹了關于golang實現基于channel的通用連接池的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。

前言

golang的channel除了goroutine通信之外還有很多其他的功能,本文將實現一種基于channel的通用連接池。下面話不多說了,來一起看看詳細的介紹吧。

功能

* 連接池中連接類型為interface{},使得更加通用

* 鏈接的最大空閑時間,超時的鏈接將關閉丟棄,可避免空閑時鏈接自動失效問題

* 使用channel處理池中的鏈接,高效

何為通用?

連接池的實現不依賴具體的實例,而依賴某個接口,本文的連接池選用的是io.Closer接口,只要是實現了該接口的對象都可以被池管理。

當然,你可以實現基于interface{}的連接池,這樣任何對象都可以被管理。

實現原理

將連接句柄存入channel中,由于緩存channel的特性,獲取連接時如果池中有連接,將直接返回,如果池中沒有連接,將阻塞或者新建連接(沒超過最大限制的情況下)。

由于面向接口編程,所有創建連接的邏輯是不清楚的,這里需要傳入一個函數,該函數返回一個io.Closer對象。

實現

由于并發問題,在需要操作池中互斥數據的時候需要加鎖。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package pool
import (
  "errors"
  "io"
  "sync"
  "time"
)
 
var (
  ErrInvalidConfig = errors.New("invalid pool config")
  ErrPoolClosed  = errors.New("pool closed")
)
 
type factory func() (io.Closer, error)
 
type Pool interface {
  Acquire() (io.Closer, error) // 獲取資源
  Release(io.Closer) error   // 釋放資源
  Close(io.Closer) error    // 關閉資源
  Shutdown() error       // 關閉池
}
 
type GenericPool struct {
  sync.Mutex
  pool    chan io.Closer
  maxOpen   int // 池中最大資源數
  numOpen   int // 當前池中資源數
  minOpen   int // 池中最少資源數
  closed   bool // 池是否已關閉
  maxLifetime time.Duration
  factory   factory // 創建連接的方法
}
 
func NewGenericPool(minOpen, maxOpen int, maxLifetime time.Duration, factory factory) (*GenericPool, error) {
  if maxOpen <= 0 || minOpen > maxOpen {
    return nil, ErrInvalidConfig
  }
  p := &GenericPool{
    maxOpen:   maxOpen,
    minOpen:   minOpen,
    maxLifetime: maxLifetime,
    factory:   factory,
    pool:    make(chan io.Closer, maxOpen),
  }
 
  for i := 0; i < minOpen; i++ {
    closer, err := factory()
    if err != nil {
      continue
    }
    p.numOpen++
    p.pool <- closer
  }
  return p, nil
}
 
func (p *GenericPool) Acquire() (io.Closer, error) {
  if p.closed {
    return nil, ErrPoolClosed
  }
  for {
    closer, err := p.getOrCreate()
    if err != nil {
      return nil, err
    }
    // todo maxLifttime處理
    return closer, nil
  }
}
 
func (p *GenericPool) getOrCreate() (io.Closer, error) {
  select {
  case closer := <-p.pool:
    return closer, nil
  default:
  }
  p.Lock()
  if p.numOpen >= p.maxOpen {
    closer := <-p.pool
    p.Unlock()
    return closer, nil
  }
  // 新建連接
  closer, err := p.factory()
  if err != nil {
    p.Unlock()
    return nil, err
  }
  p.numOpen++
  p.Unlock()
  return closer, nil
}
 
// 釋放單個資源到連接池
func (p *GenericPool) Release(closer io.Closer) error {
  if p.closed {
    return ErrPoolClosed
  }
  p.Lock()
  p.pool <- closer
  p.Unlock()
  return nil
}
 
// 關閉單個資源
func (p *GenericPool) Close(closer io.Closer) error {
  p.Lock()
  closer.Close()
  p.numOpen--
  p.Unlock()
  return nil
}
 
// 關閉連接池,釋放所有資源
func (p *GenericPool) Shutdown() error {
  if p.closed {
    return ErrPoolClosed
  }
  p.Lock()
  close(p.pool)
  for closer := range p.pool {
    closer.Close()
    p.numOpen--
  }
  p.closed = true
  p.Unlock()
  return nil
}

結論

基于該連接池,可以管理所有io.Closer對象。比如memcached,redis等等,非常方便!

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://segmentfault.com/a/1190000013089363

延伸 · 閱讀

精彩推薦
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
主站蜘蛛池模板: 久久成人亚洲 | 国产精品爆操 | 欧美日韩后 | 欧美女人天堂 | 污版视频在线观看 | 在线视频1区 | 国产91在线播放九色 | 中文欧美日韩 | 黄色av片三级三级三级免费看 | 精品999久久久 | 久久免费视频在线 | 九草视频 | 99精品视频在线看 | 草草久| 日韩视频―中文字幕 | 久久亚洲精品视频 | 十级毛片| 中国videos露脸hd | 在线区 | 日日操夜夜透 | 一级做受毛片免费大片 | 久久艹一区 | 午夜激情视频网站 | 高清国产福利 | 91一区二区在线观看 | 圆产精品久久久久久久久久久 | 久久av高清 | 中文字幕在线一 | 久久精品欧美视频 | 久久最新视频 | 国产一区免费观看 | 91久久久久久亚洲精品禁果 | 精品久久久久久亚洲精品 | 韩国十九禁高潮床戏在线观看 | 全免费午夜一级毛片真人 | 欧美久久久久久久久 | 九九黄色 | 亚洲一区二区三区在线免费观看 | 美国一级免费视频 | 欧美一区二区三区久久综合 | 一区二区三区四区五区中文字幕 |