FastAPI 中的Async (并发和async/await)

引用文地址:https://fastapi.tiangolo.com/async/

前言:fastapi是一个广泛使用的高效的restful api框架,他的作者在这篇讲解框架中使用async的说明详细举例解释了异步编程、并发和并行的区别,堪称经典,于是手痒总结如下(不敢说翻译)

async使用指导:

  • 如果这个请求比较慢,比如连接数据库读取数据、文件IO、rpc调用等一般加上async,我想普通项目里大部分请求都会多多少少跟数据库打交道,所以加的往往比较多;
  • 比较快,稳定的使用def即可,也可以把没有上面情况调用的都按照这类处理;
  • 分不清加不加就不加,放心这不是什么大的问题,我在测试中发现不加效率高一丢丢,毕竟async是要开销的,特别适合首页这种重缓存的场景;

异步编程:

Asynchronous Code是给语言层面提供一种方式描述程序在某一点等待慢操作比如慢文件读写或者需要其它资源协作,从而让计算机可以在等待中去执行其它工作。文中作者详细列举了相对于cpu和内存操作来说慢的多的慢操作如:

  • 网络通信
  • 文件读写
  • 远程api调用如rpc调用
  • 数据库操作和查询

异步是相对同步编程来说的,在执行顺序上并没有改变。实际效果就是同一台机器如果有比较多的慢操作使用异步编程可以提高吞吐率。这里再吐槽一下,大部分语言比如python、csharp、go等的async都是协程实现的,只有java是线程实现的。代价:进程>线程>协程,java不是不能用协程来实现完全是因为历史包袱,线程相对也不会丢失太多的性能。

并发和汉堡的故事

异步的描述通常称之为并发,它跟并行不是一回事,虽然他们经常都是描述在同一时间内处理不同的事情。在细节上两者大不相同,可以下面就是用汉堡的故事来理解:
你带着心爱的小妹挤进忙碌的快餐店,排队等着付钱买汉堡。
轮到你的时候,你付钱买了两个很赞的大汉堡。
付钱
收银员告诉厨房新的订单,哪怕厨房还在准备前面的汉堡
收银员告诉你取餐号码
然后你和小妹找张桌子谈谈人生谈谈理想,因为汉堡太赞需要时间慢慢做
你趁这个时间对小妹一阵猛夸,如何如何的魅力,如何如何的动人
轮到你了后去柜台取走汉堡
然后就可以和小妹一起慢慢品尝

设想一下,如果是计算机中这个故事会怎么样
排队的时候你可能需要被迫傻等,而不是做点有意义的事比如调情,因为收银员得一个个收钱
当轮到你的时候你才会忙着看菜单,点单,付钱,确认找回来的钱,就算这样你还是没有拿到汉堡,只能去找张桌子等待
直到这个时候你才可以做些有意义的事
因为你有取餐号,所以直到显示屏上通知你可以取餐都不用担心你的汉堡被偷了
最后你去柜台取餐,道谢后算是完成任务并开始任务品尝美味的汉堡。

并行汉堡

现在设想下如果不是并发,而是并行,那么你跟你的小妹来到汉堡店就不是排一个队伍了,而是并行比如8个队伍,没有收银员只有厨师。
你前面每个人都在等他们的汉堡,拿到汉堡后才能离开柜台,厨师只有交出汉堡后才会收下一位的订单。
终于等到你了,付钱,然后等待厨师去厨房做汉堡
没有取餐号,因为没人在你前面,这时你和你的小妹只能干一件事就是确保自己在第一个不让别人抢走汉堡
等待很久以后才能拿走,这里几乎没有时间给你调情,真是个悲伤的故事。
在这个并行场景中你和你的小妹是两个处理器都等待了很久。
快餐店需要8个处理器,而并发下只需要2个。
当然,这个体验肯定不好。

汉堡总结

这个场景中有非常多的等待,所以它更适合并发系统。这也是web程序遇到的问题。太多太多的用户,但是你的服务器要等待不那么快的连接,然后还要等待回应。虽然这里的等待是以毫秒记,但是加起来就很恐怖了。所以这就是为什么Web APIs都用异步。
对于大多数现有的python框架都是在异步特性出现前设计的,所以他们大多以并行的方式实现异步,性能不强。

