首页

零基础学习UI设计到底需要学些什么?

蓝蓝

在进入一个未知的范畴前,一定要先梳理这个范畴的架构,待有了对比全部认知后再深挖。学习UI规划也是相同,假如有条件,能够尝试了解一个新的互联网商品出炉的作业流程。

微交互|只要关注这6个点,交互设计师也能做好竞品分析!

雪涛

今天我们来聊聊竞品分析,它并不是像人们认为的那样——有统一的模板,因为针对不同的岗位,做的竞品分析是不同的。所以本文聊的是:交互设计师如何做竞品分析。
竞品分析是对产品、交互从业人员最基本的技能要求之一,很多刚入行的产品汪、交互喵首先要做的都是竞品分析,一来可以考考你的底子,二来可以锻炼你的逻辑思维。虽然它是基本技能,但是它的作用却非常大。
那有什么作用呢?当你设计了一个功能,别人问你为什么这么设计时,你的答案要非常专业,而不是说“我觉得……”,这时候竞品分析就派上用场了。
做竞品分析,可以避免相关设计人员站在自己的角度去思考问题,在评审的时候容易通过且能够获得大家的认同,而不会受到来自各方的质疑,这也是那么多人做竞品分析的原因之一。
当然,站在产品和运营的角度来说,做竞品分析还能开拓市场、优化产品、制定策略、确定战略等等,但是这些在我看来并不是交互设计师需要关心的事情(除了优化产品)。

怎么做竞品分析

大家在网上能看到很多竞品分析文档,会发现里面的内容非常多,而且很多都看不懂。告诉你三个字:不用看。
这些文档看起来好像很专业,但是当中涉及的数据内容、商业分析、产品战略等大部分都是笔者自己 YY 的,这个不仅对做竞品分析没什么帮助,还会使自己在做的过程中特别容易跑偏。所以你只需要关注以下六个点来做或看竞品分析文档。
  1. 找到商业需求
  2. 用户操作流程
  3. 产品功能分析
  4. 交互逻辑思考
  5. 用户使用评价
  6. 得到设计需求

01. 找到商业需求

商业需求这个点,不仅仅适用在竞品分析的开头,我们做交互文档、需求文档都要把商业需求放在首位。只有商业需求的目标明确了,才好进行下一步操作。那什么是商业需求呢?
给大家举个简单的例子:
今天接到一个产品需求:即优化产品的搜索功能。可能很多人看到这个需求就马上开始看看别人的搜索都是怎么做的,然后抄一下,改一下就好了。这样设计出来的东西,只能说是一个具体的设计任务,而不是解决实际问题的方法。
我们要先找到商业需求,为什么要优化产品的搜索功能呢?有些资深的产品经理会在需求文档中写出,而有的并不能想到这一层,仅仅只是觉得不好用所以让你去优化。所以当你的产品经理属于后者的时候,你就要提前参与到前期的工作中,给自己提问题,告诉自己为什么要去优化,以及它能带来什么效益?
当你的工作做到位的时候,并且了解的足够多的话,你很轻易的就会发现,我优化这个搜索功能的原因有两个,也就是商业需求:一是提升平台成交率,二是获取用户数据。

02. 用户操作流程

得到商业需求,我们就要做具体操作,就是找到合适的竞品。这里我扩展一个话题,就是找什么竞品。
通常,我把竞品分为三大类,分别是核心竞品、潜在竞品(类竞品)、交互参考竞品,这三类具体指的是什么,有兴趣的小伙伴可以自己去研究了解。
找到这三类竞品后,要做的就是把它们所有关于搜索功能模块的界面做一个仔细操作,并截图单独存放在一个文件夹中做深入分析。
比如这个功能涉及到的页面、动效、视觉等所有信息都进行详细观察,然后将其做成一份流程图,将所有的竞品都这样做完后,进行对比分析,你就会发现当中的差异,然后就可以知道哪种操作路径是最好或最适合你的产品的。

这图是我为了写文随便搭的,就是个demo,具体的大家还是要自己去操作。

03. 产品功能分析

当你列出所有流程操作图后,下面就可以对搜索的功能进行分析。
这块操作起来比较简单,首先建一张表,罗列出相应的支持功能,然后对支持的竞品类目打上勾,不支持的就不做处理,如下图:

这图也是我为了写文随便搭的,就是个demo,具体的大家还是要自己去操作。
做完以上操作,接下来再分析每个竞品的搜索导航是属于什么类型,这种类型对搜索有什么好处等等。包括搜索功能模块的其他信息,如展示形式、关键词、筛选字段等等,以此推导出其中的差异。当然,做其他功能也是一样,我只是拿搜索做个例子。

04. 交互逻辑思考

由这层开始,要分析功能交互的问题。在每个流程图的边上写下相关的交互逻辑,然后通过自身的行业知识来拆解竞品当中的交互信息,如:
  • 搜索之后页面的跳转的层级
  • 搜索结果展示
  • 页面布局的合理性
  • 图片比例规则
  • 按钮热区
  • 表单展示形式
  • 等等
如果你是一个资深的交互设计师,看到的信息还会更多,这块跟自身能力有关,拆解的产品、分析的交互逻辑越多,这块的梳理能力就会越强,看产品的本质也会越深。那么你分析竞品所能得到的信息也是一般交互和产品不能发掘的。(关于这块的产品拆解我后续会有文章单独说明)

05. 用户使用评价

