极致性能

前言

这篇文章主要讲目前我自己认为的最优化的性能解决方案

目前来说程序的前后分离越来越明显,而且端也是越来越多

简单点来说前端

  1. 传统的PC Web网页,虽然现在移动端盛行,但是例如企业官网、协同工作、网上商城、资讯类网站仍然需要一个传统的的WEB网站
  2. iOS、Android手机类App,人类已经离不开手机了
  3. 移动端的H5,跨平台的解决方啊,因为小程序的出现破灭了
  4. 小程序,包括微信小程序和支付宝小程序,为了构建自己的商业闭环
  5. 快应用,各大手机厂商联合搞的,类似小程序。为了不被垄断

这么复杂的前端,导致了前后分离的越来越明显,后端越来越只提供API服务,前端SPA(单页应用)

前后联动

一个完整的软件用户体验就是

  1. 用户操作
    例如注册
  2. 反馈到到端
    程序发起网络请求
  3. DNS
    网络请求通常都是域名访问、这一步会经过DNS解析拿到真实的IP地址。当然了直接写IP也行。
    通常来说这一步几乎不存在性能瓶颈DNS会有缓存,这一步的瓶颈更多的是网络延迟。这一步的优化更多的是选择一个好的DNS服务商,节点更多、延迟更低,服务更稳定。目前来说免费的就够用了
  4. API Gateway
    API网关,各大云服务商都有提供LBS,就我个人来说,必要性不是很大。如果说API流量很大,那么LBS目前的定制化功能是不够的,大公司一般会弄自己的LBS。对于小项目来说nginx足以。nginx也不会是性能的瓶颈,单机几百万并发。搞两个做备份绝大多数需求都能满足了
  5. Micro Service
    微服务,目前后端的趋势向微服务或Server Less方向发展。微服务的两大好处就是高可用解决糅合。为啥子呢?高可用的意思就是其中一个服务挂了其他的要正常。保证不全面崩溃。解决糅合就是开发上协作分工,更快交付
  6. Server Less
    目前比较新的概念,无服务开发模式。啥意思?
    目前各大云服务厂商推出了各种云存储、云直播、云分析、云数据库。人们的开发模式发生了很大变化,不再购买服务器、不再购买带宽、不再自建数据库、不再购买磁盘。人们只需专注于产品本身。人们使用云服务厂商提供的API写程序。后来人们发现,既然我全部使用的是云,那么我干嘛程序不也用云呢。于是就诞生了如AMS Lambda这样的服务。但是这个概念太新,和云服务厂商绑定的太死,灵活度不够。目前来说还不太能大规模部署,但是可以小规模试用

那么问题来了,后端性能的瓶颈几乎就落在了microservice上面

首先从语言层面来说,参考The Computer Language Benchmarks Game

  • 性能的第一档C、C++。

性能确实足够优秀,你也找不到更好的语言了。但是并不太适合microservice的开发。开发效率和工具链都不太适合,只能开发一些核心业务。

  • 性能第二档Rust、Go、Swift

这三个语言都是比较新,对人类比较友好的语言。

Rust比较像C++,说实话过于复杂了,性能接近C、C++等原生语言。目前来说网络框架和库比较少。更多的是开发一些系统级的应用,过高的复杂度在开发效率上也得不到保证。

Go比较简单,接近C的语法,各种网络框架和库层出不穷。比较适合微服务的开发

Swift苹果出品,语法上我觉得比较接近scala。目前来说也是网络框架和库比较少,更多还是开发iOS应用

  • 性能第三档Java、C#

Java目前使用最广泛的语言,框架和库数不胜数。JVM经过多年优化性能大概是C的一半。缺点就是比较吃内存,而且GC也十个问题。适合开发大型项目

C#性能上来说和Java差不多,但是框架和库相对Java来说是比较少的。没有Java活跃

  • 性能第四档JavaScript、TypeScript

本来JS应该属于第五档的语言,可是在V8加持下的Node天然的并发特性,使得它的性能和并发都能契合到微服务的开发上来

  • 性能第五档PHP、Python、Ruby

