普通视图

发现新文章,点击刷新页面。
昨天以前首页

去不图床网站架构分享

2022年9月5日 00:00

杜老师更新图床架构后,不少小伙伴反馈速度快不少,使用体验较之前提升了很多。也有小伙伴担心图片的稳定性和安全,本篇分享一下去不图床网站架构。

网站架构

其实没有多么复杂,后端并不是多个服务器,而是多个服务组成:

数据走向

  1. 当用户访问图床时,会通过前端的多吉云 CDN 国内节点加速,页面获取极限带宽为 100M;

  2. 当用户上传图片时,数据需先经过自建服务审核,再通过 FTP 协议传至存储模块;

  3. 上传带宽为 500M,理论极限值受审核速度,及 FTP 队列处理速度影响;

  4. 存储模块域名独立,通过多吉云 CDN 国内节点加速,提供高速外链服务。

参与设备

所用到的设备配置为 16H16G。存储为 512NVMe,带宽上行 100M 下行 700M。

图片文件每一小时同步备份至 NAS,保障数据安全。

写在最后

随着图床用户体量增加,原有的服务器已经无法满足运营需求,尽快杜老师做了很多次优化,但因为线路等关系,在大量上传图片时经常出错。

且受节点影响,部分地区的用户出现无法访问等情况。现图床 ICP 备案已下,正式切为国内节点,且服务器配置提升,保障了用户的使用体验。

最后还是要说一下,图床目前使用家用网络,如果出现突发停电、断网等情况则会影响服务稳定性。

杜老师目前住处的电费自动续缴,除线路整修外不会出现突然断电问题「入住一年,就出现了一次,断电了 5 分钟」

目前家中两条带宽,其中一条只跑 NAS 和图床,且 NAS 为双网卡,主要上传下载操作均不会影响到图床带宽。

除图床站点外,杜老师说评论系统、友链的朋友圈、访问统计也运行在该主机上!

杜老师说网站架构

2021年4月22日 00:00

最近调整了杜老师说的网站架构,保障平稳运行的同时降低运营的成本,此文做记录的同时也向大家分享一下目前架构,如有建议欢迎在评论区留言!

网站架构

杜老师说网站架构:

数据走向

访客通过互联网将请求发送至域名解析服务器,DNS 服务器为 Cloudflare「以下简称为 CF」仅作域名解析,并未开启缓存功能。

CF 将域名指向 CDN 地址,CDN 优先查找对应的缓存数据,如未找到缓存数据,则请求 OSS 中保存的网站数据。

OSS 的网站数据由 ECS 生成,ECS 运行 Hexo,生成的网站源码通过 API 传输至 OSS。

当访客评论时,评论数据发送给 CDN,并经由北京 ECS 存至香港 ECS 数据库。

架构优点

CDN 可以隐藏后端服务器的真实 IP,保护 ECS 不被 DDoS,同时 CDN 的缓存功能可以降低后端负载,且降低 OSS 因流量产生的费用。

ECS 通过内网连接 OSS,提升传输速率同时,降低因流量产生的费用「内网流量免费」

通过 OSS 静态网站功能可以降低 ECS 负载,且外网流量费用低于 ECS「ECS 带宽按流量付费」

多个节点数据互不影响,保障高效运行同时降低因数据丢失产生的影响。

架构缺点

两台 ECS 服务器不在同一地域,跨域访问会影响传输的速率,且会产生额外费用。

CDN 缓存会导致网站内容更新延迟,部分内容更新后需手动刷新缓存数据才可正常访问。

去不图床网站架构

2021年4月19日 00:00

最近调整了去不图床的网站架构,保障平稳运行的同时降低运营的成本,此文做记录的同时也向大家分享一下目前架构,如有建议欢迎在评论区留言!

网站架构

去不图床网站架构:

数据走向

访客通过互联网将请求发送至域名解析服务器,图床的 DNS 为 Cloudflare「以下简称为 CF」CF 已开启缓存功能,会优先查找对应的缓存数据,如未找到缓存数据,则请求 ECS 中运行的网站数据。

当访客上传图片时,通过 ECS 将数据保存至 OSS,并返回图片的访问地址。

当访客通过外链访问图片数据时,CF 优先查找对应的缓存数据,如未找到缓存数据,则请求 CDN 中的缓存数据。

如 CDN 中未找到缓存数据,则从 OSS 中调用图片数据,同时进行图片鉴黄操作,最后将数据传输给访客。

架构优点

CF 可以隐藏后端服务器的真实 IP,保护 ECS 不被 DDoS,同时 CF 的缓存功能可以降低后端负载,且降低 OSS/CDN 因流量产生的费用。

ECS 通过内网连接 OSS,提升传输速率同时,降低因流量产生的费用「内网流量免费」

架构缺点

服务节点较多,获取图片数据需经过三个节点,且三节点不在同一地域,跨域访问会影响传输的速率。

阿里云的 CDN 图片鉴黄功能非实时拦截,需人工做图片拦截操作。

简单架构中的数据走向

2019年9月21日 00:00

当我们访问一个网站时,这个数据在网络中是如何流通的,服务器之间又是如何配合处理的,今天我们来聊一下!