这块工作看着好像跟竞品分析不搭边,但却是不可缺少的一环。因为即使你做了再多的分析和拆解,看了再多的偏好数据(更何况有些公司拿到的数据并不全面),都没有看用户使用评价来的更加直观。所以看用户的使用评价变得极其重要,只有真实了解用户内心,你才能真正设计出好的产品。
我们可以通过各个渠道去了解用户对一款产品的评价,包括对某个功能的看法,当然我之前也说过,我们不能听用户的一面之词,所以需要去提炼当中的关键信息,帮助自己更好的去完善产品。
这块其实没什么好说的,在竞品分析文档中,这块内容其实不需要做过多的展示,只要拿到你的关键信息并做个大概说明,然后说出你从中得到的设计思路就可以了,我们最后还是要看输出总结,即通过做竞品分析得到的设计需求。

06. 总结输出

当我们按照上面的流程做完所有步骤之后,你就会得到你的设计需求,如:
  • 关键词搜索
  • 搜索建议
  • 条件过滤
  • 搜索历史
  • 查找相似商品
  • 让用户快速识别搜索入口
  • 字段排序
等等。
这些所有子功能都是通过做竞品分析得到的,当然你也可以通过用户调研等方式去得到设计需求。
说这么多,就是告诉他家我们做一个产品时,不是自己去YY要做什么,而是通过这一系列工作流去找到应该做的事情。这就是你在这个岗位必须做到的事情,不要以为产品或交互的工作很简单,上面的每个步骤都是需要大量时间的练习才能做好的。

小结

我们通过竞品分析来提高我们产品自身的核心竞争力,并不是为了求同,也不是为了模仿,而是为了突出自身的产品价值,正所谓知己知彼,百战不殆,竞品分析的目的并不是为了抄袭,而是为了超越竞品。
不过,竞品分析还是会有一定的局限性,比如说我们做竞品分析的时候往往容易将产品和企业文化、产品商业战略等信息剥离开来,但是对于很多产品来说,这些是很重要的东西。所以也就很容易忽视这其中的相关性,分析的时候就有可能导致片面或者出现误差。
所以我们就要不断地改进我们的竞品分析报告,学会从整体上去把握产品的脉络,才能更好地摆脱竞品分析的局限性。 

四大分析法打造你的产品说服力

雪涛

开篇明义,这四大分析法就是:市场分析、竞品分析、用户分析、需求分析。从这四个角度深入分析,就能证明你产品方案的正确性。
其实干了多年的产品老手,一眼就能看出我说的都是「废话」,谁都知道这四类分析法是做产品的基本功,做好了当然能把产品做好。是的,我写这篇文章还有一个目的:就是让大家重新重视这些「基本功」,心态归零。
很多时候,产品经理都被各业务方需求压得喘不过气,更多时间在写文档、画原型、跟项目、处理 bug 反馈中度过。各位正在看本文的产品经理可以回忆下,有多久没认真做过分析了?

话说回来,所谓「认真分析」,也是有法可依、有据可循的。今天就给大家复盘下,身为产品经理,最需要掌握的四大分析法,都如何来做。 

一、市场分析

市场分析的官方定义:
对市场容量、市场规模及市场特性等相关内容进行实事求是的经济分析及预测 。
包括三大范畴:
  • 从行业角度,要看行业有没有发展,市场规模大不大,政策好不好;
  • 从用户角度,要看市场中的用户习惯、用户构成、用户期望;
  • 从自身角度,要认清在市场中自己的优势劣势,遇到的挑战等。
如果要用一句话描述做市场分析的目的,就是看你要做的这个产品,能不能赚钱。是的,虽然很残酷,但一款不赚钱的产品,无论用户体验多好,设计多精美,技术多先进,仍旧是无法持续的。
当然,除了能不能挣钱外,还要进一步研究为什么能挣钱,怎么挣钱,怎么挣到更多钱,能挣多少钱等等。
具体的分析方法,包括:
  • 搜集相关资料,包括宏观经济、行业竞争、技术趋势、市场阶段、市场规模等;
  • 分析市场用户基本情况;
  • 分析自身基本情况。
可能会用到的一些分析模型包括:PEST、SWOT、波特五力等等,这里不再展开,大家可以按关键词搜索更多。

二、竞品分析

竞品分析和市场分析是相辅相成的,有市场就有竞争,很少有一家独大的情况,因此就需要你思考如何在激烈的竞争中脱颖而出。
竞品分析的目的:一方面是了解市场格局,判断是否有机会切入;另一方面是为了制定有利于自身的竞争策略。这个策略,不仅体现在交互设计、使用流程、用户体验上,还要考虑运营、营销、推广策略,甚至还有资本运作方式等。
因此,要求你做竞品分析时,要先定义清楚你分析的目的是什么,然后自顶向下地进行,从行业格局到功能细节,都要有所涉猎。

三、用户分析

用户分析的目的是为产品的立项或优化提供定量或定性支持 ,常见方法包括:观察用户行为、听取用户意见、收集用户数据。对于新产品,比较好用的分析方法是做用户调研。
在用户调研过程中,最需要注意的就是调查问卷的撰写,总结下我觉得需要注意的几点:
  • 避免出现诱导用户选择的选项,比如:如果给你提供一个XX功能,你会不会用。
  • 避免出现无法理解的专业术语,比如:你是否希望我们的产品采用个性化推荐算法分发内容。
  • 避免出现容易引起歧义的模糊词语,比如:你使用社交电商产品频率是多少。
  • 避免出现需要让用户思考的问题,比如:你每周共花多少钱买我们的产品。
  • 避免直接出现产品名称,比如:你觉得像喜马拉雅、得到这样的知识付费产品能解决你的问题么。
