塑封三文鱼保质期多长时间,...结合源码排查分析 -爱游戏平台

苗坤旺离型膜

作者 |?李辉责编 | 郭芮

大蒜,牛油果,西葫芦,包菜,鸡蛋,西红柿,鸡腿,三文鱼,土豆,洋葱,黄瓜,杏仁干……这是我买菜前在手机里列出的购物清单。我觉得我已经比很多相信自己脑子记得住、却常常丢三落四买了酱油忘了醋的理工男靠谱了。毕竟我买东西都是一样不少买回去的,但是每次回家还总是被老婆数落,这个不对那个不满意的。

有一天我终于忍不住爆发了,说那你给我个购物清单吧,到底要买什么?!然后她的清单发来了:

大蒜一挂,要 bio(有机)的;

西葫芦一根,注意不要破损的,指甲印太多的;

鸡蛋一盒6个装,黄壳,不要白壳;

西红柿bio 650g 8个装那种,买前捏一下,软的不能要;

两个鸡腿,500g左右盒装,盒子上要标“非转基因”;

三文鱼200g,不要冷冻,要冰鲜的,去鲜鱼柜台买;

洋葱一包,白皮圆形大个的,不要红皮;

小脆皮黄瓜,9cm左右的买6根;

杏仁干,250g一袋,碳水含量低于4%;

……

ps: 所有上述食品都要看保质期。

你可能要问:土豆不就一种吗,不就是马铃薯,洋芋?那你太天真了,德国是个有200多种土豆、能把土豆吃出花来的国度。

我在超市里盯着这个采购清单,突然无比后悔刚才的冲动。本来作为直男,采购的速度是以光速计算的,只要找到货架位置,刷刷刷把东西扔进购物车就行。现在我必须一个个按规定检查,在一排排同类但不同生产商的货中挑出符合规定的东西,还要看保质期。采购速度直接翻了五倍,本来一刻钟左右我就应该出现在收银台的,现在快一小时了我还在干果区找碳水含量低于4%的杏仁干,最后抓了一个路过的店员一起找了半天才在零食区发现。

好不容易采购完毕回家后,心想这次总该不会不满意了吧。结果棋差一着,还是被抱怨了:那盒鸡蛋有一个蛋破了。我按习惯是打开盒子,扫视一下外壳的,但我万万没想到,那个蛋底部破了。所以今后清单上又多了个标注:鸡蛋检查盒子底部,看有没有蛋液渗出。

回归正题

男人的思维方式,大多数情况下是直线式、收敛式、简单式的,他们天生排斥“不必要”的修饰和麻烦。我敢打赌,99.999%程序猿的购物单和我一样。那些各种各样的“细节”和“形式”,在女人看来无比重要的细枝末节,在多数男人看来,只是浪费时间和吹毛求疵的表现。

这和软件开发有什么关系?如果把这份购物清单看做客户发给你的产品需求,或者一份软件设计文档呢?

产品需求分析

因为工作领域关系,经常有朋友找我咨询一些软件项目的问题,比如:

开发一个教育类app多少钱?做一个网店多少钱?我想做一套在地图上实时显示数据并且分析的可视化平台,开发周期一般多久?我需要一套采购物流系统,开发周期一般多久?

我的回答一般都是以这句话反问:

我问一下,你所在城市房子多少钱一套呀?

别人一般回答:

这要看房子大小,朝向,哪个区买的,差别很大啊。

我会接着说:

做软件和买房子一样的,按软件实际的需求和开发构架的差别,开发周期和费用也是有很大的变化区间的。

然后再一步步细问对方的实际需求,最终可以得出一个大概的项目开发预算和时间预估。

需求设计文档

我平时习惯在谈项目初期,先做业务和构架需求分析,但还是时不时一个方面没考虑到,就入了坑。曾经有一个做产品经理的朋友找我合作一个项目:客户要做一个电商系统,项目第一版的要求很简单,只要能运行正常购物流程即可:

