-
2021-03-16 13:21:48
一、定义:
无状态服务:就是没有特殊状态的服务,各个请求对于服务器来说统一无差别处理,请求自身携带了所有服务端所需要的所有参数(服务端自身不存储跟请求相关的任何数据,不包括数据库存储信息)
有状态服务:容器数据持久化保持
1.有状态服务 可以说是 需要数据存储功能的服务、或者指多线程类型的服务,队列等。(mysql数据库、kafka、zookeeper等)
2.每个实例都需要有自己独立的持久化存储,并且在k8s中是通过申明模板来进行定义。持久卷申明模板在创建pod之前创建,绑定到pod中,模板可以定义多个。
二、如何选择:
有状态服务常常用于实现事务(并不是唯一办法,下文有另外的方案)。举一个常见的例子,在商城里购买一件商品。需要经过放入购物车、确认订单、付款等多个步骤。由于HTTP协议本身是无状态的,所以为了实现有状态服务,就需要通过一些额外的方案。比如最常见的session,将用户挑选的商品(购物车),保存到session中,当付款的时候,再从购物车里取出商品信息 。
有状态服务可以很容易地实现事务,所以也是有价值的。但是经常听到一种说法,即server要设计为无状态的,这主要是从可伸缩性来考虑的。如果server是无状态的,那么对于客户端来说,就可以将请求发送到任意一台server上,然后就可以通过负载均衡等手段,实现水平扩展。如果server是有状态的,那么就无法很容易地实现了,因为客户端需要始终把请求发到同一台server才行,所谓“session迁移”等方案,也就是为了解决这个问题。
有状态服务和无状态服务各有优劣,它们在一些情况下是可以转换的,或者有时候可以共用,并非一定要全部否定。
在一定需要处理请求上下文的情况下又想使用无状态服务,可以将相关的请求信息存储到共享内存中或者数据库中,参考分布式session的实现方式:
1.基于数据库的Session共享
2.基于NFS共享文件系统
3.基于memcached 的session
基于resin/tomcat web容器本身的session复制机制
基于TT/Redis 或 jbosscache 进行 session 共享
基于cookie 进行session共享
或者在业务实现上,将上下文需要的信息在请求中返回,在客户端中进行存储,只不过,这个方案存在技术风险,需要用一定的手段规避。
原文:https://blog.51cto.com/zjunzz/2549948
更多相关内容 -
关于drools有状态会话和无状态会话到底有何区别的看法
2018-06-28 15:12:57关于有状态会话和无状态的会话的区别,很多人不能真正理解,小哥也不理解,以下是官网翻译而来一、有状态会话常见用例:1. 监测 半自动买入股票市场监控与分析。 2. 诊断 故障查找,医疗诊断 3. 物流 包裹跟踪...关于有状态会话和无状态的会话的区别,很多人不能真正理解,小哥也不是很理解,但也有些看法,以下是官网翻译而来
一、有状态会话常见用例:
1. 监测
半自动买入股票市场监控与分析。
2. 诊断
故障查找,医疗诊断
3. 物流
包裹跟踪和送货配置
4. 合规
验证市场交易的合法性。
使用推理
举例:
rule "When there is a fire turn on the sprinkler"
when Fire($room : room)
$sprinkler : Sprinkler( room == $room, on == false )
then
modify( $sprinkler ) { setOn( true ) };
System.out.println( "Turn on the sprinkler for room " + $room.getName() );
end
rule "When the fire is gone turn off the sprinkler"
when $room : Room( )
$sprinkler : Sprinkler( room == $room, on == true )
not Fire( room == $room )
then
modify( $sprinkler ) { setOn( false ) };
System.out.println( "Turn off the sprinkler for room " + $room.getName() );
end
二、无状态会话常见用例:
- 验证
这个人有资格获得抵押吗? - 计算
计算抵押保费。 - 路由和过滤
将传入的邮件(如电子邮件)过滤到文件夹中。
将传入的邮件发送到目的地。
无状态会话,不使用推理,形成最简单的用例。
举例:
package com.company.license
rule "Is of valid age"
when
$a : Applicant( age < 18 )
then
$a.setValid( false );end
根据官网意思,有状态和无状态会话的一个重要区别是,无状态会话不使用推理,是一种最简单的使用方式,
那么到底怎么理解这个“推理”,这里说一下小哥的理解,举个例子来说明:有两个规则,规则一里面可以修改age,
规则二的条件是age>18,那么,插入一个age为10的对象,当你在规则一中用modify把age设置为24时,规则
引擎会意识到这个值变了,会触发规则二的执行,这就是推理
代码如下:
规则:
rule "test_1" when $p:Person(age==15) then modify($p){setAge(24)} System.out.println("-hello--"); end rule "test_2" when $p:Person(age>20) then System.out.println("-hello2--"); end
juit测试:
@Test public void test4() throws Exception { Person p1 = new Person("001", "z3", 15); FactHandle handle = kieSession.insert(p1); kieSession.fireAllRules(); kieSession.delete(handle); kieSession.dispose(); }
执行结果:
-hello--
-hello2--
那么,小哥最后总结,在实际开发中,如果规则的when中只涉及到一种对象,不需要推理,
也不关注曾经插入drools的历史数据,就用无状态会话,否则用有状态会话,哪里不理解可以加群讨论
- 验证
-
有状态和无状态的区别
2018-07-27 14:05:33有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。 无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean)...基本概念:
有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。
无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象 .不能保存数据,是不变类,是线程安全的。
代码更好理解:Java代码
public class StatefulBean { public int state; // 由于多线程环境下,user是引用对象,是非线程安全的 public User user; public int getState() { return state; } public void setState( int state) { this .state = state; } public User getUser() { return user; } public void setUser(User user) { this .user = user; } } public class StatelessBeanService { // 虽然有billDao属性,但billDao是没有状态信息的,是Stateless Bean. BillDao billDao; public BillDao getBillDao() { return billDao; } public void setBillDao(BillDao billDao) { this .billDao = billDao; } public List<User> findUser(String Id) { return null ; } }
单例模式中的有状态和无状态:
单例类可以是有状态的(stateful),一个有状态的单例对象一般也是可变(mutable)单例对象 。 有状态的可变的单例对象常常当做状态库(repositary)使用。比如一个单例对象TaskCache(Spring中配为singleton)可以 持有一个AtomicLong类型的属性,用来给一个系统提供一个数值惟一的序列号码,作为任务通迅管理的ID生成器。同时,一个单例类也可以持有一个聚 集,从而允许存储多个状态,如示例中的ExpiringMap缓存任务列表。
代码示例:Java代码
import java.util.concurrent.atomic.AtomicLong; import org.apache.mina.util.ExpiringMap; public class TaskCache { // 请求超时 private short requestTimeout; // 这个缓存Map是线程安全,并且有定时超时功能 private ExpiringMap<String, Object> tasksMap = new ExpiringMap<String, Object>(); // 线程安全的原子类,示例有状态的单例类 private static AtomicLong seqNo = new AtomicLong( 1 ); // 示例有状态的单例类 public Long nextSeqNo() { return seqNo.getAndIncrement(); } public void setRequestTimeout( short requestTimeout) { this .requestTimeout = requestTimeout; } // 启动过期检测 public void startExpiring() { tasksMap.getExpirer().setTimeToLive(requestTimeout); tasksMap.getExpirer().startExpiringIfNotStarted(); } // 停止过期检测 public void stopExpiring() { tasksMap.getExpirer().stopExpiring(); } // 取任务列表. public Object getTasks(String key) { return tasksMap.get(key); } // 去除任务列表. public Object removeTasks(String key) { return tasksMap.remove(key); } // 添加任务列表. public void addTasks(String key, Object value) { tasksMap.put(key, value); } }
单例类也可以是没有状态的(stateless) ,仅用做提供工具性函数的对象。既然是为了提供工具性函数,也就没有必要创建多个实例,因此使用单例模式很合适。平常的单例类都是没有状态的,这里就不示例了。一个没有状态的单例类也就是不变(Immutable)单例类。关于不变模式,请参考 http://www.javaeye.com/topic/959751
EJB中的有状态与无状态:
1.Stateful session bean的每个用户都有自己的一个实例,所以两者对stateful session bean的操作不会影响对方。另外注意:如果后面需要操作某个用户的实例,你必须在客户端缓存Bean的Stub对象(JSP通常的做法是用Session缓存),这样在后面每次调用中,容器才知道要提供相同的bean实例。
2.Stateless Session Bean不负责记录使用者状态,Stateless Session Bean一旦实例化就被加进会话池中,各个用户都可以共用。如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响。
3.从内存方面来看,Stateful Session Bean与Stateless Session Bean比较,Stateful Session Bean会消耗J2EE Server 较多的内存,然而Stateful Session Bean的优势却在于他可以维持使用者的状态。
Spring中的有状态(Stateful)和无状态(Stateless)
1.通过上面的分析,相信大家已经对有状态和无状态有了一定的理解。无状态的Bean适合用不变模式,技术就是单例模式,这样可以共享实例,提高性能。有状态的Bean,多线程环境下不安全,那么适合用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例。
2.默认情况下,从Spring bean工厂所取得的实例为singleton(scope属性为singleton),容器只存在一个共享的bean实例。
3.理解了两者的关系,那么scope选择的原则就很容易了:有状态的bean都使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
4.如Service层、Dao层用默认singleton就行,虽然Service类也有dao这样的属性,但dao这些类都是没有状态信息的,也就是 相当于不变(immutable)类,所以不影响。Struts2中的Action因为会有User、BizEntity这样的实例对象,是有状态信息 的,在多线程环境下是不安全的,所以Struts2默认的实现是Prototype模式。在Spring中,Struts2的Action中,scope 要配成prototype作用域。
Servlet、Struts中的有状态和无状态:
1.Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web 容器负责的。一个Servlet类在Application中只有一个实例存在,也就是有多个线程在使用这个实例。这是单例模式的应用。无状态的单例是线 程安全的,但我们如果在Servlet里用了实例变量,那么就变成有状态了,是非线程安全的。如下面的用法就是不安全的,因为user,out都是有状态 信息的。Java代码
public class UnSafeServlet HttpServlet{ User user; PrintWriter out; public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ //do something... } }
Out,Request,Response,Session,Config,Page,PageContext是线程安全的,Application在整个系统内被使用,所以不是线程安全的.
2.Struts1也是基于单例模式实现,也就是只有一个Action实例供多线程使用。默认的模式是前台页面数据通过actionForm传入,在 action中的excute方法接收,这样action是无状态的,所以一般情况下Strunts1是线程安全的。如果Action中用了实例变量,那 么就变成有状态了,同样是非线程安全的。像下面这样就是线程不安全的。Java代码
public class UnSafeAction1 extends Action { // 因为Struts1是单例实现,有状态情况下,对象引用是非线程安全的 User user; public void execute() { // do something... } public User getUser() { return user; } public void setUser(User user) { this .user = user; } }
3.Struts2默认的实现是Prototype模式。也就是每个请求都新生成一个Action实例,所以不存在线程安全问题。需要注意的是,如果由Spring管理action的生命周期, scope要配成prototype作用域。
4.如何解决Servlet和Struts1的线程安全问题,当我们能比较好的理解有状态和无状态的原理,自然很容易得出结论:不要使用有状态的bean,也就是不要用实例变量 。如果用,就要用prototype模式。Struts1 user guide里有: Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class.
总结:
Stateless无状态用单例Singleton模式,Stateful有状态就用原型Prototype模式。
Stateful 有状态是多线程编码的天敌,所以在开发中尽量用Stateless无状态,无状态是不变(immutable)模式的应用,有很多优点:不用管线程和同步的问题 ,如果值是不可变的,程序不用担心多个线程改变共享状态,所以可以避免线程竞争的bugs. 因为没有竞争,就不用用locks等机制,所以无状态的不变机制,也可以避免产生死锁现象。 -
k8s有状态与无状态的区别
2021-11-29 14:26:10无状态服务:deployment ...有状态服务:StatefulSet Deployment组件是为无状态服务而设计的,其中的Pod名称,主机名,存储都是随机,不稳定的,并且Pod的创建与销毁也是无序的.这个设计决定了无状态服务并 不适无状态服务:deployment
Deployment被设计用来管理无状态服务的pod,每个pod完全一致.什么意思呢?无状态服务内的多个Pod创建的顺序是没有顺序的.
无状态服务内的多个Pod的名称是随机的.pod被重新启动调度后,它的名称与IP都会发生变化.
无状态服务内的多个Pod背后是共享存储的.有状态服务:StatefulSet
Deployment组件是为无状态服务而设计的,其中的Pod名称,主机名,存储都是随机,不稳定的,并且Pod的创建与销毁也是无序的.这个设计决定了无状态服务并 不适合数据库领域的应用.
而Stateful管理有状态的应用,它的Pod有如下特征:
唯一性: 每个Pod会被分配一个唯一序号.
顺序性: Pod启动,更新,销毁是按顺序进行.
稳定的网络标识: Pod主机名,DNS地址不会随着Pod被重新调度而发生变化.
稳定的持久化存储: Pod被重新调度后,仍然能挂载原有的PV,从而保证了数据的完整性和一致性.对比图:
总结
本文主要介绍了无状态和有状态服务在K8S中的典型应用场景.通过对Deployment部署无状态服务所遇到问题的分析,引出了Stateful新的部署组件.它是通过支持Pod一些特性(e.g. 名称唯一性,稳定的网络标识, 稳定的持久化存储等)来实现在K8S中部署运维有状态服务.
牢记: Stateful有状态服务,每个Pod有独立的PVC/PV存储组件
-
ipv6 有状态和无状态什么意思
2021-05-15 23:58:17这是IPv6协议的一个突出特点:支持网络节点...在有状态地址自动配置的方式下,主要采用动态主机配置协议(DHCP),需要配备专门的DHCP二、无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实... -
威纶通触摸屏位状态设置和位切换开关的区别.docx
2021-07-24 12:21:23威纶通触摸屏位状态设置和位切换开关的区别 -
Kubernetes 无状态服务和有状态服务
2020-01-25 15:50:27无状态服务 是指该服务运行的实例不会在... 相关的k8s资源有:ReplicaSet、ReplicationController、Deployment等,由于是无状态服务,所以这些控制器创建的pod序号都是随机值。并且在缩容的时候并不会明确缩容某... -
什么是有状态登录和无状态登录
2019-05-14 21:55:291、有状态登录 那缺点是什么? • 服务端保存大量数据,增加服务端压力 • 服务端保存用户状态,无法进行水平扩展 ...• 客户端请求依赖服务端,多次请求必须访问同一...2、无状态登录 服务器不保存用户的登录信... -
有状态组件和无状态组件的区别
2020-03-06 20:09:10有状态组件就是一个类,无状态组件是一个函数; 区别: 1.(是否拥有state)有状态组件可以使用状态:state,无状态组件不能使用state;只有继承component这个组件它才能拥有state进行一些数据的存储和管理,仍然... -
有状态服务和无状态服务的区别是啥?阿巴阿巴
2020-10-04 12:08:33有状态和无状态服务是两种不同的服务架构,两者的不同之处在于对于服务状态的处理。服务状态是服务请求所需 的数据,它可以是一个变量或者一个数据结构。无状态服务不会记录服务状态,不同请求之间也是没有任何关系... -
有状态服务和无状态服务
2020-08-25 12:51:43服务一般分为有状态服务(Stateful Service)和无状态服务(Stateless Service)。它们的区别是,当请求发起后,服务在服务端运行时是否需要关联上下文。 有状态服务,服务端需要保存请求的信息,并且其它请求还可以... -
有状态组件 和 无状态组件的区别
2019-07-01 15:25:00一 、有状态组件 (stateful components) 平时用的大部分是有状态组件 写法: import React,{Component} from 'react'; export default class Bottom extends Component{ constructor(props){ ... -
浅谈无状态和有状态服务的区别
2019-09-26 05:36:03对服务器程序来说,究竟是有状态服务,还是无状态服务,其判断依旧——两个来自相同发起者的请求在服务器端是否具备上下文关系。 状态化请求,服务器端一般都要保存请求的相关信息,每个请求可以默认地使用以前的... -
Flink系列:有状态、无状态区别
2020-06-27 00:07:47无状态 每一条输入对应一个输出 有状态 多个输入对应一个输出 -
你知道编程中无状态和有状态的区别吗?
2020-01-16 10:26:02Java对象的状态用属性来表示,有属性,也就是对象的变量,就表示是有状态的,有状态就是线程不安全的。 关于线程安全 1) 常量始终是线程安全的,因为只存在读操作。 2)每次调用方法前都新建一个实例是线程... -
分布式系统中的“无状态”和“有状态”详解
2020-04-22 02:56:50「数据一致性」和「高可用」其实本质是一个通过提升复杂度让整体更完善的方式。 本文主要讲一些让系统更简单,更容易维护的东西——「易伸缩」,首当其冲的主题就是「stateless」,也叫「无状态」。 服务的“状态”... -
有状态服务 & 无状态服务
2018-10-26 16:38:42无状态服务:就是没有特殊状态的服务,各个请求对于服务器来说统一无差别处理,请求自身携带了所有服务端所需要的所有参数(服务端自身不存储跟请求相关的任何数据,不包括数据库存储信息) 有状态服务:与之相反,... -
如何理解有状态和无状态应用?分别有哪些实例?
2021-09-02 15:01:21无状态进程或应用可以理解为孤立的。...另一方面,有状态应用和流程则是可以周而复始、反复发生的应用和流程,例如网上银行或电子邮件。这些操作是在先前的事务背景下执行的,当前事务可能会受到先前 -
flink中 有状态计算(statefu)和无状态计算(stateless)的区别
2021-01-02 10:38:03一、有状态计算,无状态计算 apache flink来说,是支持有状态计算的。 无状态计算可以类比一下select操作,来一条,操作一条,数据不用留在系统里面。 有状态计算可以类比一下count,sum操作,这时候就需要缓存之前... -
React 有状态组件和无状态组件的区别
2019-03-24 21:50:10有状态组件的区别是它属于一个class类, 有继承, 可以通过this来接收状态和属性 如果你想用react的生命周期, 想对一些数据进行增删改查的话就要用到有状态组件 import React, { Component } from 'react' ... -
【小家java】Stream流操作的有状态 vs 无状态
2018-08-24 16:11:12说这个命题之前,我先解释一下编程里,有状态和无状态都什么意思 有状态 有状态就是有数据存储功能,线程不安全 无状态 无状态就是一次操作,不能保存数据。线程安全 下面我们先看看Srping中的Bean来辅助理解... -
react中有状态组件和无状态组件的区别和使用规则
2019-05-25 10:41:50state: 用于改变组件内容状态的值(动态) ...1.有状态组价是可以使用state的,只有继承了Component的组件才可以拥有state进行一些数据的存储和管理,同时可以拥有props 2.但是无状态组件不存在state,只会有... -
Flutter的有状态组件和无状态组件
2020-05-20 23:25:08flutter 主要有分 有状态 组件 StatefulWidget 和 无状态组件 StatelessWidget 当我我们有需要对页面的内容进行动态修改的时候 ,如果我们使用无状态组件,页面上的内容就不会被跟新 主要代码 import 'package:... -
flutter之有状态和无状态组件
2019-03-04 16:37:01无状态组件(StatelessWidget)是不可变的,这意味着它们的属性不能改变,所有的值都是最终的。 有状态组件(StatefulWidget)持有状态可能在Widget生命周期中发生变化。实现一个StatefulWidget至少需要两个类 一个... -
有状态的bean和无状态的bean的区别
2017-11-07 17:49:52有状态对象(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。每个用户有自己特有的一个实例,在... 无状态对象(Stateless Bean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安 -
单点登陆和无状态登陆
2019-08-24 13:36:24今天我们来说说什么是单点登陆和无状态登陆。 传统的项目都是使用session来验证登陆,但是在分布式项目中使用session是不行的。因为每个服务都是一个独立的项目,那么我们将服务拆分,肯定会有一个登陆的模块。... -
Flutter 无状态类、有状态类、State、生命周期
2022-04-30 13:11:03在React中,组件分为函数式组件和类式组件,它们的区别就是一个无状态、一个有状态。那么在Flutter中亦是如此,它有两种类,一种是无状态类,一种是有状态类。其生命周期的使用就是有状态类的特定用法。 无状态类 无... -
有状态Bean和无状态Bean
2019-01-16 10:23:01现实中,很多朋友对两种session bean存在误解,...有状态和无状态会话bean的本质区别是它们的生命期。 首先解释一个下面要用到的概念--用户:session bean 的用户实际上就是直接调用ejb的类的实例,甚至是这个实例... -
有状态EJB和无状态EJB的区别
2015-12-16 22:04:48前边的文章中,简单的介绍了ejb的三种bean,我们这片文章通过实例来看一下有状态的会话bean和无状态的会话bean的区别。 我们建立一个ejb项目,分别创建两个接口, 两个实现类,每个类中都有相同的方法,并在每个类...