还有一点想说的是:设计每道题的每个回答项时,都要明确每个选项你希望带来的结论是什么,这样才会促使你不断完善自己的问卷。 

四、需求分析

需求分析是我觉得四大分析里最难的,也是产品经理的必备课题,因为这背后体现的是对心理的洞察,而「人心」其实是最难猜的,抓住了人心,你的产品自然会成功。
需求分析的过程,要求产品经理具备一双敏锐的眼睛发现需求,一颗好奇心挖掘需求。日常工作中,你所面对的需求包括:客观需求和主观需求。
客观需求:是指通过行为数据、市场趋势分析、竞品调研、用户研究、体验问题等渠道收集的需求,通常要求产品经理时刻保持对行业、对数据的观察和思考。
主观需求:是明确有人向产品经理提出的需求,你的需求方可能包括老板、客户、用户、内部团队。日常工作中最复杂的情况也就是处理主观需求,因为「说服」是个非常耗时耗力的过程,但也是体现你产品能力的时候。
具体如何分析需求,其实已很多方法论,比如威格斯法、KANO模型、Y模型、四象限法等。
建议在每次分析需求时,都用如下句式对需求定义:
什么人,在什么场景下,为了达到什么目的,在遇到什么问题的情况下,希望采用什么方法来解决。
以上句式,说明了:用户角色、使用场景、目标定义、任务说明、问题描述。几乎囊括了描述一个需求的所有要素。
此外,需求分析最重要的还是如何把用户需求转化成产品方案,这一过程要求产品经理同时具备用户思维和产品思维,具体做法在此不再赘述。
最后还想再和大家强调下,分析不是目的,最重要的是通过分析得出对工作有帮助的结论 ,与你共勉。

Java跨域问题的解决方案及axios的跨域请求方法封装

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

原因

出于安全考虑,浏览器有一个同源策略。浏览器中,异步请求的地址与目标地址的协议、域名和端口号三者与当前有不同,就属于跨域请求。

限制跨域访问是浏览器的一个安全策略,因为如果没有这个策略,那么就有被跨站攻击的危险。比如,攻击者在自己的网站A放置一个表单,这个表单发起DELETE请求,删除某个用户在B网站上的个人资料。如果没有同源策略保护,那么在同一个浏览器内,如果用户已经登录了B网站,这个删除的请求就会被接受,导致在用户不知情的情况下自己在B网站中的资料被删除。

解决方式

浏览器的同源策略提升了安全性,但是给需要在不同域名下开发的开发者带来了跨域问题。

解决跨域的问题主要有: 
jsonp和cors。jsonp是利用 script 标签可以跨域加载的特性而创造出来的一种非正式的跨域解决方案。在实际开发中,推荐使用cors,即在服务端返回时加入允许跨域的请求头,允许指定域名的跨域访问。

千万要小心!这种直接加 * 号的做法是相当危险的,千万别这么做!

response.addHeader("Access-Control-Allow-Origin", "*"); 
  • 1

正确的做法:

1. 创建一个 Filter 类

/**
 * 使用Filter的方式解决跨域问题
 */ public class CorsFilter implements Filter { private static final List<String> ALLOW_ORIGINS = Config.getListString("allowOrigins", ","); private static final String REQUEST_OPTIONS = "OPTIONS"; @Override public void init(FilterConfig filterConfig) throws ServletException {
    } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String orgHeader = request.getHeader(HttpHeaders.ORIGIN); if (orgHeader != null && ALLOW_ORIGINS.contains(orgHeader)) { // 允许的跨域的域名 response.addHeader("Access-Control-Allow-Origin", orgHeader); // 允许携带 cookies 等认证信息 response.addHeader("Access-Control-Allow-Credentials", "true"); // 允许跨域的方法 response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, PUT, HEAD"); // 允许跨域请求携带的请求头 response.addHeader("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With"); // 返回结果可以用于缓存的最长时间,单位是秒。-1表示禁用 response.addHeader("Access-Control-Max-Age", "3600"); // 跨域预检请求,直接返回 if (REQUEST_OPTIONS.equalsIgnoreCase(request.getMethod())) { return;
            }
        }
        filterChain.doFilter(request, response);
    } @Override public void destroy() {

    }
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2. 在 web.xml 的最前面注册这个 Filter

<filter> <filter-name>corsfilter</filter-name> <filter-class>com.bj58.crm.plus.filter.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>corsfilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

前端使用 axios 可以先进行封装

http-util.js

let axios = require("axios"); let qs = require("qs");
axios.defaults.withCredentials = true;
axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; function post(url, param) { return axios.post(url, qs.stringify(param))
} function get(url, param) { axios.get(url, {params: param})
}

export default {
  get,
  post
};

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务




转载设计反模式之架构设计

博博

背景

 

下图所示线上故障,你的产品线是否曾经中招或者正在中招?同样的问题总是在不同产品线甚至相同产品线不同系统重复上演,这些故障有个共同特点,就是线下常规测试很难发现,即便线上验证也不易暴露。但是总是在“无变更安全日”悄然爆发,严重影响系统稳定性指标。



面对这些看似并无规律的故障,Case by case的分析无疑是低效而且不系统的,无法全面扫除稳定性测试盲区,也无法阻止悲剧在其他产品线再一次发生。为此笔者把问题聚类,根据问题特点寻求通用测试手段,并在产品线各个系统落地验证,效果显著,现把个人经验融合前辈经验产出,供大家参考,有则改之,无则加勉。

