我尝试对Scotty进行测试,以测试网络I / O效率和整体吞吐量。
为此,我设置了两个用Haskell编写的本地服务器。一个不做任何事情而只是作为API的人。
相同的代码是
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.RequestLogger
import Control.Monad
import Control.Monad.Trans
import qualified Data.Text.Internal.Lazy as LT
import Data.ByteString
import Network.HTTP.Types (status302)
import Data.Time.Clock
import Data.Text.Lazy.Encoding (decodeUtf8)
import Control.Concurrent
import qualified Data.ByteString.Lazy as LB
import Network.HTTP.Conduit
import Network.Connection (TLSSettings (..))
import Network.HTTP.Client
import Network
main = do
let man = newManager defaultManagerSettings
scotty 3000 $ do
middleware logStdoutDev
get "/filters" $ do
response <- liftIO $! (testGet man)
json $ decodeUtf8 (LB.fromChunks response)
testGet :: IO Manager -> IO [B.ByteString]
testGet manager = do
request <- parseUrl "http://localhost:4001/dummy_api"
man <- manager
let req = request { method = "GET", responseTimeout = Nothing, redirectCount = 0}
a <- withResponse req man $ brConsume . responseBody
return $! a
我写了另一个调用此服务器并返回响应的服务器。
wrk -t30 -c100 -d60s "http://localhost:3000/filters"
Running 1m test @ http://localhost:3000/filters
30 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 30.86ms 78.40ms 1.14s 95.63%
Req/Sec 174.05 62.29 1.18k 76.20%
287047 requests in 1.00m, 91.61MB read
Socket errors: connect 0, read 0, write 0, timeout 118
Non-2xx or 3xx responses: 284752
Requests/sec: 4776.57
Transfer/sec: 1.52MB
在这两台服务器都运行的情况下,我执行了wrk基准测试并获得了极高的吞吐量。
ulimit -n
256
虽然这显着高于凤凰城等其他网络服务器,但我意识到这并不意味着大多数响应是由于文件描述符耗尽而发生的500个错误。
我检查了非常低的限制。
ulimit -n 10240
我将这些限制增加到了
wrk -t30 -c100 -d60s "http://localhost:3000/filters"
Running 1m test @ http://localhost:3000/filters
30 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 105.69ms 161.72ms 1.24s 96.27%
Req/Sec 19.88 16.62 120.00 58.12%
8207 requests in 1.00m, 1.42MB read
Socket errors: connect 0, read 0, write 0, timeout 1961
Non-2xx or 3xx responses: 1521
Requests/sec: 136.60
Transfer/sec: 24.24KB
我再次运行了wrk,这次显然已经大大减少了吞吐量。
Scotty
尽管500个错误的数量减少了,但它们并没有消除。我对Gin和凤凰城进行了基准测试,他们比http-client
更好,而没有给出任何500个回复。
我错过了什么谜题?我怀疑有一个问题我没有调试。
我了解http-conduit与这些错误有很大关系,Scotty
库使用它,这与{{1}}无关。
答案 0 :(得分:1)
主要街区的第一行是罪魁祸首。 我从
改变了这一行main = do
let man = newManager defaultManagerSettings
到
main = do
man <- newManager defaultManagerSettings
瞧,瞧,没有任何问题。此外,该程序的高内存使用率从之前的1GB稳定到21MB。
我不知道原因。对此有一个解释会很好。