是不是并发比并行更好?

不,使用场景不同,并发适合web程序,但不是所有。比如科学计算,图形/音频处理,机器学习,深度学习等都适合并行计算。并行计算主要解决cpu瓶颈。

阿里云vs华为云 的容器镜像服务swr使用体验

容器镜像服务是CI构建中很重要的一换,毕竟dockerhub没有私有镜像服务,它除了给你的docker镜像加速外还可以存放你的构建,最最重要的都是免费的,目前阿里华为都有类似的服务。我一直以来使用的都是阿里云容器镜像服务,速度刚刚的,今天在整镜像的时候发现死活登录不上去,检查了一遍确认都没错,一脸懵逼,就阿里一直以来的niaoxing万一是他的问题呢于是想该用华为并对使用体验做个对比。下面是阿里登录容器镜像的截图:

这里是个人凭证页,可能企业版有所不同
  • 吐槽1:固定密码也就是我一直用的,很好很方便,虽然有点小担心,但是确实门槛低,我就不喷了。
  • 吐槽2:看到我红色涂的那个了么,没错我的账号,因为特殊原因第一个原生的账号被别人用了,经历了一顿复杂的操作后我才拿到的第二个账号,这里吐槽下阿里的账号流程乱的不行,肯定没有很好的产品梳理,最后只能人工介入,是不是很阿里的smell,有经验的在用阿里产品的多多少少应该有类似的情况喷到。
  • 吐槽3:2的问题就算了,新的账号居然给我弄一堆***,阿里的同学们请问这是什么逻辑,有重复的或者任何原因用任何字符都行,来一堆***,让人总是认为背后真实的数字是什么,结果它真实的id就是星星。。。。
  • 吐槽4:星星带来的结果就是命令行里头你会提示错误,机智如我,你可以用ID来代替,ID是一串数字,可以在右上角找到

果断开始注册华为,这里赞一下登录时候的提示,当输入手机号后它会提示你选择,如果你曾经在华为不同的业务上注册的账号里选一个。另外找回账号时它不要求你全答对,这就很严谨又很人性化,最后能把账号顺利注销开始新生活。废话不多说,进入华为swr后傻眼了

原文链接:https://support.huaweicloud.com/usermanual-swr/swr_01_1000.html

这里最重要的是第三步,得到第三步就可以拼凑出4中的登录命令。

  1. 图中3里头就是用你的ak+sk hash出了登录密码,这里要赞一下的是这种方式不会丢失你的私钥,安全比阿里好多了,个人设置的固定密钥一般都比较简单。实在偷懒把生成的后的密钥记录下来即可。
  2. 最后生成命令这里更取巧,直接用了ak,ak本身就是密钥id,也就是说只要你这个密钥还用就成立,同样的你的这个ak销毁了,登录也就失效了。
  3. 这里的区域项目名可以在华为提供的可用区域里选择。我挺好奇的是阿里只给了一个杭州节点,华为给了north和east两个,难道阿里不是份额最大的厂么。

最后吐槽一下,发现使用阿里的各种镜像服务越来越不稳定,应该不是马爸爸缺钱了,估计是被人玩坏了,比如容器镜像,最近有人利用它不限制容量的漏洞来做网盘。。。华为就不行,它有2g上限,谁的镜像能上2g啊。名族之光,技术中流不是吹的。。。

理工男对衣架的选择/衣柜收纳之衣架篇

创作立场声明:拍不好,借淘宝图一用,希望给同样在思考收纳工具的值一点参考。

衣柜困局

衣柜困局

天气冷了,又到了翻衣服的时候了

首先我是个懒人,衣服叠的乱七八糟,虽然努力过把衣物分门别类,但是怪就怪总有几天是忽冷忽热的天气。作为一个理工男抓重点是咱的习惯,衣服么格子衫牛仔裤就行了,然后就这么蹉跎讲究了十几年。这几天又鼓起勇气打算用算法来科学的规划下。

