* If you are opening a DB connection on every request there's already an issue: you should be creating a connection pool using database/sql's sql.Connect and your database driver;
* The same goes for files: there should be no need to open a file per-connection. Cache the contents or read them on application startup; whichever is appropriate.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/iwCz_pqu8R4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
If you have 1000's of connected clients, then you must have 1000's of open file handles regardless of how many are "active" at a time. This isn't "wasting" file handles, its just how network IO works. If you do not use HTTP keepalives then you can close the connection after sending the response. There may be ways to avoid having a goroutine per client -- this behavior has bothered me, but it hasn't actually been an issue in practice.
Yes, I tried going that route. But due to many methods/attributes being lowercased I realized either I copy entire net/http or modify them. The three changes I mentioned in original mail is the minimum change required for that kind of workflow to work.
if you do not call accept, then you are relying on the OS's backlog to "queue" the connections for you - this may be fine for your use case. However, file handles are very "cheap" - tens of thousands of them are fine - even hundreds of thousands can be handled depending on what you are doing.However, once you call accept, based on what you described, you would have to complete the entire request/response and then close the connection before calling accept again if you really wanted to keep open file handles to a minimum. A relatively few amount of slow clients could "block" all of your goroutines.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/iwCz_pqu8R4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I am talking in the context of https://code.google.com/p/go/source/browse/src/pkg/net/http/server.go#1694, net/http does call Accept() at the start of iteration, and it does create a new goroutine.I want to be able to use rest of awesomeness of net/http, everything http related in go-world uses net/http. I want to be able to switch off goroutine creation. This is possible only if we modify net/http in the way I suggested in the original mail.
Similarly, you should not read all connections off OS queue, and put them in memory. Sure you can write customer listener, but then you will have to coordinate things. You will have to write custom Connection object too, to keep track of count of open connections. And in order to manage the count you will need some mutex somewhere. This is bad design.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/iwCz_pqu8R4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I have tried to benchmark it with ab, but ab is telling really bad story irrespective of my changes, sometimes it give 5-6K req/sec, and sometimes less than 100 req/sec.
What would be right way to benchmark it?
If we look at the Server.Serve method: https://code.google.com/p/go/source/browse/src/pkg/net/http/server.go#1694, we see that on each HTTP request it creates a new go routine. This is not too great, if I get 1000s of incoming connections, it will create 1000s of go routines, and if each handler opens a file descriptor, or mysql connection etc, we can run out of them.
One fix for that would be for the handlers to implement some kind of limiting, so even if there are 1000s of go routine handlers created, only a handful are actually active, and rest are blocking on something.
But even then this is wasteful. I want network to take care of such things, I do not want my program to accept a connection at a rate it can not handle.
I suggest the following:
- Server struct be added a new flag, SpawnGoRoutines, default true.
- defer l.Close() becomes if srv.SpawnGoRoutines { defer l.Close() }.
- The go c.serve() becomes if srv.SpawnGoRoutines { go c.serve() } else { c.serve() }
I want to be able to create lets say 10 workers, who will all call srv.Serve(l net.Listener), thus ensuring that at any time only 10 http requests are being served. Also since no goroutines are being created and destroyed, it should be slightly better performance/gc wise.I have not tested this yet, but I do not see any reason it wont work.Should I create work on this and submit a patch, or is it somehow wrong approach?
As it stands net/http will make the server crash if ulimit is low and it gets a burst of connection.
This should be fixed. I am surprised nobody else is seeing this. If resources are cheap for you, you do not dismiss a patch that makes a library more efficient, do you? And saying this will make it worse? Have I entered some twilight zone?
On Fri, Jul 4, 2014 at 8:22 PM, minux <mi...@golang.org> wrote:
On Thu, Jul 3, 2014 at 7:02 AM, <am...@browserstack.com> wrote:
If we look at the Server.Serve method: https://code.google.com/p/go/source/browse/src/pkg/net/http/server.go#1694, we see that on each HTTP request it creates a new go routine. This is not too great, if I get 1000s of incoming connections, it will create 1000s of go routines, and if each handler opens a file descriptor, or mysql connection etc, we can run out of them.
The problem is you shouldn't create new mysql connections for each request.Solve this, and the performance will be even better.As others have said, concurrency control is easy if you implement a custom Listener.use channel to distribute heavier work to worker goroutines (or even other machines), andyou can control the number of worker goroutines.
One fix for that would be for the handlers to implement some kind of limiting, so even if there are 1000s of go routine handlers created, only a handful are actually active, and rest are blocking on something.
But even then this is wasteful. I want network to take care of such things, I do not want my program to accept a connection at a rate it can not handle.
I suggest the following:
- Server struct be added a new flag, SpawnGoRoutines, default true.
- defer l.Close() becomes if srv.SpawnGoRoutines { defer l.Close() }.
- The go c.serve() becomes if srv.SpawnGoRoutines { go c.serve() } else { c.serve() }
I want to be able to create lets say 10 workers, who will all call srv.Serve(l net.Listener), thus ensuring that at any time only 10 http requests are being served. Also since no goroutines are being created and destroyed, it should be slightly better performance/gc wise.I have not tested this yet, but I do not see any reason it wont work.Should I create work on this and submit a patch, or is it somehow wrong approach?No, this is going backwards.--Amit UpadhyayVP Engineering | BrowserStack
--You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
If we look at the Server.Serve method: https://code.google.com/p/go/source/browse/src/pkg/net/http/server.go#1694, we see that on each HTTP request it creates a new go routine. This is not too great, if I get 1000s of incoming connections, it will create 1000s of go routines, and if each handler opens a file descriptor, or mysql connection etc, we can run out of them.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/iwCz_pqu8R4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
No. Please LISTEN (read) what everybody writes and even the doc contains: net/http.ListenAndServe is a convenience function, you don't need to use it, you can write your own loop which callsAccept and Serve as you wish.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/iwCz_pqu8R4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
No. Please LISTEN (read) what everybody writes and even the doc contains: net/http.ListenAndServe is a convenience function, you don't need to use it, you can write your own loop which callsAccept and Serve as you wish.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/iwCz_pqu8R4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.