首先,为了让大家更好了解这些故障对业务系统稳定性的影响程度,需了解下何为稳定性,衡量指标就是系统可用性= MTBF / (MTBF + MTTR) , 其中MTBF, Mean Time Between Failure, 是平均无故障时间, 而MTTR, Mean Time To Repair,是平均修复时间,参考下表更加直观。

从如上数字看,5个9的故障时间月故障时间只有25s,3个9的可用性月故障时间也只有40多分钟,回想我们平时处理过的线上问题,开发和测试质量把控不过关,然后再把期望寄托在半人肉处理故障的运维团队,显然无法达到线上产品稳定性要求。

为了保障系统稳定性,提前消除风险势在必行。产品质量风险类型很多,产品研发流程的各个阶段都可能引入和存在风险,每个阶段的风险的类型和发现手段都不尽相同,为此产出如下风险模型。按照风险发生的阶段及原因,风险类型可分为:架构设计风险、编码风险、安全风险、流程规范风险、运维风险和监控风险。


本文主要讲解架构设计风险,接下来介绍的每个风险都会说明风险定义,影响,以及通过什么技术手段来进行风险识别,最后总结风险消除方案。另外每个风险都会有具体的例子来讲解,这些例子都是发生在百度内部的真实故事。


架构设计风险


架构设计风险是QA最容易忽略的,该类风险出现在研发阶段的早期,我们都知道缺陷越早的暴露后期研发的维护成本越低,而且一旦架构设计上出现了问题,影响面是涉及整个模块甚至系统的,修复代价必然非常高,因此对于架构设计的风险更要提前了解和避免。

根据既往经验,架构设计风险大概可以分为以下几个维度:交互、依赖、耦合。

交互类常见风险:重复交互、高频交互、冗余/无用交互、接口不可重用、超时重试设置不合理、IP直连、跨机房等。

依赖类常见风险:不合理强弱依赖、无效依赖、忽略第三方依赖、缓存依赖失效等。

耦合类常见风险:架构耦合不合理、缓存耦合不合理等。


一、重复交互

1、风险定义

在一次业务请求中,系统内部发起了多次完全相同的网络交互,即存在重复交互风险。从交互层级和上下游来说,重复交互有两类,整个业务请求范围内的重复和同层重复,其中同层重复交互的上下游也是相同的,本文更多关注的是整个业务请求范围内的重复交互。通常在一次业务请求中,为了提升性能和负载,尽量避免或者降低重复交互次数。

2、风险影响

重复交互增加接口耗时,降低接口性能,当重复的是跨机房交互会使得性能急剧下降影响系统稳定性,增加对下游服务的压力(模块压力增加一倍,下游服务压力增加几倍)。

3、风险识别

如果两个交互具有完全相同的请求服务对象(尤其是mysql、redis、memcache这类数据存储服务)、请求数据、返回数据,那么这两个交互就判定为重复交互;对于获取不到交互数据时也可以通过数据包size进行初判。这里可以借助开源trace系统,采集业务测试时的调用链信息,根据上面的判断规则进行风险自动识别。

4、风险消除

在对实时性要求可控的前提下,将第一次查询信息缓存下来。


  • 真实案例一:系统间重复交互。11次重复请求session,对于前端一次请求就要对session模块产生几十倍的流量冲击,所有这些交互都是完全重复的,极大的降低的了接口性能和session的负载能力。


  • 真实案例二:mysql/redis重复交互。mysql/redis作为系统中性能瓶颈,这样的重复请求无疑加速了其性能瓶颈的到达。


二、高频交互

1、风险定义

一次用户发起的请求,如果在模块之间的交互次数完全依赖于后端返回的数据条数,会给下游造成极大压力的同时,也降低了系统的稳定性。相同业务请求的模块交互次数多少不一,原因通常是代码中循环操作内部存在网络交互,总交互次数受到循环迭代的次数影响。这样的情况在模块上线初期,可能因为数据量比较小、pv比较小很容易被人忽视,当某天上线一些大数据、大客户,将会给予致命一击。

2、风险影响

循环请求次数过多会导致下游压力倍增(前端pv增加一倍,后端pv增加几十倍),接口性能不稳定,降低系统处理能力。系统稳定性完全依赖于数据的代码逻辑非常脆弱,当遇到某一个大数据时将会出现模块假死、系统雪崩、功能失败。

3、风险识别

基于上游传来的数据或某个子请求返回的数据量(通常是一个数组),针对每个数组元素进行网络请求,遍历并没有错,但是要对这个遍历的数组元素个数有限制,否则循环遍历的次数就完全依赖于数据。这里也可以借助开源trace系统,采集业务测试时的调用链信息,根据上面的判断规则进行风险自动识别。

4、风险消除

数据量要可控,结合产品业务需求,比如请求返回结果要有上限;批量请求替代逐个请求。


  • 真实案例:查询某商户物料详情,当该商户拥有大量物料,就出现了如下场景,用户的一次查询就造成服务与db之间156次交互,那该接口的性能就可想而知了,平均耗时都在3s+,用户体验极差。



三、冗余/无用交互

1、风险定义

交互依赖的数据已出现异常,还继续执行后续交互,使得后续的交互是没有任何意义的冗余交互。这些依赖的数据,可能是上游传递而来,也可能是与下游模块请求得来。

2、风险影响

冗余交互会占用系统资源,降低接口性能,从而影响系统稳定性和性能。

3、风险识别

如果交互A依赖数据B(比如交互A的请求数据中需要传入B),在B异常(比如数据为空、null、false等)情况下,还是发生了交互A,那么就认为A是冗余交互;如果操作A依赖于操作B的成功执行,当B异常时,还是发生了操作A,那么A也认为是冗余交互。可以借助开源trace系统,采集业务测试时的调用链信息,根据上面的判断规则进行风险自动识别。

