V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
beryl
V2EX  ›  程序员

状态机的理解与应用场景?

  •  
  •   beryl · 2020-09-22 13:06:17 +08:00 · 5140 次点击
    这是一个创建于 1302 天前的主题,其中的信息可能已经有所发展或是发生改变。

    抱歉,这目前不是个分享而是个讨论

    当前系统是Java 微服务架构,准备引入状态机,但是没有相关经验,也不确定是不是必须要引入

    有几个问题想和大家交流:

    1. 状态机适合在什么业务场景和架构上使用
    2. 状态机解决什么问题
    3. 微服务场景适合状态机么
    4. 有没有参考的资料可以学习下

    谢谢

    第 1 条附言  ·  2020-09-22 14:14:36 +08:00
    先解释下,其实我有有些懵,具体背景大体是:

    有个实体假设是 app, 有各种状态,新建、上线、审核中、审核成功、被使用、被销毁等等
    不同状态的变更操作,在不同的服务之间进行操作,各个服务操作又互相耦合在一起,很难维护和清晰定位。

    老板和同事建议使用状态机做统一管理,但是之前对这个并没有实际经验

    大体背景就这样子,实际状态和业务可能比这个还要复杂。。。

    (-_-
    32 条回复    2020-09-23 10:05:49 +08:00
    opengps
        1
    opengps  
       2020-09-22 13:12:17 +08:00
    状态机解决的是站点集群共享会话问题,在集群环境下,多个 web 负载机(无状态)可以更好地使用弹性伸缩,零活增加 web 机器数量来增加负载,但是对于会话状态,则需要:A 定向到某台机器 或者 B 共享到一个地方
    解析:
    A 定向到某台机器的做法,在负载均衡处可使用“改写 cookie”
    B 共享会话状态,则统一从“状态服务器”获取。也就是你说的状态机
    zoharSoul
        2
    zoharSoul  
       2020-09-22 13:33:00 +08:00
    比如交易订单状态流转
    beryl
        3
    beryl  
    OP
       2020-09-22 13:53:37 +08:00
    @zoharSoul  查了一些资料,也大都是运用在交易系统,我们目前不是这种系统,而且有多种实体,流程状态可能也要比交易要复杂
    beryl
        4
    beryl  
    OP
       2020-09-22 13:54:28 +08:00
    @opengps 如果按照这种理解,感觉当前系统不适合。我再研究研究
    reus
        5
    reus  
       2020-09-22 13:58:51 +08:00 via Android
    能不能不要乱用名词?
    状态机就是状态机,你这个叫状态服务器!
    不要用不同的概念去污染名词!
    beryl
        6
    beryl  
    OP
       2020-09-22 14:04:28 +08:00
    @reus 不是状态服务器,还是想着用状态机的概念去处理服务
    #1 的概念我理解是状态服务器
    hugedata
        7
    hugedata  
       2020-09-22 14:05:26 +08:00   ❤️ 2
    楼主和一楼说的“状态机”可能和我理解的状态转换的状态机( State Machine )不一样……
    beryl
        8
    beryl  
    OP
       2020-09-22 14:09:32 +08:00
    @hugedata 那换个问法:
    State Machine 的应用场景是什么呀,还是只是概念术语
    catror
        9
    catror  
       2020-09-22 14:09:34 +08:00
    7 楼+1,看得我一脸懵逼
    timsims
        10
    timsims  
       2020-09-22 14:15:54 +08:00
    楼主不如简述一下你想通过你所指的 “状态机” 解决怎样的问题
    beryl
        11
    beryl  
    OP
       2020-09-22 14:16:34 +08:00
    @timsims 嗯呢,补充了下问题
    opengps
        12
    opengps  
       2020-09-22 14:17:56 +08:00
    看了 append,文中“状态机”不是我理解的状态服务器
    zlowly
        13
    zlowly  
       2020-09-22 14:20:25 +08:00
    为什么我感觉题主描述的场景更接近于工作流引擎?
    beryl
        14
    beryl  
    OP
       2020-09-22 14:23:04 +08:00
    @zlowly 是想着 workflow 和 state machine 结合的方案
    jintianfengda
        15
    jintianfengda  
       2020-09-22 14:27:21 +08:00
    状态机就是用来维护实体的状态的玩意,当一个实体的状态比较多且比较复杂的时候,都可以引入状态机来统一管理状态流转,通过"动作"来进行状态的变更,我理解这个 statemachine 这个跟架构有一丢丢关系,但是不大,跟一楼说的状态服务器不是一个东西
    Lonersun
        16
    Lonersun  
       2020-09-22 14:43:08 +08:00
    您看看这篇文章,不知能不能解答一些你的问题 https://juejin.im/post/6844903817192947726
    imn1
        17
    imn1  
       2020-09-22 14:49:25 +08:00
    比较关键是状态有限(可以全部列举),每个状态都是固定的,只会出现不同的状态,而单个状态本身不变
    服务器场景我不熟,但可以从其他方面说一下问题 2

    1.有序的状态切换,这个有序是固定的、必经的,每个状态都要轮训一遍
    例如上述订单流程

    2.无序但有限几个状态之间无级切换,每次状态改变需要做固定接口的处理
    例如有限个外观主题之间切换
    我在一个 GUI 项目里面用了十多个状态机,处理一些独立的控件 event,这些控件不会和其他控件组合,一旦改变就会直接执行程序,这样只要控件的参数值有限,类型只有一个,多少个参数值就是多少个状态了

    其实可以这样说,GUI 的控件都是固定的,程序就是处理控件产生的参数改变和组合而已,理论上可以全部用状态机写,理论上;只是有些参数值和类型太多,多个控件组合出来的状态可能无穷多,状态机无法全部列举而已

    状态机是省代码和省思考,因为状态固定,状态进出处理的函数也固定(不太复杂),要想的就是状态变化的可能,穷举列出来而已
    目前我所知的状态机处理第二种还是比较麻烦的,例如 3 种状态,要列明 1-2, 2-1, 1-3, 3-1, 2-3, 3-2 等所有排列组合情况,比较好的是如果这些 123 状态只是简单的标识区别,可以 for+排列组合 来完成这个定义,如果复杂一些就不好使了,还不如写个变参函数方便

    顺便也举个不适用例子,也是这个 GUI 项目,最初想把语言切换(汉英)也写成状态机,后来考虑到将来要增加语言(日韩……),而且语言变化还有细微不同(状态不完全固定),感觉用状态机是给自己挖坑,就放弃了,改用事件信号+函数
    zhuangzhuang1988
        18
    zhuangzhuang1988  
       2020-09-22 14:52:38 +08:00
    chanxiaoxi
        19
    chanxiaoxi  
       2020-09-22 15:04:59 +08:00
    我猜你说的是 State Pattern 设计模式
    Ariver
        20
    Ariver  
       2020-09-22 15:07:33 +08:00
    工作流啊
    lzxz1234
        21
    lzxz1234  
       2020-09-22 15:08:15 +08:00   ❤️ 1
    适合场景:复杂流程对象,例如特殊类型订单,三个参与方以上的订单,用户下单,用户撤回、客服打回、商家拒单就是三个,再加上不同状态允许操作的人员不一样,很容易堆出各不相同的几十种状态来

    纯在代码靠 if else 复杂度极高,维护过程新加角色、状态或者 几条操作路径都可能导致工作量爆炸

    至于微服务和状态机的关系,这个其实没关系,更取决于业务复杂度

    资料直接看工作流就可以
    sampeng
        22
    sampeng  
       2020-09-22 15:43:37 +08:00 via iPhone
    此机非彼机…看到机字就是机器是么
    reus
        23
    reus  
       2020-09-22 15:56:00 +08:00
    @beryl 用规则引擎啊,把所有规则都写下来
    新建 app 需要什么要素,满足了才能新建
    上线需要什么条件,满足了才能上线,等等
    直接搬运现实的办事方式就行,需要什么材料,需要哪里盖章,都完备了,就可以办某件事
    不用管什么状态机,只有两种状态:条件够了,能办,条件没够,不能办。
    例如一个事情需要盖十个章,你不需要把每一种盖章组合都搞出一个状态来,你只需要说,缺哪些,不能办,就够了
    状态机这个模型,用来描述业务是不适合的,它只适合微观的场景,例如 TCP 状态机这类几十年不用变的。用状态机描述业务,一旦业务流程变了,整个状态机都要改,麻烦得很。
    liuhuan475
        24
    liuhuan475  
       2020-09-22 17:00:02 +08:00
    你说的状态机是这个吗? https://www.bilibili.com/video/BV1Eb411U7z8?p=95
    ieiayaobb
        25
    ieiayaobb  
       2020-09-22 17:38:37 +08:00
    电商业务,订单系统是个很经典的 state machine
    THESDZ
        26
    THESDZ  
       2020-09-22 17:47:53 +08:00
    将这种服务抽离成单独的服务,看业务,可以进行读写锁,大概就能满足你的需求了
    THESDZ
        27
    THESDZ  
       2020-09-22 17:48:40 +08:00
    @THESDZ 或者直接用 redis 做为 k-v 存储,业务逻辑交给业务代码处理?
    amoyiki
        28
    amoyiki  
       2020-09-22 18:02:07 +08:00
    大家有在生成上面有过 状态机吗?目前我还是用 if else
    gaius
        29
    gaius  
       2020-09-22 18:06:56 +08:00 via Android
    就是独立订单服务,有啥问题。服务只是计算,实际的状态机是后面的数据库
    SurfaceView
        30
    SurfaceView  
       2020-09-22 18:09:12 +08:00
    我做过几个。。
    1 个是播放器的 1 个是下载系统
    都深度依赖状态机 (非状态模式
    useben
        31
    useben  
       2020-09-22 18:34:55 +08:00
    我理解的状态机是分布式系统中的状转移个同步..
    SmiteChow
        32
    SmiteChow  
       2020-09-23 10:05:49 +08:00
    常规情况下要考察控制流是否经常变动,如果控制流经常变动,那么使用状态机更合适.
    如果不怎么变动,那么直接硬编码控制流为编程语言语法即可.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1009 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:23 · PVG 06:23 · LAX 15:23 · JFK 18:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.