• 不太赞同 “但如果只在某个局部使用就有点为了 React 而 React 的意思了”

    react 的本质是 state => ui, state 变 ui 变

    如果 有较高密度的 数据变化引起的 ui 变化, 就适合 react

    所谓 react 生态我是觉得挑自己想要的就好 不需要全站数据刷新的时候就没必要上 redux, 量少 localstorage 也是够用的。

    也可以参考下这里

    https://ruby-china.org/topics/38603

  • 震惊部空降了

  • 简单的或者需要 seo 的用 stimulus, 复杂的用 react/vue

  • tailwind 最好的地方就是 你想咋变就咋变

    bootstrap 我真记不住他的 css 结构 每次改个样式都很麻烦

  • 主要大多数人认为所谓的 react 是 react + redux + react router + immutable + hook + webpack plugins + fetch, axios 啥的

    而且一上就要从头开始 搞个 all in react 的前端项目, 光弄明白初始化配置, 刚接触的人一个星期都不一定能搞定。

    其实 react 可以单纯的在某个局部使用, 只依赖 react.js 甚至连 webpack 都不用配置, 直接怼进去都可以,

    一旦意识到 其实 react 的本质就是 state => ui 后, 就可以在觉得依赖数据变化的 UI component 使用 react 了

  • 哇 现在都不玩 bootstrap 上 tailwindcss 了呀

  • 楼主这种可能是对业务级别代码抽象之后, 比较方便

    其实公司流程指定的好的话, 这种挺方便的

    其实这个也是编程界的传统手艺了,在很多年前 ORM 不是很成熟的时候,

    大家上三层架构, 很多语言都会有所谓的 代码生成器的存在

    另外其实 rails 周边也有一些对常见流程的代码的整合,

    比如 gorails 小胖子 弄的 https://www.railsbytes.com 我就特别喜欢

  • 在 Rails 中集成第三方登录 at 2020年08月18日

    哈哈哈 史诗级问题

  • 高并发的电商 at 2020年08月14日

    其实就是个秒拍系统

    秒拍系统的核心理念就是

    能不动数据库就不动数据库

    那么如何在不动数据库的情况下, 解决用户高并发的问题呢? 高并发下, 要守住两个底线:

    • 库存不能为负
    • 下单成功, 且付款成功的, 一定要购买成功

    将秒拍抢购进行进一步的分析:

    1. 用户首先获得购买资格(库存足够 + 用户下单)
    2. 用户付款, 安排发货

    其实并发压力就在 1 上, 2 无所谓, 毕竟付款成功后回调大多数系统都有 retry 机制, 问题不大。 至于解决并发压力最好的方式就是让这些变成串行通过,

    最简单方式自然是 利用 redis 的原子性来进行操作

    方案 1:硬来

    redis 记录库存数量, 待秒杀开始时, 进来的请求进行下单操作, DECR 后的读书如果>=0, 则建立订单, 注意, 这里一定要利用 decr 的原子性, 在此判断之前, 不要有任何数据库操作, 否则数据库会爆

    if redis.decr(SKU_STOCK_GATE) >= 0 # 在此之前不要有数据库读写操作
      create_order(current_user, sku) #这里最好是个异步, 否则也可能造成数据库抖动
    end
    

    这种最基础的方式有一个麻烦之处, 如果有一个买家想一次购买 N 个商品, 就比较头疼了,因为我们很可能遇到这样的情况, 库存只有 1, 但是此时用户要买 2 个或者更多

    如果需求是: 如果是多个购买, 则允许最小购买数, 那就无所谓, 系统可以将其转化为单位为 1 的订单, 但是大部分是: 如果数量不够, 就建立订单失败。

    因为包含了多个购买, 所以就不能用 decr 而是要用 decrby 2 了 此时 SKU_STOCK_GATE 为 1, redis 操作完毕后, GATE 值为 -1 不满足 GATE 条件, 不能购买了。 库存不变

    但是此时就有个麻烦的地方:
    STOCK_GATE 已经小于 0 了, 但是真实的库存是 1

    此时, 如果再有人购买一个库存, 也会提示失败了

    也就是说, 这种方案的弊病就是:

    有可能出现 库存还有, 但是无法进行购买了

    其实我们可以发现, 大于 1 的购买, STOCK_GATE 有几种可能

    1. 在 STOCK_GATE 操作之前, STOCK_GATE 就已经为负数。 这种分俩情况, 第一种情况是, 前置操作是 单一购买, 以及前置操作是大于 1 的购买, 用递归的思想, 后者一定开始于前置是单一购买或 0 购买, 而没人买的话, 不存在库存不足的问题, 所以 这种问题简化成: 前置是单一购买, 且操作前 STOCK_GATE 已经为负, 这种情况很好理解, 就是没库存了, 购买失败

    2. STOCK_GATE 在操作前后,都为正, 所以没啥说的, 正常购买

    3. STOCK_GATE 在操作钱为 正, 操作后为负, 这种是库存不够, 购买失败, 理应回退库存

    但是这里就有个问题, 因为要拿到 decr 之前的数据, 所以要先 get 一下数据, 超过 1 次操作 redis 的话, 整个操作就不保证原子性了, 当并发高的时候, 就会出大问题, 例如:

    账户 A 和账户 B 请求同时 一起进来

    有可能出现这样的情况, 假设 key 的值是 0 , 当 k <0 的时候, 跳出判断, 否则执行减 1, A 和 B 一起发生 GET 请求, A 先返回 GET 请求, ruby 执行下一句 让 redis 执行 decr - 1, 但是正当 ruby 要通知 redis, 但 redis 还没执行的时候 B 的 ruby 的 GET 命令先到达了 redis , 此时 redis 也返回 0 于是根据 ruby 的逻辑, B 也会执行 -1

    解决这类问题, 自然是锁

    改进后的方案 2: lock

    使锁来保证判断的时候只有单线程,不会出现数据脏读

    begin
      block_result = lock_manager.lock!("SKU_LOCK_KEY", 2000) do
        pre_gate_value = redis.get('SKU_STOCK_GATE')
        return false if pre_gate_value <= 0  # 库存没有了
    
        after_gate_value = redis.decrby(SKU_STOCK_GATE, num
        if after_gate_value >=0 
          return true  #可以购买
        else
          redis.incrby(SKU_STOCK_GATE, num) # 将扣除的加回来
          return false  #
        end  
      end
    rescue Redlock::LockError
      # 锁超时, 理论上来说这里只有redis 和最简单的判断操作, 很难超时, 最好接入人工检查
    end
    

    通过锁可以解决问题

    但是这种方案有没有啥其他的问题呢?

    比较麻烦, 自己维护锁, 万一锁超时, 检查起来也很烦躁

    于是到了我觉得最简单的方案 3, 排队。

    方案 3: 排队

    即当发生抢购的时候, 利用 redis, 在一定时间内, 给每个参加购买的人一个号码即可, 之后入队。

    因为 push 本身靠的是 redis 来保持原子性,所以无所谓。

    之后拿一个进程单独处理这个队列, 不符合的就直接 next, 因为是独立处理, 所以压根不存在并发问题, 也就没有锁的概念。

    但是这种的缺点也很明显, 即订单生成时间与用户无关, 只与 进程处理时间有关, 但是其实这个时候秒杀用户基本也都在线, 就算建立的订单最后他没支付, 重新将库存加上即可。

  • 国际团队用的真不少

    国内介于网络原因 估计不太适用普通公司

    我是被 command + j 震惊的 无敌好用