? ? ? ?在手机上显示图片,速度是一个非常重要的体验点,试想。假设您打开一个站点,发现里面的图片一直显示失败或者是x。略微做得好一点的,可能是一个不消失的loading或者是菊花等等,但无论怎样,?没能高速的拉取和展示图片对用户体验是一个极大的挑战。那么,手机上的图片体验怎样做呢?这里笔者有些小总结:
? ? 1,降低图片的大小。
在失真度和图片大小中做好折衷,尽量利用工具降低图片的size,也能够考虑利用不同的图片格式。
? ? 2。降低图片的请求数。能够考虑把多个图片利用相似css sprite的方式进行合并,这样能够载入一次就可以;
? ? 3。考虑缓存。对图片在client进行一定的缓存,设置好缓存时长和更新机制。
? ? 4。考虑使用cdn进行载入图片。做到就近接入訪问。
? ? 5。解决DSN劫持的问题。在手机业务上的经验告诉我们,非常可能某些地区,某些运营商把我们的域名封掉或者劫持了。这样,图片的域名解释出来的IP却不是我们提供图片服务的IP,而且这样的情况非常难发现,? 由于。假设运营商通过抽样随机劫持,就非常难发现。
解决的方法能够:
?.去掉dns,改成直接訪问IP的方式,但须要解决依据用户的ip获取近期图片服务的ip地址,实现上:这里cgi在吐出訪问图片的地址的时候,获取用户的来源网关IP,调用IP地址库推断来源IP所属地和运营商。然后下发相应的图片部署接入IP,?client使用IP直连图片服务器,高速的訪问资源。
? 问题是,有实现成本,得业务自己去实现相似一个dns解释的逻辑,特别是图片放到cdn的话,这样改造就无法使用cdn带来的加速服务能力。
??
?.做好dns劫持的监控。实际上图片dns解释到的vip list肯定是在我们的一个白名单内。假设不是,则肯定属于dns劫持,client能够在某个时候拉取一下我们的vip list。作为监控和推断是否dns劫持的问题,假设dns的ip地址?不在白名单内。则替换使用白名单内的ip进行訪问。??
?.考虑备用域名的方式。即假设一个域名拉取不到,改用备用域名进行訪问。当然假设备用域名也被劫持,那就不行了。
? ?
二,优化后台的架构
? ? ?后台返回越快,前端的体验就越好,因此,也须要对后台服务的调用链进行梳理。避免循环调用,快慢混杂等问题。主要的原则比較简单,都是一些设计方面的原则
? ?1。轻重分离。服务中把訪问量大,须要速度快的服务和訪问量小,但业务逻辑复杂的流程从代码实现和物理部署上进行彻底分离。如用的接入cgi(甚至不同的域名),不同的后台server。不同的集群进行隔离。
? ? ? 假设放在一起。慢的会拖住快的,这就像木桶原理一样,终于的速度是由最慢的决定的,假设处理不好,可能导致整个服务阻塞不可用。
?
? ?2,评估好业务的訪问流程和路径设计。区分关键路径和非关键路径,设计上尽量考虑把关键路径转换为非关键路径,关键路径须要有多级容灾的考虑,非关键异常须要有监控。
? ?
? ?3,考虑异步化。异步化相比同步的实现来说略微复杂一些,或者说须要做的工作可能多些,但异步化的优点也会非常明显,特别是须要高性能的业务流程。常见的异步化实现策略是借助mq作为各个系统的缓冲,?生产者进程或者子系统把消息写入mq就可以马上返回,而消费者进程或者子系统则定时从mq读取消息继续处理,而且把处理的结果通过回调通知或者写入返回mq给到生产者查询。当然,假设生产者是不关注结果的。那?就更加简单了,丢到mq后就可以,这里的问题是整个mq是整个业务流程的关键。须要确保服务的高度可用和性能。
?
? ?4,一些配置的动态载入,本地化存储,加上基于版本号的更新机制。
笔者也发现过有些业务cgi之所以在较少请求量的时候就出现了较高的负载,终于不得不用很多其它的机器来承担相应的请求量。定位终于原因是cgi在启动的时候须要载入?非常多配置的东西,甚至非常多配置并非该cgi须要的,优化思路是:是按需载入。仅仅载入该cgi须要的;提前载入配置到共享内存。同一时候添加版本号号,维护好cgi自身进程的私有版本号和共享内存的版本号。cgi启动的时候比較版本号号,发现不同。则?真正进行文件的又一次Load到内存。另一种模式是採用配置中心进行推送的模式。实现集中管理。
?
? ?5,做好外部依赖的管理。
一个业务流程可能往往要调用到外部的系统,而且这些系统可能不是你们团队维护的,假设该系统是非关键路径还好,假设是关键路径,那么做好对外部依赖的管理就显得更加重要了,那么怎样做好外部依赖的管理呢?
? ? ? 这里有几个小的tips:
?. 对外部调用的服务单独进行封装。如设计单独的proxy去调用外部的服务。这样的优点是方便集中监控和容灾逻辑等处理,在设计上把外部因素进行物理隔离的第一步,兴许假设外部系统的协议或者ip地址得发生变化,则能够仅仅改动该模块就可以?高速修复;
?. 严重建议对外部接口进行错误和超时的监控,一旦出问题,提前预警并高速解决,这里是有血的教训的,某业务和某平台提供者两方在纠结是谁的问题上吵得不可开交,不知道是谁的问题。业务说自己没问题。平台方说自己的服务也非常快,假设?你能够拿出你的监控数据。接口超时设置是 1s, 超时的记录有n条,时间是ns。错误的记录有m条,主要错误类型是xxx。那对高速定位是非常有帮助的。
?. 考虑能否够弱化为非关键路径?有些调用可能是否无法弱化为非关键路径的,如登录态校验,失败了仅仅能是业务流程终止,给用户返回失败(当然可能存在部分业务缓存session id作为异常的时候的备用,但这个不是非常建议,原因非常easy,可能导致入口?不唯一。甚至造成安全漏洞,这里须要详细案例详细分析)。有些路径是能够设计为非关键路径的。如数据上报。
假设知道某个服务是关键路径。比方在支付前的请求billno_server获取唯一的订单号,从业务流程看。这个肯定是一个关键路径,没有订单号就无法下单,业务流程运行不下去,但假设每次下单都调用一次billno_server生成?一个订单号,偶尔的网络超时或者失败都是可能的,而对用户来说,就是此次下单提示大家都非常熟悉得不能熟悉的一句话:“系统繁忙。请稍后再试”。那么能否够做得更好呢?或者至少降低这样的概率呢?
一种思路是每次请求一批billno缓存到本地进程空间, 然后使用的时候先从本地缓存中取,没有了再去请求。一种是请求失败的时候。能否够考虑用本地随机生成一个。在极端情况下弱化对该关键路径的依赖?
? ?6。考虑到手机client的计算能力比較弱,在设计上是否把计算成本很多其它的往服务端移动,利用强大的服务器端计算能力提升用户体验,这一点也是微信架构设计给笔者的一个感受。
? ?
?三,优化链接
? ? ?怎样管理链接是一个老生常谈的话题了,这里主要长连接和短连接的问题。
当然另一些什么连接池等策略。
?
? ? ?弱网络环境下,建立链接的时间非常长,网络质量測试数据显示。建立链接占用耗时接近1/3,走短链接又导致链接频繁,所以考虑将短链接改成长链接。在碎片时间内反复利用,降低建链耗时。此外。还有下面几个优点:?
? ? ?1,C/S的持续链接使得后端能够主动push重要数据到client,比如实时的通知。新数字提醒等等。能非常好的改善体验,在短链接的情况下,仅仅能依靠client进行定时轮询,不可避免的使新数据有所延迟。
?
? ? ?2,进一步节省短链接过程中的包大小,短链接情况下,每次来回请求,都不可避免须要带上一些公共数据。
长链接仅仅用在建链接成功后的第一个包中上行这些数据。兴许包则能够省掉这些字段,进一步降低流量。?
? ? ?3。长链接还能有效的降低流量限制类手机软件导致服务不可用的问题。有些流量限制类软件会接管用户的全部网络请求。以达到流量计算和断流的目的,这样的本质上就是一种劫持。使用长链接+私有加密协议,?能够使得对方无法准确分析包情况,降低劫持到来的服务不可用情况。
?
?
? ? ?注意:使用长链接的时候。必定有长链接过期不可用的情况。因此。业务实现须要埋入重连机制。
?
?四,基于网络质量的多级服务设计
? ? ?手机的网络环境比較多样,如wifi, 3G, 4G 还有2G等。不同的网络环境的体验是不同的,对非常好的网络环境我们就不说了,关键讨论一下在2G等比較恶劣的情况下的一些思考。
1,不同的网络环境是否具备多级的服务能力?如针对2g网络的用户。显示的内容更少? 图片变成文字?一些功能入口不可用?
在网速非常慢的情况下,包的大小至关重要,直接影响成功率。能够考虑更加紧凑的协议(包含不必要的字段不发送)+压缩算法。
这里有个tips。大家知道cookie的内容都是每次跟在http请求一起发送给到服务器的。?对图片,js,ccs等建议部署其它域名进行cookie隔离,这样也能够降低一定的包大小。
?
?