PHP近些年受到HHVM、PHP7的影响,性能有了大幅度的提升。但还是不够,这是语言特性受限。还是比较适合开发传统网站

Python的性能甚至不如PHP,还是适合当工具语言使用

Ruby和Python差不多,2.0以后性能有了些提升,但是和PHP一样,开发网站的利器。

总的来说,第五档的语言由于性能的关系,都不太适合开发微服务。

抉择1

优先选择Go

优点:语法简单、天然并发、性能高、社区成熟
缺点: 缺点就是Go还是不够普及、学习成本还是有的

其次选择Java

优点:成熟的框架和库,门槛低、简单易学、适合团队写作
缺点:GC的延迟、比较吃内存,性能还是比Java差一点,但是不多,能接受

再次选择TypeScript

优点:JavaScript加强版,完全兼容js缺摒弃了js的一些缺点,成熟的社区、高并发,前后端通用
缺点:性能比Go和Java要差的多,大概有几倍的差距

综合看来,我的抉择也是大势所趋。

Java已经有20多年的历史了,经久不衰,经过了时间的考验,近年来高居各大语言排行榜第一名。都说Java已死,目前看来再活个10年完全没有问题

Go自从2009年推出以后就蓬勃发展,很多重量级应用都是Go写的。背后也有谷歌的推动。在中国几乎成为了主流语言

TypeScript微软出品,JS多年来被人诟病,但是即使这样前端也被JS一统天下,当没有缺点的JS【TypeScript】,彻底的统一前后端

抉择2

脱离了语言那就是框架了,参考Web Framework Benchmarks

JSON serialization

在JSON serialization测试环节中前十名都是Java的项目,可见Java20年的沉淀,弄出了多少优秀的框架

Go的fasthttp排在13名,但是性能差别不大,能达到第一名的80%

Js的表现差一些排在23名,但是性能也能达到第一名的44%。这个性能的差距完全是语言本身的性能差距

当然这个测试的意义对于微服务来说更多体现在框架的IO性能和JSON的序列化性能

Single query

这个是单次查询,在实际的测试中肯定是要和数据库交互的,那么这个测试的参考意义还是很大的

这个要做一些删选

排第一的是Java的vertx,go的fasthttp排在第三,能达到第一名的63%,我个人认为这个差距可能是一些实现细节的差距,Js就比较惨了排到了28名,而且只有第一名性能的26%。

Multiple queries

在实际的业务中单次查询是解决不了问题的

排第一的还是vertx,够排在第四,能达到第一名的60%,js只能达到20%

后面的结果都差不多

其实go的性能和java应该算是旗鼓相当。js比较惨的原因可能就是语言性能本身的差距

目前看来Java的可选框架还是比较多的

底层基于Netty和Undertow的性能都不会差,可选的有Spring Framework、Act Framework、rapidoid、vertx

Go来说的话fasthttp一骑绝尘

JS可选业挺多的express、koa、restify

DB

在微服务中、最终落地还是需要喝数据库打交道

SQL

MySQL vs PostgreSQL

传统关系型数据库来说就两个选择mysql和postgresql。这两者的性能相当。就更广泛的通用性来说选择mysql比较好。之前就有人得出结论web服务用mysql,分析用postgresql。简单点来说如果你的微服务是面向大众用户的话选择mysql。如果内部使用选择PostgreSQL

NoSQL

Redis vs Memcache

memcache是个纯缓存数据库,redis不仅可以做缓存还可以持久化

目前来说redis发展迅猛。个人感觉没有必要在新项目中使用memcache

MongoDB

这个似乎没得选

具体业务中使用哪种数据库根据业务类型来判断

RPC vs RUSTful

内部服务建议使用RPC达到最高性能

rpc框架还是比较多的这里比较推荐谷歌开源的gRPC和Facebook开源的thrift,其他的都不推荐,第一是不跨语言,第二就是国内的开源的尿性,要么开源了不维护,要么只开源一部分藏着掖着

对外服务建议使用RESTful达到最广泛的通用性