首先理顺的原则非常重要,凡是都要从我懒的根本基础出发,所以太过细致繁琐的收纳一律不考虑,所有改变都要服从很顺手很方便的原则。在经历了数个小时的苦思冥想后决定之前之所以总是失败是抓错了重点,不能以整洁作为收纳的目标而忽视了天气才是决定衣物分类的最最大的影响因素。

从天气出发那么考虑的周期必须是一年中的变化,看了很多收纳文章都是按照四级来区分,天哪,我这理工男要把衣物分成四类,拜托别开玩笑了。其实回忆一下几十个春秋冬夏,不难发现真正衣物有大的区分的时候只有冬天最冷和夏天之间,也就是说夏天的时候咱不可能穿棉袄,反之依然,好吧,这是废话,但是收纳咱就可以按照这个原则来了。

当季区,缓冲区,储藏区

虽然我分为了三个区,但是实际上使用中只会分两个地方,衣柜和储藏间,下面就说说我是怎么分的。

理工男对衣架的选择/衣柜收纳之衣架篇

储藏区

:我家的储藏间离房间隔着一个客厅还是挺远的,这个每个人都不一样,但是我对储藏的定义是它可以远一点,就好象是电脑上的硬盘,你可以慢一点,但是必须得够大,咱实际上的储藏间不可能大但是能装很多是一样的道理。储藏间的原则就是当季绝对不会用的衣物才存放在这里,原则上一个月甚至两个月才会进行一次储藏间的调整,哎呀越说越像硬盘了。这里遵循之前说的最远距离原则,比如夏天,储藏间里应该是羽绒服、帽子、围巾、这些东西。这里要注意的是,但凡有可能冬夏都用到的东西(嘿嘿,我不多,可能有的人多,咱不细说),只要是可能当季用到的都不放。最后在储藏间的收纳上,建议按照队列原则,即是先进后出,换句话说就是你可以从左往右移动收纳,这样先放进去的东西最后下个周期才会用到。这个时候可能有人会觉得冬夏一年就一次,春秋是通用的有两次,队列会出现两次,其实不然,看完缓冲区您再品,细品。

理工男对衣架的选择/衣柜收纳之衣架篇

下面是购买地址:

https://item.taobao.com/item.htm?id=6332490120

当季区、缓冲区:

这个基本就是卧室里的衣柜了,如果你跟我一样有一个上图中带滚轮的室内衣架那么恭喜你,这不仅方便,还是懒人必备,当季区完全可以由它担当,其他的衣物放衣柜里作为过度区。这里安利下上面的带滚轮衣架,太好用了,不仅可以随手拉来拉去快速找衣服,下面还可以放一些内衣和袜子,比起衣柜不要太方便,高度可调节到手最舒服的位置,嗯,没错,懒人抬手也是很累的好吧。

之所以这么分配几个区域就是从衣物的使用频率来区分的,当季区就像是cpu内的缓存可以最快的速度满足当前的需求,假如温度变化大了,那么才值得多花两分钟去缓冲区就像是内存,比如夏天的时候短袖就是当季区里的,长袖的衬衫就是缓冲区里的,对了我冬季也会把衬衫放在缓冲区的,秋天衬衫是在当季区。怎么区分三个区域的衣物就想想使用频率就可以知道了。下面说说在这两个区域收纳中我使用到的神器

衣架的选择

便宜就是王道

便宜就是王道

这个必须重头戏,衣物的收纳最最用到的就是衣架了,那么怎么选衣架呢,比如上图就是我选的,没错平平无奇的衣架。选它的理由无他,便宜量足,够用,所以买一把放着解决主要矛盾:挂衣服,哈哈哈哈啊理工男对衣架的选择/衣柜收纳之衣架篇

理工男对衣架的选择/衣柜收纳之衣架篇

买上面普通衣架的时候在这家小店发现了这么个新奇的东西,哎唷我去,踏破贴无米处呀。没错,懒人么除了囊肿羞涩买的普通衣架外主力肯定得靠懒人衣架了咯,上面衣架完美解决我的各种使用场景,能挂所有衣物理工男对衣架的选择/衣柜收纳之衣架篇 。

外观展示

