基本http服务性能测试(Python vs Golang)

最近学习Golang,总想体验下并发到底有多叼,必我大 python强势多少。 学习了官方教程的http 服务,用性能测试工具wrk测试了下,发现结果很令人惊讶~

wrk可以参考我的博客,有基本用法说明:http://blog.yuanzhaoyi.cn/2018/01/12/test.html

测试命令:wrk -t10 -d1m -c200 http://127.0.0.1:8080

含义:10线程,并发200链接,持续1分钟

http服务均返回基本的: "Hello World",应该不会有IO阻塞

Python 标准库BaseHTTPRequestHandler实现:

from http.server import BaseHTTPRequestHandler
from urllib import parse

class GetHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        message = "Hello World"
        self.send_response(200)
        self.end_headers()
        self.wfile.write(message.encode(‘utf-8‘))

if __name__ == ‘__main__‘:
    from http.server import HTTPServer
    server = HTTPServer((‘localhost‘, 8080), GetHandler)
    print(‘Starting server, use <Ctrl-C> to stop‘)
    server.serve_forever()

结果:每秒响应数量只有282个,测试时间越长会越低

因为是但进程,单线程,这个数据应该不错了,虽然GIL在io阻塞会释放线程,但也有一点性能消耗

Running 1m test @ http://127.0.0.1:8080
  10 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.05ms    6.73ms 265.58ms   98.90%
    Req/Sec   107.11    103.19     1.05k    84.08%
  16959 requests in 1.00m, 1.65MB read
  Socket errors: connect 0, read 19024, write 59, timeout 0
Requests/sec:    282.21
Transfer/sec:     28.11KB

异步框架为了方便,我们先用基于twisted的事件循环的tornado:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

if __name__ == "__main__":
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8080)
    tornado.ioloop.IOLoop.current().start()

结果:每秒响应数量有1300多个,明显好很多

Running 1m test @ http://127.0.0.1:8080
  10 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   147.44ms   45.17ms 467.54ms   86.25%
    Req/Sec   141.40     57.52   202.00     65.17%
  81818 requests in 1.00m, 16.15MB read
  Socket errors: connect 0, read 1, write 0, timeout 0
Requests/sec:   1361.25
Transfer/sec:    275.17KB

Python3开始支持原生的协程来处理事件循环,虽然tornado也支持,但为了方便,直接用号称最快的sanic测试吧

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/")
async def test(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=False, port=8080)

结果:每秒响应数量达到4400多了,看起来很不错了

Running 1m test @ http://127.0.0.1:8080
  10 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    45.59ms   16.91ms 255.88ms   71.70%
    Req/Sec   443.64    111.85     0.89k    68.56%
  264956 requests in 1.00m, 32.09MB read
  Socket errors: connect 0, read 67, write 0, timeout 0
Requests/sec:   4408.87
Transfer/sec:    546.80KB

最近学习了GoLang,就基于官方指南的http服务进行了基本测试:

package main

import (
    "fmt"
    "log"
    "net/http"
)

type Hello struct{}

func (h Hello) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, "Hello World!")
}

func main() {
    h := Hello{}
    err := http.ListenAndServe("localhost:8080", h)
    if err != nil {
        log.Fatal(err)
    }
}

结果也是让我大开眼界:每秒响应数量达到了35365,和python服务都不是一个量级

Running 1m test @ http://127.0.0.1:8080
  10 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     7.26ms    9.46ms 210.93ms   93.36%
    Req/Sec     3.56k     1.10k   19.98k    74.96%
  2125366 requests in 1.00m, 261.47MB read
Requests/sec:  35365.98
Transfer/sec:      4.35MB

简单总结下,测试中,内存都没有明显增长,必定没有什么操作,仅仅返回一个字符串。但是GoLang的CPU使用率明显增长,Sanic服务也有差不多的增长,其余CPU使用率增长幅度不大,但Python的服务应该都只用了CPU都一核心。但当CPU占比差不多的时候,GoLang的响应能力明显要更胜一筹。具体原因思考,除了CPU的核心使用区别之外,即真正并行的实现外,好像也没什么了。Python的异步服务和GoLang的服务应该都基于事件循环实现了协程的调度,当然实现方法肯定有很大的不同,具体还要继续学习了。不过GoLang天生并发的支持,的确对此优化的很不错。

这几个测试都是基于好奇,比较简单也不够严谨,但我觉得可以说明一些区别。如果发现什么问题,欢迎留言。

原文地址:https://www.cnblogs.com/yuanzhaoyi/p/8685535.html

时间: 2024-08-03 05:57:59

基本http服务性能测试(Python vs Golang)的相关文章

