先来个段子:【并发处理连接数】

多高?

很高!

到底多高?

没有一亿,都算少了!

.

.

.

然后就没有然后了。。。

“段子 END”

这就是目前中国企业的通病:提个概念,没有答案,最后造成概念也模糊了,其实,我感觉它根本不知道要干什么!从头到脚都是病啊!

下面,我们谈谈,web服务连接和速度问题

现在,随着网络普及,对于服务的响应速度和并发处理能力都有了不同寻常的要求

所以,对于服务的标准也越来越高

我以最简洁的说法把问题描述一下,其它不解释

1. 响应速度,是指:对于客户端请求的事务处理时间的快慢,一般,要用分布式处理来快速得到可以分布式处理的事务的结果

2. 并发处理,是指:对于客户端的请求的事务可以并行在服务端处理,一盘要有线程池,工作者的逻辑概念介入

需要澄清一个概念,并发不是指客户端并发连接到服务器!!!!!!,这个是大多数中国开发者的死穴,而且死不悔改!!!!!

所以,你要好好考虑一下,这些固执的人群里,算不算有你有一个!!!

3. 服务器硬件性能越高,自然并发能力越高(多CPU,多内核);分布式算法优秀,自然响应越快了

好吧,关于文字,我就算这么多,我的博文不是教小白上路的,而是给学者指出路上哪里有坑的。希望你好好揣摩,也许直到今天你也是不懂web的吧

//DEMO

下面,还是上例程,出自于国外的一篇文章。

原作者,出于公司商业性质,说了90%的话,剩下的10%有问题,这些都体现在他给出的源码里露出了马脚,当然这就是把正确改不能用的代价。原谅他吧,搁你身上也一样。这就是公司,万恶的公司,不关作者的事,他只是想得意一下而已!

如果你看了他的文章和源码,你还是跑不起来的,所以,听我的,看我的吧

还是那句话,不过多解释,但不会不说明,如果你需要掰着指头教你写1,2,3,那么请回到亲爱的小学,去找老去的园丁吧,哈哈哈(对了,推荐电影:神秘代码)

/////////////////////////////////////

//go-server-effic.go

package main

import (
  "fmt"
  "os"
  "runtime"
  "net/http"
)

var (
  //Max_Num = os.Getenv("MAX_NUM")
  MaxWorker = runtime.NumCPU()
  MaxQueue = 1000
)

type Serload struct {
  pri string
}

type Job struct {
  serload Serload
}

var JobQueue chan Job

type Worker struct {
  WorkerPool chan chan Job
  JobChannel chan Job
  Quit chan bool
}

func NewWorker(workPool chan chan Job) Worker {
  return Worker {
    WorkerPool:workPool,
    JobChannel:make(chan Job),
    Quit:make(chan bool),
  }
}

func (w Worker) Start() {
  go func() {
    for {
      w.WorkerPool <- w.JobChannel
      select {
      case job:= <- w.JobChannel:
        // excute job
        fmt.Println(job.serload.pri)
      case <- w.Quit:
        return
      }
    }
  }()
}

func (w Worker) Stop() {
  go func() {
    w.Quit <- true
  }()
}

type Dispatcher struct {
  MaxWorkers int
  WorkerPool chan chan Job
  Quit chan bool
}

func NewDispatcher(maxWorkers int) *Dispatcher {
  pool := make(chan chan Job, maxWorkers)
  return &Dispatcher{MaxWorkers:maxWorkers, WorkerPool:pool, Quit:make(chan bool)}
}

func (d *Dispatcher) Run() {
  for i:=0; i<d.MaxWorkers; i++ {
    worker := NewWorker(d.WorkerPool)
    worker.Start()
  }

  go d.Dispatch()
}

func (d *Dispatcher) Stop() {
  go func() {
    d.Quit <- true
  }()
}

func (d *Dispatcher) Dispatch() {
  for {
    select {
    case job:=<- JobQueue:
      go func(job Job) {
        jobChannel := <- d.WorkerPool
        jobChannel <- job
      }(job)
    case <- d.Quit:
      return
    }
  }
}

func entry(res http.ResponseWriter, req *http.Request) {
  // fetch job
  work := Job{serload:Serload{pri:"Just do it"}}
  JobQueue <- work
  fmt.Fprintf(res, "Hello World ...again")
}

func init() {
  runtime.GOMAXPROCS(MaxWorker)
  JobQueue = make(chan Job, MaxQueue)
  dispatcher := NewDispatcher(MaxWorker)
  dispatcher.Run()
}

func main() {
  Port := "8086"
  IsHttp := true
  arg_num := len(os.Args)
  if 2<=arg_num {
    Port = os.Args[1]
  }
  if 3<=arg_num {
    if os.Args[2]=="true" {
      IsHttp = true
    } else {
      IsHttp = false
    }
  }
  fmt.Printf("server is http %t\n", IsHttp)
  fmt.Println("server listens at ", Port)

  http.HandleFunc("/", entry)

  var err error
  if IsHttp {
    err = http.ListenAndServe(":"+Port, nil)
  } else {
    err = http.ListenAndServeTLS(":"+Port, "server.crt", "server.key", nil)
  }
  if err != nil {
    fmt.Println("Server failure /// ", err)
  }

  fmt.Println("quit")
}

//结果

Finally:

为了避免大家陷入困境,我只给大家指出思路,这样就不会引导大家进入似懂非懂的怪圈

1. 协程池里的协程数目应该与CPU内核数一致,这个好理解,这时候效率和利用率都是最高的

2. 每个协程运行一个工作者出来处理客户端请求(我们就是简单的打印出“Just do it”而已,不在于复杂度,在于处理流程)

好吧,再简单讲讲代码