电脑和手机可以访问;用户可以邮件注册,也能微信注册;有产品列表展示,购物车,订单,用户扫二维码支付即可;用户界面自己决定,以后可以换模板;管理员后台能管理产品,批量上传订单,上传上传图片,查看客户订单。

我自己手头有一套完整的基于spring的cms开发框架,包括前端api模块、后端管理模块、用户权限模块、数据持久化模块等等,所以上面这些按估算很容易搞定。第3点里的产品,购物车、订单分成三个小模块,做个二维码支付也不是大问题。而且第一版只要基本功能,不用考虑任何的分布式,大流量,并发抢购等今后做大了要考虑的问题,无需过度设计。

我这个朋友也是个资深程序猿出身,所以我也很放心他作为客户传话筒,所有需求遵循kiss原则,但保留基本的模块扩展性。讨论过后,这第一版的构架图简单如下图所示,我也写了个相应的需求列表。

我们这边技术层面一切ok,客户那边看起来也很佛系,对于我们写的第一版的基本需求列表没有异议,事情似乎向着阳光的方向发展。我想到了所有技术和构架上能想到的点,却单单漏了一点:

朋友是个男性产品经理。

所有该谈的事情谈定了后,最终朋友从客户那里得到了一个产品需求细节文档:

用户分级别,享受不同折扣率;

产品含品牌属性;

产品归于相应的一级和二级目录;

产品由不同供货商提供;

产品含颜色和大小等属性;

产品分官方价格和折扣价格,订单扣费按当天折扣;

支付和交易需要后台管理;

产品按重量和大小分不同的物流渠道以及关税申报登记;

订单最终价格是折扣后价格,加上动态计算的物流价格;

订单表含发票和发货模块,同时扩展物流模块;

发票模块需要调用一个第三方发票在线生成系统;

支付模块并不和支付宝直接对接,而是和一个境外第三方支付机构;

特价,打折模块;

官方blog模块;

若干其它模块......

如果真正做过电商系统的朋友,看到第5点可能会心里一颤,这个就是要做一个完整的sku系统啊!sku是大型电商系统的基础,复杂度不言而喻。按之前的开发预算和时间预估,这么多关联模块根本不可能完成。

把朋友电话里暴揍一顿后,按客户的产品需求,产品构架思维导图变成了这样。

我得到的教训就是:

在没有客户的详细需求设计文档之前,绝对不要做任何项目估算,更别提动手开发!

看到这,各位是不是很容易联想到你们的男性产品经理或是项目经理,和客户开个会后,就急冲冲地列出一份新的feature所需大致功能,然后马上发邮件或者口头传述给开发团队,程序员直接就开始开发。

这里可没有性别歧视,我工作中遇到的男性产品经理或程序猿在做功能设计文档时,常常没有女性产品经理那么细心和耐心。这种文档不明确就开发的做法,看似敏捷快速迭代,但做出来的功能往往和客户所需相差甚远,最后返工付出的代价难以计算。

分析细节标准

我们公司有个客服系统,客户在使用产品遇到问题时,会邮件或者电话给客服,客服录入系统后会分配给相应研发团队。这是一个常见的一问一答流程,我们的反馈会通过客服发给客户。

客户:我app突然登陆不了。

研发:请问您用的系统版本是什么?app的版本是什么?登陆时发生什么错误?

客户:我的系统版本是xx,app版本是xxx。输入用户民和密码后,登陆界面跳转到浏览器,然后就没反应了。

研发:请问浏览器里显示什么,有没有错误代码,是什么时候登陆的?

客户:浏览器里显示“request error”,时间是xxxx。

研发:请尝试清空app的缓存,以及浏览器的缓存。步骤如下……….

…….

有没有感觉这样的沟通成本其实很高,客户提供的信息模糊,研发问得也不尽清晰。这里和产品需求文档类似,到底细节的标准在哪?

我建议我们程序猿在做需求分析时,先向你的女朋友或妻子学习如何分析细节,比如分辨下面这些:

