tcp并发服务器(c20w)

** 原创文章,请勿转载 **

并发服务器是一个老生常谈的话题,今天这里也写一个。

1. 目标

同时在线连接20万(c20w)。

开发语言:重要的事情说三遍,GOLANG, GOLANG, GOLANG!

那为什么是20W,不是30W或其它? 这个数字随意。   :)

2. 环境:

虚拟机(xenserver),    虚出6台机器(OS: CentOS 6.6 64bit) :

. 一台服务器8核CPU,2G内存

. 五台客户端2核CPU,2G内存

3.  改centos几个参数, 6台机器一样:

# ulimit -a

看 open files

改成300000(大于20W就行) :

#  ulimit -n 300000

   改端口范围
  

# echo 1025 65000 > /proc/sys/net/ipv4/ip_local_port_range

4. golang代码

    服务端: server.go

package main

import (
    "log"
    "net"
    "sync"
    "time"
)

func main() {
    tcpAddr, err := net.ResolveTCPAddr("tcp", ":5000")

    if err != nil {
        log.Fatalln("net.ResolveTCPAddr fail", err)
    }

    listener, err := net.ListenTCP("tcp4", tcpAddr)
    if err != nil {
        log.Println("server failed to start...")
        return
    }

    defer listener.Close()
    go print()
    log.Println("begin listening, addr : ", tcpAddr)

    for {
        conn, err := listener.Accept()
        if err != nil {
            log.Println("socket accept failed. reason: ", err)
            continue
        }

        go handleConnection(conn)
    }

}

func print() {
    ticker := time.NewTicker(5 * time.Second)

    for {
        <-ticker.C
        log.Println(len(clients.Map))
    }
}

var num = 0
var num2 = 0
var clients = Clients{Map: make(map[string]int, 0)}

type Clients struct {
    sync.RWMutex
    Map map[string]int
}

func (c *Clients) Add(ip string) {
    c.Lock()
    c.Map[ip] = 1
    c.Unlock()
}

func (c *Clients) Del(ip string) {
    c.Lock()
    delete(c.Map, ip)
    c.Unlock()
}
func handleConnection(conn net.Conn) {
    ip := conn.RemoteAddr().String()
    clients.Add(ip)

    buf := make([]byte, 64)
    for {
        _, err := conn.Read(buf)
        //log.Println("n=", n)
        if err != nil {
            //log.Println(err)
            conn.Close()
            clients.Del(ip)
        }
    }
}

客户端: client.go

package main

import (
    "log"
    "net"
)

func main() {
    for i := 0; i < 40000; i++ {
        conn, err := net.Dial("tcp", "x.x.x.x:5000")
        if err != nil {
            log.Println(err)
            return
        }

        go Read(conn)
    }

    log.Println("ok")
    select {}
}

func Read(conn net.Conn) {
    buf := make([]byte, 64)
    for {
        _, err := conn.Read(buf)
        if err != nil {
            log.Println(err)
            return
        }
    }
}

结论:

开始时,服务器是2核,2G内存, 达到8W连接左右,接受新连接的速度就慢了。后来改成8核,20W连接无压力。

最终5个客户端,每个客户端发起40000个连接, 共20W连接。

服务器单进程, 接受20W个连接。CPU,内存压力都很小。

时间: 2024-10-14 06:22:26

tcp并发服务器(c20w)的相关文章

TCP并发服务器,每个客户一个子进程

在阅读完<unix 网络编程:卷一>之后,感觉作者真是unix下编程的大师级的人物.而对于我个人而言,每次阅读完一本技术书籍之后,一定还是得自己重新再写一遍程序(换点内容),复习书本中的内容(大致结构,或者说思想,相同),否则,你很难做到真的理解并掌握的地步. Okay,今天我带来的是服务器模型中的第一种,也是最基本最常用的一种模型–TCP并发服务器,每个客户一个子进程. 先简单介绍一下:TCP并发服务器,每个客户一个子进程,也就是说并发服务器调用fork派生一个子进程来处理每个子进程,使得服