首先,请自己去学习:Go的协程和渠道(文字概念可以去看书,例子,我之前的博文都有涉及,保证都是可运行的例子)

这个demo的核心:

1. 工作者工作协程,挂入调度器,取Job,执行Job,周而复始

2. 调度器,从Job队列取Job,分配给工作者,周而复始

3. web响应里,模拟了客户的请求-Job,并将此Job放入Job队列,只有有客户端请求,就周而复始的工作

好了,真的好了

师傅领进门,修行在个人

哈哈,我是教"孙悟空"的导师!,哈哈哈哈哈

祝你Go的快,Go的好,Go的高

关于Go,大概真的只能到这里啦,天下没有不散的宴席,就到这儿吧

祝,顺利!!!!!

Go http server 高并发的更多相关文章

  1. 关于SQL SERVER高并发解决方案

    现在大家都比较关心的问题就是在多用户高并发的情况下,如何开发系统,这对我们程序员来说,确实是值得研究,最近找工作面试时也经常被问到,其实我早有去关心和了解这类问题,但一直没有总结一下,导致面试时无法很 ...

  2. SQL Server 高并发Insert数据解析,实践

    在现实的生产环境中,有可能遇到高并发insert的应用.在此应用时由于堆表(Heap)和聚集表的结构不同导致在高并发的情形下insert效率不尽相同.接下来我会简单的以测试用例来简要说明.并举例说明如 ...

  3. ql Server 高频,高并发访问中的键查找死锁解析

    死锁对于DBA或是数据库开发人员而言并不陌生,它的引发多种多样,一般而言,数据库应用的开发者在设计时都会有一定的考量进而尽量避免死锁的产生.但有时因为一些特殊应用场景如高频查询,高并发查询下由于数据库 ...

  4. Sql Server 高频,高并发访问中的键查找死锁解析

    死锁对于DBA或是数据库开发人员而言并不陌生,它的引发多种多样,一般而言,数据库应用的开发者在设计时都会有一定的考量进而尽量避免死锁的产生.但有时因为一些特殊应用场景如高频查询,高并发查询下由于数据库 ...

  5. 如何在高并发分布式系统中生成全局唯一Id

    月整理出来,有兴趣的园友可以关注下我的博客. 分享原由,最近公司用到,并且在找最合适的方案,希望大家多参与讨论和提出新方案.我和我的小伙伴们也讨论了这个主题,我受益匪浅啊…… 博文示例: 1.     ...

  6. 协程--gevent模块(单线程高并发)

    先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...

  7. PHP写的异步高并发服务器,基于libevent

    PHP写的异步高并发服务器,基于libevent 博客分类: PHP PHPFPSocketLinuxQQ  本文章于2013年11月修改. swoole已使用C重写作为PHP扩展来运行.项目地址:h ...

  8. 用Netty开发中间件:高并发性能优化

    用Netty开发中间件:高并发性能优化 最近在写一个后台中间件的原型,主要是做消息的分发和透传.因为要用Java实现,所以网络通信框架的第一选择当然就是Netty了,使用的是Netty 4版本.Net ...

  9. java系统高并发解决方案-转

    转载博客地址:http://blog.csdn.net/zxl333/article/details/8685157 一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图 ...

随机推荐

  1. easyui---form表单_validatebox验证框

    第一种方式:混合写法 $("#password").validatebox({ }) <td><input type="text" name= ...

  2. Red Hat6设置使用CentOS的yum源

    环境查看 red hat系统使用自己默认的yum源未注册在使用yum安装软件的时候会出现以下错误提示 可以修改成centos的yum源 卸载yum软件 rpm -qa|grep yum|xargs r ...

  3. p740+5802+外置磁带机连线

    扩展柜型号5802 主柜型号p740 下图是连接线说明 需要连12X 和 SPCN 单个磁带机SAS线两根连接单个PCI否则,磁带无法提供多个分区使用 通过HMC或者查看资源情况 HMC配置Lpar分 ...

  4. 京东无人超市的成长之路 如何利用AI技术在零售业做产品创新?

    随着消费及用户体验的需求升级.人货场的运营效率需求提升.人工智能技术的突破以及零售基础设施的变革等因素共同推动了第四次零售革命的到来,不仅在国内,国外一线巨头互联网亚马逊等企业都在研发无人驾驶.无人超 ...

  5. 初试 Entity Framework Core 的多对多映射

    今天在博问中看到一个关于 EF Core 的提问 ef core 2.0 多对多查询的问题,由于还没使用过 EF Core 的多对多映射,于是参考 EF Core 帮助文档快速写了个 .net cor ...

  6. [No0000C3]StarUML2 全平台破解方法

    首先,找到安装目录下的"LicenseManagerDomain.js"文件,路径"StarUML\www\license\node\LicenseManagerDoma ...

  7. hive中创建子表并插入数据过程初始化MR报错解决方法

    本文继成上一篇通过hive分析nginx日志文章,详情参考下面链接: http://www.cnblogs.com/wcwen1990/p/7066230.html 接着来: 创建业务子表: drop ...

  8. 可变数组(PLSQL)

    可变数组 可变数组与嵌套表相似,也是一种集合.一个可变数组是对象的一个集合,其中每个对象都具有相同的数据类型.可变数组的大小由创建时决定.在表中建立可变数组后,可变数组在主表中作为一个列对待.从概念上 ...

  9. LeetCode 942 DI String Match 解题报告

    题目要求 Given a string S that only contains "I" (increase) or "D" (decrease), let N ...

  10. Python开发【笔记】:asyncio 定时器

    asyncio 定时器 实现: import asyncio class Timer: def __init__(self, timeout, callback): self._timeout = t ...