网络拓扑

如图,我们简单说下数据包的走向:

数据走向

首先,客户端会请求数据,请求通过外网连接到路由器,路由器会将请求的目标地址转换为内网 IP,也就是虚拟分发 192.168.1.200。

虚拟分发 IP 在 Master 服务器上面,Backup 服务器使用 Keepalived 监测其是否存活,Backup 服务器会通过 VRRP 协议,使用 24.0.0.18 组播来监测。如果 Master 宕掉了,Backup 服务器会将虚拟 IP 抢过来,下次由 Backup 负责分发,直到 Master 恢复后,会将虚拟 IP 抢回去。

还有一种情况,就是设置两个 Backup 服务器,这时需要给它们设置优先值,优先值较高的服务器充当 Master 身份,会占有虚拟 IP,当这台服务器宕机,另一台会将虚拟 IP 抢占过来,然后变成 Master 的身份。

分发器会把请求分别发送给 Web 服务器。Apache 可以解析静态的页面,动态页面会交给 PHP 处理。PHP 需要配合 MySQL 使用,在获取数据时,PHP 会先去 MemCache 中查找,如果有此数据,PHP 会直接输出给请求端,如果没有数据,PHP 会去 MySQL 查找,MySQL 将数据返回给 PHP,PHP 在收到数据之后,会将数据复制一份,放在 MemCache 中。

小红书Android客户端演进之路

2016年8月8日 19:13

小红书Android客户端第一个版本于2014年8月8日发布,转眼到了2016年8月8日,小红书Android版本发版两周年。趁机回顾一下小红书的Android版本,两年中我们踩过很多坑,收获很多经验,分享出来与大家共勉。 小红书从最初1.0到现在目前4.7版本,历经两年,安装包从原先的5M发展到现在的17M,产品模块也从原先的只有社区模块发展到了具有社区和电商两个大模块。App包含社区、电商、支付、推送、直播、统计等各种功能和模块,那么开始吧。

功能演进

两年的时间,30多个版本的迭代,许多功能都有了翻天覆地的变化。我们的新人欢迎页也是从最初的比较炫的效果发展到目前比较稳定的简洁版本。当初钟大侠花了无数个日日夜夜,苦心做出来了多个欢迎页动画,虽然现在已经不再使用,但是我们也学习到了一些新技术。后来,钟大侠还是将其贡献到了github开源社区中。 欢迎页第一版

下载地址:https://github.com/w446108264/XhsParallaxWelcome

欢迎页第二版

下载地址: https://github.com/w446108264/XhsWelcomeAnim

社区是小红书的核心价值之一,笔记是小红书社区的核心体现,毋庸置疑,笔记发布是小红书App的核心功能之一,我们一直在产品和技术上,优化我们的笔记发布流程和功能,包括我们将只支持分享单张图片,扩展到现在支持多张图片同时发布。同时支持更丰富的图片编辑效果,更加便捷的发布笔记。