领口插入衣架

领口插入衣架

懒人衣架的标志就是可以从领口插进去,也是我挑选的第一标准,这里还有几款:

1号,最常见的

1号,最常见的

2号,也很常见

2号,也很常见

3号,少见

3号,少见

4号,没见过

4号,没见过

衣领插入,最重要的特点

红色标记的距离就是能插进的领口的大小,这里1号适用性最差,2号也好不到哪去,12基本有大半衣服是插不了的,这个特性聊胜于无,3号基本能适应大部分场景,但是跟我选的4号来还是差的远。最震惊的是,哪怕冬天那小口的高领毛衣它也可以轻松的进去而不会撑开哪怕一点点,就那么一下尝试就把握圈粉了。

叠挂,神奇的功能

叠挂,神奇的功能

叠挂,节省空间,神奇的分类

之前用过类似的衣架,说实话空间确实有省下来,但是并没有那么明显的作用,反倒是对于分类有奇效,哈哈没错,分类。比如哈对于懒人来说格子衫我会挂几件差不多的在上面,然后把刚洗过的挂最下面,每次只拿最上面的,对于懒人来说有时候反复穿同一件就是因为分不清哪一个是最近洗的。当然还有其他作用,比如把差不多的衣服,差不多的裤子挂一起。这个功能还常用在我会把搭配好的一整套用三个衣架挂一起,上衣+裤子+围巾,出门一手拎出来即可。

理工男对衣架的选择/衣柜收纳之衣架篇

啥都可以挂,一个衣架解决了所有衣柜里的问题

经过我的开发,发现衣柜里头不管是衣服还是裤子,甚至围巾,皮带等等都可以用这一款衣架解决。然后我就发现假如我都买这一款衣架那么一致性带来的美感会对整个衣柜的整洁度大大加分。。。。

总结

这次的衣物收纳整理以发现了一款无人问津的小衣架结束了,很久没有动力写东西了,也许这款衣架的厂家都不知道我的这些用途吧,没办法,很多用途不是懒人你是想不到的。比如我那么执着于 从领口插进去,理工男格子衫多,总是拧纽扣我会疯的,又比如用一种衣架解决所有衣物的问题,这就像是代码重构,这里头还有点小欣喜。

这家小店铺还真的不好找。

衣架店铺名是:圣乔日用品店铺

地址是:renren3d.taobao.com

衣架1:https://item.taobao.com/item.htm?id=620851237203

衣架2:https://item.taobao.com/item.htm?id=630433034430

文章转发自:https://post.smzdm.com/p/560972/

Windows10下载所有iCloud中的照片

开始只是想集中备份所有apple设备上的照片,后来发现windows上各种方式都比较麻烦。事实证明只有icloud才是唯一一种可以持续保持手机备份更新的途径。因为云上贵州的原因,现在下载速度基本不是问题了。

我有四万七千张照片,别问我为啥有那么多照片,手机更新了,但是每次都是恢复以前的一切,但是照片庞大到传统的各种导出很无力,特别是使用了icloud也是。这里icloud一定要用微软商店中的版本,老版本就是有个安装包的那个可以点击下载所有文件,问题是不会自动下载最新的,然后下载还容易中断。最新版本会再本地出现一个icloud挂载文件夹,也是windows10最新支持的,出于备份的目的我需要有的不仅仅是镜像而是真正的下载我的拷贝。可以右击资源管理器中的icloud标识选择“Always keep on this device”,他就会自动下载所有文件。

还好我开始准备这件事,已经发现了数个文件和照片不可恢复!!!


2020年12月18日更新:这个选项的变更只是增加了本地的照片,长久不用后还是会缩小占用的空间,也就是说很多还是会白下载。最终的解决的办法是写了个脚本把icloud下的文件全部拷贝到另一个不受监控的目录,这里我使用了win32api,拷贝这个东西吃过两次亏,一次是默认的拷贝居然是链接我养成了查看实际占用磁盘大小的习惯;第二次拷贝丢失了exif,对于照片来说这个exif等附加信息还是很重要的,而最佳的保存办法就是调用系统自己的copy就是win32api了。