TCP并发服务器(五)——每个客户一个线程

TCP并发服务器(五)——每个客户一个线程 1.说明 前面4个版本都是关于进程的,可以将进程改为线程来实现. 这个最简单的版本也快于前面的所有预先派生进程的版本. 2.代码 #include "unpthread.h" void sig_int(int signo) { DPRINTF("sig_int()\n"); void pr_cpu_time(void); pr_cpu_time(); exit(0); } void *doit(void *arg) { v

TCP并发服务器(一)——每个客户一个子进程

TCP并发服务器(一)——每个客户一个子进程 1.说明 这是最传统的并发服务器,对于每一个客户请求fork一个子进程.问题在于每次fork一个子进程比较耗费时间,下面会讲预创建进程. 程序代码基于UNP的库. 程序在使用进程的模式下是最慢的. 2.代码 #include "unp.h" int main(int argc, char *argv[]) { int listenfd; socklen_t addrlen; if (argc = 2) { listenfd = Tcp_li

TCP并发服务器(四)&mdash;&mdash;预创建子进程,accept互斥锁

1.说明 Posix文件上锁可移植到所有Posix兼容系统,但是涉及到文件系统操作,可能比较费时. 本次使用线程上锁保护accept,这不仅适用于同一进程中各线程之间上锁,也适用于不同进程之间上锁. 2.进程间使用互斥锁要求 (1) 互斥锁变量必须存放在由所有进程共享的内存去. (2) 必须告知线程函数库这是在不同进程之间共享的互斥锁.要求线程支持PTHREAD_PROCESS_SHARED属性.默认属性PTHREAD_PROCESS_PRIVATE, 只允许在单个进程内使用.   3.代码 支

Linux网络编程——tcp并发服务器(多线程)

tcp多线程并发服务器 多线程服务器是对多进程服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建.据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为"轻量级"进程.线程与进程不同的是:一个进程内的所有线程共享相同的全局内存.全局变量等信息,这种机制又带来了同步问题. tcp多线程并发服务器框架: 我们在使用多线程并发服务器时,直接使用以上框架,我们仅仅修改client_fun()里面的内容. 代码示例: #

Linux网络编程——tcp并发服务器(多进程)

一.tcp并发服务器概述 一个好的服务器,一般都是并发服务器(同一时刻可以响应多个客户端的请求).并发服务器设计技术一般有:多进程服务器.多线程服务器.I/O复用服务器等. 二.多进程并发服务器 在 Linux 环境下多进程的应用很多,其中最主要的就是网络/客户服务器.多进程服务器是当客户有请求时,服务器用一个子进程来处理客户请求.父进程继续等待其它客户的请求.这种方法的优点是当客户有请求时,服务器能及时处理客户,特别是在客户服务器交互系统中.对于一个 TCP 服务器,客户与服务器的连接可能并不

Linux网络编程——tcp并发服务器(poll实现)

想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程--I/O复用之poll函数> 代码: #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/select.h> #include <sys/time.h> #include <sys/socket.h> #incl

UNIX网络编程2.9端口号2.10端口号与TCP并发服务器

LINUX环境并发服务器的三种实现模型

服务器设计技术有很多,按使用的协议来分有TCP服务器和UDP服务器.按处理方式来分有循环服务器和并发服务器. 1  循环服务器与并发服务器模型 在网络程序里面,一般来说都是许多客户对应一个服务器,为了处理客户的请求,对服务端的程序就提出了特殊的要求. 目前最常用的服务器模型有: ·循环服务器:服务器在同一时刻只能响应一个客户端的请求 ·并发服务器:服务器在同一时刻可以响应多个客户端的请求 1.1 UDP循环服务器的实现方法: UDP循环服务器每次从套接字上读取一个客户端的请求->处理->然后将