4、风险消除

代码中增加异常逻辑判断:当交互依赖的数据异常时不进行该交互。


  • 真实案例:如下调用链正常场景是先查询团单list,然后用团单list去查询每个团单的优惠。但是当查询团单列表为空时,就没有必要再调用marketing查询团单的优惠信息了,应该立即返回错误码。这里增加无效交互无疑降低了接口性能。



四、接口不可重入

1、风险定义

相同请求发给模块再次处理,不能保证结果一致,符合预期。

2、风险识别

相同请求,模块返回结果不一致亦或重复写操作产生脏数据。这里可以利用录制工具,重放请求,验证结果正确性。

3、风险消除

对于防重入可总结三点,前端加入防重复点击设置,接口层加入锁机制,db层需要加入唯一键设置。



  • 真实案例

在商家会员卡充值购买的流程中,nmq故障情况下,购买结果页显示充值失败,但是卡中余额却一直在直线增加,原因是充值接口没有做到可重入,这个case幸好在线下及时发现,否则后果不堪设想。

商家会员卡涉及到的购买流程如右下图所示:



用户提交订单并且钱包处理完成后,钱包回调交易模块的payresult接口,交易模块验证通过之后,会调用商家会员卡的rechargemoney接口给商家会员卡充值。为了提高充值接口的可用性,与交易模块有个约定了一个机制:若调用rechargemoney返回的errno不为0 ,则投入nmq重试三分钟,三分钟之内的重试均没有成功,才触发自动退款。商家会员卡模块的充值接口rechargemoney的流程图如下图所示:



在rechargemoney接口处理过程中,有一个防频繁重入的判定redis锁过程,expireTime设置时间为10s,10s内会拦截过来的重复请求,直接返回。

上述过程可以看到,前端是有无限重试策略的,因此可以认为前端无防重入,那么看接口层锁机制,重试时间3min明显大于锁有效时间10s,因此相同请求10s后锁机制也失效,再看db层,插入order_id和其他营销信息,数据库中并没有设置order_id为唯一键,因此该接口彻底失守,没有做到可重入,相同订单可以重复插入成功,从而导致业务表现为同一订单多次重复充值。

对于该案例,改进方案是首先将锁有效时间设置大于一切来源的重试时间,其次在db充值记录表中将orderid设置为主键,双重保护该接口做到可重入。


五、超时设置不合理

1、风险定义

顾名思义,就是超时并没有根据系统真实表现科学的设置。

2、风险影响

就像下图化学反应一样,不合理的超时实际设置并不会产生真正影响,但是遇到网络故障,依赖超时时,后果不堪设想。



模块交互必设超时,这是基本要求,但是超时设置过长、过短可能会适得其反。不合理超时设置主要表现为①交互超时时间设置过长,比如5s甚至10s的超时②下游超时时间大于上游超时时间。

交互超时重试时间过长,在下游偶尔出现网络抖动时连接被hang住,接口耗时增加,并且降级模块处理能力。下游超时>上游超时,上游超时后断开连接引发重试,下游还在继续上次运算(此时已经没有意义),下游负载增加N倍(取决于重试次数设置和发生重试的层数),使得系统性能急剧下降甚至雪崩。

3、风险识别

①超时时间设置过长(比如数据库connect超时1s,模块读写超时5s)

②下游超时时间大于上游超时时间。

4、风险消除

从系统整体考虑,并且结合重试和本模块计算时间的影响。下游超时<上游超时;超时时间不宜过长,根据下游接口性能设置;对于弱依赖的服务交互,超时时间更不能过长,以免弱依赖阻塞主流程。


  • 真实案例:如下图,该接口调用redis超时时间超过2s,然而Redis性能极好,单线程阻塞性server,这种长耗时会阻塞其他请求,很容易引起系统雪崩,应该把redis连接超时时间修改适当小。



六、重置不合理

1、风险定义

顾名思义,就是重试并没有根据系统真实表现科学的设置。

2、风险影响

任何网络交互都可能失败,为了保证最终交互成功,通常交互失败/超时、数据错误后再次与该模块交互,即发生了重试。重试的次数设置不当,轻者交互成功率不达标,业务失败率增高,严重者引发系统雪崩。

3、风险识别

查看框架配置文件中重试次数配置,是否简单粗暴的经验值设定重试次数,比如一律重试3次,查看代码中逻辑控制的重试限制(这种很隐蔽)。

4、风险消除

相对于固定的重试序列,随机重试序列也可能给系统带来风险,例如可能会降低下游模块的cache命中率,降低系统性能,甚至引起雪崩。

评估重试机制:

1) 真的需要在每一层都努力重试吗?

2) 真的需要这么多次重试吗?

3) 真的需要在连接,写,读这三者失败后都重试吗?

  • 按照业务需求和模块性能设置重试次数

  • 弱依赖不用重试也可以

  • 下游模块性能好,基本不会超时,也可以不重试

  • 大部分情况下,重试次数为1已经足够


  • 真实案例

如图为某产品线的架构,整个系统中,上游模块对下游模块所有的交互,重试次数都是设成3次,交互失败包括连接失败,写失败,读失败这三种情形。如果是写和读失败,那么要关闭当前连接,再重新发起连接。



