背景
你有没有遇到这样的情况,系统平时运行的好好的,但是由于流量上来后,或者是被依赖的外部服务响应慢了,或者干脆不响应了,系统突然就崩溃了?没错,这就是同步开发的最大问题。这里来分析一下同步开发模式和异步开发模式。
同步通信与异步通信
同步通信:通信线程发送消息后,线程等待应答,应答回来后,将应答消息发送给业务处理线程。同步开发时,业务处理线程经常也是通信线程。
异步非阻塞通信(NIO):通信线程发送消息后,不是在那里死等应答消息,而是去发送其他的消息,等应答回来后,再将消息转发给处理线程。通信线程和业务处理线程时分开的,这就需要有机制将应答消息跟请求消息关联起来。
同步开发与异步开发
同步开发:当业务逻辑需要访问外部服务时,发送请求消息后,线程等待应答,当应答回来后处理后续逻辑。
异步开发:当业务逻辑需要访问外部服务时,发送请求消息后,线程将该任务挂起,然后去处理其他的业务逻辑,等到应答回来后,再去唤醒对应的业务逻辑。这里就需要一种机制,将怎么将当前任务挂起,并且应答消息回来后,能够将唤醒之前挂起的业务。
异步通信性能高得到了业界的认可,而异步开发模式,业务用的缺少之又少。
优缺点
同步开发最大的问题是并发性能不够,而且不稳定,会依赖于所访问的外部服务,如果外部响应慢了或者不响应了,就会严重影响自己的处理能力,甚至直接奔溃。原因如下: 比如一条消息处理时间是200毫秒,那么一个线程每秒最多能处理5条消息,那么就算开100个线程,也就每秒500个请求的处理能力。但是如果处理这个消息,需要依赖外部服务时,通常处理时间可能需要到500毫秒甚至更好,那么100个线程每秒最多也就处理200个请求。那如果被以来的服务也出问题了呢?他原来响应时间是200毫秒,现在变得更长,甚至不响应,一般超时时间是10秒,那么就相当于100个线程每秒只能处理5个请求,这样在高峰期直接把系统搞奔溃。 通常一个系统有很多服务,只要一个服务依赖的外部服务出现问题,它有可能占用你所有线程,导致其他的服务也同样有问题。 你也许会说可以继续启线程,但是线程是有开销的,这样就会堆大量的线程,最终导致系统奔溃。
异步开发可以很好的解决这类问题,因为线程不需要去等待外部的应答,仅仅将一个事务对象挂起,如果对方不及时响应,最多也就占用一点点内存,而不需要通过不停的启线程来增加系统并发能力。
曾经做个类似的测试,使用tomcat框架的同步通信,就算是跑空业务,每秒最多也就处理1200个请求。 而使用异步开发框架做同样的测试,基本可以将1G的网卡跑满,每秒处理的请求可以达到近10万。
但是异步开发会比较麻烦,没有一定的功底很容易出问题,业界也很少有此类软件开发架构。
林栖云的EL-PAAS微服务架构采用的是异步开发架构设计,有一套完整的异步开发框架,用起来很方便,性能并发性和稳定性都非常的好。