1.有状态对象和无状态对象
1.1有状态对象
简单说,就是普通java类,带有属性,并且属性是可以修改的,也就是这种对象是可以进行数据存储的。注意属性一定要可以修改,那么这个类的实例就是有状态。也就是你拿到这个对象,有可能被人修改过,也就是可能发生过状态变化
1.2无状态对象
简单说,就是对象中的属性不会被更改,不管谁拿过去用过之后没有任何变化 。一般而言,spring中使用 @service注解标注的类所产生的对象就是无状态的。
这里其实引出了另外一个概念,在spring中什么样的bean可以被设置为单例,其实就是无状态的bean可以被设置为单例模式。
2.服务的有状态和无状态
一个web 应用程序协议的“状态” ,通常指的是两个相互关联的用户交互操作保留的某种公共信息,它们通常用来存储工作流或者用户状态信息等数据。最常见的就是用户身份信息,这些信息可以被指定为不同的作用域,比如request session 或者全局作用域,存储它们的责任既可以由客户端服务也客户由服务端负责。
虽然存储状态给软件开发提供了很多便利,但是在分布式系统中有很大的限制。
比如在负载均衡方面,在有状态的模式下,一个用户的请求必须被提交到保存有其相关状态的服务器上,否则这些请求可能无法被理解。这就意味着在此模式下服务器无法对用户请求进行自由调度;
与此相关的另一个问题就是容错性,倘若保有用户信息的服务器宕掉了,那么该用户最近的所有交互操作都将无法被透明的移送到备用服务器上,除非该服务器时刻与主服务器同步全部用户的状态信息。
2.1 无状态的服务
客户端的请求每次都必须具备足够的信息,服务端通过这些信息就可以识别客户端身份。
- 无状态的优点:
- 客户端请求不依赖服务端的信息,任何多次请求不需要访问到同一台服务器
- 服务端的集群和状态对客户端透明 ,也就是说服务端可以任意的迁移或者伸缩
2.2 有状态的服务
有状态的服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,最典型的就是http中的 session
- 有状态的缺点:
- 服务端保存大量数据,增加服务端压力
- 服务端需要保持用户状态,无法进行水平扩展
- 客户端请求依赖服务端,多次请求必须访问同一台服务器
2.3服务例子
客户端想服务端传递sessionId 就是一种有状态服务的体现;
像github上这种使用凭证登录的方式就是无状态服务的体现。