import threading
import os, time, threading
from tqdm import tqdm
from pathlib import Path
from multiprocessing import Pool, cpu_count
from tqdm.contrib.concurrent import process_map
import win32file

total_file_size = 0
lock = threading.Lock()
base_dir = Path('xxxx')
des_dir = Path('xxxx')
file_names = os.listdir(str(base_dir))
pbar = tqdm(total=len(file_names))


def try_open(file_name):
    # print('opening at %s:\t\n' % str(time.strftime('%H:%M:%S', time.localtime())) + str(file_path))
    start_time = time.time()
    global pbar
    source_path = os.path.join(str(base_dir), file_name)
    des_path = os.path.join(str(des_dir), file_name)
    if not os.path.exists(des_path):
        # 拷文件
        # 文件已存在时,1为不覆盖,0为覆盖
        win32file.CopyFile(source_path, des_path, 1)
    pbar.update(1)


if __name__ == '__main__':
    start_time = time.time()
    r = process_map(try_open, file_names, max_workers=5)
    # with Pool(cpu_count()-2) as pool:
    #     pool.map(try_open, files)

    print("--- %s seconds at %s---" % (time.time() - start_time, time.strftime('%H:%M:%S', time.localtime())))
    # s1=os.stat(os.path.join(str(basepath),'12715.mp4'))
    # print(s1)
    # s2=os.stat(os.path.join(str(basepath),'438.mp4'))
    # print(s2)

Photoprism ,Seafile,Nextcloud,Joplin,文件相册笔记管理

本来应该分开单独写的,太久没写东西懒惰了干脆一次写完吧。

有了nas后一直在试着挖掘它的潜力,这里不得不提zerotier这个东西,完美的解决穿透和跨网的加密问题,实在是家庭nas必备。走的是udp,除了第一次连接略有延迟外速度都不错也很稳定,现在属于self-host基石中最重要的一个了。

nas玩了好多年,现在稳定使用的事赛扬的cpu和六块大硬盘。系统使用的是windows server 2019,为啥没用黑群辉,为啥没用linux。作为母系统来说win绝对是最好的,个人nas经常要解决的就是长期运行、不可间断的,比如百度网盘,长时间跑脚本的数据,这些都要求系统跟pc有很大的兼容,所以应用上win胜出。win server还提供了block级别的重复数据,所以省心的给你节省空间。这块其实专门写个专题都有必要。

好了回到主题的服务上,当然肯定都是泡在linux,宿主在windows下毫无违和感,运行的很棒。首先最重要的服务莫过于文件管理,之所以使用Seafile那是因为他的稳定和高效,请记住,php的东西都很吃资源,所以尽管nextcloud生态很好我也放弃了,如果我是大的cpu可能会考虑吧。稳定第一,nas本来就是比较耗费时间的事情,所以所有服务我都希望一次配置终生享受,或者很简单的维护,seafile配置好后同步非常稳定,很好的默默无闻的在后台工作。效率排到第二是因为cpu是赛扬,属于小功率的u,如果本来十几天的事情能通过效率在一天解决那为什么要花十几天呢。这里不得不提,所有跟php有关的服务都会效率低下,所以如果配置php相关的要留心。这里要说下只要go的服务,目前为止效率都很高!!!比如后面说的photoprism和msysgit。seafile不是go的,内核是c写的,效率就更别说了。

Seafile提供webdav服务,可以很高效的提供给joplin支持,joplin效率不高,但是它的重点在笔记体验和检索上。

最后Photoprism,最惊艳了,说说相比其他相册和文件服务没有的优点吧:

  • 最爱:go写的,无处都能感受到异步的存在,就是事情在做,还能给你的操作反馈,不会让你觉得它崩溃了,joplin在导入我的evernote笔记时就崩溃了。
  • 不更改现有的文件结构,也不用导入,直接挂在现有的图片库即可。扫描后会在目录中放入一些缩略等数据。对于有洁癖的人来说,还提供导入文件夹的模式,就是会自动将导入文件夹的图片提取出来,也不会动未识别的文件,这一块目前只有看套他这么做了的。
  • AI标签,很多相册都陆续支持这个功能了,但是photoprism做的最好,它能在很弱的设备商正常工作,效率还不低。应该是在识别的时候自动调节了识别参数,这个就很注重细节了,同样体验就非常好。
  • 在上面的这些原因下,在索引和扫描时你就能实时看到扫描的成果,然后你就很有耐心等下去。充分利用了多核的优势,go的速度真的是非常快,让照片的浏览急速无比。

