支援高併發的基於epoll的go伺服器模型

2021-10-10 14:30:55 字數 4308 閱讀 7816

參照使用go編寫,基於epoll io復用模型,多協程同時監聽埠epoll,基於工作池,防止無限制協程個數

服務端:

select {}//阻塞

}func startepoll()

epoller, err := mkepoll()

if err != nil

go start(epoller)

for

log.printf("accept err :%v", e)

return

}log.printf("accept a conn")

if err := epoller.add(conn); err != nil

}}func start(epoller *epoll)

for _, conn := range connections

//_, err = io.copyn(conn, conn, 8)

//if err != nil

// conn.close()

//}"recv conn buf %s", string(buf))

var task ntask

task.conn = conn

task.epoller = epoller

workerpool.addtask(task)}}

}workerpool.go

package main

import (

"io"

"log"

"net"

"sync"

)type ntask struct

type pool struct

}func newpool(w int, t int) *pool ),

}}func (p *pool) close()

func (p *pool) addtask(task ntask)

p.mu.unlock()

p.taskqueue <- task

}func (p *pool) start()

}func (p *pool) startworker() }}

}func handleconn(task ntask)

task.conn.close()

}"read client data")

opsrate.mark(1)

}

epoll.go

package main

import (

"golang.org/x/sys/unix"

"log"

"net"

"reflect"

"sync"

"syscall"

)type epoll struct

func mkepoll() (*epoll, error)

return &epoll,

connections: make(map[int]net.conn),

},nil

}func (e *epoll) add(conn net.conn) error )

if err != nil

e.lock.lock()

defer e.lock.unlock()

e.connections[fd] = conn

if len(e.connections)%100 == 0

return nil

}func (e *epoll) remove(conn net.conn) error

e.lock.lock()

defer e.lock.unlock()

delete(e.connections, fd)

if len(e.connections)%100 == 0

return nil

}func (e *epoll) wait() (net.conn, error)

e.lock.rlock()

defer e.lock.runlock()

var connections net.conn

for i:=0; i < n; i++

return connections, nil

}//根據net.conn獲取實際的fd值

func socketfd(conn net.conn) int

客戶端:

clientepoll.go

//使用多個epoll

for i :=0; i < 4; i++

select {}//阻塞

}func mkclient(addr string, connections int)

var conns net.conn

for i := 0; i < connections; i++

if err := epoller.add(c); err != nil

}log.printf("init connections %d count", len(conns))

go start(epoller)

tts := time.second

if connections > 100

for i := 0; i < len(conns); i++ }}

}select {}

}func start(epoller *epoll)

for _, conn := range connections

if err := binary.read(conn, binary.bigendian, &nano); err != nil

conn.close()

continue

} else

err = binary.write(conn, binary.bigendian, time.now().unixnano())

if err != nil

conn.close()}}

}}

高併發伺服器(基於epoll)

本章節是用基本的linux unix基本函式編寫乙個完整的伺服器和客戶端例子,可在linux ubuntu 和unix freebsd 上執行,客戶端和服務端的功能如下 客戶端從標準輸入讀入一行,傳送到服務端 服務端從網路讀取一行,把小寫變為大寫,然後輸出到客戶端 客戶端收到服務端的響應,輸出這一行...

基於epoll的簡單高併發伺服器程式

epoll,select,poll都是基於linux unix的io復用技術。所謂io復用簡單來說就是讓核心來告知我們哪些檔案描述符讀或寫準備就緒。具體定義大家可以查閱各類書籍。epoll相對於select和poll來說對核心資源的利用更高效,因為select和poll是需要將帶有檔案描述符的資料結...

基於Redis Memcached的高併發秒殺設計

如何設計高併發時的秒殺,是面試電商技術職位時必考的題目。今天在這裡分享一下基於redis或memcached的技術方案,能解決重複提交 超發 高併發的問題。預定義總庫存 define total stock 5 預定義商品編號 define item id item 001 userid get u...