小红书的笔记展现形式和大多数其他的图片社交App类似,我们也支持图上标签功能。最初小红书图上标签是同其他App类似的黑色的标签。不过在3.0之后,小红书创造了独特的树状标签,给用户带来焕然一新的体验,同时也被其他App竞相模仿。新的标签给技术也带了很多的挑战,我们重新定义了标签的结构,以及标签的生成和展示。可以查看我以前的博客,来看看我是怎样做标签的动画的。(http://blog.isming.me/2016/06/07/path-property-animation/

UI的改版,功能上的改动还有很多,这里不再一一提起。小红书Android整体上的风格和iOS保持一致,不过我们在15年初开始,对于App内的细节进行Material Design 适配,包括一些按钮风格、点击效果、字体规范、对话框等等,希望为Android用户带来更好的使用体验。

技术选型进化

在技术选型上,这里主要讲一下网络层的框架选型升级和图片加载库的升级。

网络框架的演进

App的最初框架是由钟大侠一人花了10来天完成,包括基本的网络请求框架、App大体的架构以及一些主要的功能。最初时候选择框架的原则就是选择自己最熟悉的,因此我们采用了async-http这套框架作为我们底层的网络请求框架,框架完成了网络的异步请求与回调,能够满足当时的需求。

然而仅仅不到半年之后,我们就决定了使用Volley来替换。替换以后,底层的网络请求代码更加清晰,在Volley返回的结果即直接返回了我们需要的Object,同时将统一的错误处理、公共的参数处理和一些公共的返回使用的参数,全部放在我们自定义的Request当中,这样外部请求所需要传入的参数更少,对于错误的处理更加简单,只需要考虑业务需要的Response,其他全局的返回内容则无需进行干扰。通过Volley的引入,帮助我们在业务的开发上变得更加便捷。引入Volley之初,Volley的底层使用的是HttpClient+HttpURLConnection,后期通过网上的资料发现OkHttp使用NIO更加高效,并且被Android 引入作为系统底层的网络请求,我们也将Volley的底层也替换为OkHttp。

与此同时,小红书的api请求也在不断进行RESTful,我们遇到一个问题就是经常找一个api的定义比较麻烦。大约在15年11月份,我们引入了Retrofit,通过二次改造,使其支持了公共参数的构建,以及对于GsonConvert的改进支持直接返回我们需要的Object,而且对于RESTful风格的良好支持给我们提供了极大的便利。配合RxJava,我们可以方便的进行多个api的同时请求、api返回的多个线程的切换。

图片加载框架的演进

小红书的笔记是以图片加文字为主体的内容,因此会有大量的图片显示需求。和网络框架选型类似,早期选择了比较熟悉的UIL来做图片加载,可以同时支持本地图片和网络图片的加载,在当时可以满足我们的基本需求。

15年初,我们开始使用更加高清的图片,随之加载速度变慢,占用更多的内存,而且这个时候UIL的作者基本很少维护。我们开始调研使用新的图片加载框架。此时Fresco刚刚出来,还不太稳定,当时没敢用。给我们的可选项有Picasso和Glide两个可选项,Picasso比较轻量,但是相比于UIL在性能上没有太好的提高。Glide代码量较大,不过它会在本地保存多份缓存(原始图片和实际显示尺寸的图片),这样加载本地缓存的时候,可以直接显示大小刚好的尺寸,减少解码的时间,因此会比UIL要快很多。

15年下半年,我们需要支持gif的动画显示,而Glide对动画的兼容性又不是特别好,这个时候我们直接切到了Fresco。同时Fresco对webp的良好支持,使得我们在后期切换到webp格式的时候,减少了很多工作量。Fresco在4.4及以下版本使用匿名内存来作为内存缓存,为我们减少OOM做了巨大的贡献。

我们使用的这几个图片加载框架,每个框架的使用都有非常大的区别,这就导致迁移的时候工作量巨大。为了降低迁移成本,我们封装了自己的ImageLoader,在ImageLoader中来实现具体的图片加载,这样保证在迁移的时候,最大程度的降低代码的改动(不过在迁移到Fresco的时候还是改动巨大,因为我们不能直接使用ImageView了o(︶︿︶)o。

推送的升级

推送,我觉得也有必要说一说。最初我们快速选用了百度云推送,在当时看来百度的推送比较稳定,同时接入比较简单。实际使用了一年之后,发现送达率不是特别高,并且数据统计做的不太好,无法比较好的统计推送效果。在调研之后,我们决定迁移到小米推送+友盟推送的模式,针对小米用户开启小米推送,其他用户采用友盟推送,为了平滑过渡,在切换期间同时向未升级的老用户继续使用百度云推送进行推送。

架构升级

由于一直以来在业务开发占用的时间比较多,目前App的整体架构没有做过太大的改变。

在Adapter的使用方面,我们将ListView或RecyclerView的Item放到单独的ItemHander,这样可以在不同的页面可以通过将不同的Item组装到一起,从而满足不同地方的需求。这样可以在ListView或RecyclerView来复用相同的代码,提高代码的可维护性。

前面网络层说到我们的错误处理,这个也是做过比较大的升级。最初时候,网络错误、http请求错误、后台和客户端的错误,都分别在不同的层级进行处理。目前我们在发生错误的时候将错误全部以Exception的方式抛出,最后在上层进行错误的处理。

App中的状态同步,早期使用使用数据库缓存部分数据,或者使用LocalBroadcast进行广播通讯,前者有很多的限制,后者使用起来较为复杂。近期我们改用EventBus进行状态同步,同时这样也使得各个页面之间的耦合也低。

App中占比很大的部分是从网络请求数据,获得数据后进行展示,还是以MVC为主。在一些模块的部分地方,做一些databinding,MVP等的测试。后面有机会会更多大范围的重构。

其他周边进化

我们的开发最初是使用Eclipse进行开发的,但是Eclipse仅仅存在了不到一个月。在我苦口婆心的劝说下,钟大侠和我一起切换到了Android Studio。而这导致我们的项目目录一直都是使用Eclipse时代的目录格式,直到今年年初才切换到Android Studio推荐的目录格式,切换完目录为我们做debug和release差异化提供了极大的便利。

APK最初大约只有5M,历史最高峰达到了23M,在App减肥上我们也做了一些努力,主要是使用tinypng压缩图片,so只保留arm的支持。项目的复杂也使得每次编译都变得很慢,关于这个可以看下我以前的gradle加速http://blog.isming.me/2015/03/18/android-build-speed-up/

现在持续集成还是蛮火的,自然我们也在用。最初的时候,我们每天需要手动打包,打完包之后打开fir的网站,将apk传上去,然后在公司的微信群吼一声,告诉大家我们发包了。经历一段时间后,我们编写了一个Gradle插件帮助我们自动上传到fir,在之后我们搭建了Jenkins自动完成这一系列步骤,并通过邮件告知大家,然后就可以愉快的玩耍了。

Jenkins

未完待续

本文介绍了我们两年来的一些大的变化,通过一篇文章可能很多东西还是说不清楚,暂时就写这么多。目前项目的组织架构还没有特别大的变化,我们目前已经在做一些小范围的测试,后面将对继续不断的进化和演进。

看完评论一下吧

❌
❌