怀旧服1.13 术士单刷厄运东月牙钥匙

开始都放弃了,但是每次去拿fm药都很麻烦,于是一查真有个up主做到了。

这里要说一的是如果你是牺牲毁怎么样都过了,如果跟我一样懒得洗天赋那么就要注意了。我是暗毁,跟up主一样,前面up说的很仔细也都很顺利,最后boss却死去活来几次都没过,我才发现,up主抓的那个荒野萨特tmd居然是56的jy,我找遍了一个fb都是55的,哎,这就是命。最后测试猎人萨特发现一次就过了,比up主轻松多了。抓了lr就无所谓技能了,怎么打都能过,最后我的萨特还剩三千六血。。。。[呲牙],希望对后面刷小鬼的有帮助,食谱有望了

塑料模具(注塑模具)海关编码为:8480719090

更新目前8480710090已过期,改为8480719090可用

塑料模具(注塑模具)海关编码为:8480710090,冲压模具(钣金模具)海关编码为:8480410090


塑料制品(塑料件)海关编码为:39269090
模具一般按用途来归海关编码 请告诉具体用途 下面是按用途或制作材料的模具叫法,在实际报关中可以用制作对象的名称来命名,例如 刹车座模具 属于压膜 报关时可以用刹车座模具来报关,模具应该属于金属模具(压铸模具) 84804100
以下是模具的分类:
工具类:
金属拉拔 挤压用模具 82072090
锻压 冲压冲孔用模具 82073000
机器类:
1.   84389000  糖果模具
2.   84490090  铝制模具(制作帽子模具)
3.   84669300  钻孔定位模具(用于加工割草机零部件钻孔定位用)
4.   84801000  浇铸用模具
5.   84804100  金属模具(压铸模具 金属注模)
6.   84804900  金属模具(除上面   浇铸用模具   压铸模具 金属注模 外的其他金属铸造用模具)
7.   84805000  玻璃定形模具
8.   84807100  注塑模具 (压模 注模)
9.   84807900  吹塑模具 滚塑模具 挤出模具 发泡模具
现在海关编码是10位,可以在海关网查询更细的分类。

简单地说就是用我司名义进出口,由我司提供全套出口报关资料:核销单;合同;发票;装箱单;报关委托书;重柜纸;报关单;其他必须证书:如商检证、植检证、许可证、配额等;作为配套出口服务项目,我们根据《中华人民共和国海关管理条例》通过合法、正当手续办理货物进出口。因单证所发生的问题将由我公司负责。

flask wtform中枚举的使用

wtform可以非常友好的管理好表单的交互以及服务端验证。最近开始使用postgres,发现也能非常友好的支持enum类型,但是在实际的操作中发现了一个bug。这里我们使用form.populate_obj方法从form中更新字段到obj,使用form.process(obj)方法从obj更新到form。sqlalchemy使用枚举类型定义的字段,form中使用selectfiled或者其子类。

修改了好多回,反反复复跟踪后才明确这个问题,在第一次给form赋值时无错,第一次保存时也无错,bug出在form的存储数据上,就是对field.data的操作。原来在wtform中会判断field.data是否是filed.choices中的值,源代码如下:

file:core.py    
def pre_validate(self, form):
        for v, _ in self.choices:
            if self.data == v:
                break
        else:
            raise ValueError(self.gettext('Not a valid choice'))

self.data有时候是form中选中input的value值,有时候是枚举类型,要修复这个bug就要在所有枚举类型的基础类BaseEnum上改写eq和hash两个内置函数,使得双等“==”操作既能比较字符串,也能比较枚举类型,修改后修复。

gunicorn vs uwsgi 性能对比,以flask run为基准

