这些天你听到了很多关于“微服务”的话题。SpringBoot是构建单个微服务应用程序的理想选择,但您还需要以某种方式将它们相互连接起来。这就是SpringCloud试图解决的问题,尤其是SpringCloudNetflix。它提供各种组件,例如:结合Eureka服务发现和Ribbon客户端负载均衡,为内部“微服务”提供通信支持。但是,如果您想与外界通信(您提供外部API,或者只是从您的页面使用AJAX),将各种服务隐藏在代理后面是一个明智的选择。作为常规选项,我们将使用Nginx作为代理。但Netflix带来了自己的解决方案——智能路由Zuul。它具有许多有趣的特性,可用于身份验证、服务迁移、分层卸载和各种动态路由选项。同时,它是用Java编写的。如果Netflix使用它,与本地反向代理相比它是否足够快?或者当我们需要更大的灵活性(或其他特性)时,它是否适合与Nginx结合使用。免责声明:不要认为这是一个严肃的基准。我只是想感受一下Nginx和Zuul之间的区别,因为我没有在互联网上找到任何基准(也许我搜索的时间不够长)。它不遵循任何推荐的基准测试方法(预热时间、测试次数......),我只是在不同的可用区使用3个EC2实例(这不能保证)。测试那么我做了什么?测试是比较两种解决方案的原始性能,没有任何其他特殊功能。我只是同时发出单个HTTP请求以获取一个HTML页面(大小约为26KB)。我使用ApacheBench以200个并发线程启动测试(我也尝试过httpperf,但它对CPU要求较高,所以我选择了要求较低的ab)。直接连接首先,我对不通过任何反向代理直接访问HTTP服务器的性能很感兴趣。Ab在可以直接访问目标服务器的机器上运行。$ab-n10000-c200http://target/sample.html....DocumentPath:/sample.htmlDocumentLength:26650bytesTotaltransferred:268940000bytesHTMLtransferred:266500000bytesRequestspersecond:2928.45[#/sec](mean)Timeperrequest:68.295[:0.341[ms](mean,acrossallconcurrentrequests)Transferrate:76911.96[Kbytes/sec]receivedConnectionTimes(ms)minmean[+/-sd]medianmaxConnect:4336.03266Processing:20357.535392Waiting:20356.434266Total:24687.866423Percentageoftherequestsservedwithinacertaintime(ms)50%6666%6775%6980%7090%7495%8198%9199%92100%423(longestrequest)很好,几个测试显示相似的值:2928、2725、2834、2648req/s。有一些偏差,但这些数字现在并不重要。现在我可以通过Nginx使用Nginx代理服务了。只需更新Nginx配置以代理到目标服务器,例如:server{listen80default_server;listen[::]:80default_serveripv6only=on;#Makesiteaccessiblefromhttp://localhost/server_namelocalhost;#allowfileuploadclient_max_body_size10M;location/{proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$remote_addr;proxy_set_headerHost$host;proxy_passhttp://target:80;}}像以前一样运行测试,输入:$ab-n50000-c200http://proxy/sample.html...ServerSoftware:nginx/1.4.6ServerHostname:proxyServerPort:80DocumentPath:/sample.htmlDocumentLength:26650bytesConcurrencyLevel:200Timetakenfortests:52.366secondsCompleterequests:50000Failedrequests:0Totaltransferred:1344700000bytesHTMLtransferred:1332500000bytesRequestspersecond:954.81[#/sec](mean)Timeperrequest:209.465[ms](mean)Timeperrequest:1.047[ms](平均值,跨所有并发请求)传输率:25076.93[Kbytes/sec]receivedConnectionTimes(ms)minmean[+/-sd]medianmaxConnect:35011.748114Processing:3715911.9160208Waiting:3615911.91604402P总计ercentageoftherequestsservedwithinacertaintime(ms)50%20966%21275%21480%21690%22095%22498%23299%238100%256(longestrequest)测试结果为954、954、941req/s性能和延迟(符合预期)都变差了。通过Zuul现在我们在同一台机器上安装了Zuul。它的应用本身很简单:@SpringBootApplication@Controller@EnableZuulProxypublicclassDemoApplication{publicstaticvoidmain(String[]args){newSpringApplicationBuilder(DemoApplication.class).web(true).run(args);}}我们还需要在application.yml中定义固定路由规则:zuul:routes:sodik:path:/sodik/**url:http://target现在我们尝试运行测试:$ab-n50000-c200http://proxy:8080/sodik/sample.htmlServerSoftware:Apache-Coyote/1.1ServerHostname:proxyServerPort:8080DocumentPath:/sodik/sample.htmlDocumentLength:26650bytesConcurrencyLevel:200Timetakenfortests:136.164secondsCompleterequests:50000Failedrequests:2(Connect:0,Receives-responses:2xx,Lengthnxred:Tonxntransfers2)1343497042bytesHTMLtransferred:1332447082bytesRequestspersecond:367.20[#/sec](mean)Timeperrequest:544.657[ms](mean)Timeperrequest:2.723[ms](mean,acrossallconcurrentrequests)Transferrate:9635.48[Kbytes/sec]receivedConnectionTimemeans[/ms]minsd]medianmaxConnect:21292.321010处理:15532321.646110250等待:10505297.24419851Total:17544333.146710270Percentageoftherequestsservedwithinacertaintime(ms)50%46766%55375%62680%68490%89695%116398%153199%1864100%10270(longestrequest)结果比我(乐观的)logs的猜测差(我们可以看到在Zuul中有两个'引发HTTP连接池超时的相应异常)。Apparentlythetimeoutis10secondsbydefault.我们再进一步测试,得到了更多的结果:DocumentPath:/sodik/sample.htmlDocumentLength:26650bytesConcurrencyLevel:200Timetakenfortests:50.080secondsCompleterequests:50000Failedrequests:0Totaltransferred:1343550000bytesHTMLtransferred:1332500000bytesRequestspersecond:998.39[#/sec](平均)Timeperrequest:200.322[ms](平均)Timeperrequest:1.002[ms](平均,acrossallconcurrentrequests)传输率:26199.09[Kbytes/sec]receivedConnectionTimes(ms)minmean[+/-sd]medianmaxConnect:2167.916126Processing:15184108.3Waiting394:13183105.92021934Total:18200107.82181983Percentageoftherequestsservedwithincertaintime(ms)50%21866%22875%23580%23990%25495%28798%40599%450100%1983(Wow,longestrequestimprovement)我认为JavaJIT编译对性能有所帮助,但要验证这是否只是巧合,请重试:1010req/sec。最终结果令我惊喜。结论Zuul的原始性能非常接近Nginx。事实上,我的测试结果在热身后甚至稍微好一些(重申免责声明-这不是一个严肃的基准)。Nginx表现出更可预测的性能(变化更少),遗憾的是在Zuul预热期间我们遇到了一些故障(150000个请求中有2个,但你的微服务应该是容错的,对吧?)。因此,如果您正在考虑使用Zuul的一些额外功能,或者想通过将其与其他Netflix服务(例如Eureka)集成来获得更多服务功能,Zuul看起来非常有希望作为简单反向代理的替代方案。也许这也是Netflix使用的,所以您也可以尝试一下。【本文为专栏作家“翟永超”原创稿件,转载请联系作者获得授权】点此查看该作者更多好文
