• 比如 PHP

  • 你在 location 里面添加这2个试试看,具体说明请参考 nginx 的文档:

    proxy_http_version 1.1;
    proxy_set_header Connection "";
    
  • 把Nginx配置贴上来看看?

  • 看这个 TIME_WAIT 是 nginx 和 puma 之间的连接,试试设置 nginx upstream keepalive 应该能解决这个问题。

  • 可以多创建一个表,记录被用户单条忽略的动态:

    ignored_events
    ------------------------
    user_id,  event_id
    3      ,  10
    

    然后加一个 not exists 或者 not in 查询

    select e.* from events e, event_subscribers es
        where e.user_id = es.subscribed_user_id
          and es.user_id = 3
          and e.id not in (
            select id from ignored_events ie
              where ie.user_id = 3
          )
    
    
  • 文章写的好详细,赞。

    如果担心大数据量的性能问题,还有一个选择是用 PostgreSQL 的 array ,可以给它设置 GIN 类型的索引,本质上是一个全文索引的字段,Rails 也有相关的 gem : https://github.com/tmiyamon/acts-as-taggable-array-on

  • [*0..5, *2..8, *3..12, 2, 2, 2, 2].each{|i| print' '*(40-2*i-i/2)+'*'*(4*i+1+i)+"\n"}
    
  • 可以看一下 ProxySQL 它能满足你提到的这些需求: https://github.com/sysown/proxysql

    另外一个是 Vitess 但我对它不熟,听 Github 的人说他们在评估这个,你也可以看一下: https://github.com/vitessio/vitess

  • ActiveJob 目的是为了并发/异步执行,改成长度为1的队列,未免削足适履,更合适的解决方案是用 flock,用 Exclusive lock 和 None blocking 来保证一个文件只能被一个 JobWorker 处理,同时也有并发处理多文件的能力

    f = File.open(...)
    if f.flock(File::LOCK_EX | File::LOCK_NB)
      ...
    end
    
  • 直觉是不可能,在我自己机器上跑了一下,结果是相反的,你的ruby是什么版本?

    2.3.2 :018 > Benchmark.measure { maxa(1000)}
     => #<Benchmark::Tms:0x007fcd7a884b78 @label="", @real=3.692405005916953, @cstime=0.0, @cutime=0.0, @stime=0.040000000000000036, @utime=3.6, @total=3.64> 
    2.3.2 :019 > Benchmark.measure { maxf(1000)}
     => #<Benchmark::Tms:0x007fcd7b027b00 @label="", @real=0.8660073862411082, @cstime=0.0, @cutime=0.0, @stime=0.009999999999999898, @utime=0.8300000000000001, @total=0.84> 
    

    好像在2.4测试就反过来了,是因为2.4的那个Array#max实现更新吗,等下再看看...

  • 推模式问题在于任何影响订阅关系的行为,比如屏蔽或者取消屏蔽,还需要对已经推送的event进行修改

  • 和推不一样的,推的模式在产生event的时候,需要写入大量数据,而且这种设计也没有 屏蔽/取消屏蔽 导致数据不正确的问题

  • 我觉得拉的模式缺点讲得不正确,把event和friendship强关联的设计是这个造成这个缺点的主要原因,而不是拉模式本身的问题。

    正确设计应该有一个中间表,比如 event_subscribers ,表结构是这样的:

    user_id, subscribed_user_id
    3      , 4
    3      , 8
    1      , 4
    1      , 10
    

    SQL查询是固定的:

    select events.* from events, event_subscribers
        where events.user_id = event_subscribers.subscribed_user_id and event_subscribers.user_id = 3
    

    所有的屏蔽,过滤都是对event_subscribers这个中间表数据做操作

  • 可以先用数组的前一个元素做group_by,然后用map!方法将后一个元素做replace:

    data = [['A', '123'], ['A', '1223'], ['A', '12343'], ['A', '122XX33'], ['B', '678'], ['B', '612378'], ['B', '67XX8'], ['C', '100'], ['C', '1000']]
    
    data.group_by(&:first).each{|_, v| v.map!(&:last)}
    
    # => {"A"=>["123", "1223", "12343", "122XX33"], "B"=>["678", "612378", "67XX8"], "C"=>["100", "1000"]} 
    
  • 除了添加额外字段对比session之外,你也可以用一样的思路依赖devise内置的model Trackable(通常我都会建议在使用devise的项目中设置这个模块)的字段sign_in_count,然后写一个hook,几行代码就可以满足你的需求:

    Warden::Manager. after_authentication do |record, warden, options|
      warden.session(options[:scope])[:sign_in_count] = record.sign_in_count
    end
    
    Warden::Manager.after_fetch do |record, warden, options|
      if record.sign_in_count != warden.session(options[:scope])[:sign_in_count]
        warden.logout(options[:scope])
        throw :warden, :scope => options[:scope], :message => "Signin from another IP address #{record.last_sign_in_ip}"
      end
    end
    

    基本上做devise的扩展都是通过hook来进行,非常简洁方便。

  • 想了一个无需默认0 Hash的一行版:

    a.inject({}){|m, (k, v)| m.merge(k => v.to_i) {|k, old, new| old + new} }
    
  • 这个弱鸡的换行问题 at 2017年12月11日
    params.values_at(:begin_integral, :end_integral, ...).all?(&:present?)
    
  • 你这个只有对单个created_at进行查询,RTree索引在这里和BTree相比没有优势

  • 对,ActiveRecord的PG支持有range这个类型,Mysql就比较落后了,得自己去实现,就是提到的扩展问题3: http://edgeguides.rubyonrails.org/active_record_postgresql.html#range-types

  • Ruby 爬虫框架 at 2017年11月07日

    现在的爬虫趋势是用headless chrome,通过 amazon lambda 运行,之前写过2个脚本,支持ajax,加上css selector/xpath,用来抓数据非常方便,大规模爬虫,代理IP,都很容易设置。

    如果做爬虫框架的话,求支持这种模式。

  • 有etag和last-modified

  • curry和数学中定义各种符号一样,主要是用来抽取公用部分,简化代码。

    比如高中数学中的累加符号Σ

    对应到Ruby代码,我们可以定义一个sigma lambda

    sigma = -> (f, a, b) { a.upto(b).map{|n| f.(n)}.inject(:+)}
    

    然后用curry定义数字累加操作和平方累加操作:

    sum_of_number = sigma.curry.(-> (n) {n})
    sum_of_square = sigma.curry.(-> (n) {n * n})
    
    sum_of_number.(1,10)
    sum_of_square.(1,10)
    

    可以用相同的代码来定义累乘符号∏

    pi = -> (f, a, b) { a.upto(b).map{|n| f.(n)}.inject(:*)}
    

    更进一步,Σ和∏都是范围操作,我们可以用curry抽取出来:

    range = -> (x, f, a, b) { x.(a.upto(b).map{|n| f.(n)})}
    sigma = range.curry.(-> (r) {r.inject(:+)})
    pi = range.curry.(-> (r) {r.inject(:*)})
    
    products_of_number = pi.curry.(-> (n) {n})
    
    products_of_number.(1,10)
    
  • 贴一下我之前给一个类似项目做的性能优化, 单机目标500RPS 跑wrk本机测试,单机结果1105RPS, 这是在一台每月200元的2核4GB最低配云主机跑的结果:

      10 threads and 100 connections
      Thread Stats   Avg      Stdev     Max   +/- Stdev
        Latency     8.95ms    1.59ms  54.36ms   82.69%
        Req/Sec   224.23    142.93   484.00     79.00%
      11171 requests in 10.10s, 3.05MB read
    Requests/sec:   1105.64
    Transfer/sec:    309.35KB
    

    你要问什么架构?基于rails-api,redis存储,都是大路货,没什么高端科技 150台机器...只能说楼主有钱,请我!每小时仅收费$300,保证赚回你的机器钱