其实,关于这两个词语,我们经常听到,网上也有很多文章介绍,大家可以自行搜索。这里只谈一谈个人对它们的理解。
下面分别从编程语言和系统架构的角度聊一聊stateless和stateful。
编程语言
首先,我们看一个Java API的例子:
Java的SDK提供了两种遍历List的方式,一种是使用foreach;一种是使用iterator,如下:
List<String> list = new ArrayList<String>();
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
List<String> list = new ArrayList<String>();
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
第一种方式是调用list.get(i),这个api就是stateless的,因为get方法的实现不会保存一个“状态”,多次调用都是返回同一个元素。
第二种方式是调用iterator.next(),这个api就是stateful的,因为next方法的实现会保存一个“状态”:游标信息,前后两次调用返回不同元素。
接下来,从向对象编程(OOP:object orentied programming)和函数式编程(FP:functional programming)角度聊一聊stateless和stateful。
系统架构
首先,从网络协议角度来看,http协议是stateless的,tcp协议是stateful的,ip协议是stateless的。虽然说,http协议本身是stateless的,但是很多web 应用却是stateful的,因为web应用保存了用户的session信息,这样对登陆之前和登陆之后用户请求的处理是不同的。但是,对于很多web api service来讲,可能就是stateless的,因为其不需要用户登陆,而只需要用户提供验证的credentials,对多次请求的处理逻辑是一样的。
对于系统内部,负责权限验证部分的component,如果把session信息存放在内存,则它是stateful的;如果放在standalone的session store(比如:redis)里面,则它是stateless的。当这个component是stateless时,其可以很容易的实现水平扩展,就不需要考虑sticky session等问题。
现在很流行一个词serverless(无服务),相比于serverful,其核心思想就是”不需要一直霸占一个server来保持running“,而是通过事件来触发,接收到事件时,才开始分配服务器资源并启动定义好的function,执行完function,就回收服务器资源,整个过程就像程序运行过程中调用一个函数,所以这样一个function本身是stateless的。可以看到,serverless能够充分利用服务器资源,因为function执行完就会释放掉,但是,它有一个显著问题就是”冷启动“,因为不像serverful的应用,代码只需要第一次启动的时候加载完成即可;serverless的应用,每次事件触发执行function,都需要加载。
现在很多cloud平台都有推出serverless功能,但最早的应该是AWS lambda。
References