# 深入浅出爬虫之道: Python、Golang与GraphQuery的对比

深入浅出爬虫之道: Python.Golang与GraphQuery的对比 本文将分别使用 Python ,Golang 以及 GraphQuery 来解析某网站的 素材详情页面 ,这个页面的特色是具有清晰的数据结构,但是DOM结构不够规范,无法通过单独的选择器定位页面元素,对页面的解析造成了一些曲折.通过这个页面的解析过程,深入浅出的了解爬虫的解析思想与这些语言之间的异同. 深入浅出爬虫之道: Python.Golang与GraphQuery的对比 一.前言 1. 语义化的DOM结构 2. 稳

Python与Golang协程异同

背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位. 进程和线程的关系: 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. CPU的最小调度单元是线程不是进程,所以单进程多线程也可以利用多核CPU. 协程的定义: 协

关于linux上cron服务的python封装工具

关于cron:定时任务服务,一般linux自带且已启动.(pgrep cron查看cron服务是否启动了.) 关于plan:一个通过python来定制cron服务的工具.其官网:http://plan.readthedocs.org/ plan的使用例子: 例子1: from plan import Plan cron = Plan() output = dict(stdout='~/stdout.log', stderr='~/stderr.log') cron.command('date',

DevOps架构下如何进行微服务性能测试

一. 微服务架构下的性能测试挑战 微服务与DevOps 微服务是实现DevOps的重要架构 微服务3S原则 DevOps核心点 微服务架构下的业务特点 亿级用户的平台 单服务业务随时扩容 服务之间存在相互调用关系 版本更新快,上线周期短 微服务架构下的性能测试挑战 单服务流量激增时扩容调用链条变长,调用关系更加复杂微服务拆分导致故障点增多▼ ▼ ▼单服务变更性能影响如何评估?性能瓶颈在各微服务间漂移,如何做好性能测试?应对突发流量需求,扩容能否解决问题,如何扩容?服务实例数量众多,如何收集信息,

GetNumber的实现(Python &amp; Java &amp; Golang)

TCO2014的编程赢取门票的题目,大致是从一个数组(大小为K),可以选取1-K个数,必须保证这n个数是从1-n,返回所有的选取方法个数. 思路:首先是得到从1开始连续的数,保存每个数的个数.然后通过排列组合得到结果. 当时采用的Python编写,大致的模样是这样(题目要求的类名就略去了): def getNumber(type): c = [0] * len(type) s = 0 p = 0 for x in type: if x <= len(type): c[x-1] += 1 for

2019年Python、Golang、Java、C++如何选择?

前言 作为开发者我们都知道,开发后台语言可选择的方向会很多,比如,Java,go,Python,C/C++,PHP,NodeJs….等很多,这么多语言都有什么样的优势?如果让你学习一门后端语言,又该如何选择呢? Java 编译语言,速度适中(2.67s),目前的大型网站都是拿java写的,比如淘宝.京东等.主要特点是稳定,开源性好,具有自己的一套编写规范,开发效率适中,目前最主流的语言. 作为编程语言中的大腕.具有最大的知名度和用户群.无论风起云涌,我自巍然不动.他强任他强,清风拂山岗:他横由他

Python与Golang对比

一:前言 刚看了一篇软文,说什么“才华是改变人生最有效的途径”,反正呢,大体就是科技进步,要想一直在车上,就得不断的学习,刚好最近也准备学习Golang,最近火的不能在火了吧,刚好也有些Python基础,所以就想在学习Golang的同时,对比着Python,查漏补缺下Python的知识,我终相信语言是相同的,只是个别语法不一样,翻看以前写的Python笔记,现在回过头看看,挺潦草的哈,所以也准备借这个机会,把Python的笔记该重构的重构,该补充的补充,同时记录下Golang的学习历程. 二:特

Jmeter服务性能测试工具

Jmeter性能测试工具 下载地址:http://jmeter.apache.org/download_jmeter.cgi Windows下使用 这里我们选择Binaries包,jmeter不需要安装直接解压使用,但是需要配置Java环境 安装jdk,这里就不说了 配置Java环境变量: win7系统 计算机--属性--高级系统设置--高级--环境变量--系统变量--新建 变量名:JAVA_HOME 变量值:C:\ProgramFiles (x86)\Java\jre1.8.0_101    

用Python解析Golang源文件

在给ulipad代码编辑器做一个支持Golang的plugin,这个文件是plugin所需的mClassBrowser.py文件的一部分 GolangParse.py import re def parseFile(filename): dict = {'import':[], 'struct':{}, 'func':[]} in_import = False lines = open(filename).readlines() for linen in range(0, len(lines))