如果一台bs假死,到该bs的请求会超时。(注意区分模块假死和真死,假死情况下,模块端口打开,能够接收上游连接,但是由于各种原因(如连接队列满,工作线程耗尽,陷入死循环等),不会返回任何应答,上游模块必须等待超时才知道失败,连接超时,写超时和读超时都有可能。而在真死情况下,模块端口关闭,或者干脆程序退出,上游模块连接它会很快得到失败返回码,这个返回码由下游模块的操作系统协议栈返回的,如ECONNREFUSED错误码代表端口不存在,连接被拒绝。) 

那么as有1/3的概率需要重试,as重试的过程中,ui可能早就认为as已经超时了,所以ui也开始重试,ui重试的过程中,webserver可能认为ui已经超时了,所以webserver也开始重试……就这样,整个系统的负载急剧增加,到达bs的qps会是平时的27倍,直到系统崩溃为止。


七、IP直连服务方式

1、风险定义

A,B两个系统交互,B系统分布式部署,A-B连接是通过配置B系统所有IP方式。

2、风险影响

当B系统分布式服务中某一台挂掉时,不能做到failover,导致故障影响扩大。

3、风险消除

通过bns或者组的方式进行连接。


  • 真实案例

某产品线依赖服务redis调用均采用ip列表的方式,如果redis proxy出现单机故障,需要人工介入进行切流量止损。单机发单重启修复周期有时会达小时级别,因此线上服务在故障期间会长时间处于切流量状态,高峰期单机房容量会存在风险。如同时有其他机房服务异常,则无法执行既定预案止损。并且如想下掉故障proxy,只能采用发上线单修改线上配置的方式。止损操作复杂,周期长,效率低下,具体case如下:

(1)用户中心redisproxy单机故障,人工切流量止损,恢复服务花费2小时,期间线上处于切流量状态。

(2)商品中心redis proxy单机故障,会存在扣除库存失败的风险。恢复服务花费半小时,后续又再次发生宕机,发单下掉故障proxy。

如上对应前面讲的故障时间,该服务sla月可用性已不足3个9。


八、跨机房请求

1、风险定义

交互的两个模块分别部署在不同机房。

2、风险影响

跨机房交互由于存在网络延时,严重影响接口性能、请求成功率,极大的降低了系统稳定性。

3、风险识别

①配置错误(ODP框架)ral-service中配置的服务后端IP的Tag不能为空(在ral中,会将Tag为空的也认为是本机房)②上游传入idc错误,Idc是完全匹配,nj和nj02就不相同,因此如果上游传入nj02,当前模块的idc是nj,就会找不到对应的Tag而只能使用default。

4、风险消除

主要关注配置是否合理,由于线上配置很难在线下验证正确性,肉眼排查难免遗漏,因此可通过线上机房流量切换演练验证。


九、不合理强/弱依赖

1、风险定义

所谓强依赖就是,请求链路中某个服务失败/结果异常/无结果后,核心逻辑必失败,否则就认为是弱依赖。不合理的强弱依赖有两类,本应该是弱依赖的设置为强依赖,本应该是强依赖的设置为弱依赖。

2、风险影响

系统稳定性取决于调用链中所有依赖稳定性最差的依赖,如果将稳定性较差的服务作为强依赖将严重影响稳定性

3、风险识别

强弱依赖的合理性是需要结合业务判断的,如果业务返回结果不可或缺该依赖,那么就该设置强依赖;如何判断该依赖是否为强依赖可以通过故障模拟验证,如果模拟该依赖异常时导致调用异常,则判断其为强依赖。

4、风险消除

①调整不合理的强弱依赖关系,将业务非强依赖服务降级;②通过系统优化及运维优化等手段提高强依赖的稳定性。③对强依赖结果进行全面校验,保证强依赖故障能够及时被发现。


  • 真实案例

用户下单请求到trade模块,是通过消息队列nmq保证下单后的商户通知功能,通知商户是借助公共服务云推送,这里云推送被实现成了强依赖,也就是当云推送如果失败,返回给本次请求失败。

某次下单高峰期时,云推送出现故障,无法给ios用户推送消息,nmq收到请求失败后,会持续不断的重发,nmq的通道堵塞之后也影响了trade模块向nmq的请求故障不断往上层蔓延,最后用户无法下单。



对于如上案例,工程师最后去掉对云推送强依赖代码,服务才慢慢恢复,但已造成非常大的损失。


十、无效依赖干扰

1、风险定义

服务启动流程中与该依赖建立了连接,但是整个逻辑处理过程中无需依赖该服务,无任何业务关联性。

2、风险影响

其实该风险是不合理依赖的一个特例,无业务关联性的依赖应该及时去除,否则会影响整体服务稳定性。

3、风险识别

与依赖服务只有一次链接交互,无其他交互,就可以初步判断该依赖为无效依赖,为了准确评估可再结合代码排查。


  • 真实案例

某产品线由于配置管理较乱,有个服务每次启动都会判断多个与业务完全不依赖的服务启动情况,这几个依赖服务处于无人维护状态,非常不稳定,从而导致该服务启动失败率非常高。


十一、第三方依赖

1、风险定义

请求的完成,需要依赖产品外的其他服务,都称之为第三方(tp)依赖,按照公司又分为公司外第三方,比如糯米酒店依赖携程服务;公司内第三方,比如passport相对于手百。

2、风险影响

第三方服务的性能,正确性,稳定性直接影响自身服务,尤其是第三方强依赖,当第三方依赖出现异常,很可能导致自身产品受到损失;公司外第三方依赖有些是小型公司,技术和运维能力有限,其服务的性能,正确性、稳定性不是很高。

3、风险识别

