专栏首页天马行空布鲁斯空谈stateless和stateful

空谈stateless和stateful

其实,关于这两个词语,我们经常听到,网上也有很多文章介绍,大家可以自行搜索。这里只谈一谈个人对它们的理解。

下面分别从编程语言和系统架构的角度聊一聊stateless和stateful。

编程语言

首先,我们看一个Java API的例子:

Java的SDK提供了两种遍历List的方式,一种是使用foreach;一种是使用iterator,如下:

  • foreach
List<String> list = new ArrayList<String>();
for(int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
  • iterator
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。

  • 面向对象编程里面的方法/函数叫做method;函数式编程里面的方法/函数叫做function。
  • 函数并不一定都是stateless的,只有纯函数(PF:pure function)才是stateless。纯函数的特征就是其返回只跟函数的输入参数有关,不依赖于其它的state。
  • 其实不管是method,还是function,只要是符合纯函数特征,都是stateless。
  • stateless方法/函数的优点是,在并发环境下,不会由于state的变化导致side effect。
  • Java 8新增了对lambda表达式的支持,其实就是对函数式编程的支持,在很多场景下这非常有用并且便于理解,比如List的排序API,需要传入一个比较器,在Java 8之前需要用匿名类(其实这个类并没有任何意义)来实现,而在Java 8之后就可以直接用lambda。

系统架构

首先,从网络协议角度来看,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

  • https://en.wikipedia.org/wiki/Stateless_protocol
  • https://www.cnblogs.com/dogharry/p/4305044.html
  • https://blog.csdn.net/tantexian/article/details/48288761

本文分享自微信公众号 - 天马行空布鲁斯(gh_2feda5c053bd),作者:huazailmh

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-04-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ​空谈Security之Authentication和Authorization

    authentication和authorization这两个单词看起来很像,并且它们经常被一起提及到,但是,请注意,它们指代的是不同的概念,authentic...

    Bruce Li
  • 浅析一个sql server数据库事务死锁问题

    一个学生管理系统,数据库是sql server,有一个Web API用于创建student。student对象的表结构如下:

    Bruce Li
  • 浅析Tomcat高并发之连接池、线程池

    记得大学的《网络工程》有一个课后作业:用Java实现一个web服务器,当时想的是为了提高吞吐量,可以用多线程实现,即对于每一个客户端请求连接,都启动一个线程来处...

    Bruce Li
  • Python每日一题:装饰器(一)

    关于Python装饰器,考点很多,这里在网上找到一个对Python装饰器解释的很详细的回答。因为是英语的,并且比较长,将通过两篇来进行翻译。原文链接如下:

    用户7685359
  • 如何用Tensorflow完成手写数字识别?

    深度学习最经典的任务问题就是分类。通过分类,我们可以将照片中的数字,人脸,动植物等等分到它属于的那一类当中,完成识别。接下来,我就带着大家一起完成一个简单的程序...

    HuangWeiAI
  • 【JS】741- JavaScript 闭包应用介绍

    来源 | https://www.zoo.team/article/vue3-jsx

    pingan8787
  • .NET Core 实现 腾讯云云解析简单客户端

    腾讯云的.NET SDK虽然非常强大,但是对他的产品支持不是很完全,域名的云解析就没有SDK,所以自己写了一个,初衷是用来做动态DNS的,也准备接入多个云厂商,...

    晓晨
  • DNS域传送漏洞(二)

    本篇将介绍使用nmap扫描器和dig来得到DNS Zone Transfer记录。

    HACK学习
  • docker构建自定义镜像

    要构建一个镜像,第一步准备所需要的文件,第二步编写Dockerfile文件,比如我现在构建一个java web镜像

    用户2409797
  • 微信小程序_01程序结构

    注意 AppID 目前个人无法申请,使用企业账号可以申请,我们就选择"无AppID"

    酷走天涯

扫码关注云+社区

领取腾讯云代金券