呃,好吧,当我没说……

我的建议是需求也业务拆分尽可能详细,考虑周全,最好能覆盖今后绝大部分的测试用例。

比如需要开发一个用户注册登录的功能,从某个男性产品经理嘴里说出来可能就一句话:给我开发一个用户系统,能注册,能登录,三天够不够?

从女性角度,她们习惯把一件简单的事情变的复杂化——如果这里的简单并没有你想象的那么简单呢?

如果你足够细心,就需要和客户做仔细沟通后达成共识,最终交付给研发团队的应该是如下一份需求kickoff列表(只是举例,考虑并非100%全面):

用email注册还是用户名注册?

如果是用户名,最短几位,最长几位,允许特殊字符吗,密码最短几位,最长几位?

如果email注册,是密码一起填写注册,还是有验证步骤?

点击注册前,是否展示用户协议。不勾选显示什么错误?

如果有验证步骤,需要手机验证吗?如果要,要对接哪个api,验证码长短,过期时间?

手机验证码发送时间间隔,以及发送频率限制;

如果只需邮箱验证,发送给用户的激活链接有效期多久,过期了怎么办?

验证这个业务要不要持久化?

发送激活邮件的模板,html还是txt,谁来设计?

激活链接过期后,显示什么错误,然后跳转到验证邮件重发界面?

激活链接激活后,显示什么信息,自动跳转到哪个界面,比如设置密码界面?

密码设置允许特殊字符吗,最短几位,最长几位?

密码入库前采用何种加密算法,以哪个属性作为salt?

用户密码设置成功后,跳转哪个界面,显示什么消息?

用户后期允不允许改用户名或注册邮箱吗?

用户后期修改密码是否需要邮件或手机验证?

允不允许单用户多地点登录,如果不允许,显示什么错误自动登出?

支不支持单点登录sso?

要不要开发移动端app,需不需要提供注册和登录api?

api需不需要支持oauth2,或是token?

登录构架是单体还是需要考虑分布式session?

用户权限系统设计,多role或是单role设计?

鉴权系统设计是无状态还是有状态?

用户自己或者管理员关于权限系统的操作流程是什么?

有没有第三方sns接口注册接入,如果接入,需不需要同步头像,需不需要同时必须新建本地账号。

第三方sns接入的流程,回调接口,以及界面设计;

相关前端和app界面设计图,错误对话框ui;

......

需求文档越详细,后期开发与测试遇到的误解就越少,试错成本也越低。

该文档必须保持在线实时更新,有任何变更,研发团队必须第一时间得知。不要通过短信或者email更改需求,这会使团队和产品经理陷入无尽的扯皮炼狱之中。

细节的力量

如果说女性太注重于细节,是期待对方给足自己安全感。那么我们在做项目时注重细节,其实也是给自己一种安全感:减少返工。一个口碑好的软件,肯定是从用户需求分析开始就研究细节,设计时重视细节。

大部分程序猿都是非常看重技术,但从男性视角介入软件产品设计时,很容易陷入工程师思维:先考虑怎么做,再考虑做什么,最后考虑为什么做?一看到新项目,脑海里浮现的立刻是各类框架、各类中间件、高并发,恨不得立刻开机撸码。

而从女性角度介入软件产品设计时,她们往往会带有与生俱来的消费者直觉,会从第三方角度看事情。

我这里不是简单地贴职场标签,而是提醒不管是程序猿还是程序媛们,思考一下自己在设计产品时思维的盲区。

最后,女人天生都是产品经理,只不过:

作者简介:李辉,德国硕士毕业后,在软件咨询业工作多年,涉猎前后端及移动开发构架。现在德国博世智能家居部门任高级软件工程师。

声明:本文为作者独家投稿,作者独立观点,不代表 csdn 立场。

?热 文?推 荐?

??windows 7 时代即将终结!

??王欣“马桶 mt”改名“mt”;任正非点赞苹果;酷派 27 岁总裁上任 | 极客头条

