Switching from net/http to fasthttp, is it worth it?

xuanbao · · 1176 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;m currently using net/http package and after looking of the awesome-go github page, I found there&#39;s an alternative to the package which seems to be better. I heard a lot of good thing about the fasthttp package, but one thing that makes me stop from using is the websocket support. As listed on the page, this library doesn&#39;t support sockets &#34;yet&#34; (saw a post in 2015 where they&#39;ve been saying this will be fixed..). My question now is if it would be worth it to switch to fasthttp for production and if I switch, is there an workaround for using sockets? </p> <hr/>**评论:**<br/><br/>yangjunwei: <pre><p>no</p></pre>titpetric: <pre><p>basically</p></pre>kostix: <pre><p>Please read <a href="https://groups.google.com/d/topic/golang-nuts/OaQu4QezAr0/discussion">this thread on <code>golang-nuts</code></a> where the <code>fasthttp</code>&#39;s author states their stance on the HTTP RFC.</p></pre>dchapes: <pre><p>Basically <code>fasthttp</code> is <strong>not</strong> an HTTP server. It works with common HTTP clients but does not implement HTTP (i.e. a perfectly valid HTTP RFC complaint browser, tool, robot, etc may not work with this; there is a reason there are standards and not &#34;implement whatever subset/extensions you like&#34;).</p></pre>shahix: <pre><p>If you want to use standard libraries and expect compatibility with community packages, answer is no.</p></pre>tgulacsi: <pre><p>Appending to the list of cons of fasthttp (incompatibility, websocket): http/2. Which is a must if you want low-latency future-proof web app.</p></pre>mixedCase_: <pre><p>At the point the net/http package may prove to be a performance problem, you have to consider also ditching Go altogether for a lower level language and probably consider writing your own TCP/IP stack.</p> <p>In other words, no, it&#39;s very much unlikely you&#39;d want to stop using net/http.</p></pre>evanbyrne: <pre><p>I wouldn&#39;t go that far. If you are running into performance issues with net/http on a large-scale system that fits the niche, fasthttp is fast enough to be worth a look.</p></pre>mixedCase_: <pre><p>I find it hard to imagine any task that requires that performance from the HTTP routing, that you could be using Go for it, and that couldn&#39;t be better served with nginx. Then again I am no veteran, I would love to hear an example.</p></pre>evanbyrne: <pre><p>Anything where your network handling is the bottleneck, like serving from a cache. Honestly I&#39;m a little perplexed as to what you see Nginx being a solution for. If you are putting Go behind a reverse proxy, then it still has to interface with that reverse proxy somehow. If you could elaborate on what kind of situations that Nginx might improve performance that would be helpful.</p></pre>joushou: <pre><p>By being a fast cache. Faster than fasthttp.</p></pre>evanbyrne: <pre><p>You mean a page cache? By virtue of running as the server, a Go application can be pretty creative when it comes to caching.</p></pre>joushou: <pre><p>Ah, sorry, I thought it would be implicit: A HTTP entity cache, so that the Go server does not need to spin up its comparatively slow HTTP stack (regardless of using fasthttp or not). You know, like Varnish/Squid/others.</p> <p>I would recommend Varnish if you&#39;re looking to cache, but that&#39;s a personal opinion.</p></pre>evanbyrne: <pre><p>I would agree with you that such a type of caching seems to be better suited for Varnish. The use-case for Varnish is pretty narrow though, and over-reliance on it seems to be a limiting factor in a lot of content publishing platforms I&#39;ve seen.</p></pre>kl0nos: <pre><p>There are so many use cases that net/http would be a bottleneck and fasthttp would help, ex api which serve a value that is changing once every xx seconds, so basically you are serving value from memory to hundreds of thousands clients/s. Try harder next time.</p></pre>joushou: <pre><p>If you serve a value that changes once every xx seconds, then that sounds like you&#39;re looking for a fast cache.</p> <p>Fasthttp benefits become even more moot if you&#39;re serving API&#39;s that do something, rather than static content, as the CPU time most likely far exceeds the net/http overhead.</p> <p>I&#39;d love for net/http to get faster, and fasthttp certainly has a purpose, but let&#39;s not try to teach premature optimisation.</p></pre>kl0nos: <pre><p>That&#39;s why I wrote that it changes every couple of seconds and you have a lof of those values and routes, if you profile your code then fetching those values would be still little of CPU overall time. I don&#39;t teach anyone premature optimization, always measure before, but there are cases you know where you will have bottlenecks, if you are experienced enough you see use patterns and you will optimize in early stage anyway. If i look at the code I can pretty much see almost every allocation, cache impact, branch miss predictions etc. If you architect software and know how it will be used then you know where your bottlenecks are most of the time. So let&#39;s not make any perf advice premature optimization advice also.</p></pre>joushou: <pre><p>... It still sounds like caching by something much faster than what you can write in Go is the way to go, giving your example.</p> <p>But it seems like we agree on measurements before optimisation.</p></pre>kl0nos: <pre><p>Sure, but this doesn&#39;t change that my example is valid. </p> <blockquote> <p>It still sounds like caching by something much faster than what you can write in Go is the way to go, giving your example.</p> </blockquote> <p>Someone could write it in C to get it even faster but why? if Go will be enough? This what you wrote is an perfect example of premature optimization.</p></pre>joushou: <pre><p>Indeed it is valid. However, given the example, sacrificing net/http for fasthttp to gain the ability to send a static value extremely fast sounds like you&#39;re doing what in your backend application what your network architecture should do for you: cache. I cannot imagine a variation of your example where fasthttp would be a good solution. That is, apart if you&#39;re trying to serve way too many users with a single server, which is a terrible thing to do for <em>many</em> reasons.</p> <p>My original mention of a cache was to show that there are <em>other</em>, potentially more suitable ways out of this performance problem. You seemed to be arguing somewhat blindly pro-fasthttp, which to me seemed like premature optimisation (I have now said &#34;premature optimisation&#34; more today than I usually do in a year).</p></pre>kl0nos: <pre><p>I agree that there are other potentially more suitable ways to solve that problem. It&#39;s always about what works for you/your team, if Go+fasthttp works for your team and this solves your problem then use it. I am just opposing to thesis that fasthttp doesn&#39;t have any use case comparing to net/http. Like always it depends on many requirements. </p></pre>kl0nos: <pre><p>Your own TCP/IP stack? You are exaggerating. Ask anyone who wrote their own TCP/IP stack if that was worth it. You have pretty fast TCP/IP stack in BSD already, no need to write your own. There was also a lot of improvements in network scheduling in Linux 4.x kernel. If you have performance problems and need user space TCP/IP to bypass kernel then there are already solutions that you can use instead of reinventing the wheel, like DPDK (user space networking stack) where you can use polling instead of interrupts. But please don&#39;t propose own TCP/IP stacks as viable solution, this should be last resort. I am 100% sure that OP do not need one, so he should not consider it at all.</p></pre>mixedCase_: <pre><blockquote> <p>Your own TCP/IP stack? You are exaggerating.</p> </blockquote> <p><em>whoosh</em></p></pre>joushou: <pre><p>The kernel network stack shows signs of fatigue around the 10Gb/s mark on normal systems. I seriously doubt OP is in that region.</p> <p>But while you can gain some leeway going from net/http to fasthttp, I agree that you have <em>other</em> problems if you&#39;re hitting this performance limit. Not necessarily in choice of tooling as much as in load distribution architecture. Faster tools just extend your deadline for making things scaleable.</p></pre>jns111: <pre><p>I&#39;m running a bunch of services with the net/http package on low spec machines. CPU and Mem is never a problem. However, compatibility is if you want to use 3rd party packages/frameworks with their own implementation of &#34;context&#34;, which is a horrible idea. The best you can do is to stick to the http.Handler interface. Wheter it&#39;s a simple handler or a middleware, simply use the http.Handler interface. If you are unhappy with performance you will most likely find a ton of mistakes in your own code rather than in the net/http implementation that is responsible for poor performance.</p></pre>bmurphy1976: <pre><p>Riddle me this: do you need it? If you can answer that question then you can answer your question yourself. I suspect you don&#39;t know the answer to my question so the answer to your question is almost certainly no.</p></pre>ar1819: <pre><p>You should only use fasthttp if you serving most of your content from hot cache and you have more than 150k rps for that service. Basically fasthttp purpose is to have something like scriptable nginx (which also exists BTW). In any other scenario - like, for example, you interact with DB or external cache, the wins from using fasthttp will be unnoticeable. </p></pre>itsmontoya: <pre><p>Fasthttp is actually super slow when you add real world pauses. Most benchmarks are tuned in a particular way to make the author library look fantastic.</p> <p>We performed many real world tests and saw a performance DECREASE against stdlib</p></pre>3Dennis: <pre><p>I benchmarked fasthttp, net/http and labstack/echo some time ago with loader.io (and I recommend you to do benchmarks yourself and relax), nginx as reverse proxy.</p> <p>net/http and labstack/echo were using the same amount of CPU and memory. fasthttp was more efficient, that is true, it was consuming less memory and CPU, but I realized that for me the difference is not important.</p></pre>dlsniper: <pre><p>Do you realize that echo is using net/http?</p></pre>3Dennis: <pre><p>I have seen many other benchmarks where echo was benchmarked with net/http, so no, I was not aware that it is using net/http.</p> <p>For example, in this test echo-prefork is second best</p> <p><a href="https://www.techempower.com/benchmarks/#section=data-r13&amp;hw=ph&amp;test=plaintext" rel="nofollow">https://www.techempower.com/benchmarks/#section=data-r13&amp;hw=ph&amp;test=plaintext</a></p> <p>Another benchmark <a href="https://github.com/smallnest/go-web-framework-benchmark" rel="nofollow">https://github.com/smallnest/go-web-framework-benchmark</a></p></pre>dlsniper: <pre><p>The prefork stuff seems to be removed from the current HEAD of Techempower repository. And it wasn&#39;t specific to echo, all Go stuff seems to have had it. </p> <p>The fact that you see them tested apart is that echo has more routing stuff under the hood than the standard library. A summary look ok it should show this quickly. Currently, the only other implementation of the http protocol that I&#39;m aware of in Go is fasthttp, which has many issues, like not having websockets or http2 support plus a bunch of missing (edge?) cases from HTTP/1.1</p> <p>So while things might look pretty on the surface, I highly recommend doing the due diligence next time before assuming things. Also the whole benchmarks argument is hilariously deceptive since nobody will ever pull those numbers on a single machine doing any kind of meaningful workload and to think that the difference of a few nanoseconds will be of importance when you are on a virtualized environment (the cloud) or multi-tenant network or IO bound workload needs more reading/profiling of the system (as the router will be the least of concerns)</p></pre>3Dennis: <pre><p>Ok, forget about echo.</p> <p>I still recommend to bechmark fasthttp and net/http using loader.io or other simmilar site. The difference should be unimportant.</p></pre>dlsniper: <pre><blockquote> <p>The difference should be unimportant.</p> </blockquote> <p>Which difference?</p></pre>wot-teh-phuck: <pre><p>To be fair, the test might have been to measure the overhead added by echo...</p></pre>dlsniper: <pre><p>Naaah, I think it&#39;s just a classic case of speaking about something w/o understanding it.</p></pre>Spirit_of_Stallman: <pre><blockquote> <p>worth it to switch to fasthttp for production</p> </blockquote> <p>We use very heavy application with huge number of intensive connections. In case of &#39;net/http&#39; it used a huge number of resources, had big delays/latency and bunch of bugs (such as hung and unclosable connections, beast memory leaks; go 1.3|1.4|1.5). Thought already to change language. But has somehow come across fasthttp (likely has seen post right there). After fast migration I could not believe my eyes: on monitoring of system resources impression that is started nothing, but the application works properly, and does all the work, and it makes it really <em>fast</em> :) In this case it became a silver bullet.</p> <p>But when I tried to use fashttp in small projects where productivity is not the main task- it has not been the huge win. Incompatibility with a large number middlewares and incomplete realization of rfc (no HEAD method, for example; oh c&#39;mon!). So need choose for each particular case and requirements.</p> <blockquote> <p>is there an workaround for using sockets?</p> </blockquote> <p><a href="https://github.com/leavengood/websocket" rel="nofollow">leavengood/websocket</a> - websockets for fasthttp.</p></pre>peterbourgon: <pre><blockquote> <p>In case of &#39;net/http&#39; it used a huge number of resources, had big delays/latency and bunch of bugs (such as hung and unclosable connections, beast memory leaks; go 1.3|1.4|1.5).</p> </blockquote> <p>Can you quantify &#34;huge number of resources,&#34; especially relative to your expectation? And can you provide links to, say, 3 of these &#34;bunch of bugs&#34;?</p></pre>joushou: <pre><p>There <em>have</em> been quite a few issues, so I do not think we should doubt that problems were found. However, I doubt that the data from 1.3-1.5 is useable anymore, as a lot of things have happened since then.</p></pre>peterbourgon: <pre><p>Can you link 3 or 5 of your &#34;quite a few&#34;?</p></pre>joushou: <pre><p><a href="https://github.com/golang/go/issues?utf8=%E2%9C%93&amp;q=is%3Aissue%20net%2Fhttp" rel="nofollow">https://github.com/golang/go/issues?utf8=%E2%9C%93&amp;q=is%3Aissue%20net%2Fhttp</a></p> <p>There&#39;s plenty, both open and closed. Panics, http borks (headers, close behaviour, ...), odd cases of poor performance and more. I&#39;m sure you can go through some of them yourself.</p></pre>peterbourgon: <pre><p>Linking to every GitHub issue tagged with net/http is a cop-out, I hope you will agree. Can you please link to 3-5 of the <em>specific</em> issues you&#39;ve experienced? Since you and the parent have claimed and validated respectively specific pain from specific bugs in the HTTP package, I would hope direct references shouldn&#39;t be difficult to dig up.</p></pre>joushou: <pre><p>No, I do not agree.</p> <p>However, to entertain your laziness, I do recall opening <a href="https://github.com/golang/go/issues/14046" rel="nofollow">https://github.com/golang/go/issues/14046</a>, which ended up being a fatal runtime bug. As for workaround examples, HTTP/2 had to be disabled as a few browsers couldn&#39;t communicate with the server at all on the initial HTTP/2 release, and we had to set various socket options ourselves to ensure proper behaviour that http.ListenAndServe at least initially did not handle. However, I no longer work at the place, and don&#39;t have access to the full list of hacks deployed.</p> <p>With all due respect, I cannot understand why you find it hard to believe that net/http, a very large blob of code, should have bugs like any other project would have.</p></pre>peterbourgon: <pre><p>Thank you for linking to one specific bug that you found. Very esoteric! I&#39;m glad it was fixed. Can you provide two or four more links like that one?</p> <p>Of course I don&#39;t find it hard to believe that net/http has bugs. I&#39;m sure it does. I&#39;m trying to make sure that strong generalizations like &#34;net/http uses a huge number of resources&#34; or that it has a &#34;bunch of bugs [like] beast memory leaks&#34; are reified with specific examples. Otherwise, they&#39;re FUD.</p></pre>joushou: <pre><p>I think you misunderstood my original comment. I&#39;m saying that I do not have any doubt that he had such issues (like I did), but that data from go1.3 (or go1.5) is not representative for go1.8/tip. h2 is still not optimal (<a href="https://github.com/golang/go/issues/18404" rel="nofollow">https://github.com/golang/go/issues/18404</a>, <a href="https://github.com/golang/go/issues/18801" rel="nofollow">https://github.com/golang/go/issues/18801</a>, ...), but the h1 part is quite decent by now.</p></pre>Spirit_of_Stallman: <pre><blockquote> <p>And can you provide links to, say, 3 of these &#34;bunch of bugs&#34;?</p> </blockquote> <p>Special for you was look in our archives. <a href="https://groups.google.com/forum/#!topic/golang-bugs/yd2vxsj4nQE" rel="nofollow">1</a>, <a href="https://groups.google.com/forum/#!topic/golang-bugs/Yed2xrnijvg" rel="nofollow">2</a>, <a href="https://groups.google.com/forum/#!topic/golang-bugs/lwDJyXhu1NY" rel="nofollow">3</a>, <a href="https://groups.google.com/forum/#!topic/golang-bugs/Q06jb_rqtJo" rel="nofollow">4</a>. I think I can find more bugs and in more detail when I arrive to work. About resources I won&#39;t answer now. There was it already nearly two years ago, and I definitely didn&#39;t leave such documentation. It is possible to consider that here you have caught me :)</p></pre>peterbourgon: <pre><p>Nice, thanks!</p> <p>edit: hmm. #1 was a bug in httputil.DumpRequestOut, not sure if that qualifies. #2 wasn&#39;t a bug, but a change in unspec&#39;d behavior. #3 and #4 were legit (though somewhat esoteric) bugs in 1.4.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1176 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传