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

摸完鱼就放国庆,祝大家国庆快乐

  •  
  •   timeromantic · 2019-09-30 12:15:27 +08:00 via Android · 3676 次点击
    这是一个创建于 1883 天前的主题,其中的信息可能已经有所发展或是发生改变。
    摸鱼鱼塘 2.0 版本发布

    https://printf520.com/hot.html

    欢迎体验新版

    更新说明
    https://printf520.com/single.html?id=69


    之前一直打算优化热榜的历史架构问题,在讲优化点前,先看一看热榜遗留的历史问题:

    热榜数据由一整个 json 串组成,造成的问题就是后期无法对热榜的历史数据查看,和每一条数据后期进行条件性筛选。
    高强度的零散数据写入和读取,关系型数据库在表结构的扩展和数据库的写入造成问题
    一次性获取几百条热榜数据,api 接口需要传输接近 20kb 的数据量,在用户高峰时期造成了热榜的卡顿
    解决问题一:

    对于造成上面三点的历史原因分析在于在初期创立热榜这个页面,基于快捷开发,产品先上,用户体验优化后期跟进的原则。所以遗留了这些问题,目前正是后期的优化时间点。先看第一个点,前期为了快速开发,数据的存储放在 mysql,并且由表的一个字段存储。表的结构如下图 1.0:



    1.0 表结构图

    可以看到在之前的设计里面每次 api 返回的数据其实就是一个 str 字段,当然这样的设计对于数据的读取和写入都是十分方便的,但是如果后期想要对热榜单独的每一条数据进行分类,这个 json 数据就显得十分的不方便了,加之综合第二点关系型数据库并不适合这样零散的数据,所以为了解决这一点,我选择了 nosql 领域比较成熟的一款数据库软件——mangodb。

    解决问题二:

    其实若不是第二点的原因,想要单独的存储每个数据不一致的热榜信息,mysql 也是可以胜任的,不过主要是因为不同的网站热榜所带的参数不一致,所以这个时候 mangodb 的面向文档存储就很适用了。对于文档型存储,其数据是用二进制的 Json 格式 Bson 存储的。数据就像 Ruby 的 hashes,或者 Python 的字典,或者 PHP 的数组,适用这样的数据类型完全可以满足每个热榜的数据差异性,并且 mangodb 没有固定的表结构,不用为了修改表结构而进行数据迁移,比如如果业务需要在原有的表增加一个字段用于记录每行数据的点击量,如果使用 mysql 我们需要修改整个表结构,然后再更新整个字段,但是对于 mangodb 来说,基于文档的存储可以不用修改表结构,直接把带有用户点击量的字段插入到表里即可。

    解决问题三:

    之前有不少的用户反馈一次性获取 200 条热榜数据,会响应一段时间,接到这个问题后,发现其中一个原因就是因为 api 每次需要返回的数据量过大,在不增加服务器带宽和使用加速 CDN 的情况下,我使用的解决方式是开启 API 的 gzip 模式,开启 gzip 后 api 返回的不再是原滋原味的原生数据,而是通过服务器端压缩后传输的 gzip 压缩数据,带来最直接的效果就是数据被压缩了不少,对比图如下:



    3.0 压缩后的 api 数据大小



    3.1 压缩前的 api 数据大小

    从 2 张图的对比可以看到,开启 gzip 后的 api 返回数据明显比未开启前小了不少,数据越小传输速度越快,当然压缩带来的成本是 API 在每次返回数据前 CPU 会执行压缩算法,不过在当前带宽不足,而 CPU 足余的情况下可以忽略不计,并且压缩后的数据可以直接存放在 redis 的缓存里面,避免二次压缩。值得一提的是 Golang 语言并不需要使用 Nginx 和 tomcat 的服务器软件,所以开启 Golang 的 http gzip 需要由自己实现,下面贴出 Golang 开启 Gzip 的关键代码段:

    package main

    import (
    "compress/gzip"
    "io"
    "net/http"
    "strings"
    )

    type gzipResponseWriter struct {
    io.Writer
    http.ResponseWriter
    }

    func (w gzipResponseWriter) Write(b []byte) (int, error) {
    return w.Writer.Write(b)
    }

    func makeGzipHandler(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
    if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
    fn(w, r)
    return
    }
    w.Header().Set("Content-Encoding", "gzip")
    gz := gzip.NewWriter(w)
    defer gz.Close()
    gzr := gzipResponseWriter{Writer: gz, ResponseWriter: w}
    fn(gzr, r)
    }
    }

    func handler(w http.ResponseWriter, r *http.Request) {

    w.Header().Set("Content-Type", "text/plain")
    jsonStr := `{"Code":0,"Message":"获取数据成功","Data":"热榜数据","CreateTime":1569673821}]}`
    w.Write([]byte(jsonStr))
    }

    func main() {
    http.HandleFunc("/a", makeGzipHandler(handler)) // 设置访问的路由
    http.ListenAndServe(":1113", nil)
    }
    32 条回复    2019-10-08 09:49:57 +08:00
    xuromky
        1
    xuromky  
       2019-09-30 14:01:06 +08:00
    还有三个小时就下班的我已无心工作
    charleyking
        2
    charleyking  
       2019-09-30 14:03:38 +08:00
    终于更新了,又可以快乐的摸鱼了
    timeromantic
        3
    timeromantic  
    OP
       2019-09-30 14:13:19 +08:00 via Android
    @charleyking 哈哈,更新了一些遗留问题。欢迎常来
    timeromantic
        4
    timeromantic  
    OP
       2019-09-30 14:13:41 +08:00 via Android
    @xuromky 同,无心工作
    Understarry
        5
    Understarry  
       2019-09-30 14:20:07 +08:00
    无心工作+1
    fyxtc
        6
    fyxtc  
       2019-09-30 14:34:24 +08:00
    赞,收藏了
    jy02201949
        7
    jy02201949  
       2019-09-30 14:37:17 +08:00
    我洗好手,剥好橘子就等着下班了现在,谁也不别想让我今天下午工作!!!
    kkshell
        8
    kkshell  
       2019-09-30 14:40:21 +08:00
    无心工作
    timeromantic
        9
    timeromantic  
    OP
       2019-09-30 14:43:47 +08:00 via Android
    @jy02201949 下午人体宕机
    jy02201949
        10
    jy02201949  
       2019-09-30 14:46:46 +08:00
    @timeromantic #9 老铁你这网站我打不开
    timeromantic
        11
    timeromantic  
    OP
       2019-09-30 14:56:11 +08:00 via Android
    @jy02201949 建议用 chrome 打开
    sunziren
        12
    sunziren  
       2019-09-30 15:00:36 +08:00
    你这网站,真的太卡了。
    unco020511
        13
    unco020511  
       2019-09-30 15:04:42 +08:00
    这加载有点太慢了啊老哥
    timeromantic
        14
    timeromantic  
    OP
       2019-09-30 15:08:59 +08:00 via Android
    @sunziren 今天下午人流量太大了。看来要加服务器了
    @unco020511
    hikarumx
        15
    hikarumx  
       2019-09-30 15:18:05 +08:00
    非常好,简单清爽
    G2838
        16
    G2838  
       2019-09-30 15:22:20 +08:00
    这加载有点太慢了啊老哥
    SSW
        17
    SSW  
       2019-09-30 15:22:49 +08:00
    你在今天放出来,这摸鱼的人也太多了,鱼塘都炸了
    doveyoung
        18
    doveyoung  
       2019-09-30 15:23:38 +08:00
    我昨天还在摸,今天就打不开了烙铁,是带宽不够了吗
    MX123
        19
    MX123  
       2019-09-30 15:31:53 +08:00
    为什么不用电报群?
    timeromantic
        20
    timeromantic  
    OP
       2019-09-30 15:32:27 +08:00 via Android
    鱼塘炸鱼了,人太多。哈哈,该升级服务器了
    @SSW
    @doveyoung
    @G2838

    多刷新还是可以打开
    timeromantic
        21
    timeromantic  
    OP
       2019-09-30 15:33:23 +08:00 via Android
    @MX123 好的,建议不错,可以加电报群,不过不是所有人都能顺利翻墙
    VensonEEE
        22
    VensonEEE  
       2019-09-30 15:50:03 +08:00
    @timeromantic
    大佬,有没有能缓存这些文章的 app ;
    各自的排版,风格不同,大部分网页打开需要多一次展开操作、或者跳转到 app 的提示;
    虽然说法律上不可行,但真的体验难受。
    Saszr
        23
    Saszr  
       2019-09-30 15:50:56 +08:00
    建议那个二维码不放在热点页,放在联系页(页面首次加载出现二维码影响美感 2333
    timeromantic
        24
    timeromantic  
    OP
       2019-09-30 16:06:46 +08:00 via Android
    @VensonEEE 抱歉,确实从法律上来说,如果直接抓取内容或者显示是侵权的。
    mcluyu
        25
    mcluyu  
       2019-09-30 16:29:49 +08:00
    摸了一圈才过了 29 分钟
    timeromantic
        26
    timeromantic  
    OP
       2019-09-30 16:31:26 +08:00 via Android
    @mcluyu 摸一圈这么快!
    qsbaq
        27
    qsbaq  
       2019-09-30 16:33:21 +08:00
    无心工作+1
    t1o1
        28
    t1o1  
       2019-09-30 17:28:15 +08:00
    一直在用。。。
    byfz
        29
    byfz  
       2019-09-30 17:32:23 +08:00
    一直在刷,刚试了,标签可以自由拖动,挺好的
    byfz
        30
    byfz  
       2019-09-30 17:35:02 +08:00
    可惜每次刷新都会重置为默认顺序
    timeromantic
        31
    timeromantic  
    OP
       2019-09-30 17:44:03 +08:00
    @byfz 拖到了后需要点击右下方的保存按钮
    mcluyu
        32
    mcluyu  
       2019-10-08 09:49:57 +08:00
    @timeromantic 7 天前仿佛就在昨天,好像一瞬之间😭
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1067 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:27 · PVG 04:27 · LAX 12:27 · JFK 15:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.