??java 这一年都经历了什么?

?“对不起,你的离职是我的错!”

??gartner的预言:通向混合it之旅

??阿里“菜鸟”ai?

??刚刚!华为又被美国盯上了!

??心疼!能为程序员男友做些什么吗?

print_r('点个好看吧!');var_dump('点个好看吧!');nslog(@"点个好看吧!");system.out.println("点个好看吧!");console.log("点个好看吧!");print("点个好看吧!");printf("点个好看吧!");cout?<

点击“阅读原文”,打开 csdn app 阅读更贴心!

喜欢就点击“好看”吧

模糊查询有以下三种方法(convert转成string)(between and?)(datediff()函数)

字段 ?createtime ?

查询??2018-12-24

1.convert转成string,在用like查询。第一种方法应该适用与任何数据类型 ; ?

select top 10 * from table where convert(varchar,createtime,120) like '2018-12-24'

2.between ??第二种方法适用string外的类型 ?

select * from table1 where yourtime between '2017-06-30 0:00:00' and '2018-12-24 24:59:59'";

3 datediff()函数 ? ?第三种方法则是为date类型定制的比较实用快捷的方法。

select * from table1???where datediff(day,yourtime,'2018-12-24')=0?

sql语句格式化日期 去掉毫秒

--从第一位开始取到第十六位结束

select substring( convert(varchar,getdate(),120),1,16) from a

?

问题

我的简书爱游戏官网登录入口主页

gc超阈值

在之前的5分钟内,垃圾收集花费的平均时间为每分钟36.4秒。临界阈值60% node_manager_gc_duration has become bad: avgrage time spent in garbage collection was 36.4 seconds(s) per minute over the prevoies 5 minute(s). critical threshold: 60% the healthy test result for yarn_resourcemanagers_health has become concerning

排查

查看nodemanage日志

日志中每隔几秒就会发生gc且老年代回收( cms )的时间比较久 爱游戏平台官网问题查询 关键字: node_manager_gc_duration 从社区的答复来看, 大多数的建议是调整nodemanager的堆大小和监控值, 但是并没说到问题的原因, 接着继续排查吧

点击图标库, 查看进程使用情况

发现最近时间段堆内存一直接近最大值, 且每次回收掉的内存非常少; 查看7天数据gc和堆内存的占用处于持续上升的状态, 初步定位是内存泄漏 查看30天发现29号的时候内存突降, 之后又开始持续上升至峰值徘徊, 其实29号的前几天也是不正常的

查看日志和进程信息, 29号的9点确有异常, 触发了yarn节点重启机制 , 发生内存溢出生成了dump文件

内存泄漏

yarn默认没有开启gc的打印, 需要自己在cdh进行配置, 搜索java_gc_args,在对应位置填上-xloggc:gc.log -xx: printgctimestamps -xx: printgcdetails, 配置生效需要重启该节点( 可选项 )

1. 查看gc详情

jstat -gcutil 25678 3000 100 从图中来看明显是有问题的;ygc和fgc代表新生代和老年代gc的次数, 每隔几秒次数就会递增, 且老年代的空间一直没有回收掉

2. 分析在堆中对象的数量和占用字节

执行su -s /bin/bash -c ''/usr/java/jdkl.8.0_202-amd64/bin/jmap -histo:live 20886" yarn | more

如果提示jdk版本的报错, jmap前加上运行参数的全路径;如果报unable to open socket file: target process not responding or hotsport vm not loaded, 则切换到进程的用户;如果切换时报this account is currently not available, 则可用root用户su -s指定用户去执行命令

从命令结果来看, 占用最多的是字符串和byte数组, 但是不知道里面的内容是什么, 所以需要mat去分析堆中对象的详情

3. 将dump文件导入到mat中

su -s /bin/bash -c '/usr/java/jdkl.8.0_202-amd64/bin/jmap -dump:format=b,file=/tmp/nnm.dump 20886' yarn, 如果已经发生了内存溢出生成了dump文件, 则不需要执行这一步