第三方依赖的可靠性是不可控的也是我们系统建设中不可避免的,那么只能尽量降低第三方依赖不稳定对自身的影响。

4、风险消除:

  • 尽量避免第三方强依赖;

  • 超时设置,重试设置结合第三方容量,平均响应时间,部署情况;

  • 增加第三方依赖挂掉,假死,接口变更的校验及容错降级处理,从架构和云微商做到各个TP方与自身业务的解耦;

  • 运维上,提高第三方依赖可靠性,使用内网bns,vip请求,且避免跨机房交互。


  • 真实案例

某产品线依赖A,B,C三个tp方数据进行汇总展示,每次都需要调用三方都有结果时再进行聚合,否则认为整个流程失败,而三个tp方稳定性不尽相同,其中B是个小公司,经常出现故障,导致自身服务经常故障。

对此工程师对各个TP方加上了全面校验,当验证故障后自动调用降级操作,去掉该tp依赖。从此服务稳定性大大提升。


十二、缓存穿透

1、风险定义

前端请求一个肯定不存在的key,导致每次请求都会请求后端原始数据,使得缓存被“穿透”,当该类请求高并发时,那么后端压力凸显。

2、风险影响

缓存穿透后,每个请求都会到达后端服务,对后端服务压力突增;当缓存穿透的并发较高(尤其是恶意攻击),后端服务很可能被压垮,导致整个系统瘫痪。

3、风险原因

一种可能是对于主从分离系统,缓存失效时间小于主从延迟时间,尤其是跨机房的主从分离,主从延迟在某些时候会达到数秒甚至数十秒,这是如果缓存时间设置过小,就会导致所有缓存读写记过均为失效结果,进而请求后端服务获取新的数据。另一种可能是查询结果为空的情况。

4、风险消除

  • 对于查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存;

  • 对于一定不存在的key进行过滤,把这些key放到一个大的bitmap上;

  • 设计的时候考虑,当缓存失效时,系统服务的情况及应对措施。


十三、缓存失效/缓存雪崩

1、风险定义

大量缓存同时过期失效,前端请求同时到达后端服务。

2、风险影响

当并发量足够大(比如秒杀,抢购),后端服务很可能被压垮,导致整个系统雪崩。

3、风险识别

缓存设置时间相同,失效周期也相同,导致多个缓存同时失效。

4、风险消除

  • 不同的key,设置不同的过期时间,让缓存失效的时间点尽量散列均匀;

  • 在缓存试下后,通过加锁或者队列来控制读数据库读写缓存的线程数量(比如对某个key只允许一个线程查询和写缓存,其他线程等待);

  • 做二级缓存,A为原始缓存,A2位拷贝缓存,A1失效时,可以访问A2A1缓存失效设置为较短,A2设置为长期。


  • 真实案例

某产品线监控发现机器A机器的8688端口挂掉了,经追查发现一个广告配置下发的接口(/api/v1/ipid)挂掉了,据统计,前一天23点到当日9点之间,该接口被访问了400+次,正常来讲,这种广告配置下发的接口一天最多几百个请求量。

经查,客户端有一个零点定时触发策略,零点会同时启动很多服务,平时并发请求会命中缓存,不会造成太大压力,可是当时正赶上缓存时间到期,大量请求将服务接口压死,端口挂掉。

对此临时方案是在接入层nginx配置文件中加入了流量控制机制,用lua脚本来将零点的请求屏蔽掉,长期方案是避免这种缓存集体失效的情况。


十四、 架构耦合不合理

1、风险定义

系统架构和设计上存在着耦合,包括模块耦合、接口耦合、消息队列耦合。具体体现在,主次不分的功能在一个模块或者接口中实现,nmq中不同重要性的命令耦合在同一个module中。

2、风险影响

整个系统稳定性<最不稳定的功能稳定性,不重要的功能可能拖垮重要功能

3、风险消除

整体思路就是,重要与不重要拆分,实时与非实时拆分,在线与离线拆分,根本上解决就是架构解耦,但是系统发展到一定阶段再拆分代码成本很高,这里可以通过运维方法控制解耦,具体见如下案例。


  • 真实案例

某产品线的一级服务和二级服务共同依赖一个基础服务,由于二级服务的一个bug拖垮基础服务,从而导致一级服务不可用,对此解决方案是通过运维将不同上游流量分开。



十五、缓存耦合不合理

思想同2.1.14这里不再赘述。


总结


本文给出了常见的15种架构设计风险,希望大家能够在实际工作中参考审视自己系统是否也存在同样的风险,尽早消除,提高稳定性!



转载各大团队校招笔试题集锦

博博

UCDCHINA上海群友们这两年收集整理的校招面试题,包含目前国内几家顶尖互联网企业。适用于产品及设计岗的各位小伙伴参考学习。如果有任何想法,也欢迎在群里踊跃发言。反正说的不好也不罚钱╮(╯▽╰)╭


阿里的面试题

 


请系好安全带,有一大波阿里面试题正在向你涌来。。。



报告,我感觉我和阿里的面试题八字不合,可以看看其他公司的面试题吗?

腾讯的面试题


其他公司的面试题


 


是不是感觉很难?是不是感觉无从下手?多多参与群内讨论,众多大佬给你指点迷津!




 


好了~最后的压轴面试题来了,大家可以踊跃发表感想。答出来的可以找大佬要棒棒糖当奖励



如何成为前端开发高手?

