当前位置: 首页 > news >正文

无状态服务(stateless service)

一、定义

无状态服务(stateless service)对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说数据库),服务器本身不存储任何信息

有状态服务(stateful service)则相反,它会在自身保存一些数据,先后的请求是有关联的

二、优劣

有状态服务常常用于实现事务(并不是唯一办法,下文有另外的方案)。举一个常见的例子,在商城里购买一件商品。需要经过放入购物车、确认订单、付款等多个步骤。由于HTTP协议本身是无状态的,所以为了实现有状态服务,就需要通过一些额外的方案。比如最常见的session,将用户挑选的商品(购物车),保存到session中,当付款的时候,再从购物车里取出商品信息

有状态服务可以很容易地实现事务,所以也是有价值的。但是经常听到一种说法,即server要设计为无状态的,这主要是从可伸缩性来考虑的。如果server是无状态的,那么对于客户端来说,就可以将请求发送到任意一台server上,然后就可以通过负载均衡等手段,实现水平扩展。如果server是有状态的,那么就无法很容易地实现了,因为客户端需要始终把请求发到同一台server才行,所谓“session迁移”等方案,也就是为了解决这个问题

6486d16d-38c6-38de-837f-637ff99c30d4.png

三、session和cookie

基于session和cookie都可以实现事务,可以认为,session是有状态的,而cookie是无状态的

四、无状态实现事务的方法

并不是一定要用有状态服务才能实现事务,本文提供另外的几种方案作为参考
举一个多次提交的场景作为例子:用户需要提交很多数据,分为2个页面提交

d2a571e3-dea4-3fad-bf5b-e896730ebf10.png

这里就涉及到2次http请求,第一次提交字段1、2、3,第二次提交字段4、5、6

用session很容易实现这个需求,server只需要将第一次提交的数据,保存在session里,然后返回第2个表单作为相应;然后取出第一次提交的数据,和第二次提交的数据汇聚以后,一起存入数据库即可

不用session同样也可以实现,server接收到第一次请求以后,将数据作为隐藏元素,放在第2个表单里返回;这样用户第2次提交的时候,就隐含地再次提交了第一次的数据;server将所有数据存入数据库
用HTML5,则还可以进一步优化,client可以将第一次提交的数据,保存在sessionStorage里
用cookie也是类似的道理,同样可以实现,但是不太好

总的来说,3种替代方案(隐藏表单元素、sessionStorage、cookie)都避免了在server端暂存数据,从而实现了stateless service。本质上,这3种方案的请求里,都包含了所有必须的数据,符合本文一开始的定义

五、将有状态服务转换成无状态服务

根据本文一开始的定义,除了将所有信息都放在请求里之外,还有另外一种方法可以实现无状态服务,即将信息放在一个单独可共享的地方,独立于server存在
比如,同样还是采取session的方式,在服务端保存数据,减少每次client请求传输的数据量(节省流量);但是将session集中存放,比如放在单独的session层里。这种情况下,server同样是无状态的,可以做水平扩展

47bd72bf-1162-33d2-be07-0ddcebdc633a.png

六、无状态类

引申一下,JAVA里有一种类的设计,可以称为无状态类。这种类的特征是只有方法没有字段,在三层架构(展现层、逻辑层、持久层)里,逻辑层经常可以看到这种类
我觉得无状态类和stateless server在思想上是一样的,这个类本身是没有状态的,所以当外部要调用它的方法时,需要在方法参数中传来所需的所有信息,不依赖该类自身的状态(字段值),在并发环境下,可以避免多线程带来的副作用

七、总结

有状态服务可以比较容易地实现事务,在不需要考虑水平扩展时,是比较好的选择
无状态服务的优势在于可以很方便地水平伸缩,但是在实现事务时,需要做一些额外的动作
可以通过剥离session等方法,将一个有状态服务,转换成无状态服务

 

相关文章:

  • kubectl delete pod Terminating 删不掉
  • spring zuul Ribbon 配置
  • selenium 代理
  • 在Ubuntu 10.04上安装java 1.5 java 1.6
  • 超级简单:共享两个自动生成存储过程的工具
  • 拍照黑科技上线 用2000万四镜头定格跨年瞬间
  • Easyui layout设置满屏效果
  • 用算法撩妹都不会,别跟我说你是程序员
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 设计模式系列之「责任链模式」
  • 20 个常用的 CSS 技巧
  • 为什么要使用Gradle?
  • Docker CE 安装
  • 常用收藏与分享
  • padding和margin的区别和作用及各种场合出现的bug
  • Angular 响应式表单之下拉框
  • angular2 简述
  • Create React App 使用
  • CSS实用技巧干货
  • HTTP--网络协议分层,http历史(二)
  • Java小白进阶笔记(3)-初级面向对象
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • quasar-framework cnodejs社区
  • TypeScript迭代器
  • 构建二叉树进行数值数组的去重及优化
  • 深入 Nginx 之配置篇
  • 微信开放平台全网发布【失败】的几点排查方法
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 一个项目push到多个远程Git仓库
  • 用quicker-worker.js轻松跑一个大数据遍历
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 运行时添加log4j2的appender
  • 正则表达式
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (转)大型网站架构演变和知识体系
  • . NET自动找可写目录
  • .form文件_SSM框架文件上传篇
  • .NET CLR Hosting 简介
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .net2005怎么读string形的xml,不是xml文件。
  • [Android View] 可绘制形状 (Shape Xml)
  • [C/C++随笔] char与unsigned char区别
  • [CCIE历程]CCIE # 20604
  • [CSS] 点击事件触发的动画
  • [flask] flask的基本介绍、flask快速搭建项目并运行
  • [Gradle] 在 Eclipse 下利用 gradle 构建系统
  • [HackMyVM]靶场Crossbow
  • [IE6 only]关于Flash/Flex,返回数据产生流错误Error #2032的解决方式
  • [IE9] IE9 Beta崩溃问题解决方案
  • [Latex学习笔记]数学公式基本命令
  • [LeetCode] Merge Two Sorted Lists