点击histogram->右键对象list objects->with outgoing references

发现缓存大量spark job的shuffle索引文件路径, 但实际上appcache下并没有文件, 所以推断这个是shuffle的临时文件, 查阅源码证明推断正确, externalshuffleservice的executorremoved()和applicationremoved()方法; 为什么这类文件会这么多, 在哪个地方引用的呢?

解决思路

去spark的web界面去查看该job执行时,是否发生大量的shuffle操作, 如果是可尝试去调整代码上或job运行参数, 以来减少数据的混洗

通过分析, 该job( application_1588204334324_0246 )其实早已经执行完了, 却还是一直触发gc的告警, hdfs上本地的shuffle文件也不存在了, 进一步推断是yarn缓存管理的问题

寻找spark yarn中控制shuffle缓存的配置并修改 ###排查spark源码 根据调用堆栈搜索shuffleindexcache,shuffleindexinformation,cachebuilder, 在源码中找到关键类externalshuffleblockresolver

string indexcachesize = conf.get("spark.shuffle.service.index.cache.size", "100m");

cacheloader indexcacheloader =

new cacheloader() {

public shuffleindexinformation load(file file) throws ioexception {

return new shuffleindexinformation(file);

}

};

shuffleindexcache = cachebuilder.newbuilder()

.maximumweight(javautils.bytestringasbytes(indexcachesize))

.weigher(new weigher() {

public int weigh(file file, shuffleindexinformation indexinfo) {

return indexinfo.getsize();

}

}).build(indexcacheloader);

查看源码得知缓存的统计是根据索引文件大小叠加的, 即shuffleindexinformation的size相加; 根据上面的缓存键值分布图做空间推测

shuffleindexinformation的size平均为152字节, 则100mb可存放的对象数为 689852 个 = 100(mb) * 1024 * 1024 / 152key是file类型的, 每个对象占用920字节, 则缓存中key占用的空间为 605 mb = 689852 * 920 / 1024 / 1024

结合mat的总览图, 缓存对象占用817mb, 那么和推断的值705mb = 605 100基本是吻合的; spark管理这一块的缓存只累加了value的文件容量, 而忽略了key占用的内存, 个人感觉这一块会有隐患, 如果shuffleindexinformation的size值很小, 那么key的数量会非常的多, 如果内存配置不够大那么发生内存溢出的概率比较大

更改源码

在github上查看这个类的提交记录没有找到相关的修复, 提下issue或pr看官方有什么答复; 有个要注意的小点, 源码中缓存使用的是localcache.localloadingcache, 调用get方法的时候会同时load进缓存中, 且externalshuffleblockresolver中有提供清理过期文件的操作

方案1: cacheloader构造时重写weigher()方法中加入key的容量统计方案2: 执行清理操作时同时清理缓存 30672 pr

查看hadoop的源码

堆中存在着大量路径信息, 所以可以尝试去搜索关键字如 appcache, 结合调用堆栈可找到相关类resourcelocalizationservice,yarnconfiguration,localcachecleaner,查看源码得知yarn提供资源缓存的清理, 默认值10分钟执行一次,清理的阈值为10g

解决

调整堆内存, 调整shuffle index大小或更改源码( 不推荐 )

参考

apche贡献指南 hadoop源码 spark源码 yarn resourcemanager内存泄漏 大数据运维日常-yarn 运维、巡检、监控、调优、排障 cdh文档

分享
文章爱游戏平台的版权声明:除非注明,否则均为苗坤旺离型膜原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
applausebadlaughcoffeefabulousfacepalmfecesfrownheyhainsidiouskeepfightingnoprobpigheadshockedslapsocialsweattolaughwatermelonwittywowyeahyellowdog
评论列表 (暂无评论,12人围观)

还没有评论,来说两句吧...

微信二维码
微信二维码
支付宝二维码
网站地图