周周

      web前端开发工程是是一个很新的职业,在国内乃至国际上真正开始受到重视的时间不超过五年。web前端开发,是从网页制作演变而来的,名称上有很明显的时代特征。随着人们对用户体验的要求越来越高,前端开发的技术难度越来越大,web前端开发工程师这一职业终于从设计和制作不分的局面中独立出来。

       早期的前端其实就是table布局,后来发展到所谓的div+css网站重构,再到现在的让人眼花缭乱的各种各样的新技术,web前端技术发展是非常快速的,因此选择了前端这个行业就意味着不停的学习吧。让我们先看看张克军绘制的前端知识体系结构:

      前端开发的核心是HTML+CSS+JavaScript。本质上他们构成了一个MVC框架,即HTML作为信息模型(Model),css控制样式(View),JavaScript负责调度数据和实现某种展现逻辑(Controller)。

      HTML

      1.标签的分类,

      2.标签表示一个元素

      3.按性质分类:block-level 和 inline-level

      4.按语义分类:

            Headings:h1,h2,h3,h4,h5,h6

            paragraphs:p

            Text formatting:em,strong,sub,del,ins,small

            Lists:ul,li,ol,dl,dt,dd

            Tables:table,thead,tbody,tr,th,td

            Forms and input: form,input,select,textarea

            Others:div,span,a,img,<!---->

            HTML5:header,footer,article,section

       XHTML

       XHTML于2000年的1月26日成为W3C标准。W3C将XHTML定义为的HTML版本,XHTML将逐渐取代HTML。XHTML是通过把HTML和XML各自的长处加以结合形成的。XHTML语法规则如下:

      属性名和标签名称必须小写

      属性值必须加引号

      属性不能简写

      用ID属性代替name属性

      XHTML元素必须被正确地嵌套

      XHTML元素必须被关闭

     标签语义化

     为表达语义而标记文档,而不是为了样式,结构良好的文档可以向浏览器传达尽可能多的语义,不论是浏览器位于掌上电脑还是时髦的桌面图形浏览器。结构良好的文档都能向用户传达可视化的语义即使是在老的浏览器,或是在被用户关闭了CSS的现代浏览器中。同时结构良好的HTML代码也有助于搜索引擎索引你的网站。

      不要使用table布局,table是用来表格显示的。

      不要到处滥用div标签,div是用来分块用的。

      不要使用样式标签,如font,center,big,small,b,i,样式可以用CSS来控制,b和i可以用strong和em来代替。

      不要使用换行标签<br />和空格来控制样式,请用CSS。

      尽量不要使用内联CSS

      CSS

      1.css基础知识

        层叠和继承

        优先级

        盒模型

        定位

        浮动

     2.css进阶

        css sprite

        浏览器兼容性

        IE haslayout和block format content

        css frameworks 

        css3

        css性能优化

        less and sass

        css sprite主要用于前端性能优化的一种技术,原理是通过多张背景图合成在一张图片上从而减少http请求,加快载入速度。

        浏览器兼容性

        绝大部分情况下,我们需要考虑浏览器的兼容性,目前正在使用的浏览器版本非常多,IE6,IE7,IE8,IE9,IE10,Chrome,Firefox,Safari。

        IE haslayout和block format content

        IE haslayout是一个Internet explore for Windows的私有概念,他决定了一个元素如何显示以及约束其包含的内容、如何与其他元素交互和建立联系、如何响应和传递应用程序事件、用户事件等。而有些HTML元素则默认就有layout。目前只有IE6和IE7有这个概念。BFC是W3C css2.1规范中的一个概念,他决定了元素如何应对其内容进行定位。以及与其他元素的关系和相互作用。这个其实和浏览器的兼容性有关,因为决大部分的兼容性问题都是他们引起的。参考:css BFC和IE haslayout介绍。

        css framework

        css框架是一系列css文件的集合体,包含了基本的元素重置,页面排版、网格布局、表单样式,通用规则等代码块,用于简化web前端开发的工作,提高工作效率。目前常见框架有:

       960 grid system

       blueprint css

       bluetrip

       minimum page

       还是一个比较出名的和特殊的框架是Twitter的bootstrap,bootstrap是快速开发web应用程序前端的工具包。它是一个css和HTML的集合,它使用了的浏览器技术,给你的web开发提供了时尚的版式,表单,buttons,表格,网格系统等等。它是基于less开发的,不支持IE6,在IE7和IE8里效果也不咋地。

       css3

       虽然css3还没有正式成为标准,但是IE9+,Chrome,Firefox等现代浏览器都支持css3。css3提供了好多以前需要用JavaScript和切图才能搞定的功能,目前主要功能更有:圆角、多背景、@font-face、动画与渐变、渐变色、box阴影、RGBa-加入透明色、文字阴影。

       css性能优化

       css代码是控制页面显示样式与效果的最直接“工具”  ,但是在性能调优时他们通常会被web开发工程师所忽略,而事实上不规范的css会对页面渲染的效率有严重影响,尤其是对于结构复杂的web2.0页面,这种影响更是不可磨灭的。所以,写出规范的、高性能的css代码会极大地提高应用程序的效率。

       less and sass

       less和sass都是css预处理器,用来为css增加一些编辑的特性,无需考虑浏览器的兼容问题,例如你可以在css中使用变量、简单的程序逻辑、函数等等在编程语言中的一些基本技巧,可以让你的css更加简洁。适应性更强,代码更直观等诸多好处。

        sass基于ruby开发,less既可以在客户端运行,也可以借助node.js或者rhino在服务器端运行。

    

UI设计师如何提升自己?

蓝蓝

UI设计师提升自己没有捷径,就是多练。联系当然也要分阶段和方法。且在练习前的审美也很重要。下面先说说练习的几个阶段。

日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档