之前一直在用gunicorn,这次折腾新项目突发奇想来对比下flask run \gunicorn\uwsgi的性能。不是非常严谨的测试,希望也能有一定的参考意义,结果也很有意思。

gunicorn很火,uwsgi以前用的人多,但是现在少了感觉不怎么听到,这东西是用c写的,带了光环的。flask run这里只是作为基准参考,压力测试工具为ab test,前置了nginx把静态文件剥离了,两者都使用unix domain socket通信隔离了http微乎其微的影响,两者都是用了2process+2thread,压力为100-1000。下面是三种方式的结果:

#基准flask run 100-1000
Server Software:        nginx
Server Hostname:        xxx
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Document Path:          /
Document Length:        6223 bytes
Concurrency Level:      100
Time taken for tests:   7.418 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      6489000 bytes
HTML transferred:       6223000 bytes
Requests per second:    134.81 [#/sec] (mean)
Time per request:       741.790 [ms] (mean)
Time per request:       7.418 [ms] (mean, across all concurrent requests)
Transfer rate:          854.27 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        5   47  69.2      6     296
Processing:   231  662 186.7    679    1736
Waiting:      231  662 186.7    679    1736
Total:        241  709 159.6    702    1742
Percentage of the requests served within a certain time (ms)
  50%    702
  66%    735
  75%    788
  80%    821
  90%    881
  95%    958
  98%   1111
  99%   1178
 100%   1742 (longest request)
# uwsgi result
Server Software:        nginx
Server Hostname:        erp.ljmold.cn
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Document Path:          /user/login
Document Length:        6223 bytes
Concurrency Level:      100
Time taken for tests:   9.741 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      6489000 bytes
HTML transferred:       6223000 bytes
Requests per second:    102.66 [#/sec] (mean)
Time per request:       974.096 [ms] (mean)
Time per request:       9.741 [ms] (mean, across all concurrent requests)
Transfer rate:          650.54 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        5  130 246.7      9    1750
Processing:     4  533 732.3    437    7584
Waiting:        4  533 732.3    437    7584
Total:          9  664 765.4    473    7742
Percentage of the requests served within a certain time (ms)
  50%    473
  66%    656
  75%    751
  80%    858
  90%   1272
  95%   1719
  98%   2526
  99%   4081
 100%   7742 (longest request)

#gunicorn 100-1000
 Server Software:        nginx
Server Hostname:        erp.ljmold.cn
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256

Document Path:          /user/login
Document Length:        6223 bytes

Concurrency Level:      100
Time taken for tests:   9.678 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      6489000 bytes
HTML transferred:       6223000 bytes
Requests per second:    103.33 [#/sec] (mean)
Time per request:       967.779 [ms] (mean)
Time per request:       9.678 [ms] (mean, across all concurrent requests)
Transfer rate:          654.79 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        4   82 233.2      6    2275
Processing:     4  584 891.2    306    7272
Waiting:        4  584 891.4    303    7272
Total:         10  667 907.5    389    7278

Percentage of the requests served within a certain time (ms)
  50%    389
  66%    573
  75%    682
  80%    868
  90%   1487
  95%   2506
  98%   3374
  99%   4788
 100%   7278 (longest request)
  1. 总共耗时上差的微乎其微,这点差别不能说明什么;
  2. 两者都完成了所有请求,这里说一下,之所以选1000就是因为2000两种方式都会崩溃;
  3. 平均时间uwsgi胜出,这里差别不明显,但是也说明总体性能上uwsgi做的彻底;
  4. 连接时间上,两者明显在1000下都吃力了,但是uwsgi表现更好,除了c我觉得使用uwsgi自己的协议也有关系;
  5. 最后也是最重要的,在高并发下,明显uwsgi的表现更好一点,很有意思的是在80%以下的正常流量范围内反倒gunicorn更好,而且效果显著,100ms还是比较可观的,我想这才是大家都用gunicorn的主要原因吧。

最后别人说的总归是片面,还是自己动手对性能有更全面的了解。顺便说一下对flask自带的小服务器刮目相看

第一次买房记

没买房的人都亏了。

背景:作为本地人多少都有房子的,所以很长时间里我的观念中就是不要参合买房大战,房奴过的都很艰辛。买房的念头就是从户口问题开始的,孩子过一年就要上小学了,户口于是打算迁到城里,没成想今年开始政策不允许了,因为迁户口用的房子性质有问题,哎,政府的锅为什么要让老百姓买单,气。周围问了一遍,发现不买房上学真的是个问题。

看房:本来我们这是个小县城,随着经济快速发展我也从市中心一次次往外搬,出于对老城区的感情和学区的要求看的都是绣湖区块。正好碰上拆迁潮,新小区没有几个,还都是期房,价格超出预算很多,只能放弃。如果不买老城区心里有受不了住的比现在还远的落差,于是开始看二手房。

二手房:一直知道二手房坑多,看房的时候中介啊朋友啊说了各种故事。好在表哥刚刚买了二手房,可信的咨询就比较多了。作为二手房价格肯定比新房便宜多了,但是比新房多出几个成本:中介费、过户契税、营业增值税、土地出让金(如果是安置房,我买的就是这种)。然后作为二手房也有他的好处,比如学区稳定,不会像期房开始各种承诺,后面各种问题落实不了,甚至有的证件齐全却发不下房产证,本来买房就是为了入学,所以二手房是更好地选择。

中介:二手房避不开中介,哪怕你跟房东认识也必须邀请有执业资格的中介签订第三方契约。中介费就是个头疼的问题了,特别是高价的房子,因为中介费是按照百分比算的,比如义乌最大的中介坐标大概是2%,上海大概1.5左右。200万的房子中介费就是四万了。托表格的福,他花了很多时间找到了私人中介按照固定费算。有的中介带你看房后会要求签署一个协议,这个协议会锁定你半年左右时间,这段时间里哪怕你跟别人交易用的其它中介也要付中介费给协议方,要小心哦。

出让金:这个大多出现在安置房中,我觉的这个挺流氓,集体土地低价变成国有土地后居然还要交钱,无语了。这一项最重要的是用房产证来实际计算,因为变数很大,很多中介会把四五十万的出让金粗算成三十多万,就是为了促成成交。作为大头之一,直接影响到最后总的预算。

契税:这个倒是固定的,项目可能多,但是不会有变数。

营业增值税:这个是为了防止炒房出台的,一般购买时问清楚房东持有的年限就好,大城市这个影响比较大,义乌只限两年,碰到的比较少。

按揭:这是我最大的痛,如果有公积金一定要公积金贷,便宜很多很多,平常看不出来,累积起来能省三分之一。一般都是四大行操作,利率都是国家标准,打听好再去办。现在还会附带保险要求,这个就有点耍流氓,而且跟你卡绑定,逃都逃不掉。

车位:很重要,特别老城区的车库都炒到天价了,这次买的并没有车位,略有遗憾,幸好周围有新建的停车场还能自我安慰下。二手房大多老小区,所以停车一定要计划好,当然好的停车位房价总价自然也是高的。最好能有两个车位,毕竟现在车便宜了。

买房决心的因素:大概位置和学区一般开始就能定下来,预算一看便知。那么最后下决定买哪套我觉得跟心理预期最重要,简单说就是自己满意就好。

  • 小区的东南角,采光和视野应该是最好的;
  • 中间楼层,太低采光不好和蚊虫多,也不够安静,太高风大,不坐电梯就太可怕了;
  • 靠近公园,适合晚饭后散步、孩子们玩耍,近了去的才会多,城里我一直认为公园是最宝贵的,也是这套我最满意的地方;
  • 商场在小区的西面,大概几百米吧,正好吵不到,购物也方便;
  • 幼儿园在马路对面,可惜这几年不去住,否则午餐回家吃都妥妥的;
  • 小学大概1km,走路可及;
  • 离市政府不远,主要是考虑保值,涨价就不去想了,也不打算再卖;
  • 租赁:原先租户是一个单位,价格高出市场价40%,相当满意,打算多租两年,让财务缓一缓;
  • 总价比预期高了一点,这还是在房东砍价后的,可能买房时间不好吧,跟大量拆迁户正面作战;