Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 15896 articles
Browse latest View live

如何开一场高效的会议?

$
0
0

本文节选自少数派编辑部出品的 《Power+,你的生产力补给包》栏目。Power+ 聚焦于效率工具和生产力技巧的挖掘,辅以对 App、数字生活方式的探讨,以每周 4 次、总计超过 200+ 期的频率更新,为你提供源源不断的生产力补给包,帮你解决具体的、直接关系到每天生活工作的痛点。

⚡️ 点此了解 Power+ 每周更新目录


注:本文所讨论的会议,主要指小规范、议事性的会议,不包含大型的、非议事性的会议,如员工大会等。

只要你不是独立工作的自由职业者,在工作中就不得不面对会议。面对面的沟通,有着即时通讯工具和电话语音无法替代的魅力。从本质上来说,它传达信息的方式更加高效,信息量也更加丰富。相比起在微信上你一言我一语,面对面的交流不仅仅可以快速地得到反馈,并且除了文字之外,你的声音、语气、姿态同样在传递着信息。

然而,许多人也同样讨厌会议。冗长的节奏,即兴的跑题,敌对的氛围,模糊的结论……这些都让会议要不然变得漫长而无效,要不然变得沉闷而无趣。那么,如果才能开一场高效的会议呢?少数派这里有一份指南,从会前、会中、会后三个阶段,教你如何开一场高效的会议。你可以把它当作一份检查清单,每次开会时,对照一下每一项是否做到了。

会前:明确目标,普及信息,精选人员

一场高效的会议,一定有着充足的准备。不要小看了这一点,在许多会议上,参会人并不知道目标是什么,而被匆忙地拉进一场会议,这时候既没有准备好发言的内容,也不清楚具体的议程,自然就慢慢陷入了鸡同鸭讲的无效沟通之中。那么,会前我们需要做好哪些事情呢?

确定会议的目标

在 Facebook,扎克伯克要求所有人在开会前,都先想好一个最基础的问题:本次会议的目标是什么?在他看来,会议可以分为两大类:决策型会议、讨论型会议。前者必须输出一个明确的决定,如项目评审会、预算审批会,而后者则可能是召集所有人一起讨论问题,共享信息,如晨会、头脑风暴、项目沟通会等。

在开会之前,就应该想好,这次会议最终希望输出的结果是什么,是一个决定,还是一系列可行的方案,或者,是需要所有人关于项目达成某种共识。

选择合适的会议类型、场地与时长

一旦确认了会议的目标,其实就间接确定了会议的类型、场地与时长。不同类型的会议,有不同的开法和场地选择。

例如,如果是一次头脑风暴,那么就应该选择气氛相对轻松的会议环境,最好有沙发、白板和一些零食,以调动每个人的创意思维。

而如果是一次进度沟通会,需要各方互通一下当前项目的进展,自然这样的会议应该保持精简,可以选择一个不需要座位的小房间,所有人站着开会。Facebook 的研发经理也喜欢把这样的会议安排在临近午饭前的时间,这样所有人都会希望尽早高效地结束会议,不影响自己的午餐时间。

同时,针对决策类的会议,许多科技公司的高管都分享过,保持会议有效的秘诀之一就是简短,人的注意力和精力都是有限的,曾在雅虎、谷歌担任高管的 Marissa Mayer,她要求会议尽量保持在 5-10 分钟之间,快速讨论,快速决策。

准备议程

一无所知地走进会议室是不负责任的,这要求所有参会者提前知道会议的议程与背景资料。作为会议的组织人,制定议题是一项非常重要的责任,它要求我们准备如下事项:

  • 会议的时间、地点、参与人;
  • 本次会议希望达成的目标;
  • 当前已经掌握的背景资料和信息;
  • 将会议的几项重要议题列成一个清单;
  • 针对每项议题,提供当前已有的方案、决定或要求每个人针对议题做出的准备;
  • 针对每项议题,预估所需要的会议时间;

提前准备好这些信息后,至少提前 24 小时把它发给参会的人,并要求每一个人在参会前阅读,并做出相应的准备。

Office 中就有许多可用的议程模板

只邀请必要的人

无论是 Apple、Facebook 还是 Google,这些公司对会议都有一个共同的要求:小规模,只邀请必要的人。2011 年 Larry Page 回归谷歌重新出任 CEO 时,甚至要求每个会议最多不超过 10 个人。Steve Jobs 在开会时,如果觉得你是多余的,甚至会把你从会场中赶出去。亚马逊的 CEO 则要求每场会议的人数,订两份批萨就够了。

会中:高效沟通必备的三个技巧

在会议正式开始后,这三个技巧,可以保持一场会议高效地进行。

角色扮演:掌握职责

成功的会议需要角色扮演,每个人各司其职。一般来说,主持人、记录者、决策者都是几个常见的角色。

对于主持人来说,最重要的工作就是维持秩序。你需要制定会议发言的规则是什么,并在合适的时机进行干预。例如,发言按照什么顺序,每个人发言是否有时间限制,在哪些环节不要打断或评价他人的想法等等。随着会议的进行,跑题、陷入僵局、激烈的争吵,都是一场会议可能会出现的情况,主持人一定要表现出掌控力,对这些情况进行处理,例如,在争论不休时,及时地叫停所有人,并用表决、决策人拍板的形式等方式来有序地推进会议。

记录者的工作主要分为两个部分,一个是记录当前会议讨论的内容和决定,以在会后形成会议纪录发给所有相关人。此外,在会议过程中往往会涉及到新的议题或新冒出来的待讨论事项,记录者也应该对这些「节外生枝」的内容进行归纳总结,以在会后决定是否需要另行讨论。

决策者需要保证对于所有人来说,会议输出的结果是唯一的。在缺少决策人的时候,各方都会觉得自己更占理,自己的方案更优,最终要么僵持不下,要不各怀心思。决策者的存在,不仅仅是做出决定,更是统一所有人的认识,以确保在会后大家往同一个方向走。

除了这些常规角色外,你还可以根据实际需要增添。比较有意思的是,在亚马逊,会议室里被要求摆上一张空椅子,充当顾客的角色,以提醒所有参会者在做任何决定时,都不要忘了从顾客的角度和感受出发。

计时器:掌握时间

前面提到了,在会议前就应该对每一项议题制定合理的预估时间,并在会议过程中严格遵守,以防止无限制地拖长会议。

计时器是很重要的工具,相比起用手机上的计时器 app,准备一个实体的计时器可能更好。一方面,实体的计时器可以摆放在会议室内明显的地方,所有参会者都能直接看到。另一方面,实体计时器可以有更醒目的外形和响亮的提醒响铃。

宜家的 奥格宁计时器,以及  Time Timer 是许多人的最爱。后者是 Google Ventures 的合伙人 Jake Knapp 推荐的计时器,表盘上红色的区域会随着时间的流逝而逐渐减少,更让参会人有时间的紧迫感。

议题清单:掌握进度

还记得在会前准备好的议程吗?在实际开会时,把它制作成一份检查清单,每讨论完一个议题,就打一个勾,这是 Facebook 的 COO Sheryl Sandberg 的建议。一方面,确保每一个议题都已经有了一个明确的结果;另一方面,如果你提前勾完了这份清单,就让会议提前结束。

会后:有结论,有责任

尽早发出会议记录

在会议结束后,尽早发出会议记录。由于这份记录主要是由记录者一个人整理的,它可能会有遗漏,可能会使用了对方不熟悉的表达,可能会有错误的记录……尽早将会议记录发给所有相关人,可以让其它参会者审阅,以提出问题或作出补充。

分配到责任人

Steve Jobs 会在会议结束后,将任务指派给每一位责任人。这也往往是决策者的工作,不仅仅做出决定,更要负责落实决定的执行。

在现实中,我们往往看到邮件里的会议记录,写满了各个结论,却没有明确的责任人,从而导致后续的推诿和扯皮。会议的记录者也有必要及时和决策者确认,在会议记录中,直接标明每项决定和执行事项的负责人,让所有相关人清楚后续的行动和责任人。


> 本文节选自少数派编辑部出品的《Power+,你的生产力补给包》栏目,订阅 Power+,了解更多提升效率的技巧


【日本经济被建筑业“绑架”了】很多人看到日本基础设施发达,认为这是国民经济富足的一种体现。阿列克斯·科尔对这种说法提出了质疑,其认为日本基础设施过剩,很多需求其实是被人为创造出来的,而这背后是日本政府

$
0
0

虎嗅注:如果你去日本旅游,可能会对这个国家复杂的交通网络感到惊讶,大概也会因此认为,这就是日本基础设施发达,甚至是国民经济富足的一种体现。但是有人却对这种说法提出了质疑,其认为日本基础设施过剩,很多需求其实是被人为创造出来的,而这背后是日本政府在买单。这到底是怎么回事?


本文来自微信公众号“人文学会”(ID:HES1929),作者:作者:陈兴杰,人文经济学会特约研究员。


日本拥有全世界最繁华的都市群,同时保持着原始的自然环境,这是日本给人的第一印象。茂盛的森林,宁静的湖泊,湍急的溪流,这些无不令人向往。不过,事情的真相很可能让人失望。日本对自然的改造相当深刻。


全国有113条河流,110条河流经过人工改造。或用混凝土封闭河床,河岸加工,或干脆修筑堤坝。表面湍急的河流,实际已被驯服。日本一半海岸被混凝土覆盖,使其免受海水的侵蚀。 日本自然环境看似精致优美,其实到处是人工干预的结果。真正粗朴原始的自然环境,少之又少。

 

不要误会,这篇文章不是环保主义批判词,而是谈日本社会的一个问题: 基础设施过剩

 

日本经济经过三四十年高速发展,到1990年代,突然衰落下来。这是二十年来国际经济领域的热门话题。这个现象也引起一些非知名学者兴趣。阿列克斯·科尔是一位美国人,从幼年起就随家人在日本居住,此后在耶鲁大学和牛津大学学习中国文化。科尔最感兴趣的是国家还是日本。他凭着自己的观察和思考,试图从一个独特角度揭示日本社会的弊病。

 

“画孰最难,犬马最难,鬼魅最易。”这是《韩非子》里的一句话,意思是说,画画这件事情,画具体的犬马困难,画虚无的鬼魅反而容易,因为画者可以随意发挥。2002年科尔写了一本书谈日本经济,用的就是《犬与鬼》这个标题。

 

科尔认为,日本追求现代化的过程,陷入某种困境。繁荣偏离真实含义,幻觉主导进程。其中很重要的幻觉是,认为建设越多越好,基础设施没有止境。这个角度很新颖,此前没有学者论述。从论述证据和方法来看,科尔所批判的,也许是真相。

 

科尔认为,日本的工程建设太多,很多根本没必要。大量河流被“U形”混凝土化、堤坝化,名义是防止自然灾害,实际上山区没有住多少人;修建良好的道路像蛛网一般,蜿蜒进入深山密林,那里实际上人迹罕至。大型水坝蓄满用不着的水和电,一些大桥连接着人烟罕至的岛屿。二战以后,日本修建了太多铁路码头,高速路网。相对于经济能力,日本基础设施是超前的,过剩的,很多甚至是无用的。

 

基础设施发达,无论足迹到哪,总感觉安全便利。它给人的直观感受是:日本真是发达富足的国家。这也是外国游客到日本常有的体会。少有人追问:基础设施如此发达,真有这个必要吗?大量基础设施投入,何时能收回成本呢?

 

事实上, 日本大量基础设施建设,很多就没考虑收益问题,买单者是日本政府

 

从上世纪50年代起,日本政府就启动大规模的基础设施建设,修筑公路、建设水坝到防止流失,开支越来越大。工程建设通常会有边际收益递减的规律。一旦建设饱和,收益就会递减,甚至根本没有收益。日本基础设施建设几十年,似乎没有停下的迹象。总有修不完的路,总有架不完的桥,很多需求是被创造出来的。半个多世纪,日本人修筑了几千公里的防波堤,仿佛这几十年里,日本突然面临海水侵蚀。

 

1990年代初,日本基础设施投资额占GDP总值的18.2%,同期英国为12.4%,美国为8.5%。2001年,日本的这个数字仍达到13%,在发达国家里很少见。日本在建筑领域的投资,超过当时美国的军事耗资。日本政府每年的财政预算,与公共事业相关的预算高达40%,总额是美国近10倍。要知道,日本的国土面积不到美国的5%。

 

政府大规模投入,是日本建筑业辉煌的根本原因。日本政府为什么这么做呢?科尔认为有以下几方面的原因。

 

首先是迎合国民心理。日本是多灾害的国家,频繁的自然灾害对国民心理影响很大。上世纪中叶,日本受环保主义思想的影响还较少,“与自然作斗争”的传统观念还有很大市场。政客抓住这个心理,在国土建设上投入巨资资金,算是打造“日式富足”的生活方式。

 

其次,由于长期承接政府工程,大型建筑私企和政府部门关系密切,建筑利益集团出现。大型工程基本被大成、鹿岛等几个建筑商承包,他们建立起行业壁垒,排斥中小公司进入。建筑领域看似自由竞争,其实已被财阀垄断。

 

日本政坛一向以廉洁著称,建筑却是腐败高发区,时不时曝光营私舞弊和贿赂事件。建筑工人、退休工人及其家属,他们组成团体,作为建筑公司的后援。政府人员退休后,往往会加入这些团体,成为建筑公司的幕僚后盾。这就是在日本影响力很大的“特殊法人”,这些团体既受大公司供养,还能从政府那里拿到补贴。他们是日本建筑业扩张的一大推手。

 

建筑工程已是日本最大的行业之一。据统计,1998年日本建筑业的就业人口达690万人,占日本劳动力总数的10.1%,相当于欧盟和美国相关数字的两倍。将公共工程派生的相关就业人口算进来,专家估计,这个数字估计还会增加一倍。有庞大就业人口作为选民,那些好大喜功,热衷于大兴土木的政客就容易出头。

 

1990年代以后,日本经济萎靡不振,可能也刺激了建筑业发展。通过基础设施建设来“创造就业”,并“刺激需求”,这是主流经济学界流行的思想。经济越不景气,政府越要开动马力,大兴工程。农林水产省、建设省(后并入国土交通省)都是执掌公共预算的大户,他们也在不馀余力地创造需求,好让本部门扩充权力。

 

这实际是凯恩斯经济学在日本的应用。人为创造需求其实就是吸毒,只有加大剂量才能让各界满意,一旦戒断,将面临短期大量失业和经济萧条,这是政客所不愿见到的。

 

科尔认为,日本建筑行业的繁荣,已经脱离经济需求。最重要的标志,就是缺乏利润考核。没有利润考核,任何需求都形同鬼魅,变得膨胀而虚假。日本人当然可以呼吁更安全的国土环境,成本是多少,谁将为此买单,这些都是需要追问的话题。在政府资助的行业,考核指标失效,一切凭主观猜想和选民人数,政客也从中作梗。

 

过度建设是有后果的。日本政府欠下债务,高企的民间储蓄经政府之手,输送到无效率的工程建设上。建筑行业高薪稳定,吸引大量就业,而服务业和互联网的就业人口减少。科尔写《犬与鬼》是在2002年,如果他看到今天日本互联网的落后,我想他一定会把它归结于建筑业吸收了太多聪明的大脑。很多国家的经济问题是“脱实向虚”,而日本的问题很显然是“脱虚向实”。日本经济被建筑业绑架了,这个国家变得死板沉闷,缺乏活力。

 

这就是《犬与鬼》这本书谈到的重点问题。阿列克斯·科尔认为,这只是日本社会官僚体制化的一个表现。表面上看,日本是高度发达的资本主义国家,实际上官僚体制束缚无处不在。日本自然环境失去纯朴气息,变得矫揉造作,只是冰山一角。

 

作为美国人,科尔对日本社会的了解有多深入呢?这确实存在疑问,《犬与鬼》也被很多人批评为危言耸听,夸大其辞。这本书重版几次,在日本也有争议。不过,科尔具有很多日本学者没有的品质,那就是对官僚系统的深刻怀疑。科尔认为,日本是美好的国家,可惜正在失去活力,官僚体系则是罪魁祸首。日本人应反思官僚体制对国家的控制和吸血。这样的论断,显然比《菊与刀》这种剖析国民性的作品更有警世意义。

 

最近几年,中国建筑公司的工程能力在国际市场拥有很强的竞争力,很多人为此把中国称为“基建狂魔”。有这样的建设能力,当然是好事情。中国长期是一个基础设施缺乏的国家,经济发展过程中,对基础设施需求很大。无论铺路架桥,发展高铁高速,还是建设码头港口,似乎都取得不错的效益。很多人因此产生幻觉,认为基础设施建设不应只计算经济利益,要多要考虑社会效益。至于社会效益如何衡量?这时候,就是鬼魅易画的一本账。

 

前段时间,有人说中国应加大西部地区的铁路建设。他的理由是,东部铁路网覆盖率已达到323公里/万平方公里,西部地区铁路覆盖率仅为75.4公里/万平方公里,只有东部覆盖率的1/4不到,低于全国132公里/万平方公里的平均水平。他说:“铁路是重要的基础设施,也是地区经济发展的重要带动力。国家应加大西部铁路建设,让区域发展不均衡问题得到有效解决。”

 

我想,对中国人口经济分布有起码了解的人都知道,这种算账方式纯属胡扯。以胡焕庸线为界,东部43%国土聚集全国90%以上人口,西部57%国土只有不到10%人口。至于经济体量差距,则更加悬殊。 无视这些差距,把东西部铁路覆盖率拿出来对比,要求“平衡发展”,简直是耍流氓。然而,正是这种荒唐提议,居然获得了很多网友的支持。

 

一些网友说,目前中国已经拥有过剩的建筑工程能力,为何不优先在本国建设?哪怕经济不划算,建成也总比没有强吧?这种骄傲中带着盲目,正是所我担心的倾向。

*文章为作者独立观点,不代表虎嗅网立场
本文由 人文学会©授权 虎嗅网发表,并经虎嗅网编辑。转载此文章须经作者同意,并请附上出处( 虎嗅网)及本页链接。原文链接https://www.huxiu.com/article/236638.html
未来面前,你我还都是孩子,还不去下载 虎嗅App猛嗅创新!

十倍效能提升:Web 基础研发体系的建立

$
0
0

1 导读

web 基础研发体系指的是, web 研发中一线工程师所直接操作的技术、工具,以及所属组织架构的总和。在过去提升企业研发效能的讨论中,围绕的主题基本都是——”通过云计算、云存储等方式将底层核心技术封装成基础设施“。而我们在实践中发现,在

  • 互联网渗入到各行各业,业务爆发
  • 企业竞争白热化,对速度和品质要求越来越高
  • 一线工程师队伍越来越庞大,管理成本增高

这样的多重背景下,除了底层核心技术外,一线 web 研发效能的问题也逐渐成为决胜战场的重要因素。

然而在现实中我们看到,因为一线的研发工作可替换性强,所以并没有受到足够的重视,同时也缺少更统一、更有深度的规划和管理。实际上,将一线工程师所直接接触到的应用框架、测试、部署、监控等领域作为一个完整的体系来思考,并打造成一体化的基础设施,能为企业的业务研发带来巨大的效能提升。

在《月相》一章中,我们将介绍Web 基础研发体系有哪些构成部分,并且将深入到关键性的技术和问题中。《潮汐》一章将介绍如何配合这套研发体系,在组织结构上做出一些调整,通过管理手段进一步挖掘团队潜力,打造更高效的组织。

另外,希望这些内容也能为一线工程师提供一些职业规划上的引导。

2 月相

我们将要讨论的研发体系,涵盖了”研发流程“和”系统“两个维度。可以用一张大图来描绘:

可以看到,将这些内容作为一个整体,符合目前互联网公司”核心技术“ + ”web 研发能力“ 的模式,能快速产出应用。其中,”用户“、”权限“、”流程“可以说是绝大部分系统的铁三角,因此我们也划入到了基础研发体系中。

接下来看每个部分。从流程的角度来说,提升效能的关键在于”工具化“和”自动化“,我们就以这两点来切入。

2.1 设计

首先是设计,设计与编码的结合是目前业界想象空间最大,但也是最不成熟的领域。对于自动化的实现,目前的尝试大致可以归纳成两类:

第一类,与设计师约定规则,按规则转化设计稿。这种方式的关键在于,“既要规则简单易于被设计师接受,又要保证视觉上的关系能完整转化成程序中的关系“。我们举个例子来说明”视觉上的关系“和”常见的程序中的关系“: 网页上这样一个场景:

可以很容易地理解为一个 Tab 组件里面嵌着一个按钮,他们是”嵌套关系“,在程序中用 html 可能这样写:

<Tabs><Tabs.Pane title="tab1">	<Button/></Tabs.Pane><Tabs.Pane title="tab2" /></Tab>

但是在现代的设计工具中,图层信息表示的仅仅是视觉上的前后关系。

这就出现了一种不匹配,设计师可以通过一万种方式来表达同样的视觉效果。因此,要保证正确识别关系,必须和设计师约定只能以某种方式来创建图层。但问题是这种约定本身对设计师来说没有实际意义,对他来说只是约束。除了嵌套关系以外,位置关系也是同样的问题——目前设计工具产出的设计稿只是某一种具体尺寸的视觉效果,而我们实际产品的尺寸会因设备不同而不同的,甚至可以随着浏览器窗口的缩放等功能动态变化:

怎么来表示这种变化对设计师来说也是额外的约束。乐观的是,从技术角度来说,总归是可实施的。

第二类尝试,像游戏一样做专用的设计工具,则从根本上解决了上述问题。

( React Studio)

思路很简单,既然设计师能有多种方式来表达,那么我们从工具角度来约束,是不是就不会有问题了?虽然同样有约束,但是对设计师来说负担要小多了,不需要额外记忆,按照工具的指引使用即可。我们甚至还可以提供一些高级功能防止出现一些人为错误,以此来吸引设计师。这种方式唯一的缺点是有一次性的学习成本。

虽然目前的自动化方案,都还只是从“视觉稿”到“程序静态视图”的自动化,并不包括交互逻辑的自动化,但已经有了巨大的意义。在前端程序员工作的统计中发现,他们有一半以上的时间都是在”调整大小、调整位置、对像素、对色值“,而且越是好的前端,这个时间比例越大。因为写逻辑是可以通过提升自身素质实现量级缩小的,而写样式这个工作本身很难实现量级的时间缩短。

如果在研发体系中,设计稿能自动转化成可用的代码,无疑对传统的 web 页面研发会有巨大的提升。虽然做专用工具看起来应该是最终的方向,但在目前的现实环境中,可能会因为加重设计师的使用负担而被抵制,所以通过在原有设计工具上做约定的方式来过渡可能更合适。在用约定的方案里,怎样让约定即不给设计师造成太大的负担,又能解决上述的规则转化问题,就成了重点。在实践中的解法是,通过工具的高级能力来补偿设计师。这部分细节已在《 设计稿自动生成可用页面的展望》中详细描述过,这里不再赘述。

2.2 研发、测试和监控

我们将这三个环节合在一起来讨论,是因为他们存在技术决策上的上下游关系。过去在大团队中规划研发体系,常常会出现一种现象,就是研发、测试、监控都是由不同团队规划的,而每个团队都想着做平台。后来慢慢发现这个思路是有问题的,因为做平台必然要考虑到不同端的接入,要花成本将自己的服务抽象得足够底层,花成本对不同的端做适配。而在这三个环节中,研发中的 运行时框架(应用框架)是工具化和自动化的核心,只要对运行时框架多进行一点点投入,后面测试、反馈、监控的研发成本就能降到非常低!

举个前端的例子。在搭建可视化页面搭建平台时,我们设计了一个将“所有组件数据都统一到一棵树”上的方案。

在传统的 React 中所有组件的 state 和 props 合起来才能表达一个页面唯一的状态,state 和 props 分散在组件中,不易收集。而在这个设计中,全局的 state tree 即表达了页面的一个状态,如果将每一次变化后的state tree 都存起来,即可通过回放来展现页面动态变化的过程。更进一步的是,利用这个特性,我们在 200 行代码之内就实现了“录制即测试用例”的功能。用户无需写任何晦涩的用例代码,在调试自己写的页面时只要觉得没问题,就可以将刚才的调试过程保存成一个用例。

再举一个接口层的例子。我们运行时框架的接口采用了 GraphQL ,并且告别了手动写接口的形式,全部利用视图勾选生成。

这解决了两个研发中常见的问题:

  • 杜绝了手工约定接口时可能出现的拼写等错误。
  • 能自动统计到所有对某一接口进行消费的页面,一旦接口进行调整,可以自动通知到下游,甚至能自动生成适配代码,不影响下游。

这也就极大地减轻了测试环节的压力。之前的思路基本都是通过扫描代码去发现接口错误,要消耗大量资源,现在看起来没必要了。

这两个例子都是从研发的角度来思考所看到的收益,我们再单独从测试与监控的角度来看。

测试领域有一个热点,—— UI 自动化。目前的 UI 自动化有两种方案,图片对比 与 dom 树对比。

( Screenster)

这两种方案都有一个共同的缺点,即“无法正确地识别变化的类型”。例如现在有个需求,视图上的两个元素需要调换一下位置,但逻辑并没有变,希望测试平台不报警。除非人工干预,否则这两种方案都很难判断出来,因为他们是以”最后渲染结果“作为判断依据的。但是如果我们的测试是针对运行时框架来设计的话,就很容易实现。以上面研发时所讲的组件树方案为例,页面到底有没有逻辑性的变化只和 state tree 有关,因为页面的状态是 state tree,而逻辑操作的也是 state tree,所以我们只要认为 state tree 没变,就可以认为页面没有发生变化,不用触发报警。

除了能识别变化外,利用运行时框架的设计,我们还能实现更先进的功能,例如 B/S 架构中还原浏览器端出错现场的问题。在过去 debug 时,我们通常都要与测试交流,按照操作步骤手工还原到现场,如果能由程序自动化一次性达到出错现场,那无疑能给 debug 速度带来质的提升。要实现这种能力的关键点在于,任何表示页面状态的数据,都要能暴露到外部,也能由外部传入进行重置。一旦有一个决定页面状态的变量在函数中,不能取出,不能序列化后传给服务端,就无法做到。毫无疑问,这种能力也是需要应用框架来支持的。例子中 state tree 的设计,有一部分原因就是出于支持这种能力的考虑。

再来看监控领域的热点,“无埋点”监控,和自动化测试有异曲同工之妙。“无埋点”指的是无手工在代码中的埋点,通常是使用可视化的技术来进行“标记”。

( GrowingIO)

目前业界的一些方案中,遇到的问题同样是不能正确地识别变化。例如当页面上的元素改变了位置,埋点能不能不受影响?在可视化搭建平台这个项目里,我们同样是在应用框架这个层面设计了解决方案:

我们的页面使用一种类似于模板的方式来嵌套组件,这个结构我们称为 component tree,这个结构是静态可分析的,所以可以很容易地实现可视化。用户如果想要控制组件使其产生变化,那么必须给组件取个唯一的名字,在逻辑代码中使用这个名字对它的数据进行操作来实现改变。

有了这个前提,无需任何额外的投入,就已经实现了“无埋点”。因为“埋点”本身就是对逻辑功能的统计,所以埋点一定会埋在有逻辑相关的组件上,因此一定会有唯一的名字,那么无论组件怎么变化,只要没有被删除,我们的埋点信息就不会受到影响。同时,如果一个有埋点的组件出现了改名或者删除,我们还能自动提示报警。而这些功能,同样是在不到200行的代码就实现了。

(埋点取名)

综上,从测试和监控两个角度我们也可以看到,只要运行时框架提供一点点帮助,就能以极小的成本来实施。针对确定的上游研发框架来进行下游的开发,不用再考虑对各种框架的兼容问题,也可以让下游在能力上走得更远,实现更多先进的功能。

2.3 框架核心技术

我们在线下交流中发现,很多团队对框架的投入只停留在写小工具和包装开源框架上。因为看不清方向,不知道如何投入,也不知道投入后有多少收益,所以不敢深入。其实方向和具体应该投入哪些技术,都是有迹可循的。这个踪迹的源头我们在 《 理想的应用框架》中曾提到过的,就是程序的本质—— 数据和逻辑

2.3.1 数据

先具象一点来说数据。框架的数据就是框架运行时内部保存的对象等数据结构,只要回答好两个问题就能展现出强大的威力:

  • 数据在哪?
  • 数据的生命周期是怎样的?

知道数据在哪,是管理数据的基本条件。应用的任何状态,都可以看做是内部数据的一种表现。因此只有框架掌握了所有数据,才有可能实现例如还原现场之类的功能。这对我们的研发有两点指导意义:

一是在使用已经有控制反转和依赖注入的 web 框架时,应该完全遵循框架的约定,将服务等对象的管理完全由框架。有的框架语法写起来比较麻烦,可以通过命令行或者IDE工具来自动生成。

二是在我们改造或者创造框架时,应该把数据的统一管理作为最基本的底线,这是上下游实现自动化的基础。上一节中所提到的测试录制的能力,就是建立在统一数据源的基础上。再举个更有意思的例子,过去的前端的 ajax 请求基本都是独立调用 api,无中心的模式。这种模式可能会出现的问题是:

请求A发出后,由于网络等问题,一直未返回,这时用户有重新发送一次请求 A1。结果 A1 迅速返回在回调函数中提示成功。然后请求 A 超时返回,在回调中提示失败,导致最后用户看到的是失败的信息。

当引入 saga 之后,所有异步的操作都统一收归到通信管道中,就能进行跨请求的管理了。单个异步请求的取消、多个异步请求到底是独立、还是竞争、还是只保持最后一个,就都能很容易地实现了。基于中心化的请求管理,还能进行可视化:

(kuker)

继续讲到第二个问题,数据的生命周期是怎样的?生命周期通常是由外部事件来触发,或者自己运行到某一阶段自动触发的。对深度开发来说,有两个基础能力必须由框架来提供。即框架要支持:

  • 手动驱动生命周期
  • 内部数据的复制和置换

手动驱动生命周期对自动化测试之类的功能来说很重要,特别是在做一些基础性的测试时,有了这个能力就不用再完全模拟外部的触发条件。而内部数据的复制和置换则能为录制、还原现场、协同等高级功能提供基础。我们现在就在尝试基于这种能力,实现“用户可以将自己的出错场景一键发送给开发人员来复现”的功能。值得注意的是,有的语言中复制对象是非常昂贵的操作,这时可能就需要考虑,是否使用 immutable 的数据格式会更好?还是依靠一些约定和标记提供自身提供廉价的复制能力?限于篇幅,在此就不再展开。对框架中的数据问题感兴趣的读者可以去搜索 Single Source of Truth 和 Shared Mutable State 之类的话题,业界已经有非常多的精彩讨论。

2.3.2 逻辑

聊完数据,终于来到最有意思的逻辑部分。框架从某种意义上来说,就是提供了一种逻辑表达的方式。要在逻辑表达上提升效能,有两个发展阶段:

  • 提供一些模式或技术。让用户写出低耦合、易重用、易扩展的代码。在写代码时提高效能。例如 MVC、IOC 等等。
  • 针对不同场景设计更合理的 DSL,能实现代码、图等表达方式的互相转换。在研发的整条链路上实现自动化。

我们看到大部分的框架都处于第一个阶段,不管是服务器端的 MVC 还是前端的 MVVM 。但也有少量第二阶段的尝试。例如 Flow Based Programming,试图完全用数据流向的角度来诠释业务中的逻辑。它的代码可以天然被分析成图,甚至能在运行时进行观察:

( noflo)

还有《理想的应用框架》中提到的基于事件来表示业务逻辑,也是一种 DSL。但这些尝试离最终的目标仍然有差距,最终理想的状态应该是能实现业务流程图、时序图、决策树等业务领域常用的表达方式与代码的互转。虽然有差距,而且看起来要走的路还很长,但是针对一些已经比较稳定的场景,已经有一些好的经验。CMS 框架 Drupal就是一个很好的例子。它定义好了数据发布的整个流程和相应的钩子系统,让开发者用模块的方式在钩子里去修改或者增加自己的功能。曾经一度实现了一个非常繁荣的社区。更值得肯定的是,社区中很多模块都是可视化的,最终用户不需要写任何代码,按照模块的可视化指引就能完成相应的功能。这实际上就等同于 DSL 与代码的互转了。

不管哪一个阶段的关键技术,都离不开分析 语义的能力。直白一点来说,就是“知道哪段代码是干什么”的能力。

在第一阶段的框架中,最影响效能的因素并不是”要写代码的多少“,而是写按框架概念写出来的代码是否易于理解、易于维护。这一点在越是大型、越是多人参与的项目中,越是明显。而代码的“语义”是否清晰在某种程度上直接决定了我们是否能通过技术手段来提升可维护性。例如,在使用依赖注入的系统中,如果所有代码的注入声明都清晰地表明了注入的到底是什么的话,那我们就很容通过语言层面的支持或者简单字符串匹配得到依赖关系图。反之,如果注入的信息模糊,既可能是函数也可能是 model,没有任何明显约束的话,那就可能得通过语法树,找到注入的入口才能分析出来,这样实现的成本就成倍增加了。

( Rekit Studio依赖分析图)

相比于依赖分析,更重要的是“ 调用关系分析”,它对于帮助理解流程,特别是排查问题特别有用。举个简单的例子,在数据驱动的前端框架中,因为视图完全是数据的展现,发现视图不对了,如果能动态展示出修改了数据的业务堆栈(不是函数堆栈),就非常有用。不需要再一步一步断点。

当然实现起来也更难。难点有两个:一是依赖分析一般是运行前的,是静态的,而调用关系一般是运行时的,是动态的;二是依赖通常是声明出来,容易读出来,而调用通常是在主动式的语句中,会遇到条件判断、循环、甚至通过变量在不同函数、类作用域中传递,比较难分析。这种难,其实也就是语义不清。在框架的设计或者我们自己的改造中,可以通过三点来尽量提供明确的语义:

  • 尽量转主动为被动
  • 尽量片段化
  • 消除用户代码中的副作用和对外部作用域中变量的依赖

前两点很好理解,被动声明式的代码结构更容易被分析。虽然在实践的时候需要大量经验,来保障设计出来的声明格式即能覆盖所有场景又要容易编写,但是它带来的收益也是最可观的。GraphQL 就是一个最好的例子,在服务器端用声明的结构将数据结构和关系表达出来,在客户端用声明的结构将要获取的数据结构表达出来,后端就可以使用统一的引擎来生成调用,省去的大量写接口的时间。第二点,尽量片段化是指我们在引导用户写代码的时候,应该把生命周期等等概念拆得尽可能小,使语义更细致。写起来繁琐的问题可以通过工具或者语法糖去解决。

第三点最重要,消除副作用指的是任何时候运行用户的代码片段应该都不会对外部环境产生影响。而消除对外部作用域中变量的依赖指的是对要用的数据、服务尽量都用参数的形式传入。这样做的好处有两个,对于一些复杂的,难以分析的调用的关系,可以将要观测的对象包装一下再传入,这样就能动态得到调用关系。在整体运行前,因为无副作用,也可以很容易地通过试运行这些片段来得到一些信息。虽然现在的语法树工具已经比较流行,但真的要完全通过语法分析来得到足够的语义仍然有很大的工作量。而上述的这三点,可以看做是快速、廉价的实现方式,并且实践中效果非常不错。

综合

最后值得一提的是,上面所讲到的数据和逻辑中的原则与技术并不是相互独立的。在《 前端服务化——页面搭建工具的死与生》和《 通天塔之石——企业级前端组件库方案》这两篇文章中看到,我们所使用的很多技术,其实是混合支撑着数据修改追溯、组件属性可视化等功能。他们中间有的也有着依赖关系。但相比于“数据和逻辑”这两个源头,这些并不重要。只要掌握了这两个源头面对的问题,其他都是能推导出来的。

对开源框架如何使用也是同样的道理。对于严肃的企业生产来说,应该找到业务所面临场景的源头,吸收解决问题的先进的想法,但自己实现,就像编程语言各自实现语言特性一样。而不应该只是停留在包装开源框架这个层次。开源框架为了适应尽量广的场景,有更大的群众基础,给出的一定是普适性的方案,这种普适性在业务发展到一定程度,有了足够多的独特性之后就会变成巨大的包袱反噬研发效能。等到了这个时候再考虑自己研发,其迁移、适配、研发成本以及带来的风险可能会变得非常大。而我们从前文看到,掌握了框架研发的几个核心,从小的场景就开始投入,成本并不高。最重要的是长久积累形成体系后,所带来的“流程上自动化“、”降低下游实现成本”等能力能持续地帮助企业提升研发效能。

2.3 通用子系统与核心接口

从流程的角度来看,提升效能的主要是靠自动化。而从系统的角度来说,则主要是靠能力的复用。”用户“、”流程“、”权限“几乎是任何业务系统中都存在的,因此将这三者也纳入到了基础研发体系的范围。在这里我们并不打算深入到每个系统所面临的具体问题中,只讲两点:

一、产品化或者子系统化,不要过早平台化,对将来系统整体打包有益。过去的互联网公司习惯将这些公用系统平台化,各个业务系统来接入。但这几年互联网业务进入的都是新领域,面临的市场、用户常常是需要隔离的。这个时候系统整体复制的能力就变得非常重要,所以一开始就将这三者以子系统或者子产品的方式来对待,能为之后的发展提供更多的灵活性。

二、三者不是并列关系,不用纠结于能力解耦,制定核心系统接入规范才是最重要的。权限系统无论是 RBAC 还是 DAC 都离不开用户系统的支持。流程则是既依赖于权限也依赖于用户。如果把运行时框架看做是主板,这三者应该是主板上的补充部分,一起为核心系统的接入提供针脚。同样是为了系统整体打包的能力,应该尽早制定核心系统接入的规范。

3 潮汐

在《月相》一章我们探讨了 web 基础研发体系的构成及部分重难点。相比于具体技术本身,这套方案对组织成长和重塑的意义更大。在这一章中我们会先从大团队中两个有启发性的问题出发,逐步深入到如何打造一个更高效的研发组织方案中。虽然问题出现是在大团队的,但对小团队仍有两点借鉴意义:

  • 小团队随着业务发展会长成大团队,也可能碰到一样的问题。
  • 问题本身萌芽于成长过程之中,予以正确的指导能更加节约人力,助力公司发展。

3.1 平台林立

首先注意,我们讨论的仍是 web 层的问题。这个现象在有多个不同业务的大公司中最常见。出现这种现象的原因有两个,一是公司到了万人规模,实际上就相当于上百个百人规模的小公司,必然想法很多,出现重复的自然也多。

另一个更重要是,在 web 这个领域,特别是前端, 基础设施变化太快

无论是浏览器底层所支持的 api,还是 javascript 语言本身变化都非常快。底层一变化,研发的各个环节必然出现基于新技术的空缺,很多框架和平台就是随着这些空缺出现的。现象本身存在即合理,但如果有更好的统一管理,是能从如下两个方面提取出巨大的效能的。

一、 如果将研发流程中的各个环节中独立的平台统一,可以极大地加速业务开发。直接决定业务发展速度的是进行业务开发的工程师。他们最希望的就是只有一个平台将研发的所有流程都搞定,并且尽量自动化。平台一多,对业务开发工程师来说,学习、沟通、协作的成本就会陡增。这个成本有多大?在我们通过线下了解发现,这个成本很多时候甚至会超过业务开发本身。

二、 加大对趋势和方向的研究,预防无序的框架和平台的投入,这样能尽量防止走偏和无效劳动,也是一种提升。越是大的团队,这一点越明显。“基础设施变化”这样一个滚滚巨轮这些年压碎了多少框架和平台,其中很多产生的效益都不足以覆盖其研发成本。更坏的是,出于个人利益等原因,有的平台过时了也不肯下线,阻挡了整个团队随基础设施一起进步的机遇,消耗的是更多的未来的人力。

我们在《月相》中提出的研发体系就是实现这两个提升的具体手段。

首先,有一个完整的体系来将研发流程当成一个整体对待,并且通过统一的平台来实现,能更好地实现流程的自动化。降低一线工程师沟通、学习成本。

其次,对运行时框架的投入,本身就包含着对趋势和新技术的研究,可以缓解被基础设施带着跑的问题。并且我们看到运行时框架研究到了一定程度,能够极大的减少后续测试、监控实现的成本,也降低了基础设施变化所产生的多米诺效应。这里对管理带来的反思是,我们应该谨慎“平台化”的思考。特别是下游环节,因为“平台化”的思维,必然要考虑对各种不同的端进行适配,必然要制定各种规范,这些都是人力成本。如《月相》中所示,上游理清楚并且统一后,下游是能有针对性地、很低成本地实现的,根本不需要“平台级”的成本投入。当然,在这里所说的只是减少技术上的投入,环节本身还是非常重要的。

平台林立从某一方面来说也表示着团队内部有着大量的无序的力量,这种力量在团队出现不同环节的分工时就产生了,尽早地建立研发体系就能尽早地将这些力量用起来,创造真正的价值。

3.2 资源池

很多大公司的 web 研发团队都被当成资源池来用,哪个业务需要就投入到哪里。现象的直接原因有两个:一是 从管理的角度来说,web 层的研发工作相对来说可替换性强,具备形成资源池的可能。二是 web 研发处于业务决策链底层,人员相对来说最紧张,因此通过资源池的方式能动态地支持业务开发,是最简单的解决方案。但这个方案其实是相当低效的。我们从对工程师个人的关注来切入这个话题。

首先从主观的角度出发,一个有激情,对职业未来充满憧憬的工程师与苦大仇深的工程师在效率上是有成倍差别的。除了其本身的性格外,造就这两种态度有很大一部分是职业上升渠道的问题。首先,和任何能被当成资源池来用的工作一样,因为可替换性强,所以不容易被重视。其次,目前的上升渠道不够。web 研发工程师的上升渠道要么是纵向的,当业务发展得足够好,重要性提高,成为系统负责人。要么是横向的,随着团队扩大,管理需要,成为管理者。这两者一个基于业务一个基于人力,和技术相关不大。所以有才华的工程师自然会想要造框架、造平台,努力成为公司技术中重要的一部分。但没有正确的引导,就会成为上面所说”无序的力量“,发展得不对反而会变成公司的消耗。而当他发现自己付出的努力得不到回报的时,就有可能变成苦大仇深的工程师。

最终影响的不只是工程师自身,公司也会要在管理成本上为其买单。我们在与一些资深 hr 交流时,他们进一步说明了这个问题。在公司工作了四、五年的员工,是已经融入了公司,理解公司文化也了解公司问题的人,算是中流砥柱。如果得不到好的上升,可能会有两种情况:其中有想法有行动力的,多半会选择离开。既会对组织稳定性会造成影响,也会让公司付出的培养成本付诸东流,对公司来说可算是很大的损失;另一种更不好的则是既不离开,也不像以前一样努力。他们在团队内有一定的话语权,却丧失了进去的激情,不再发挥积极的作用。当公司需要快速扩张、快速发生变革的时候,他们就会成为隐性的管理成本。

而解决方案,其实很简单。大公司内部通常都有”框架组“、”平台组“类似的部门,但基本都停留在”可用“阶段就完成任务了。这远远不够,如果将建立 web 基础研发体系作为目标,以产品化为衡量标准,加强重视和投入。 web 工程师的上升渠道就会得以扩张,公司内无序的力量就会进入到正确的领域。创造的价值又能进一步为研发提供能量,形成一个正循环,逐步缓解人力紧张的态势,资源池现象也就自然会消失。这很像我们身体受伤时,外部肿胀只是炎症的表现,消炎了,肿胀自然也就好了。重点是找到关键进行消炎,而不是围着外部现象思考。

建立体系还能带来的好处是,通过提升 web 研发的效率,降低业务研发所需的人数,能帮助大公司重新回到小步快跑的节奏。张小龙有一篇演讲《 警惕KPI和复杂流程》,讲到了小团队的重要性,随着互联网公司的竞争越来越激烈,这种重要性会变得越来越高。我们从一些互联网的新巨头上,其实已经看见了“ 核心技术+基础web研发能力”来快速出产品,占领市场的趋势。对小公司来说,统一的 web 基础研发体系,是帮助实现超车的重要一环。对大公司来说,则是进一步挖掘效能,防止掉队的必修课了。

4 后记

这篇文章笔者前后重写了三次,因为面对 web 一线工程师这样一个庞大的群体,效能提升已经不仅仅是技术或管理某一方面的事情,而是要综合各个方面来寻求个人和公司发展的共赢。 web 一线研发是很多工程师进入这个领域最开始做的事情,但是笔者看到了很多有才华的人困在了低效、重复的工作里面,努力了也因为方向不对而徒劳。这对个人和公司都是损失。在技术上找到方向,在管理上予以支持,多方发力,其实能提升的效能远超十倍。当然,一篇文章不足以实现任何改变,这篇文章最主要的目还是抛砖引玉,也希望对这个方向有想法,志同道合的朋友联系我,一起交流,一起推动。

邮箱: ariesate@outlook.com

5 答读者问

问:研发体系的统一规划不是破坏了竞争和创新吗?

答:统一规划并不是指不要竞争,不要创新。而是防止开倒车的情况出现,是给竞争和创新指定一个方向。例如我们在文中理清上下游关系,目的是指导研发力量应该往哪里投入,在投入的过程中仍然可以采取竞争的形式。

 

问:框架研发提升效能的趋势?

答:分两个方向。一是框架本身,会朝着“增强对用户代码的理解和控制力”这个方向前进。用户按框架写的代码,能不能通过工具分析出具体的语义?人工的低级错误能不能自动检测出来并自动修正?能不能转化成某种人类习惯的表达方式,比如图?当控制力达到一定程度后,这些能力都实现后,再往下应该就是代码的自动生成。

另一个值得一提的是框架能力与业务特有属性会一起沉淀到 IDE 上,会出现面向专有框架的 IDE,面向单个具体工程的 IDE。分析图,自动扫描工具都由 IDE 作为载体,就像很多游戏的专用编辑器一样。只有沉淀到 IDE 上才是最便捷、最有针对性的。对这个方向感兴趣的读者可以跟我邮件讨论,目前我们已经有一些初步的想法。

 

问:文章中讲到的问题都是大公司的,对小团队来说,什么时候应该开始建立自己的基础研发体系?

答:研发体系的建立可以分为规划和实施两个阶段。规划的话,从一开始就应该有所规划。在前期人力不够的情况下,不用强行追求打造自己的框架和工具,可以用开源的。但应该始终把开源的东西拿到自己的体系中,清楚地知道它在自己体系中的角色,也清晰地知道自己用了它的什么特性,未来还需要补充什么。什么时候开始实施其实有一个象征性的标准,也是我们前面在无序的力量中提到的——出现了不同环节的分工时。有的团队业务扩张太快,人力一直不够,那么建议按五分之一到三分之一的比例来抽出人力打造基础设施。磨刀不误砍柴工,何况投资得到的回报是电锯呢。

研究称过早用社交媒体影响女孩心理健康

$
0
0

英国《生物医学中心·公共卫生》杂志期刊 20 日发表一项研究说, 如果女孩在青春期早期 10 岁时就开始过多使用社交媒体,可能会影响她们在青春期后期阶段的心理状况,但研究人员目前没有在男孩身上观察到这一现象。英国埃塞克斯大学和伦敦大学学院的学者合作,调查了社交媒体使用对青少年心理健康的影响。

他们使用了此前在英国开展的一项大型调查里年轻人组的数据,这项调查关注近一万名年龄在 10 岁到 15 岁之间的英国青少年,就他们在上学日的社交媒体互动时长进行了问卷调查。

对数据分析后,研究团队发现,青春期女孩使用社交媒体的时间比男孩长,随年龄增长,无论男孩还是女孩使用社交媒体的时间都会上升。

通过对幸福感和“困难与长处问卷”的打分,研究人员对这组年轻人的心理健康状况又进行了评估。结果显示,在整个青春期期间,女孩的幸福指数下降了 3 分,男孩的幸福指数则下降了 2 分;同时,男孩在“困难与长处问卷”指标上的评分下降,女孩的评分则提高了,由此说明女孩在心理健康状况上经历了更多消极方面。

不过,报告的通讯作者、埃塞克斯大学学者卡拉·布克说:“我们没有观察到社交媒体的使用和男孩的心理健康状况之间有关联,所以导致男孩心理健康状况下滑的可能是其他因素,比如花在打游戏上的时间。”

布克说,这项研究显示密切注意孩子——尤其是女孩——在青春期早期使用社交媒体的情况非常重要,“因为这可能会影响她们青春期后期甚至成年后的心理健康状况。”

但研究人员也指出,由于这项研究使用的是自我报告数据,并且只记录了上学日的社交媒体互动,因此社交媒体和心理健康之间的关系仍然可能会被低估。

查看评论

Redis性能调优 - 简书

$
0
0


Redis性能调优

尽管Redis是一个非常快速的内存数据存储媒介,也并不代表Redis不会产生性能问题。
前文中提到过,Redis采用单线程模型,所有的命令都是由一个线程串行执行的,所以当某个命令执行耗时较长时,会拖慢其后的所有命令,这使得Redis对每个任务的执行效率更加敏感。

针对Redis的性能优化,主要从下面几个层面入手:

  • 最初的也是最重要的,确保没有让Redis执行耗时长的命令
  • 使用pipelining将连续执行的命令组合执行
  • 操作系统的Transparent huge pages功能必须关闭:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
  • 如果在虚拟机中运行Redis,可能天然就有虚拟机环境带来的固有延迟。可以通过./redis-cli --intrinsic-latency 100命令查看固有延迟。同时如果对Redis的性能有较高要求的话,应尽可能在物理机上直接部署Redis。
  • 检查数据持久化策略
  • 考虑引入读写分离机制

长耗时命令

Redis绝大多数读写命令的时间复杂度都在O(1)到O(N)之间,在文本和官方文档中均对每个命令的时间复杂度有说明。

通常来说,O(1)的命令是安全的,O(N)命令在使用时需要注意,如果N的数量级不可预知,则应避免使用。例如对一个field数未知的Hash数据执行HGETALL/HKEYS/HVALS命令,通常来说这些命令执行的很快,但如果这个Hash中的field数量极多,耗时就会成倍增长。
又如使用SUNION对两个Set执行Union操作,或使用SORT对List/Set执行排序操作等时,都应该严加注意。

避免在使用这些O(N)命令时发生问题主要有几个办法:

  • 不要把List当做列表使用,仅当做队列来使用
  • 通过机制严格控制Hash、Set、Sorted Set的大小
  • 可能的话,将排序、并集、交集等操作放在客户端执行
  • 绝对禁止使用KEYS命令
  • 避免一次性遍历集合类型的所有成员,而应使用SCAN类的命令进行分批的,游标式的遍历

Redis提供了SCAN命令,可以对Redis中存储的所有key进行游标式的遍历,避免使用KEYS命令带来的性能问题。同时还有SSCAN/HSCAN/ZSCAN等命令,分别用于对Set/Hash/Sorted Set中的元素进行游标式遍历。SCAN类命令的使用请参考官方文档: https://redis.io/commands/scan

Redis提供了Slow Log功能,可以自动记录耗时较长的命令。相关的配置参数有两个:

slowlog-log-slower-than xxxms  #执行时间慢于xxx毫秒的命令计入Slow Log
slowlog-max-len xxx  #Slow Log的长度,即最大纪录多少条Slow Log

使用 SLOWLOG GET [number]命令,可以输出最近进入Slow Log的number条命令。
使用 SLOWLOG RESET命令,可以重置Slow Log

网络引发的延迟

  • 尽可能使用长连接或连接池,避免频繁创建销毁连接
  • 客户端进行的批量数据操作,应使用Pipeline特性在一次交互中完成。具体请参照本文的Pipelining章节

数据持久化引发的延迟

Redis的数据持久化工作本身就会带来延迟,需要根据数据的安全级别和性能要求制定合理的持久化策略:

  • AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响
  • AOF + fsync every second是比较好的折中方案,每秒fsync一次
  • AOF + fsync never会提供AOF持久化方案下的最优性能
  • 使用RDB持久化通常会提供比使用AOF更高的性能,但需要注意RDB的策略配置
  • 每一次RDB快照和AOF Rewrite都需要Redis主进程进行fork操作。fork操作本身可能会产生较高的耗时,与CPU和Redis占用的内存大小有关。根据具体的情况合理配置RDB快照和AOF Rewrite时机,避免过于频繁的fork带来的延迟

Redis在fork子进程时需要将内存分页表拷贝至子进程,以占用了24GB内存的Redis实例为例,共需要拷贝24GB / 4kB * 8 = 48MB的数据。在使用单Xeon 2.27Ghz的物理机上,这一fork操作耗时216ms。

可以通过 INFO命令返回的latest_fork_usec字段查看上一次fork操作的耗时(微秒)

Swap引发的延迟

当Linux将Redis所用的内存分页移至swap空间时,将会阻塞Redis进程,导致Redis出现不正常的延迟。Swap通常在物理内存不足或一些进程在进行大量I/O操作时发生,应尽可能避免上述两种情况的出现。

/proc/<pid>/smaps文件中会保存进程的swap记录,通过查看这个文件,能够判断Redis的延迟是否由Swap产生。如果这个文件中记录了较大的Swap size,则说明延迟很有可能是Swap造成的。

数据淘汰引发的延迟

当同一秒内有大量key过期时,也会引发Redis的延迟。在使用时应尽量将key的失效时间错开。

引入读写分离机制

Redis的主从复制能力可以实现一主多从的多节点架构,在这一架构下,主节点接收所有写请求,并将数据同步给多个从节点。
在这一基础上,我们可以让从节点提供对实时性要求不高的读请求服务,以减小主节点的压力。
尤其是针对一些使用了长耗时命令的统计类任务,完全可以指定在一个或多个从节点上执行,避免这些长耗时命令影响其他请求的响应。

关于读写分离的具体说明,请参见后续章节

主从复制与集群分片

主从复制

Redis支持一主多从的主从复制架构。一个Master实例负责处理所有的写请求,Master将写操作同步至所有Slave。
借助Redis的主从复制,可以实现读写分离和高可用:

  • 实时性要求不是特别高的读请求,可以在Slave上完成,提升效率。特别是一些周期性执行的统计任务,这些任务可能需要执行一些长耗时的Redis命令,可以专门规划出1个或几个Slave用于服务这些统计任务
  • 借助Redis Sentinel可以实现高可用,当Master crash后,Redis Sentinel能够自动将一个Slave晋升为Master,继续提供服务

启用主从复制非常简单,只需要配置多个Redis实例,在作为Slave的Redis实例中配置:

slaveof 192.168.1.1 6379  #指定Master的IP和端口

当Slave启动后,会从Master进行一次冷启动数据同步,由Master触发BGSAVE生成RDB文件推送给Slave进行导入,导入完成后Master再将增量数据通过Redis Protocol同步给Slave。之后主从之间的数据便一直以Redis Protocol进行同步

使用Sentinel做自动failover

Redis的主从复制功能本身只是做数据同步,并不提供监控和自动failover能力,要通过主从复制功能来实现Redis的高可用,还需要引入一个组件:Redis Sentinel

Redis Sentinel是Redis官方开发的监控组件,可以监控Redis实例的状态,通过Master节点自动发现Slave节点,并在监测到Master节点失效时选举出一个新的Master,并向所有Redis实例推送新的主从配置。

Redis Sentinel需要至少部署3个实例才能形成选举关系。

关键配置:

sentinel monitor mymaster 127.0.0.1 6379 2  #Master实例的IP、端口,以及选举需要的赞成票数
sentinel down-after-milliseconds mymaster 60000  #多长时间没有响应视为Master失效
sentinel failover-timeout mymaster 180000  #两次failover尝试间的间隔时长
sentinel parallel-syncs mymaster 1  #如果有多个Slave,可以通过此配置指定同时从新Master进行数据同步的Slave数,避免所有Slave同时进行数据同步导致查询服务也不可用

另外需要注意的是,Redis Sentinel实现的自动failover不是在同一个IP和端口上完成的,也就是说自动failover产生的新Master提供服务的IP和端口与之前的Master是不一样的,所以要实现HA,还要求客户端必须支持Sentinel,能够与Sentinel交互获得新Master的信息才行。

集群分片

为何要做集群分片:

  • Redis中存储的数据量大,一台主机的物理内存已经无法容纳
  • Redis的写请求并发量大,一个Redis实例以无法承载

当上述两个问题出现时,就必须要对Redis进行分片了。
Redis的分片方案有很多种,例如很多Redis的客户端都自行实现了分片功能,也有向Twemproxy这样的以代理方式实现的Redis分片方案。然而首选的方案还应该是Redis官方在3.0版本中推出的Redis Cluster分片方案。

本文不会对Redis Cluster的具体安装和部署细节进行介绍,重点介绍Redis Cluster带来的好处与弊端。

Redis Cluster的能力

  • 能够自动将数据分散在多个节点上
  • 当访问的key不在当前分片上时,能够自动将请求转发至正确的分片
  • 当集群中部分节点失效时仍能提供服务

其中第三点是基于主从复制来实现的,Redis Cluster的每个数据分片都采用了主从复制的结构,原理和前文所述的主从复制完全一致,唯一的区别是省去了Redis Sentinel这一额外的组件,由Redis Cluster负责进行一个分片内部的节点监控和自动failover。

Redis Cluster分片原理

Redis Cluster中共有16384个hash slot,Redis会计算每个key的CRC16,将结果与16384取模,来决定该key存储在哪一个hash slot中,同时需要指定Redis Cluster中每个数据分片负责的Slot数。Slot的分配在任何时间点都可以进行重新分配。

客户端在对key进行读写操作时,可以连接Cluster中的任意一个分片,如果操作的key不在此分片负责的Slot范围内,Redis Cluster会自动将请求重定向到正确的分片上。

hash tags

在基础的分片原则上,Redis还支持hash tags功能,以hash tags要求的格式明明的key,将会确保进入同一个Slot中。例如:{uiv}user:1000和{uiv}user:1001拥有同样的hash tag {uiv},会保存在同一个Slot中。

使用Redis Cluster时,pipelining、事务和LUA Script功能涉及的key必须在同一个数据分片上,否则将会返回错误。如要在Redis Cluster中使用上述功能,就必须通过hash tags来确保一个pipeline或一个事务中操作的所有key都位于同一个Slot中。

有一些客户端(如Redisson)实现了集群化的pipelining操作,可以自动将一个pipeline里的命令按key所在的分片进行分组,分别发到不同的分片上执行。但是Redis不支持跨分片的事务,事务和LUA Script还是必须遵循所有key在一个分片上的规则要求。

主从复制 vs 集群分片

在设计软件架构时,要如何在主从复制和集群分片两种部署方案中取舍呢?

从各个方面看,Redis Cluster都是优于主从复制的方案

  • Redis Cluster能够解决单节点上数据量过大的问题
  • Redis Cluster能够解决单节点访问压力过大的问题
  • Redis Cluster包含了主从复制的能力

那是不是代表Redis Cluster永远是优于主从复制的选择呢?

并不是。

软件架构永远不是越复杂越好,复杂的架构在带来显著好处的同时,一定也会带来相应的弊端。采用Redis Cluster的弊端包括:

  • 维护难度增加。在使用Redis Cluster时,需要维护的Redis实例数倍增,需要监控的主机数量也相应增加,数据备份/持久化的复杂度也会增加。同时在进行分片的增减操作时,还需要进行reshard操作,远比主从模式下增加一个Slave的复杂度要高。
  • 客户端资源消耗增加。当客户端使用连接池时,需要为每一个数据分片维护一个连接池,客户端同时需要保持的连接数成倍增多,加大了客户端本身和操作系统资源的消耗。
  • 性能优化难度增加。你可能需要在多个分片上查看Slow Log和Swap日志才能定位性能问题。
  • 事务和LUA Script的使用成本增加。在Redis Cluster中使用事务和LUA Script特性有严格的限制条件,事务和Script中操作的key必须位于同一个分片上,这就使得在开发时必须对相应场景下涉及的key进行额外的规划和规范要求。如果应用的场景中大量涉及事务和Script的使用,如何在保证这两个功能的正常运作前提下把数据平均分到多个数据分片中就会成为难点。

所以说,在主从复制和集群分片两个方案中做出选择时,应该从应用软件的功能特性、数据和访问量级、未来发展规划等方面综合考虑,只在 确实有必要引入数据分片时再使用Redis Cluster。
下面是一些建议:

  1. 需要在Redis中存储的数据有多大?未来2年内可能发展为多大?这些数据是否都需要长期保存?是否可以使用LRU算法进行非热点数据的淘汰?综合考虑前面几个因素,评估出Redis需要使用的物理内存。
  2. 用于部署Redis的主机物理内存有多大?有多少可以分配给Redis使用?对比(1)中的内存需求评估,是否足够用?
  3. Redis面临的并发写压力会有多大?在不使用pipelining时,Redis的写性能可以超过10万次/秒(更多的benchmark可以参考 https://redis.io/topics/benchmarks
  4. 在使用Redis时,是否会使用到pipelining和事务功能?使用的场景多不多?

综合上面几点考虑,如果单台主机的可用物理内存完全足以支撑对Redis的容量需求,且Redis面临的并发写压力距离Benchmark值还尚有距离,建议采用主从复制的架构,可以省去很多不必要的麻烦。同时,如果应用中大量使用pipelining和事务,也建议尽可能选择主从复制架构,可以减少设计和开发时的复杂度。

Redis Java客户端的选择

Redis的Java客户端很多,官方推荐的有三种:Jedis、Redisson和lettuce。

在这里对Jedis和Redisson进行对比介绍

Jedis:

  • 轻量,简洁,便于集成和改造
  • 支持连接池
  • 支持pipelining、事务、LUA Scripting、Redis Sentinel、Redis Cluster
  • 不支持读写分离,需要自己实现
  • 文档差(真的很差,几乎没有……)

Redisson:

  • 基于Netty实现,采用非阻塞IO,性能高
  • 支持异步请求
  • 支持连接池
  • 支持pipelining、LUA Scripting、Redis Sentinel、Redis Cluster
  • 不支持事务,官方建议以LUA Scripting代替事务
  • 支持在Redis Cluster架构下使用pipelining
  • 支持读写分离,支持读负载均衡,在主从复制和Redis Cluster架构下都可以使用
  • 内建Tomcat Session Manager,为Tomcat 6/7/8提供了会话共享功能
  • 可以与Spring Session集成,实现基于Redis的会话共享
  • 文档较丰富,有中文文档

对于Jedis和Redisson的选择,同样应遵循前述的原理,尽管Jedis比起Redisson有各种各样的不足,但也应该在需要使用Redisson的高级特性时再选用Redisson,避免造成不必要的程序复杂度提升。

Jedis:
github: https://github.com/xetorthio/jedis
文档: https://github.com/xetorthio/jedis/wiki

Redisson:
github: https://github.com/redisson/redisson
文档: https://github.com/redisson/redisson/wiki

[原]互联网金融的分类监管主体

$
0
0

      根据最新出台的《关于促进互联网金融健康发展的指导意见》,对互联网金融涉及的业态和对应的监管主体进行了明确,总结如下:

一,互联网金融是传统金融机构与互联网企业(以下统称从业机构)利用互联网技术和信息通信技术实现资金融通、支付、投资和信息中介服务的新型金融业务模式。

二,主要业态:

 (1) 互联网支付。互联网支付是指通过计算机、手机等设备,依托互联网发起支付指令、转移货币资金的服务。互联网支付业务由 人民银行负责监管。

  ( 2 )   网络借贷。网络借贷包括个体网络借贷(即P2P网络借贷)和网络小额贷款。个体网络借贷是指个体和个体之间通过互联网平台实现的直接借贷。在个体网络借贷平台上发生的直接借贷行为属于民间借贷范畴,受合同法、民法通则等法律法规以及最高人民法院相关司法解释规范。个体网络借贷要坚持平台功能,为投资方和融资方提供信息交互、撮合、资信评估等中介服务。 个体网络借贷机构要明确信息中介性质,主要为借贷双方的直接借贷提供信息服务,不得提供增信服务,不得非法集资。网络小额贷款是指互联网企业通过其控制的小额贷款公司,利用互联网向客户提供的小额贷款。网络小额贷款应遵守现有小额贷款公司监管规定,发挥网络贷款优势,努力降低客户融资成本。网络借贷业务由 银监会负责监管。

   ( 3 )  股权众筹融资。股权众筹融资主要是指通过互联网形式进行公开小额股权融资的活动。股权众筹融资必须通过股权众筹融资中介机构平台(互联网网站或其他类似的电子媒介)进行。股权众筹融资业务由 证监会负责监管。

 (4) 互联网基金销售。基金销售机构与其他机构通过互联网合作销售基金等理财产品的,要切实履行风险披露义务, 不得通过违规承诺收益方式吸引客户;基金管理人应当采取有效措施防范资产配置中的期限错配和流动性风险;基金销售机构及其合作机构通过其他活动为投资人提供收益的,应当对收益构成、先决条件、适用情形等进行全面、真实、准确表述和列示,不得与基金产品收益混同。第三方支付机构在开展基金互联网销售支付服务过程中,应当遵守人民银行、证监会关于客户备付金及基金销售结算资金的相关监管要求。 第三方支付机构的客户备付金只能用于办理客户委托的支付业务,不得用于垫付基金和其他理财产品的资金赎回。互联网基金销售业务由 证监会负责监管。

  (5) 互联网保险。保险公司应建立对所属电子商务公司等非保险类子公司的管理制度,建立必要的防火墙。保险公司通过互联网销售保险产品,不得进行不实陈述、片面或夸大宣传过往业绩、违规承诺收益或者承担损失等误导性描述。互联网保险业务由 保监会负责监管。

   (6) 互联网信托和互联网消费金融。信托公司通过互联网进行产品销售及开展其他信托业务的,要遵守合格投资者等监管规定,审慎甄别客户身份和评估客户风险承受能力,不能将产品销售给与风险承受能力不相匹配的客户。互联网信托业务、互联网消费金融业务由 银监会负责监管。

  

  

作者:tenfyguo 发表于 2017/08/02 20:36:50 原文链接 https://blog.csdn.net/tenfyguo/article/details/76595953
阅读:1238 评论:1 查看评论

DataMan-美团旅行数据质量监管平台实践

$
0
0

背景

数据,已经成为互联网企业非常依赖的新型重要资产。数据质量的好坏直接关系到信息的精准度,也影响到企业的生存和竞争力。Michael Hammer(《Reengineering the Corporation》一书的作者)曾说过,看起来不起眼的数据质量问题,实际上是拆散业务流程的重要标志。 数据质量管理是测度、提高和验证质量,以及整合组织数据的方法等一套处理准则,而体量大、速度快和多样性的特点,决定了大数据质量所需的处理,有别于传统信息治理计划的质量管理方式。
本文将基于美团点评大数据平台,通过对数据流转过程中各阶段数据质量检测结果的采集分析、规则引擎、评估反馈和再监测的闭环管理过程出发,从面临挑战、建设思路、技术方案、呈现效果及总结等方面,介绍美团平台酒旅事业群(以下简称美旅)数据质量监管平台DataMan的搭建思路和建设实践。

挑战

美旅数据中心日均处理的离线和实时作业高达数万量级, 如何更加合理、高效的监控每类作业的运行状态,并将原本分散、孤岛式的监控日志信息通过规则引擎集中共享、关联、处理;洞察关键信息,形成事前预判、事中监控、事后跟踪的质量管理闭环流程;沉淀故障问题,搭建解决方案的知识库体系。在数据质量监管平台的规划建设中,面临如下挑战:

  • 缺乏统一监控视图,离线和实时作业监控分散,影响性、关联性不足。
  • 数据质量的衡量标准缺失,数据校验滞后,数据口径不统一。
  • 问题故障处理流程未闭环,“点”式解决现象常在;缺乏统一归档,没有形成体系的知识库。
  • 数据模型质量监控缺失,模型重复,基础模型与应用模型的关联度不足,形成信息孤岛。
  • 数据存储资源增长过快,不能监控细粒度资源内容。

DataMan质量监管平台研发正基于此,以下为具体建设方案。

解决思路

整体框架

构建美旅大数据质量监控平台,从可实践运用的视角出发,整合平台资源、技术流程核心要点,重点着力平台支持、技术控制、流程制度、知识体系形成等方向建设,确保质量监控平台敏捷推进落地的可行性。数据质量监控平台整体框架如图1所示:

图1 质量监控平台整体框架图

建设方法

以数据质量检核管理PDCA方法论,基于美团大数据平台,对数据质量需求和问题进行全质量生命周期的管理,包括质量问题的定义、检核监控、发现分析、跟踪反馈及知识库沉淀。数据质量PDCA流程图如图2所示:

图2 数据质量PDCA流程图

关键流程:
质量监管平台建设实践应用及价值体现,离不开管理流程、技术实现和组织人员的紧密结合,主要包含如下8大流程步骤:

  1. 质量需求:发现数据问题;信息提报、收集需求;检核规则的需求等。
  2. 提炼规则:梳理规则指标、确定有效指标、检核指标准确度和衡量标准。
  3. 规则库构建:检核对象配置、调度配置、规则配置、检核范围确认、检核标准确定等。
  4. 执行检核:调度配置、调度执行、检核代码。
  5. 问题检核:检核问题展示、分类、质量分析、质量严重等级分类等。
  6. 分析报告:数据质量报告、质量问题趋势分析,影响度分析,解决方案达成共识。
  7. 落实处理:方案落实执行、跟踪管理、解决方案Review及标准化提炼。
  8. 知识库体系形成:知识经验总结、标准方案沉淀、知识库体系建设。

质量检核标准

  • 完整性:主要包括实体缺失、属性缺失、记录缺失和字段值缺失四个方面;
  • 准确性:一个数据值与设定为准确的值之间的一致程度,或与可接受程度之间的差异;
  • 合理性:主要包括格式、类型、值域和业务规则的合理有效;
  • 一致性:系统之间的数据差异和相互矛盾的一致性,业务指标统一定义,数据逻辑加工结果一致性;
  • 及时性:数据仓库ETL、应用展现的及时和快速性,Jobs运行耗时、运行质量、依赖运行及时性。

大数据平台下的质量检核标准更需考虑到大数据的快变化、多维度、定制化及资源量大等特性,如数仓及应用BI系统的质量故障等级分类、数据模型热度标准定义、作业运行耗时标准分类等和数仓模型逻辑分层及主题划分组合如下图3所示。

图3 质量检核标准图

美旅数仓划分为客服、流量、运营、订单、门店、产品、参与人、风控、结算和公用等十大主题,按Base、Fact、Topic、App逻辑分层,形成体系化的物理模型。从数据价值量化、存储资源优化等指标评估,划分物理模型为热、温、冷、冰等四类标准,结合应用自定义其具体标准范围,实现其灵活性配置;作业运行耗时分为:优、良、一般、关注、耗时等,每类耗时定义的标准范围既符合大数据的特性又可满足具体分析需要,且作业耗时与数仓主题和逻辑分层深度整合,实现多角度质量洞察评估;针对数万的作业信息从数据时效性、作业运行等级、服务对象范围等视角,将其故障等级分为S1:严重度极高;S2:严重度高; S3:严重度中; S4:严重度低等四项标准,各项均对应具体的实施策略。整体数据质量的检核对象包括离线数仓和实时数据。

监管核心点

图4 数据质量监管功能图

数据质量功能模块设计的主要功能如上图4所示,包括:监控对象管理、检核指标管理、数据质量过程监控、问题跟踪管理、推荐优化管理、知识库管理及系统管理等。其中过程监控包括离线数据监控、实时数据监控;问题跟踪处理由问题发现(支持自动检核、人工录入)、问题提报、任务推送、故障定级、故障处理、知识库沉淀等形成闭环流程。

管理流程

流程化管理是推进数据问题从发现、跟踪、解决到总结提炼的合理有效工具。质量管理流程包括:数据质量问题提报、数据质量问题分析、故障跟踪、解决验证、数据质量评估分析等主要环节步骤;从干系人员的角度分析包括数据质量管理人员、数据质量检查人员、数据平台开发人员、业务及BI商分人员等,从流程步骤到管理人员形成职责和角色的矩阵图。如图5所示:

图5 数据质量流程图

问题汇总:数据质量提报、ETL处理及监控过程上报、数据质量检查点等多方来源,其中ETL处理部分为程序自动化上报,减少人为干预。

问题分析:通过规定的角色和岗位的人员对汇总问题分析和评估,由统一公共账号自动推送提醒消息至责任人。

问题工单:对采集的问题经过分析归类,主要划为信息提示和故障问题两大类,信息提示无需工单生成,故障问题将产生对应的工单,后推送至工单处理人。

故障定级:针对生成的问题工单判断其故障级别,其级别分为:S1、S2、S3、S4等四类(如图3所述),针对尤为严重的故障问题需Review机制并持续跟踪CaseStudy总结。

知识库体系:从由数据问题、解决方案、典型案例等内容中,提炼总结形成标准化、完备知识库体系,以质量问题中提炼价值,形成标准,更加有效的指导业务、规范业务,提高源头数据质量,提升业务服务水平。

质量流程管理:

  • 流程原则:统一流程、步骤稳定。
  • 权限控制:流程节点与人员账户号绑定,若节点未设置人员账户即面向所有人员,否则为规定范围的人员。
  • 权限管理:可结合美团平台的UPM系统权限管理机制。

技术方案

总体架构

DataMan系统建设总体方案基于美团的大数据技术平台。自底向上包括:检测数据采集、质量集市处理层;质量规则引擎模型存储层;系统功能层及系统应用展示层等。整个数据质量检核点基于技术性、业务性检测,形成完整的数据质量报告与问题跟踪机制,创建质量知识库,确保数据质量的完整性(Completeness)、正确性(Correctness)、当前性(Currency)、一致性(Consistency)。

总体架构图如图6所示:

图6 质量监管DataMan总体架构图

  • 数据源及集市层:首先采集数据平台质量相关的元数据信息、监控日志信息、实时日志、检测配置中心日志、作业日志及调度平台日志等关键的质量元数据;经数据质量集市的模型设计、监控对象的分类,加工形成完整、紧关联、多维度、易分析的数据质量基础数据模型,为上层质量应用分析奠定数据基础。数据来源自大数据平台、实时数仓、调度平台等,涉及到Hive、 Spark、Storm、 Kafka、MySQL及BI应用等相关平台数据源;
  • 存储模型层:主要功能包括规则引擎数据配置、质量模型结果存储;以数据质量监控、影响关联、全方位监控等目标规则引擎的推动方式,将加工结果数据存储至关系型数据库中,构成精简高质数据层;
  • 系统功能层:包括配置管理、过程监控、问题跟踪、故障流程管理、实时数据监控、知识库体系的创建等;处理的对象包括日志运行作业、物理监控模型、业务监控模型等主要实体;
  • 系统展示层:通过界面化方式管理、展示数据质量状态,包括质量监控界面、推荐优化模块、质量分析、信息展示、问题提报、故障跟踪及测量定级、系统权限管理等功能。

技术框架

前后端技术

图7 技术架构图

DataMan应用系统其前端框架(如上图7)基于Bootstrap开发,模板引擎为FreeMarker,Tomcat(开发环境)作为默认Web容器,通过MVC的方式实现与应用服务层对接。Bootstrap的优势基于jQuery,丰富的CSS、JS组件,兼容多种浏览器,界面风格统一等;FreeMarker为基于模板用来生成输出文本的引擎。后台基于开源框架Spring4,Spring Boot,Hibernate搭建,其集成了Druid,Apache系列和Zebra等数据库访问中间件等,为系统的功能开发带来更多选择和便利。

Zebra中间件

系统数据库连接采用中间件Zebra,这是美团点评DBA团队推荐的官方数据源组件,基于JDBC、API协议上开发出的高可用、高性能的数据库访问层解决方案;提供如动态配置、监控、读写分离、分库分表等功能。Zebra整体架构如图8所示:

图8 Zebra架构图

Zebra客户端会据路由配置直连到MySQL数据库进行读写分离和负载均衡。RDS是一站式的数据库管理平台,提供Zebra的路由配置信息的维护;MHA组件和从库监控服务分别负责主库和从库的高可用。Zebra支持丰富的底层连接池;统一源数据配置管理;读写分离和分库分表;数据库的高可用。

数据模型

整个质量监管平台数据流向为数据质量元数据信息采集于美团平台,包括数据仓库元数据信息、质量检测元数据、调度平台日志信息、监控日志及实时元数据信息等,加工形成独立数据质量的集市模型,以此支撑应用层系统的数据需求。应用层系统数据库采用关系型数据库存储的方式,主要包含了规则配置管理信息、数据质量结果库等信息内容。数据流向层级关系图如下:

图9 数据流向层级图

数据平台层:基于美团大数据平台的数据质量元数据是质量分析和监管的来源,是整个系统最基础重要资源信息,此数据主要包括:数仓元数据信息,如数仓模型表基本信息、表存储空间资源信息、表分区信息、节点信息、数据库meta信息、数据库资源信息等;运行作业调度日志信息,如作业基本信息、作业运行资源信息、作业调度状态信息、作业依赖关系信息及作业调度日志监控信息等;质量检测元数据信息主要来源于SLA、DQC(美团内部系统)检测结果的信息。实时元数据采集于调度平台实时作业运行的API接口调用分析。
质量集市层:DM数据质量集市的独立创建是依托基础元数据信息,根据质量监管平台配置的引擎规则ETL加工形成。规则库引擎如数仓应用主题的划分规则、数仓逻辑分层约束、数据库引擎分类、模型使用热度等级、模型存储空间分类、资源增长等级、历史周期分类、作业重要级别、作业运行耗时等级、作业故障分类、及数据质量标准化定义等;在管理方向上,如模型或作业所属的业务条线、组织架构、开发人员等;在时效上分为离线监控数据、实时数据集市等。从多个维度交叉组合分析形成模型类、作业类、监控日志类、实时类等主题的等易理解、简单、快捷的数据质量集市层,强有力的支撑上层应用层功能的数据需求。数据质量集市DM主要模型如图10所示:

图10 数据质量集市模型图

  • 模型设计:“统一规范、简单快捷、快速迭代、保障质量”,基于美团平台元数据、平台日志、实时数据接口等来源,通过制定的规则、标准,形成可衡量、可评估的数据质量集市层,主要包含公共维度类、模型分析类、作业监控类、平台监控类等主要内容;
  • 实时数据:针对实时作业的监控通过API接口调用,后落地数据,实时监控作业运行日志状态;
  • 数据加工:基于美团平台离线Hive、Spark引擎执行调度,以数仓模型分层、数仓十大主题规则和数据质量规则库等为约束条件,加工形成独立的数据集市层。

应用分析层:应用层系统数据采用关系型数据库(MySQL)存储的方式,主要包含了规则配置管理信息、数据质量分析结果、实时API落地数据、故障问题数据、知识库信息、流程管理及系统管理类等信息内容,直接面对前端界面的展示和管理。

系统展示

数据质量DataMan监控系统一期建设主要实现的功能包括:个人工作台、信息监控、推荐信息、信息提报、故障管理、配置管理及权限系统管理等。系统效果如图11所示:

图11 系统效果图

个人工作台

在系统中将个人待关注、待处理、待优化、待总结等与个人相关的问题和任务形成统一的工作平台入口,通过公共账号推送的方式,第一时间提醒个人,通知反馈问题的提出者,保障问题可跟踪,进度可查询,责任到人的工作流程机制。

离线监控

系统可定时执行模型监控、作业监控、平台日志监控等元数据质量规则引擎,开展数据仓库主题模型、逻辑层级作业、存储资源空间、作业耗时、CPU及内存资源等细化深度分析和洞察;按照质量分析模型,以时间、增长趋势、同环比、历史基线点等多维度、全面整合打造统一监控平台。

实时监控

从应用角度将作业按照业务条线、数仓分层、数仓主题、组织结构和人员等维度划分,结合作业基线信息,实时监控正在运行的作业质量,并与作业基线形成对比参照,预警不符合标准的指标信息,第一时间通知责任人。实时作业运行与基线对比监控效果如图12所示:

图12 实时作业运行监控图

推荐信息

系统通过规则引擎的设置和自动调度的执行,从存储资源配置、数据模型优化、作业优化、日志错误超时、预警通知等方面考虑,以制定的质量标准为评估依据,自动检测评估,汇总问题,形成可靠的推荐优化内容,并在达到阈值条件后主动推送消息,触发后续任务开展。

公共账号

通过“数据治理公共账号”机器人发送消息模式,将预判触发的预警通知、任务分配、任务提醒和风险评估等信息第一时间通知相应的负责人员,开启工作流程。

故障处理

支持自动提报和人工填报两种模式,以闭环工作流方式开展工作,确保问题故障可跟踪、可查询、可定级、可考核、可量化,以责任到人、落地可行的处理模式,严控数据质量,从根本上提高数据质量,提升业务服务水平。

DataMan质量监管系统的投入运营,优化数据存储资源、提高作业性能、降低任务耗时、推进了管理工作的规范化和精细化。信息推荐功能以推送通知的形式将待优化、存风险和超时故障信息第一时间发送个人工作台,以工作流机制推动开展;模型监控、作业监控功能在数据存储、模型建设、作业耗时等场景合理的控制资源,节省了投资成本。 问题提报和故障管理功能的有效结合,将问题发现、提报、任务分配、处理完成及Review总结沉淀等形成了责任到人、问题可询的闭环流程。随着系统的深入运行,将在实时数据监控、质量故障统计管理、数据质量考核机制、数据资产质量权威报告、知识库体系标准化及流程深化管理等功能方面持续推进和发挥价值。

总结

数据质量是数据治理建设的重要一环,与元数据管理、数据标准化及数据服务管理等共同构建了数据治理的体系框架。建设一个完整DataMan质量监管平台,将从监控、标准、流程制度等方面提升信息管理能力,优先解决所面临的数据质量和数据服务问题,其效果体现以下几个方面:

  • 监控数据资产质量状态,为优化数据平台和数据仓库性能、合理配置数据存储资源提供决策支持;
  • 持续推动数据质量监控优化预警、实时监控的机制;
  • 重点优先监控关键核心数据资产,管控优化20%核心资源,可提升80%需求应用性能;
  • 规范了问题故障的跟踪、Review、优化方案。从数据中提炼价值,从方案中形成标准化的知识体系;
  • 由技术检测到业务监督,形成闭环工作流机制,提高整体数据质量,全面提升服务业务水平。

数据质量是数据仓库建设、数据应用建设和决策支持的关键因素,可通过完善组织架构和管理流程,加强部门间衔接和协调,严格按照标准或考核指标执行落地,确保数据质量方能将数据的商业价值最大化,进而提升企业的核心竞争力和保持企业的可持续发展。

招聘

最后插播一个招聘广告,我们是一群擅长大数据领域数据建设、数仓建设、数据治理及数据BI应用建设的工程师,期待更多能手加入,有兴趣的同学可以发邮件给yangguang09#meituan.com,zhangdexiao#meituan.com。

作者简介

德晓,美团点评数仓专家、大数据高级工程师,长期从事数据仓库、数据建模、数据治理、大数据方向系统实践建设等,现为美团点评大交通数据仓库建设负责人。

一篇文章讲清NB-IoT技术(推荐收藏)

$
0
0

【原创声明】

作者:王一鸣

来源:物联江湖(iot521)

欢迎转载,请保留本声明,谢谢 !

作者文章链接:

物联网的网络视角物联网解析2物联网的价值

边缘计算1边缘计算2边缘网络接入方式

物联网平台PredixGE的物联网平台Jasper

共享经济共享单车技术

物联网的技术本质物联网技术语言物联网技术全矩阵图景物联网技术概念

蓝牙技术蓝牙Mesh∣从M2M到物联网∣物联网网络结构∣网络的未来


一直以来,人们通过相应的终端(电脑、手机、平板等)使用网络服务,“个人”一直是网络的用户主体。个人对网络质量的要求“高”且“统一”:玩网络游戏必需要低时延,下载文件或看网络视频则期望高带宽,通话需要声音清晰,而接收的短信绝不能有遗漏。

对于移动通信网络,运营商们尽可能地维系着低时延、高带宽、广覆盖、随取随用的网络特性,以保证良好的用户体验,以及营造出丰富多姿的移动应用生态。

对于个人通信业务,虽然用户的要求很高,但整体上对网络质量的需求是一致的,运营商只需要建立一套网络质量标准体系来建设、优化网络,就能满足大多数人对连接的需要。

随着网络中用户终端(手机、PAD等)数量的增长逐渐趋缓,M2M应用成为了运营商网络业务的增长发力点,大量的M2M应用终端则成为了网络的用户。M2M应用终端(传感设备、智能终端),本质上就是物联网终端,它们通过装配无线通信模组和SIM卡,连接到运营商网络,从而构建出各类集中化、数字化的行业应用。

不同于个人通信业务, 在物联网终端构建的行业应用中,各领域应用对信息采集、传递、计算的质量要求差异很大;系统和终端部署的环境也各不相同,特别是千差万别的工业环境;此外,企业在构建应用时,还需要考量技术限制(供电问题、终端体积等)和成本控制(包括建设成本和运营成本)。因此,千姿百态的行业应用具有“个性化”的一面,使得连接的需求朝着多样性的方向发展。

1.物联网业务需求的差异化,体现在两个方面

一方面,不同的终端和应用对网络特性有不同的要求。传统的网络特性包括:网络接入的距离、上下行的网络带宽、移动性的支持、还有数据收发的频率(或称为周期性)、以及安全性和数据传输质量(完整性、稳定性、时效性等)。这几个方面可浓缩成三个方面,为“接入距离”、“网络特性”、“网络品质”。“接入距离”主要分为近距接入和远距接入两种。网络的“特性”和“品质”则是体现需求差异化的主要因素,例如传感器终端的“网络特性”可能是:只有向云端发送的“上行数据”,而没有接收的“下行数据”。

另一方面,网络还需要“照顾”原本不太被关注的终端特性,以适应各类的行业应用需求:对“能耗”和“成本”的控制。

(1)能耗

个人用户大多数时间都是处于宜居的环境中,智能终端常伴左右,并且在人类活动的环境中总能找到充电的“电源插头”,所以这些终端的生产厂家对电池的电量并不敏感。

而物联网终端的工作环境相比较个人终端的工作环境,则要复杂的多。有些物联网终端会部署在高温高压的工业环境中,有些则远离城市、放置在人迹罕至的边远地区,还有一些可能深嵌地下或落户在溪流湖泊之中。

很多设备需要电池的长期供电来工作,因为地理位置和工作环境无法向它们提供外部电源,更换电池的成本也异常高昂。所以“低功耗”是保证他们持续工作的一个关键需求。在不少应用场景中,一小粒电池的电量需要维持某个终端“一生”的能量供给。

(2)成本

个人使用的终端,不论是电脑还是手机,其功能丰富、计算能力强大、应用广泛,通信模块只是其所有电子元件和机械构建中的一小部分,在总的制造成本中占比较低。

个人终端作为较高价值的产品,用户、厂家对其通信单元的固定成本并不特别敏感。而物联网终端则不同,许多不具备联网功能的终端原本只是简易的传感器设备,其功能简单、成本低廉,相对于传感设备,价格不菲的通信模块加入其中,就可能引起成本骤升。

在应用场景中大量部署联网的传感设备,往往需要企业下决心提高终端的成本投入。而与此矛盾的是:简单的传感器终端上传网络的数据量通常都很小;它们连接网络的周期长(网络的使用频次低);每一次上传信息的价值都很低。终端成本和信息价值不成比例,使得企业会在大量部署物联网终端的决策上犹豫不前。如何降低这些哑终端(单一的传感器终端)的通信成本,是一个迫在眉睫的难题。

此前提及的能耗问题,如果不妥善解决,也会影响到物联网应用的运营成本:如果终端耗电过快,就需要不断地重新部署投放或更换电池。

2.低功耗、低成本是物联网通信的一大需求

原本的网络对应用并不敏感,只要提供统一的高质量网络通道(标准唯一),就可以满足大多数用户的需求。不论用户喜欢使用什么样的业务,都可以通过高品质的网络质量来获得通信服务,网络能够满足个人用户的大多数要求。

然而随着行业应用的深入,网络设计和建设者必须关注到应用、终端的差异性,也就是网络需要针对终端、应用做出相应的调整和适配。

在此前提到的网络特性和终端特性中:“距离、品质、特性”和“能耗、成本”,前后两类特性存在密切的关联关系:通信基站的信号覆盖越广(“距离长”),则基站和终端的功耗越高(“能耗高”);要实现高品质、安全可靠的网络服务(“品质高”),需要健壮的通信协议实现差错效验、身份验证、重传机制、以建立端到端的可靠连接,保证的基础就是通信模块的配置就不能低(“成本高”)

运营商在推广M2M服务(物联网应用)的时候,发现企业对M2M的业务需求,不同与个人用户的需求。企业希望构建集中化的信息系统,与自身资产建立长久的通信连接,以便于管理和监控。

这些资产,往往分布各地,而且数量巨大;资产上配备的通信设备可能没有外部供电的条件(即电池供电,而且可能是一次性的,既无法充电也无法更换电池);单一的传感器终端需要上报的数据量小、周期长;企业需要低廉的通信成本(包括通信资费、装配通信模块的成本费用)。

以上这种应用场景在网络层面具有较强的统一性,所以通信领域的组织、企业期望能够对现有的通信网络技术标准进行一系列优化,以满足此类M2M业务的一致性需求。

2013年,沃达丰与华为携手开始了新型通信标准的研究,起初他们将该通信技术称为“NB-M2M(LTE for Machine to Machine)”。

2014年5月份,3GPP的GERAN组成立了新的研究项目:“FS_IoT_LC”,该项目主要研究新型的无线电接入网系统,“NB-M2M”成为了该项目研究方向之一。稍后,高通公司提交了“NB-OFDM”(Narrow Band Orthogonal Frequency Division Multiplexing, 窄带正交频分复用)的技术方案。

(3GPP,“第三代合作伙伴计划(3rd Generation Partnership Project)”标准化组织;TSG-GERAN (GSM/EDGE Radio Access Network):负责GSM/EDGE无线接入网技术规范的制定)

2015年5月,“NB-M2M”方案和“NB-OFDM方案”融合成为“NB-CIoT”(Narrow Band Cellular IoT)。该方案的融合之处主要在于:通信上行采用FDMA多址方式,而下行采用OFDM多址方式。

2015年7月,爱立信联合中兴、诺基亚等公司,提出了“NB-LTE”(Narrow Band LTE)的技术方案。

在2015年9月的RAN#69次全会上,经过激烈的讨论和协商,各方案的主导者将两个技术方案(“NB-CIoT”、“NB-LTE”)进行了融合,3GPP对统一后的标准工作进行了立项。该标准作为统一的国际标准,称为“NB-IoT(Narrow Band Internet of Things,基于蜂窝的窄带物联网)”。自此,“NB-M2M”、“NB-OFDM”、“NB-CIoT”、“NB-LTE”都成为了历史。

2016年6月,NB-IoT的核心标准作为物联网专有协议,在3GPP Rel-13冻结。同年9月,完成NB-IoT性能部分的标准制定。2017年1月,完成NB-IoT一致性测试部分的标准制定。

在我看来,促成这几种低功耗蜂窝技术“结盟”的关键,并不仅仅是日益增长的商业诉求,还有其它新生的(非授权频段)低功耗接入技术的威胁。LoRa、SIGFOX、RPMA等新兴接入技术的出现,促成了3PGG中相关成员企业和组织的抱团发展。

和其竞争对手一样,NB-IoT着眼于低功耗、广域覆盖的通信应用。终端的通信机制相对简单,无线通信的耗电量相对较低,适合小数据量、低频率(低吞吐率)的信息上传,信号覆盖的范围则与普通的移动网络技术基本一样,行业内将此类技术统称为“LPWAN技术”(Low Power Wide Area,低功耗广域技术)。

NB-IoT针对M2M通信场景对原有的4G网络进行了技术优化,其对网络特性和终端特性进行了适当地平衡,以适应物联网应用的需求。

在“距离、品质、特性”和“能耗、成本”中,保证“距离”上的广域覆盖,一定程度地降低“品质”(例如采用半双工的通信模式,不支持高带宽的数据传送),减少“特性”(例如不支持切换,即连接态的移动性管理 )。

网络特性“缩水”的好处就是:同时也降低了终端的通信“能耗”,并可以通过简化通信模块的复杂度来降低“成本”(例如简化通信链路层的处理算法)。

所以说,为了满足部分物联网终端的个性要求(低能耗、低成本),网络做出了“妥协”。NB-IoT是“牺牲”了一些网络特性,来满足物联网中不同以往的应用需要。

1.部署方式


为了便于运营商根据自由网络的条件灵活运用,NB-IoT可以在不同的无线频带上进行部署,分为三种情况:独立部署(Stand alone)、保护带部署(Guard band)、带内部署(In band)。

Stand alone模式:利用独立的新频带或空闲频段进行部署,运营商所提的“GSM频段重耕”也属于此类模式;

Guard band模式:利用LTE系统中边缘的保护频段。采用该模式,需要满足一些额外的技术要求(例如原LTE频段带宽要大于5Mbit/s),以避免LTE和NB-IoT之间的信号干扰。

In band模式:利用LTE载波中间的某一段频段。为了避免干扰,3GPP要求该模式下的信号功率谱密度与LTE信号的功率谱密度不得超过6dB。 

 除了Stand alone模式外,另外两种部署模式都需要考虑和原LTE系统的兼容性,部署的技术难度相对较高,网络容量相对较低。

2.覆盖增强

为了增强信号覆盖,在NB-IoT的下行无线信道上,网络系统通过重复向终端发送控制、业务消息(“重传机制”),再由终端对重复接受的数据进行合并,来提高数据通信的质量。

这样的方式可以增加信号覆盖的范围,但数据重传势必将导致时延的增加,从而影响信息传递的实时性。在信号覆盖较弱的地方,虽然NB-IoT能够保证网络与终端的连通性,但对部分实时性要求较高的业务就无法保证了。

在NB-IoT的上行信道上,同样也支持无线信道上的数据重传。此外,终端信号在更窄的LTE带宽中发送,可以实现单位频谱上的信号增强,使PSD(Power Spectrum Density,功率谱密度)增益更大。通过增加功率谱密度,更利于网络接收端的信号解调,提升了上行无线信号在空中的穿透能力。

通过上行、下行信道的优化设计,NB-IoT信号的“耦合损耗(coupling loss)”最高可以达到164dB。

(备注: 耦合损耗,指能量从一个电路系统传播到另一个电路系统时发生的能量损耗。这里是指无线信号在空中传播的能量损耗)

为了进一步利用网络系统的信号覆盖能力,NB-IoT还根据信号覆盖的强度进行了分级(CE Level),并实现“寻呼优化”:引入PTW(寻呼传输窗),允许网络在一个PTW内多次寻呼UE,并根据覆盖等级调整寻呼次数。

常规覆盖(Normal Coverage),其MCL(Maximum Coupling Loss,最大耦合损耗)小于144dB,与目前的GPRS覆盖一致。

扩展覆盖(Extended Coverage),其MCL介于144dB与154dB之间,相对GPRS覆盖有10dB的增强

极端覆盖(Extreme Coverage),其MCL最高可达164dB,相对GPRS覆盖强度提升了20dB。

3. NB-IoT低功耗的实现

要终端通信模块低功耗运行,最好的办法就是尽量地让其“休眠”。NB-IoT有两种模式,可以使得通信模块只在约定的一段很短暂的时间段内,监听网络对其的寻呼,其它时间则都处于关闭的状态。这两种“省电”模式为:PSM(power saving mode,省电模式)和eDRX(Extended Discontinuous Reception,扩展的不连续接收)

(1) PSM模式

在PSM模式下,终端设备的通信模块进入空闲状态一段时间后,会关闭其信号的收发以及接入层的相关功能。当设备处于这种局部关机状态的时候,即进入了省电模式-PSM。终端以此可以减少通信元器件(天线、射频等)的能源消耗。

终端进入省电模式期间,网络是无法访问到该终端。从语音通话的角度来说,即“无法被叫”。

大多数情况下,采用PSM的终端,超过99%的时间都处于休眠的状态,主要有两种方式可以激活他们和网络的通信:

当终端自身有连接网络的需求时,它会退出PSM的状态,并主动与网络进行通信,上传业务数据。

在每一个周期性的TAU (Tracking Area Update,跟踪区更新)中,都有一小段时间处于激活的状态。在激活状态中,终端先进入“连接状态(Connect)”,与通信网络交互其网络、业务的数据。在通信完成后,终端不会立刻进入PSM状态,而是保持一段时间为“空闲状态(IDLE)”。在空闲状态状态下,终端可以接受网络的寻呼。

在PSM的运行机制中,使用“激活定时器(Active Timer,简称AT)”控制空闲状态的时长,并由网络和终端在网络附着(Attach,终端首次登记到网络)或TAU时协商决定激活定时器的时长。终端在空闲状态下出现AT超时的时候,便进入了PSM状态。

根据标准,终端的一个TAU周期最大可达310H(小时);“空闲状态”的时长最高可达到3.1小时(11160s)。

从技术原理可以看出,PSM适用于那些几乎没有下行数据流量的应用。云端应用和终端的交互,主要依赖于终端自主性地与网络联系。绝大多数情况下,云端应用是无法实时“联系“到终端的。

(2) PSM模式

在PSM模式下,网络只能在每个TAU最开始的时间段内寻呼到终端(在连接状态后的空闲状态进行寻呼)。eDRX模式的运行不同于PSM,它引入了eDRX机制,提升了业务下行的可达性。

(备注:DRX(Discontinuous Reception),即不连续接收。eDRX就是扩展的不连续接收。)

eDRX模式,在一个TAU周期内,包含有多个eDRX周期,以便于网络更实时性地向其建立通信连接(寻呼)。

eDRX的一个TAU包含一个连接状态周期和一个空闲状态周期,空闲状态周期中则包含了多个eDRX寻呼周期,每个eDRX寻呼周期又包含了一个PTW周期和一个PSM周期。PTW和PSM的状态会周期性地交替出现在一个TAU中,使得终端能够间歇性地处于待机的状态,等待网络对其的呼叫。

 

eDRX模式下,网络和终端建立通信的方式同样:终端主动连接网络;终端在每个eDRX周期中的PTW内,接受网络对其的寻呼。

在TAU中,最小的eDRX周期为20.48秒,最大周期为2.91小时

在eDRX中,最小的PTW周期为2.56秒,最大周期为40.96秒

在PTW中,最小的DRX周期为1.28秒,最大周期为10.24秒

总体而言,在TAU一致的情况下,eDRX模式相比较PSM模式,其空闲状态的分布密度更高,终端对寻呼的响应更为及时。eDRX模式适用的业务,一般下行数据传送的需求相对较多,但允许终端接受消息有一定的延时(例如云端需要不定期地对终端进行配置管理、日志采集等)。根据技术差异,eDRX模式在大多数情况下比PSM模式更耗电。

4. 终端简化带来低成本

针对数据传输品质要求不高的应用,NB-IoT具有低速率、低带宽、非实时的网路特性,这些特性使得NB-IoT终端不必向个人用户终端那样复杂,简单的构造、简化的模组电路依然能够满足物联网通信的需要。

NB-IoT采用半双工的通信方式,终端不能够同时发送或接受信号数据,相对全双工方式的终端,减少了元器件的配置,节省了成本。

业务低速率的数据流量,使得通信模组不需要配置大容量的缓存。低带宽,则降低了对均衡算法的要求,降低了对均衡器性能的要求。(均衡器主要用于通过计算抵消无线信道干扰)

NB-IoT通信协议栈基于LTE设计,但它系统性地简化了协议栈,使得通信单元的软件和硬件也可以相应的降低配置:终端可以使用低成本的专用集成电路来替代高成本的通用计算芯片,来实现协议简化后的功能。这样还能够减少通信单元的整体功耗,延长电池使用寿命。

5.业务在核心网络中的简化

在NB-IoT的核心网络(EPC- Evolved Packet Core,即4G核心网)中,针对物联网业务的需求特性,蜂窝物联网(CIoT)定义了两种优化方案:

CIoT EPS用户面功能优化(User Plane CIoT EPS optimisation)

CIoT EPS控制面功能优化(Control Plane CIoT EPS optimisation)

(1) 用户面功能优化

“用户面功能优化”与原LTE业务的差异并不大,它的主要特性是引入RRC (无线资源控制)的“挂起/恢复(Suspend/Resume)流程”,减少了终端重复进行网络接入的信令开销。

当终端和网络之间没有数据流量时,网络将终端置为挂起状态(Suspend),但在终端和网络中仍旧保留原有的连接配置数据。

当终端重新发起业务时,原配置数据可以立即恢复通信连接(Resume),以此减去了重新进行RRC重配、安全验证等流程,降低了无线空口上的信令交互量。

(2) 控制面功能优化

“控制面功能优化”包括两种实现方式(消息传递路径)。通过这两种方式,终端不必在无线空口上和网络建立业务承载,就可以将业务数据直接传递到网络中。

备注:通信系统的特性之一是控制与承载(业务)分离,直观的来说就是业务的控制消息(建立业务、释放业务、修改业务)和业务数据本身并不在同一条链路上混合传递。NB-IoT的控制面功能优化则简化了这种惯常的信息业务架构。

CP模式的两种实现方式,即两种数据传递的路径:

 

A.在核心网内,由MME、SCEF网元负责业务数据的转接

在该方式中,NB-IoT引入了新的网元:SCEF(Service Capa- bility Exposure Function,服务能力开放平台)。物联网终端接受或发送业务数据,是通过无线信令链路进行的,而非无线业务链路。

当终端需要上传数据时,业务数据由无线信令消息携带,直接传递到核心网的网元MME(Mobility Management Entity,4G核心网中的移动性管理实体),再由MME通过新增的SCEF网元转发到CIoT服务平台(CIoT Services,也称为AP-应用服务)。云端向终端发送业务数据的方向则和上传方向正好相反。

路径:UE(终端)-MME-SCEF- CIoT Services

B.在核心网内,通过MME与业务面交互业务数据

在该方式中,终端同样通过无线信令链路收发业务数据。对于业务数据的上传,是由MME设备将终端的业务数据送入核心网的业务面网元SGW,再通过PGW进入互联网平台;对于下传业务数据,则由SGW传递给MME,再由MME通过无线信令消息送给终端。业务数据上传和下传的路径也是一致的。

路径:UE(终端)-MME-SGW-PGW-CIoT Services

按照传统流程(包括用户面优化方案),终端需要和网络先建立SRB(Signaling Radio Bearer)再建立DRB(Data Radio Bearer),才能够在无线通道上传输数据。而采用控制面优化方案(CP模式),只需要建立SRB就可以实现业务数据的收发。

(3)功能优化模式总结

CP方式借鉴了短距通信的一些设计思路,非常适合低频次、小数据包的上传业务,类似于短信业务。但网络中“信令面”的带宽有限,CP方式所以并不适合传递较大的业务数据包。UP模式则可以满足大数据业务的传递。

不论是UP模式,还是CP模式,本质上都是通过无线通信流程的简化,节省了终端的通信计算和能量消耗,提升了数据传递效率。

6.连接态的移动性管理 

最初,NB-IoT的规范是针对静态的应用场景(如智能抄表)进行设计和制定的,所以在Rel-13版本(2016年6月)中它并不支持连接状态下的移动性管理,即不支持“无线切换”。在随后的Rel-14版本中,NB-IoT会支持基站小区间的切换,以保证业务在移动状态下的连续性。

从NB-IoT的特性中可以看出,其通过“信号增强”、“寻呼优化”加强了通信覆盖的深度。主要通过三个方面,来“照顾”终端对低耗电、低成本的要求:

1、引入了低功耗的“睡眠”模式(PSM、eDRX);

2、降低了对通信品质要求,简化了终端设计(半双工模式、协议栈简化等);

3、通过两种功能优化模式(CP模式、UP模式)简化流程,减少了终端和网络的交互量。

这些对广域移动通信技术的“优化”设计,使得NB-IoT更加适合于部分物联网的场景应用,也就是LPWA(低功耗广域网)类型的应用。并且由于引入了睡眠模式,降低了通信品质的要求(主要是实时性要求),使得NB-IoT的基站比传统基站,能够接入更多的(承载LPWA业务的)终端。

采用NB-IoT的终端可以在满足低功耗的需求下,用于较高密度部署、低频次数据采集的应用(包括固定位置的抄表、仓储和物流管理、城市公共设置的信息采集等),或者是较低密度部署、长距离通信连接的应用(包括农情监控、地质水文监测等)。

当然,作为一种LPWAN技术,NB-IoT有其固有的局限性,它显然并不适用于要求低时延、高可靠性的业务(车联网、远程医疗),而且中等需求的业务(智能穿戴、智能家居)对于它来说也稍显“吃力”。

在物联网技术生态中,没有一种通信接入技术能够“通吃”所有的应用场景,各种接入技术之间存在一定的互补效应,NB-IoT能够依靠其技术特性在物联网领域中占据着一席之地。

文:王一鸣

对你有什么借鉴意义吗,可以加我微信:ss05050228

我拉你进入江湖群聊




转:他很了解中国:美商务部长谈美中贸易战

$
0
0

他很了解中国:美商务部长谈美中贸易战

2018-03-23 Ross 向小田经济观察

威尔伯·罗斯(Wilbur L. Ross, Jr.),美国投资家,美国商务部长, 擅长重组不同行业的破产企业,诸如,钢铁、煤矿、电信、跨国投资公司和纺织等行业,尤其精通杠杆收购,有“破产重组之王”之称。

罗斯:我们为什么走到这一步非常耐人寻味。二战刚结束的时候,有一个政策上的决定。美国那时有着巨大的贸易顺差,事实上,直到1970年代中,我们都是顺差。不管怎么说吧,二战刚结束的时候,在政策方面做出了这样的决定:我们必须帮助欧洲和亚洲重振,走出战争劫难。所以我们有意减少了对这些国家的贸易壁垒,有意向他们提供马歇尔计划和其它形式的援助。在当时这可能是很好的公共政策。他们的错误是,没有制定或标明时间限制。所以,想想看,当时给德国做出的让步完全恰当,可是现在已经不是1950年代初了,德国现在是超级出口大国了,有巨额的贸易顺差,是非常强大的国家。所以,我们的政策没有与时俱进。结果呢,我们处在这样一个荒唐的环境下:来自美国或多数国家的汽车,如果出口到欧洲,有10%的关税,是我们征收的关税的四倍。然后在这之上,还有增值税(VAT),把关税的影响又略微扩大了。对中国来说,因为中国加入世贸组织时还是个艰难奋斗、相对较小的经济体,他们对汽车征收的关税是25%。他们现在是世界最大的汽车市场。为什么这一点很重要呢?这是因为我们的贸易逆差有两个根本来源。一个是地理性的,那就是中国;另一个是产品,那就是汽车。所以,如果我们要想以有意义的方式减少我们的整体贸易逆差的话,我们必须解决中国问题和汽车问题。

美商务部长谈钢铝关税和美中贸易

记者:部长先生,很高兴见到您。

美国商务部长威尔伯·罗斯:很高兴见到您,格莱塔。

记者:总统对钢铁征收25%的关税,对铝材征收10%的关税,为什么?

罗斯:有几个原因。这两个产业因高度补贴和不公平的外国竞争而受到重创,这些竞争在部分程度上造成荒唐的全球产能过剩,而这又以中国为首。

记者:但是要征关税,你必须要有某种授权。宪法赋予国会这种权力,除非有法规允许总统以国家安全为由采取行动,或者我们也可以诉诸于世贸组织。我们有这些选项,对吧?

罗斯:是的。这些年来,我们发起了很多涉及钢铁的贸易诉讼。我们事实上对不同国家发起过100多起反倾销或反补贴关税的诉讼。发起了104起,针对34个国家。所以这是个十分普遍的问题。从单一国家来说,中国向来是最大的违规者。因为这些措施必须要遵守世贸规则,中国最近做的更多的是,他们说要精确到产品,在一起诉讼案中,甚至说要在0.2毫米内,他们还说要精确到国家。这就让他们较为容易规避惩罚,因为你可以改变一点尺寸,生产上加工一下。或者不管有没有进一步加工,还可以通过其他国家转运。所以关税的问题是,虽然限制了行为,但是并没有真正解决整体上的问题,因为这个问题开始通过其他国家冒出来。

记者:所以原因是经济上的还是国家安全方面的?因为我理解的是,总统没有走世贸组织,很可能是因为能被规避掉,容易被钻漏洞,而且程序繁琐。但是他是以国家安全为由通过赋予的法律采取行动的。所以说,是经济上还是基于国家安全?

罗斯:232条款中在这里适用的技术性条款定义的相对宽泛。包括的因素有就业影响、关键产业的健康持续状况,还有很多非专业人员通常不会认为是国家安全的东西。不过你听到过我们的一些国家安全顾问还有我们的国防部多次说过:“经济安全是国家安全。”

记者:我们进口的钢铁多数来自加拿大、墨西哥、巴西和韩国。只有4%的钢来自中国。你如何平衡国家安全和经济影响。即便是从经济的角度,从中国进口的似乎是微不足道的。

罗斯:这就是我刚才讲的。中国是世界产能过剩的主要来源。全球有大约4亿吨的产能过剩,半数在中国。中国的经济体量虽然比我们小得多,但是现在每月的钢铁产量比我们一年的产量还要多。想想这种比例上的失衡吧。他们每年出口1亿多吨钢铁,出口了之后,他们还有很大的产能过剩。他们钢铁的出口量相当于美国钢铁的消费总量。非常不成比例。我前面和你提到的那些原因,转运,生产时稍微改变下形状,所有这些因素都让人觉得不像以前那样全是中国的问题。但是问一问美国或欧洲的钢铁产业里的任何人,他们都会告诉你,真正的问题,真正大问题的根源在哪里。

记者:为什么这次征关税时让加拿大和墨西哥得到豁免?

罗斯:有几个原因,最重要的是,如果我们限制与它们的活动,但它们也是我们钢铁的两个重要出口市场。加拿大和墨西哥占了我们钢铁出口总量的大约90%。所以说,如果我们关闭了与这两个国家的双向贸易,我们得不到好处,反而会破坏很多非常重要的活动,其中重要的一个是北美大陆的安全。

记者:中国对关税做出回应了吗?你有没有听到中国商务部的消息?

罗斯:他们对此予以批评,但尚未表示会采取什么确切行动。他们表示,很可能会向世贸组织抗议,因为虽然法律不受世贸组织约束,但我们仍然是世贸组织成员。

我们相信,我们在世贸组织可以拿出很好的国家安全理由,因为世贸规则明确有国家安全方面的内容,我们与各国的自由贸易协定里也有。

记者:如果我错了请纠正我。世贸组织的法官,不论他们的裁决是有利于还是不利于美国,如果日内瓦的法官告诉一个主权国家什么是国家安全,什么不是,我认为不太寻常。我不清楚以前是不是有过这种情况。

罗斯:我不认为以前有过。我认为,这是众多阻碍之一。如果世贸组织告诉我们的总统什么符合我们的国家安全利益,在美国会非常不受欢迎。

记者:可是美国别的一些公司或组织、产业和部门提出了抱怨。比如,我注意到,大豆,美国生产大豆的人不喜欢征收关税的想法,因为中国购买60%的大豆,而他们担心中国不再买大豆了。

罗斯:是的。可是首先,大豆是中国饮食结构的关键组成部分,是中国人饮食结构中非常重要的蛋白质来源。我们是世界大豆市场的一个重大因素,我不是很确定中国能否找到替代来源,取代我们的多数大豆。不过,就算他们真这么做了,日本和其它市场如今也在消费这些大豆。所以,中国要找到其他大豆生产方,必须要付高价,他们只能这么做,才能让巴西、阿根廷这样的国家,从传统客户转移走,改为替中国生产大豆。他们必须付高价,这就会让中国增加成本,而这又为我们的大豆生产商打开市场。所以,临时的干扰可能会有,但在我看来,最终不会有巨大的净损失,这是因为,货物转向中国后会出现我们可以填补的真空。

记者:我采访过川普总统很多次,那时他还不是候选人,还没当总统,只是商人。他总是爱说,中国在坑美国。每次采访中,甚至在我根本没有问这个问题时,他都会插话表达这种观点。为什么我们会出现这样的差异?比如说,中国对美国汽车收的关税这么高?为什么会走到这一步?

罗斯:我们为什么走到这一步非常耐人寻味。二战刚结束的时候,有一个政策上的决定。美国那时有着巨大的贸易顺差,事实上,直到1970年代中,我们都是顺差。不管怎么说吧,二战刚结束的时候,在政策方面做出了这样的决定:我们必须帮助欧洲和亚洲重振,走出战争劫难。所以我们有意减少了对这些国家的贸易壁垒,有意向他们提供马歇尔计划和其它形式的援助。在当时这可能是很好的公共政策。他们的错误是,没有制定或标明时间限制。所以,想想看,当时给德国做出的让步完全恰当,可是现在已经不是1950年代初了,德国现在是超级出口大国了,有巨额的贸易顺差,是非常强大的国家。所以,我们的政策没有与时俱进。结果呢,我们处在这样一个荒唐的环境下:来自美国或多数国家的汽车,如果出口到欧洲,有10%的关税,是我们征收的关税的四倍。然后在这之上,还有增值税(VAT),把关税的影响又略微扩大了。对中国来说,因为中国加入世贸组织时还是个艰难奋斗、相对较小的经济体,他们对汽车征收的关税是25%。他们现在是世界最大的汽车市场。为什么这一点很重要呢?这是因为我们的贸易逆差有两个根本来源。一个是地理性的,那就是中国;另一个是产品,那就是汽车。所以,如果我们要想以有意义的方式减少我们的整体贸易逆差的话,我们必须解决中国问题和汽车问题。

记者:当您或者我们的其他政府官员说,进入中国的美国汽车要缴25%的关税,而进入美国的汽车却不必如此,中国怎么说?

罗斯:哦,他们承认这点。

记者:他们不认为这是个问题?不在乎?或者他们表示也许应当有所改变?

罗斯:他们说的是,---这是真的,他们说的是,他们的贸易顺差也给他们造成了一个问题,因为这影响了中国境内的货币供应量。所以,他们认识到他们这一边也有问题。但他们一门心思专注本国的经济发展,你也可以理解他们可能会这么做。他们做的非常出色,把一个80%是农村、20%是城市的国家变成了一半以上是城市。这大大提高了大城市民众的生活水平。但是却没有惠及小村庄里的人。他们的城乡收入差距仍然非常的大。

记者:中国仍然拥有巨额的美国国债,超过一万亿美元、一万一千亿美元。您对他们抛售债务以及这将对两国之间的问题所造成的影响有没有任何紧张或担忧?

罗斯:我不认为会有这种情况。原因有两点。首先,如果他们抛售这么多的债务,他们会因为现有的市场价值而蒙受损失。损失究竟多大,很难判断,但他们很可能会亏损。所以这是一个阻遏因素。另一个问题是,他们会把钱放到哪里去呢?没有多少市场可以吸收一万亿美元。看看欧洲的政府债券利率吧,一般都比美国的低得多。看看日本,这也是一个发放债券的大国,他们的利率也比这里的低得多。所以,中国在债券现行价值方面立即会蒙受损失,他们拿到的利率也会减少。所以我不认为这是他们非常想做的事情。

记者:考虑到我们只从中国进口很少比例的钢这样的事实,而且我知道川普总统出于国家安全而征收关税时会有例外豁免,很多人认为这只是想对中国盗窃技术以及强迫美国公司进入中国时必须转让技术的做法实施惩罚。这些公司被迫要披露他们的技术,这就产生了这样一种长远前景:当我们的经济更多地转型到人工智能和机器人时,他们会飞速地乘风追赶。

罗斯:另外还有一项正在由美国贸易代表莱特希泽大使展开的知识产权调查。那项调查是要解决知识产权、技术转让、强迫合伙、破坏网络安全等这类的问题。所以这不是232条款的目的。232条款是要努力帮助受到重创的两大产业,在进口倾销的重创下,它们的规模被砍了一半。我们失去了绝大多数的铝业。我们消费的产品中只有极小的一部分是我们自己生产的。在钢铁方面,我们也失去了大量的就业岗位,大量的冶炼厂关门了。这与国家安全直接相关。只有一家国内生产商制造陆军车辆、悍马车和海军舰艇上的装甲板。如果那家厂商倒闭了,我们就只能依靠外国人来为我们供应那种装甲板了。

记者:所以,我们不担心加拿大或墨西哥,或者巴西或韩国,我们是不是能从其它市场得到它?

罗斯:他们不生产那种产品,钢不是。。。。。。

记者:只有中国造钢?

罗斯:不,我没说中国。

记者:只有国内厂家?

罗斯:我没有说中国。装甲板是一种非常、非常特别也非常复杂的合金。除了美国,哪里都没有大市场。不仅仅是钢制装甲板。铝、极高纯度的铝合金现在也只剩下了一家供应商。问题是这样的:没有足够的军事需求能够维持那家供应商的生存。我们需要一个强劲的商业市场来让那家供应商维持生意。但是如果你关掉冶炼厂,那整家冶炼厂就关掉了。这跟汽车不一样,你可以每小时跑22英里,也可以跑80英里。对冶炼厂,基本上你不是开就是关。这是一个问题。另一个问题是,业界举步维艰,跟不上技术发展了。这是一个真正的问题,因为随着技术变化,产品变得越来越复杂,特别是合金,那些不同的材料。所以这是一个非常复杂的局面,而不是简单地说:‘他们只消费这么一点比例,为什么要担心?’。

记者:看看谁支持谁反对很有意思。布朗参议员是民主党人,他来自俄亥俄州,这是个产钢州。他就非常赞成。我想这是因为俄亥俄的就业吧。但这会不会也带来就业损失呢?我知道一旦重新启动美国钢厂,就会带来就业机会。然而,是不是也会有与此有关的就业损失呢?

罗斯:好,我们就来谈谈这个。如果真的造成就业流失,那是因为那些消费钢和铝的产业所受的价格冲击。那我们就来看看这些产业。一罐百威啤酒(Budweiser)的钢铁成本只有零点几美分。一罐百威啤酒卖不少钱,这时候多花0.5美分或者是0.25美分实在微不足道。金宝汤(CampbellSoup)也一样,可口可乐(CocaCola)和百事可乐(Pepsi)也一样。对于汽车来说,钢铁所占的汽车造价成本大概不到1%。所以如果按最极端的例子计算,所有钢铁都被征收25%的关税,而且所有这些都反映到汽车的价格上,那基本上一辆普通汽车每个月会多出4美元。所以价格确实有提升,但是并没有达到会造成汽车行业大幅度裁员的程度。与此同时,我们的经济很强劲。所以,制造业的就业流失比起经济不景气的时候会小得多。你看现在很多人重回就业市场。上个月,我们的劳动参与率上升了0.3%。实际上目前在我们的国家的很多地方,我们缺少劳动力,特别是有技能的劳动力。冶炼厂工人需要的技术很复杂。因为现在这些行业已经不是大量使用体力劳动了,很多都是电脑操纵机器,非常复杂。因此这些都是非常高薪的工人。

记者:所以这最主要是针对中国,因为我们会豁免一些国家。

罗斯:是的。

记者:为什么欧洲国家反对这个关税?他们对我们发出了威胁,在2003年小布什总统时期,就曾实施过一个短期关税,欧洲国家就威胁了佛罗里达的橘子产业。为什么是欧洲?这场纠纷跟他们有什么关系?

罗斯:关系在这里:他们也遭受到中国和其他地方的倾销,他们担心如果我们建立起一道墙,有效地阻碍了中国,他们就会遭受更多倾销。这是他们采取现在这种态度的一个很大原因。另一个原因是,他们担心我们会采取其它会更直接影响他们的贸易措施。就像我们之前讨论过的那样,这么多年来,欧洲都被娇惯坏了,与我们相比,他们有更高的关税和更多的贸易壁垒。他们还害怕这将是一场全面运动的开始。不过,我们看看他们威胁要做的事情,比如波本酒…

记者:波本酒,那就是给麦康奈尔参议员将了一军。他来自肯塔基州。他们看起来是在针对美国不同州的不同产品。

罗斯:是的。但是首先,他们必须通过世贸组织,---除非他们违反规定。其次,世贸组织还要裁定我们有过错。不然的话,按照世贸组织的规定,他们采取任何那些措施都是非法的。我们先把这个放到一边。如果真的这样做有什么结果?他们谈到的是价值大约35亿美元的产品。35亿美元是美国GDP的0.2%。所以对我们整体经济来说,这不算什么。与此同时,这些产品的出口不会归零。就算波本酒被加了关税,我保证那些爱喝波本酒的人肯定会多付一点钱来买这些酒,因为在世界其他地方很难找到这种酒。所以这是个小问题。我知道在个别行业会产生问题,但是这比关税对经济造成的直接影响甚至还要小。比如说,姑且假设25%和10%的关税全都反映到价格里,把钢和铝加在一起,这相当于90亿美元,不到我们国家经济总量的0.5%。所以,这不是攸关生死的问题。

记者:在我看来,他们不会去世贸组织,美国没有通过世贸组织处理这个问题。中国也不会去世贸组织,现在基本上就只是美中两国之间的事情了,美国将了中国一军,现在轮到中国反击了。

罗斯:我不认为是这样,比那个更复杂。我们希望最后所有问题都会得到解决,全世界会最终处理产能过剩问题。全球的钢铁行业对这个问题的讨论已经有两年了,但是一直都是纸上谈兵。实际上,中国都没有给全球钢铁论坛该给的全部数据。这个架构并不那么有用。

记者:大约六个月之前,如果我说错了请纠正我,这是另一个话题了,您说到阿富汗,说到在那里采矿,帮助阿富汗政府。现在这个怎么样了?

罗斯:打仗的时候你也采不了什么矿,而现在阿富汗还在打仗。一些有丰富矿藏的省份现在被塔利班控制。所以现在,我们在那儿做不了太多的事情。

记者:最后一个问题。您喜不喜欢您的工作?

罗斯:特别喜欢。

记者:特别喜欢?

罗斯:特别喜欢,是的。

记者:您会继续干下去吗?

罗斯:每分钟都有挑战。

记者:确实。一点都不无聊,对吧?

罗斯:一点儿都不。

记者:您对国务卿蒂勒森有什么看法。

罗斯:我非常尊重国务卿蒂勒森。我认为他非常真诚,做了很多有益的事情。我也非常了解蓬佩奥。我觉得他是个很好的接班人选。

记者:部长先生,很高兴见到您。

罗斯:很高兴见到您,格莱塔。



 

用Python构建你自己的RSS提示系统

$
0
0

人生苦短,我用 Python,Python 是非常棒的快速构建应用程序的编程语言。在这篇文章中我们将学习如何使用 Python 去构建一个 RSS 提示系统,目标是使用 Fedora 快乐地学习 Python。如果你正在寻找一个完整的 RSS 提示应用程序,在 Fedora 中已经准备好了几个包。

Fedora 和 Python —— 入门知识

Python 3.6 在 Fedora 中是默认安装的,它包含了 Python 的很多标准库。标准库提供了一些可以让我们的任务更加简单完成的模块的集合。例如,在我们的案例中,我们将使用 sqlite3模块在数据库中去创建表、添加和读取数据。在这个案例中,我们试图去解决的是这样的一个特定问题,在标准库中没有包含,而有可能已经有人为我们开发了这样一个模块。最好是使用像大家熟知的 PyPI Python 包索引去搜索一下。在我们的示例中,我们将使用 feedparser去解析 RSS 源。

因为 feedparser 并不是标准库,我们需要将它安装到我们的系统上。幸运的是,在 Fedora 中有这个 RPM 包,因此,我们可以运行如下的命令去安装 feedparser:

$sudo dnf install python3-feedparser

我们现在已经拥有了编写我们的应用程序所需的东西了。

存储源数据

我们需要存储已经发布的文章的数据,这样我们的系统就可以只提示新发布的文章。我们要保存的数据将是用来辨别一篇文章的唯一方法。因此,我们将存储文章的标题和发布日期。

因此,我们来使用 Python sqlite3 模块和一个简单的 SQL 语句来创建我们的数据库。同时也添加一些后面将要用到的模块(feedparse,smtplib,和 email)。

创建数据库

#!/usr/bin/python3
import sqlite3
import smtplib
from email.mime.text import MIMEText
 
import feedparser
 
db_connection=sqlite3.connect('/var/tmp/magazine_rss.sqlite')
db=db_connection.cursor()
db.execute(' CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)')

这几行代码创建一个名为 magazine_rss.sqlite 文件的新 sqlite 数据库,然后在数据库创建一个名为 magazine 的新表。这个表有两个列 —— title 和 date —— 它们能存诸 TEXT 类型的数据,也就是说每个列的值都是文本字符。

检查数据库中的旧文章

由于我们仅希望增加新的文章到我们的数据库中,因此我们需要一个功能去检查 RSS 源中的文章在数据库中是否存在。我们将根据它来判断是否发送(有新文章的)邮件提示。Ok,现在我们来写这个功能的代码。

def article_is_not_db(article_title, article_date):""" Check if a given pair of article title and date
 is in the database.
 Args:
 article_title (str): The title of an article
 article_date (str): The publication date of an article
 Return:
 True if the article is not in the database
 False if the article is already present in the database"""
 db.execute("SELECT * from magazine WHERE title=? AND date=?", (article_title, article_date))
 if not db.fetchall():
 return True
 else:
 return False

这个功能的主要部分是一个 SQL 查询,我们运行它去搜索数据库。我们使用一个 SELECT 命令去定义我们将要在哪个列上运行这个查询。我们使用 * 符号去选取所有列( title 和 date )。然后,我们使用查询的 WHERE 条件 article_title 和 article_date 去匹配标题和日期列中的值,以检索出我们需要的内容。

最后,我们使用一个简单的返回 True 或者 False 的逻辑来表示是否在数据库中找到匹配的文章。

在数据库中添加新文章

现在我们可以写一些代码去添加新文章到数据库中。

def add_article_to_db(article_title, article_date):""" Add a new article title and date to the database
 Args:
 article_title (str): The title of an article
 article_date (str): The publication date of an article"""
 db.execute("INSERT INTO magazine VALUES (?,?)", (article_title, article_date))
 db_connection.commit()

这个功能很简单,我们使用了一个 SQL 查询去插入一个新行到 magazine 表的 article_title 和 article_date 列中。然后提交它到数据库中永久保存。

这些就是在数据库中所需要的东西,接下来我们看一下,如何使用 Python 实现提示系统和发送电子邮件。

发送电子邮件提示

我们使用 Python 标准库模块 smtplib 来创建一个发送电子邮件的功能。我们也可以使用标准库中的 email 模块去格式化我们的电子邮件信息。

def send_notification(article_title,article_url):""" Add a new article title and date to the database
 
Args:
article_title (str): The title of an article
article_url (str): The url to access the article
"""
 
smtp_server=smtplib.SMTP('smtp.gmail.com', 587)
smtp_server.ehlo()
smtp_server.starttls()
smtp_server.login('your_email@gmail.com', '123your_password')
msg= MIMEText(f'\nHi there is a new Fedora Magazine article : {article_title}. \nYou can read it here {article_url}')
msg['Subject'] = 'New Fedora Magazine Article Available'
msg['From'] = 'your_email@gmail.com'
msg['To'] = 'destination_email@gmail.com'
smtp_server.send_message(msg)
smtp_server.quit()

在这个示例中,我使用了谷歌邮件系统的 smtp 服务器去发送电子邮件,在你自己的代码中你需要将它更改为你自己的电子邮件服务提供者的 SMTP 服务器。这个功能是个样板,大多数的内容要根据你的 smtp 服务器的参数来配置。代码中的电子邮件地址和凭证也要更改为你自己的。

如果在你的 Gmail 帐户中使用了双因子认证,那么你需要配置一个密码应用程序为你的这个应用程序提供一个唯一密码。可以看这个 帮助页面

读取 Fedora Magazine 的 RSS 源

我们已经有了在数据库中存储文章和发送提示电子邮件的功能,现在来创建一个解析 Fedora Magazine RSS 源并提取文章数据的功能。

def read_article_feed():""" Get articles from RSS feed """
feed=feedparser.parse('https://fedoramagazine.org/feed/')
 for article in feed['entries']:
 if article_is_not_db(article['title'],article['published']):
send_notification(article['title'],article['link'])
add_article_to_db(article['title'],article['published'])
 
if__name__== '__main__':
read_article_feed()
db_connection.close()

在这里我们将使用 feedparser.parse 功能。这个功能返回一个用字典表示的 RSS 源,对于 feedparser 的完整描述可以参考它的 文档

RSS 源解析将返回最后的 10 篇文章作为 entries ,然后我们提取以下信息:标题、链接、文章发布日期。因此,我们现在可以使用前面定义的检查文章是否在数据库中存在的功能,然后,发送提示电子邮件并将这个文章添加到数据库中。

当运行我们的脚本时,最后的 if 语句运行我们的 read_article_feed 功能,然后关闭数据库连接。

运行我们的脚本

给脚本文件赋于正确运行权限。接下来,我们使用 cron 实用程序去每小时自动运行一次我们的脚本。cron 是一个作业计划程序,我们可以使用它在一个固定的时间去运行一个任务。

$chmod a+x my_rss_notifier.py
$sudo cp my_rss_notifier.py/etc/cron.hourly

为了使该教程保持简单,我们使用了 cron.hourly 目录每小时运行一次我们的脚本,如果你想学习关于 cron 的更多知识以及如何配置 crontab,请阅读 cron 的 wikipedia 页面

总结

在本教程中,我们学习了如何使用 Python 去创建一个简单的 sqlite 数据库、解析一个 RSS 源、以及发送电子邮件。我希望通过这篇文章能够向你展示,使用 Python 和 Fedora 构建你自己的应用程序是件多么容易的事。

这个脚本在 GitHub上可以找到。

 

来自:http://developer.51cto.com/art/201803/568656.htm

 

工作笔记5 - websocket心跳重连机制

$
0
0

心跳重连缘由

在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开,

而浏览器不会执行websocket 的 onclose方法,我们无法知道是否断开连接,也就无法进行重连操作。

如果当前发送websocket数据到后端,一旦请求超时,onclose便会执行,这时候便可进行绑定好的重连操作。

因此websocket心跳重连就应运而生。

 

如何实现

在websocket实例化的时候,我们会绑定一些事件:

 
var ws = new WebSocket(url);
ws.onclose = function () {
    //something
};
ws.onerror = function () {
    //something
};
ws.onopen = function () {
   //something
};
ws.onmessage = function (event) {
   //something
}
 

如果希望websocket连接一直保持,我们会在close或者error上绑定重新连接方法。

 
ws.onclose = function () {
    reconnect();
};
ws.onerror = function () {
    reconnect();
};
 

这样一般正常情况下失去连接时,触发onclose方法,我们就能执行重连了。

 

那么针对断网的情况的心跳重连,怎么实现呢。

简单的实现:

 
var heartCheck = {
    timeout: 60000,//60ms
    timeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);    
     this.start(); }, start: function(){ this.timeoutObj = setTimeout(function(){ ws.send("HeartBeat"); }, this.timeout) } } ws.onopen = function () { heartCheck.start(); };
ws.onmessage = function (event) {
    heartCheck.reset();
}
 

如上代码,heartCheck 的 reset和start方法主要用来控制心跳的定时。

什么条件下执行心跳:

当onopen也就是连接上时,我们便开始start计时,如果在定时时间范围内,onmessage获取到了后端的消息,我们就重置倒计时,

距离上次从后端获取到消息超过60秒之后,执行心跳检测,看是不是断连了,这个检测时间可以自己根据自身情况设定。

判断前端ws断开(断网但不限于断网的情况):

当心跳检测send方法执行之后,如果当前websocket是断开状态(或者说断网了),发送超时之后,浏览器的ws会自动触发onclose方法,重连也执行了(onclose方法体绑定了重连事件),如果当前一直是断网状态,重连会2秒(时间是自己代码设置的)执行一次直到网络正常后连接成功。

如此一来,我们判断前端主动断开ws的心跳检测就实现了。为什么说是前端主动断开,因为当前这种情况主要是通过前端ws的事件来判断的,后面说后端主动断开的情况。

 

我本想测试websocket超时时间,又发现了一些新的问题

1. 在chrome中,如果心跳检测 也就是websocket实例执行send之后,15秒内没发送到另一接收端,onclose便会执行。那么超时时间是15秒。

2. 我又打开了Firefox ,Firefox在断网7秒之后,直接执行onclose。说明在Firefox中不需要心跳检测便能自动onclose。

3.  同一代码, reconnect方法 在chrome 执行了一次,Firefox执行了两次。当然我们在几处地方(代码逻辑处和websocket事件处)绑定了reconnect(),

所以保险起见,我们还是给reconnect()方法加上一个锁,保证只执行一次

 

目前来看不同的浏览器,有不同的机制,无论浏览器websocket自身会不会在断网情况下执行onclose,加上心跳重连后,已经能保证onclose的正常触发。

 

判断后端断开:

    如果后端因为一些情况断开了ws,是可控情况下的话,会下发一个断连的消息通知,之后才会断开,我们便会重连。

如果因为一些异常断开了连接,我们是不会感应到的,所以如果我们发送了心跳一定时间之后,后端既没有返回心跳响应消息,前端又没有收到任何其他消息的话,我们就能断定后端主动断开了。

一点特别重要的发送心跳到后端,后端收到消息之后必须返回消息,否则超过60秒之后会判定后端主动断开了。再改造下代码:

 

 
var heartCheck = {
    timeout: 60000,//60ms
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
     this.start();
    },
    start: function(){
        var self = this;
        this.timeoutObj = setTimeout(function(){
            ws.send("HeartBeat");
            self.serverTimeoutObj = setTimeout(function(){
                ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
            }, self.timeout)
        }, this.timeout)
    },
}

ws.onopen = function () {
   heartCheck.start();
};
ws.onmessage = function (event) {
    heartCheck.reset();
}    
ws.onclose = function () {
    reconnect();
};
ws.onerror = function () {
    reconnect();
};
 
 

 

PS:

    因为目前我们这种方式会一直重连如果没连接上或者断连的话,如果有两个设备同时登陆并且会踢另一端下线,一定要发送一个踢下线的消息类型,这边接收到这种类型的消息,逻辑判断后就不再执行reconnect,否则会出现一只相互挤下线的死循环。

 

整理了一个简单的demo到github,点击查看https://github.com/zimv/WebSocketHeartBeat

 

原文链接:http://www.cnblogs.com/1wen/p/5808276.html



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



人是怎么废掉的? - 知乎

$
0
0

1. 害怕改变,没有勇气及时止损。要么沉溺于过去的辉煌,要么屈服于现实的安稳。人生只有一次,生命短暂多舛,多听听自己内心的声音,才能活出不废的人生啊。

2. 只接受碎片化的信息,不进行系统完整的梳理与思考。刷微博、刷知乎,被动接受许多资讯,但不进行自主思考,没有形成自己的观点,充实自己的内心。

3. 拖延症、拖延症、拖延症。下午再做吧,晚上再做吧,明天再做吧,下周再做吧,明年吧……

4. 不进行总结与输出。不能进行输出的知识永远是别人的知识,只有把知识融入自己的逻辑体系,通过自己的思维方式输出出来,这份知识才能真正为你所用。

5. 沉迷于短期成就感,不作长期投入。于是许多人沉迷打网游、看爽文、微博抽奖等等能获得短期成就感的事情,没有毅力去运动、学习。但实际上,这些通过长期的努力才能看到回报的事情,会让人生拥有质的飞跃。

6. 工作日随波逐流,休息日躺在床上。对自己的工作与生活都缺乏规划,最终只能“废掉”,泯然众人矣。

7. 作践身体。好的身体意味着充沛的精力、比别人更长的工作时间、更多的专注力,也意味着用更少的毅力就能坚持更难的事情。

8. 眼高手低,读书不多、做事不多,想得太多。不能沉下心来做事,总是梦想自己能做这做那, 寄希望于过去或未来,却不肯在当下付出努力。不读书、不实干,沉浸幻想,患得患失。做了一万个决定,却不肯实施一个。


居然破百赞啦!谢谢大家的支持呀!添加几条~


9. 长期且无意义的熬夜。熬夜不仅对身体有多种危害,更直接的是严重影响第二天的工作效率、精神状态和社交心情。无意义的熬夜毁掉的是当天夜晚,更是毁掉了第二个白天。长期熬夜将导致日复一日的低效率生活。

10. 没有尝试新事物的勇气,无法走出“舒适区”。固步自封,安于现状,过着不满意的生活却不敢放弃,面向多重选择的未来却不敢追求。怕苦怕累怕失败,走不出自己的“舒适区”。

11. 不为自己的未来投资。只看眼前,不看以后,不懂理财,不买保险,不在自己身上作投资。越是年轻的时候,越是要懂得在自己身上投资,自己给自己的回报是最大的。

12. 生活习惯毫无节制。饮食无节,饮酒无度,沉迷游戏,拒绝运动,不断放任自己,不去养成健康的生活习惯,不懂得控制自己的欲望,身体和意志都在放任中被消磨。

13. 被外界的琐事占据大部分时间。对人生没有明确的规划,兵来将挡,水来土掩,什么事情逼到眼前就做什么事情,不会判断、不懂拒绝,被一些无意义的琐事占据了大量时间,每天精疲力尽却没有实质性的进步。

14. 机械工作,拒绝思考。每天机械化地工作,不问为什么,不思考更好的工作方法,工作多年,能力没有得到明显提升。

15. 缺乏“高亲密度社交”。这里的“高亲密度社交”,指的是与真正拥有亲密关系的人,进行高质量的心灵沟通。人生中能拥有几个能够进行“高亲密度社交”的亲友,能够极大程度上减轻压力、缓解抑郁。世界上只要存在一个真正理解你的人,你就永不孤独。请千万珍惜这样的人。


评论区里有很多知友问“怎样解决这些问题”,这里先占个坑,明天来具体写一写~


400赞了!非常感谢各位小天使的点赞!依约来写一写 “怎样解决这些问题”。在评论里看到好多人表示中枪,其实里面有很多条也是答主本人……很多方法我也在摸索中,将我的思考写出来同大家探讨,希望可以对困惑的朋友们有所帮助。


很多人一定都是这样: 并不是不知道应该做什么,而是明明知道应该做什么,却无法下定决心去做,或无法坚持做。并且越是这样,越觉得自己“废了”、“没救了”,焦虑不已,干着急。

下文中这些方法也许可以帮助你下定决心、坚持行动:


1. 不管怎么样,先做了再说。许多人做事之前会顾虑很多,如果这样做不是最好的选择怎么办,如果这件事不适合我怎么办,如果不能成功只是浪费时间怎么办。能进行这样的思考固然是好事,但更多时候会让我们陷入犹豫不决、只思考不行动的怪圈。这个时候,不如先什么都不顾虑,想做的事情就做了再说,在行动中慢慢调整方向,直到找到最适合自己的方法。很多时候你会发现,大多数问题是只有你真正去做了才会发现的,行动之前的空想没有太大的意义。

2. 认清自己真正的“舒适区”,听从你心,无问西东。有些人总是跳不出自己的“舒适区”,但你想过没有,这所谓的“舒适区”是你真正喜欢的吗?是不是不愿走出安稳的被迫选择?是不是因为对自己不够自信所以不敢向前迈出一步?“心甘情愿”才是做好一件事情的最大动力,你最喜欢做的事情,才是你真正的“舒适区”。

3. 给自己足够的阶段性奖赏。为什么读书的时候,我们能坚持学习,通过考试;打网游的时候,我们能坚持打怪,实现升级,可面对自主学习、提高工作能力、锻炼身体等等事情的时候,我们却很难坚持下来呢?究其原因,是这些事情需要长期坚持才能看见成效,不像背几天书就能通过考试,打几个怪就能升一级一样,能在短期内看到切实的效果。这时候,我们就要学会自己给自己足够的阶段性奖赏,将一个大目标分解成一个一个的小目标,让枯燥漫长的过程被成就感填满,每一个小小的成就感,都是不断坚持的动力。

4. 学会拒绝,懂得取舍。不要让自己的工作、生活被没有意义的琐事占据。拒绝不想去的饭局、不想逛的街、不想聊的天,并不会让你失去真正的朋友。拒绝没有效率的杂事、建立简洁的工作模式,反而会提升你的工作效率。

5. 坚持思考,坚持输出。将学到的知识、自己的思考、动人的故事等等,所有你觉得有趣、有用的东西写下来。输出、输出、输出,通过这个过程,输入进脑海中的知识才能真正融入你的逻辑习惯于思维体系,为你所用。输出不仅能帮助你梳理、巩固知识,锻炼你的语言表达能力,分享出来还能帮助到更多的人,坚持几个月,它一定会带给你不一样的惊喜。

6. 不要吝啬在自己身上的投资。打个比方,很多人愿意给车买很贵的保险,却不给自己购买保险;愿意花大价钱去保养车,却不愿意花钱保养自己的牙齿。给自己的投资才是最超值的投资,试着把以前用在物品上的钱用在自己身上吧,花钱学习,花钱护理自己的身体,花钱为自己的将来购买一份保障,多爱自己一些,为自己而活。


如果喜欢这个答案,不要只点感谢,点个赞再走好不好~谢谢啦么么哒~!

点赞的人最可爱~!

我们整理了20个Python项目,送给正在求职的你

$
0
0

关注「实验楼」,每天分享一个项目教程   

职场中一贯有 “金三银四”、“金九银十”的说法。 如果你是一名正在求职或准备跳槽的程序员,不妨趁着这两个月时间好好准备一下。

正文共:6737 字 

预计阅读时间:15 分钟

职场中一贯有 “金三银四”、“金九银十”的说法。尤其是3、4月刚过完年后,很多企业的员工会选择离职,大量空缺职位被放出,同时HR招聘压力增大,求职者往往可以借此机会,获得一个更好的报价。 如果你是一名正在求职或准备跳槽的程序员,不妨趁着这两个月时间好好准备一下。

而在程序员的求职中, 「项目经历」往往是最重要的一环,它能最直观地体现你的编程能力。对于在校生来说,一个好的「项目经历」甚至可以等同于工作经验。 可以说,把项目经历写好了,求职就通过了一半。

而在项目的描述中,最看重的就有三点。

  • 这个项目跟应聘的职位之间的关联性。

  • 这个项目的工程量或知名度。

  • 这个项目是否有一些数据,证明你做到了,并且让你有所收获。

这些项目描述,都是需要证据的,而最好的证据就是你的GitHub代码链接,或者是你这个项目的一个线上版本——有可能是一个网站,或是一个demo。只要有这样的效果, 对于审核简历的人来说,他一眼就能看出来这个项目的技术水平,是一个很大的加分项。

在这里,我们准备了这20个Python项目,领域包含「Python Web」「Python爬虫」「Python游戏」「Python机器学习」「Python安全」等。如果在求职前缺少项目经验,或是想做些项目提升一下编程能力,都可以选择几个项目好好做一下。 做完后加入一些拓展,放在自己的Github上,一定能给你的简历、面试加分不少。


一、Python 爬虫

Python3 实现火车票查询工具

课程链接:https://www.shiyanlou.com/courses/623

使用 Python3 抓取 12306 网站信息,完成一个火车票查询工具。该项目练习 Python3 基础及网络编程,以及 docopt,requests,prettytable 等库的使用。

项目效果:


高德API+Python解决租房问题

课程链接:https://www.shiyanlou.com/courses/599

使用Python脚本爬取某租房网站的房源信息,利用高德的 js API 在地图上标出房源地点,找到距离工作地点1小时车程的房源!在项目实现的过程中将熟悉requests、BeautifulSoup、csv等库的简单使用。

项目效果:


给Python3爬虫做一个界面.妹子图网实战

课程链接:https://www.shiyanlou.com/courses/813

一个综合性项目,不但要写爬虫抓取妹子图网的图片,还要用 PyQt 给爬虫程序做一个交互界面。完成后不管是效果还是实用性都是满分!话不多说,下面开车~滴滴滴~

项目效果:

更多爬虫课程:

  • python 网站信息爬虫:https://www.shiyanlou.com/courses/969

  • Python3 实现淘女郎照片爬虫:https://www.shiyanlou.com/courses/595

  • 基于 Flask 及爬虫实现微信娱乐机器人:https://www.shiyanlou.com/courses/581

  • python 二手房信息爬取与数据呈现:https://www.shiyanlou.com/courses/869


二、python人工智能

NBA常规赛结果预测:利用Python进行比赛数据分析

课程链接:https://www.shiyanlou.com/courses/782

本课程将利用NBA在2015~2016年的比赛统计数据进行回归模型建立,最终在今年2016~2017的常规赛中预测每场比赛的输赢情况。

项目效果:


使用 Python 实现深度神经网络(会员)

课程链接:https://www.shiyanlou.com/courses/814

本课程手把手教你使用 Python 实现一个深度神经网络,让你在实际动手的过程中理解深度学习的一些基本原理,带你真正入门深度学习。

课程列表:


基于卷积神经网络实现图片风格的迁移(仿Prisma)

课程链接:https://www.shiyanlou.com/courses/861

教计算机学习梵高作画——本课程基于卷积神经网络,使用Caffe框架,探讨图片风格迁移背后的算法原理,手把手教你实现和Prisma一样的功能。

项目效果:


更多人工智能课程:

  • 深度学习初探——入门DL主流框架:https://www.shiyanlou.com/courses/744

  • Python3 色情图片识别:https://www.shiyanlou.com/courses/589

  • 神经网络实现人脸识别任务:https://www.shiyanlou.com/courses/707

  • 人机对战初体验:Python基于Pygame实现四子棋游戏:https://www.shiyanlou.com/courses/746

  • 利用TensorFlow进行自然语言处理:https://www.shiyanlou.com/courses/1026

  • 基于TensorFlow实现卷积神经网络:https://www.shiyanlou.com/courses/893

  • 基于SVM的猫咪图片识别器:https://www.shiyanlou.com/courses/794

  • 使用卷积神经网络进行图片分类:https://www.shiyanlou.com/courses/820


三、Python Web

Python Flask Web框架

课程链接:https://www.shiyanlou.com/courses/29

本课程使用Python Flask Web框架来创建简单的博客,涉及环境安装,运行调试,静态文件,渲染模板,数据的请求接收以及重定向,响应和会话。适合有一定编程基础,与对于linux有一定了解,想更加熟悉和巩固python的同学。

课程列表:

Django 搭建简易博客

课程链接:https://www.shiyanlou.com/courses/487

本教程介绍如何一步步使用 Django 开发一个简单的博客 Web应用,涉及 Django Web开发,MVC,Template等知识点,适用于有 Python 和 Django 基础的同学。

课程列表:

基于 Flask 与 MySQL 实现番剧推荐系统(会员)

课程链接:https://www.shiyanlou.com/courses/633

本课程是基于 Python 的 Flask 框架和 MySQL 实现的简单的番剧推荐系统。在本课程中我们将学到如何用 Python 连接 MySQL 数据库,如何查询和展示数据及设计推荐算法等知识。


更多PythonWeb课程:

  • Flask + VueJS 全栈 Web 开发实战:https://www.shiyanlou.com/courses/878

  • Django打造文件分享系统:https://www.shiyanlou.com/courses/993

  • 利用Flask-AppBuilder 快速构建Web后台管理应用:https://www.shiyanlou.com/courses/870

  • Python3 基于 Flask 框架搭建个人博客:https://www.shiyanlou.com/courses/1047

  • 基于Flask/RethinkDB实现TODO List:https://www.shiyanlou.com/courses/359

  • Flask 实现简单聊天室:https://www.shiyanlou.com/courses/81

  • Python 实现 Redis 异步客户端:https://www.shiyanlou.com/courses/518


四、Python 数据分析

使用逻辑回归预测IPO市场

课程链接:https://www.shiyanlou.com/courses/1034

在20世纪90年代末,获得了对的IPO(首次公开募股)就像赢得彩票一样。在本次实验中我们通过对一系列数据进行清洗、建模、分类,来获一个可以预测IPO市场的简单模型。本课程源自异步社区的《Python机器学习实践指南》第4章,感谢异步社区授权实验楼发布。


Spark 机器学习之电影推荐系统(会员)

课程链接:https://www.shiyanlou.com/courses/831

MLlib 是运行在 Spark 上一个机器学习算法库,借助 Spark 的内存计算,可以使机器学习的模型计算时间大大缩短。本节课基于协同过滤算法实现简易电影推荐。


Python实现从excel读取数据并绘制成精美图像(会员)

课程链接:https://www.shiyanlou.com/courses/791

这个世界从古至今一直是一个看颜值的世界。对于我们作报告,写文章时使用的图片,也是一样的。一图胜千言,一张制作精美的图片,不仅能展示大量的信息,更能体现绘图者的水平,审美,与态度。本课程实现使用 pythonexcel读取数据,并使用 matplotlib绘制成二维图像。这一过程中,将通过一系列操作来美化图像

项目效果:

更多python数据分析课程:

  • Python 数据分析入门与进阶 :https://www.shiyanlou.com/courses/764

  • eBay 在线拍卖数据分析:https://www.shiyanlou.com/courses/714

  • Twitter数据情感分析:https://www.shiyanlou.com/courses/722

  • Kaggle 项目实战--回归预测波士顿房价 :https://www.shiyanlou.com/courses/1010

  • Pandas 使用教程:https://www.shiyanlou.com/courses/906

  • NumPy 使用教程:https://www.shiyanlou.com/courses/912


五、Python 小应用

Python 图片转字符画

课程链接:https://www.shiyanlou.com/courses/370

本实验用 50 行 Python 代码完成图片转字符画小工具。通过本实验将学习到 Linux 命令行操作,Python 基础,pillow 库的使用,argparse 库的使用。本课程难度简单,属于 Python 中基础课程。课程教学视频:https://www.bilibili.com/video/av13422372/

项目效果:


Python3 图片隐写术(会员)

课程链接:https://www.shiyanlou.com/courses/651

通过Python3实现将关键信息隐藏在图片的效果,主要目的是为了不让预期接收者以外的人知晓传递的内容。与电视剧中使用特殊墨水传递信息一样,表面看就是一张什么都没写的白纸,实则暗藏着重要信息。

项目效果:


使用 Python 解数学方程(会员)

课程链接:https://www.shiyanlou.com/courses/729

本课程将介绍如何用python解决数学题。 说到数学题,相信大家都不陌生,从小学到大学都跟数学打交道。 其中初中的方程组,高中的二次曲线,大学的微积分最为头疼,今天我们将使用python 来解决方程组问题,微积分问题,矩阵化简。

项目效果:


更多Python 小程序:

  • Python文本解析器:https://www.shiyanlou.com/courses/70

  • python 实现简单计算器: https://www.shiyanlou.com/courses/965

  • Python 实现英文新闻摘要自动提取:https://www.shiyanlou.com/courses/741

  • Python 3 实现 Markdown 解析器:https://www.shiyanlou.com/courses/708

  • 使用 Python 创建照片马赛克:https://www.shiyanlou.com/courses/1041

  • 使用Python定制词云:https://www.shiyanlou.com/courses/756

  • 利用微信API将你的微信变为聊天机器人:https://www.shiyanlou.com/courses/684

六、python安全

Python 破解验证码

课程链接:https://www.shiyanlou.com/courses/364

本课程通过一个简单的例子来实现破解验证码。从中我们可以学习到 Python 基本知识,PIL 模块的使用和破解验证码的原理。本项目难度中等。适合有 Python 基础的人群进行学习。

Python开发木马程序(会员)

课程链接:https://www.shiyanlou.com/courses/853

本次实验将指导如何使用Python开发具有记录键盘输入、屏幕截图、网络传输等功能的黑客木马程序,详细讲解了相关的linux设备文件的原理,缓冲区处理,多进程和网络编程等相关知识。

Python3基于Scapy实现DDos(会员)

课程链接:https://www.shiyanlou.com/courses/683

本次实验通过使用Scapy来实现SYN洪水攻击,并基于SYN洪水攻击来实现DDOS。并详细讲解了Scapy库的基本用法,以及SYN洪水攻击和DDOS攻击的基础知识!

更多人工智能课程:

  • Python实现Zip文件的暴力破解:https://www.shiyanlou.com/courses/636

  • Python打造漏洞扫描器:https://www.shiyanlou.com/courses/761

  • Python3 实现可控制肉鸡的反向Shell:https://www.shiyanlou.com/courses/594

  • Python 实现密码强度检测器:https://www.shiyanlou.com/courses/712

七、Python 游戏

200行Python代码实现2048

课程链接:https://www.shiyanlou.com/courses/368

本实验仅用200行的 python 代码完成2048小游戏的编写。通过本实验将学习 Python 基本知识,状态机的概念,以及编写 python 游戏的步骤。为 Python 的进阶课程,需要用户具有 Python 的语法基础。

项目效果:

pygame开发打飞机游戏

课程链接:https://www.shiyanlou.com/courses/49

使用Python快速开发一款PC端玩耍的微信打飞机游戏,基于pygame实现。本课程源自Kill-Console博客:http://www.cnblogs.com/dukeleo/p/3339780.html。本课程难度中等,属于python中等的项目课程,需要有 pygame 和 Python 基础。可以在之前的课程当中先学习一些基础的 pygame 知识然后再学习本课程。

项目效果:

基于Pygame开发贪吃蛇和俄罗斯方块(会员)

课程链接:https://www.shiyanlou.com/courses/940

本课程基于Pygame开发贪吃蛇和俄罗斯方块,通过逐步学习Pygame基础知识,到从零开始实现游戏开发,课程难度由浅入深,内容通俗易懂,确保同学们能够很好的掌握和理解。

项目效果:

更多Python 小游戏:

  • python 实现推箱子游戏:https://www.shiyanlou.com/courses/968

  • Python3 实现推理游戏Bagels:https://www.shiyanlou.com/courses/1043

  • Python 实现康威生命游戏:https://www.shiyanlou.com/courses/769

  • 数独游戏的Python实现与破解:https://www.shiyanlou.com/courses/728


除此之外,还有更多有趣的Python在实验楼等着你,点击“阅读原文”或进入“实验楼小程序”即可找到。




  


点击进入【实验楼小程序】

随时随地,学习编程


推荐阅读:



能不用事务就尽量别用 - CSDN博客

$
0
0

概述


以前在公司里,有个牛人对俺说:

事务就是个垃圾,能不用就尽量不用。

当时我刚从传统行业切换到互联网行业,对这个牛人说的这句话是嗤之以鼻的,怎么可能不用事务呢?后来随着开发了多个高并发应用后,才知道这个牛人说的是对的。下面说两个亲身经历的案例来说明这个问题。


库存扣减接口(写事务)


当时我们有个业务,在购物车阶段的时候,就开始占用库存了,这个库存占用接口的流量非常大。当时我开发完这个接口后,测试人员的压测结果是

2500/TPS

我觉得低了,就开始怀疑测试人员是否不够专业,测试用的服务端应用服务器和数据库是否不给力,发起请求的压测客户端机器是否给力,jmeter用的是否正确。全部检查完后,发现测试手法是完全OK的。

于是仔细的检查代码,也没发现啥。后来灵光一闪,想起那个牛人说过得的话,就尝试把事务去掉。我们用的是Spring的 @Transactional(rollbackFor = Exception.class)的开启事务的。我把这行代码删除掉后,压测结果是:

3700/QPS

提高了蛮多,这个压测结果已经能满足线上流量要求了。开了事务为啥性能差这么多,底层原因目前还没仔细去研究。但是从压测结果来看,去掉事务后,性能有提升。

这里部分网友可能有疑问,如果线程操作的是多张表的写入和更新操作,如果不用事务的话,一致性怎么保证? 好问题。当时我是使用 逻辑回滚的手段来保证数据的一致性,是需要自己写代码进行数据回滚的。因为当时要操作的表只有两张,代码写起来还好些。

如果很多张表的话,用逻辑回滚就比较麻烦了。对于这种很多张表的,而流量又不是很大那种的话,还是使用事务方便一些。


读接口(读事务)


当时有个输出商品的接口,读取逻辑如下:

先从memcache读取,如果没有读取到,则从DB读取。

开发完这个接口后,做压测时,我先预热一些数据到memcache上,想看看memcache的读取性能。压测结果不太理想。当时找了很久都没找到原因,后来我用top命令观察了一下,发现只要一压测,应用还是会跟mysql有交互。理论上是不会的,因为数据都在memcache上,一旦命中就走了,不会去读取数据库。

最后面发现原来用了Spring的

@Transactional(readOnly = true)

只要你在接口上面加了这个注解,Spring还是会跟Mysql打交道的。并发的量一旦大了,就开始影响性能了。

GitHub - yzhang921/CBoard: An easy to use, self-service open BI reporting and BI dashboard platform.

$
0
0

Quick start

Quick Start from docker

We provide a docker image build on centos6 with a sample dataset in it.

docker pull peterzhang921/cboard:0.4.1
docker run --rm -itd --name=cboard -p 8026:8080 --privileged=true peterzhang921/cboard:0.4.1

# after docker container is start then attach into it and start tomcat server
docker attach cboard
/opt/apache-tomcat/bin/startup.sh

# wait after server successfully started
tail -f /opt/apache-tomcat/logs/catalina.out

Acccess cboard with url  http://docker-hostip:8026/cboard

  • username: admin , password: root123
  • There is no prepared charts and dashboard in it
  • Meta data of CBoard is stotred in embedded DB H2 with file storage, user can change or add your own configuration by yourself then build project and docker image again
    • how to rebuild docker
    # use configuration files in h2 folder, use env parameter then all the files in h2 folder will overwrite same files in resource folder
    maven clean package -Denv=h2
    # build docker image
    docker build --network=host -t cboard .

Build project by yourself

Prerequisite

Before the start, make sure you have setup environment:

  • JDK version above 1.8
  • MySQL
  • Maven
  • Tomcat
  • Phantomjs (for export dashbaord)
  • Mail Servier

How to build project

  • 1 Download or git clone project
git clone https://github.com/yzhang921/CBoard.git
  • 2 Install metadata of CBoard (take MySQL database as example)

    • 2.1 Install demo metadata and sample foodmart db
      • Download  cboard_demo & foodmart
      • Enter into the path of these two files
      • Use MySQL Command Line tool login and execute
          source cboard_demo.sql
          source foodmart.sql
      • After success completed, check if cboard_demo2 and foodmart2 databases have been created
    • 2.2 You can alternative choose start from a blank setting
          -- CREATE DATEBASE cboard;
          Execute ddl to create metadata table: sql/mysql/mysql.sql
  • 3 Modify metadata connection properties file according to your db environment

    CBoard/src/main/resources/config.properties
    validationQuery=SELECT 1
    jdbc_url=jdbc:mysql://localhost:3306/cboard # set to your metadata db connection url, if you are using demo db, change db name to cboard_demo2
    jdbc_username=root # change to the username/password of your db
    jdbc_password=111111
    
    # Service configuration
    dataprovider.resultLimit=300000
    admin_user_id=1
    phantomjs_path=D:/phantomjs-2.1.1-windows/bin/phantomjs.exe  # change to the install path of your phantomjs
    web_port=8026 #
    web_context=  # web context name of your app, can be blank for ROOT deploy
    
    # configuration of Mail service
    mail.smtp.host=127.0.0.1
    mail.smtp.port=8825
    mail.smtp.from=test@test.com
    #mail.smtp.username=test@test.com
    #mail.smtp.password=111111
    #mail.smtp.ssl.checkserveridentity=false
    
    # Cache Properties if you wanna use redis as cache layer
    cache.redis.hostName=127.0.0.1
    cache.redis.port=6379
  • 4 Comile and package project with Maven

    cd root path of CBoard
    # Install SQLServer JDBC Driver into your local respository
    mvn install:install-file -Dfile=lib/sqljdbc4-4.0.jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0 -Dpackaging=jar
    mvn clean package
  • 5 Deploy war to Tomcat application

  • Copy CBoard/target/cboard.war to webapp folder of Tomcat and rename cboard.war would be better to change name to ROOT.war
  • Start up Tomcat
  • 6 Access CBoard
http://_yourserverip_:8080
Default login username and passwor: admin/root123
  • 7 For Demo DB user, check and test the source of foodmart 

从Uber微服务看最佳实践如何炼成?

$
0
0

导读:Uber成长非常迅速,工程师团队快速扩充,据说Uber有2000名工程师,8000个代码仓库,部署了1000多个微服务。微服务架构是Uber应对技术团队快速增长,功能快速上线很出色的解决方案。本文偏向微服务的入门篇,以Uber微服务为例,进行了深入浅出的讲解。

微服务特性

对于微服务没有适当的定义,你可以说它是一个框架,由小型的、独立的可部署的服务组成,执行不同的操作。

微服务专注于单个业务领域,可以作为完全独立的可部署服务,并在不同的技术栈上实现它们。

单体架构和微服务架构区别

在使用微服务构建自己的应用程序之前,需要清楚地了解应用程序的范围和功能。

微服务特性

  • 解耦 - 系统内的服务在很大程度上是解耦的。因此,整个应用程序可以轻松构建,更改和缩放
  • 组件化 - 微服务被视为独立的组件,可以轻松替换和升级
  • 业务能力 - 微服务非常简单,专注于单一功能
  • 自治 - 开发人员和团队可以独立工作,从而提高速度
  • 持续交付 - 通过软件创建,测试和批准的系统自动化,允许软件的频繁发布
  • 责任 - 微服务不像项目那样专注于应用程序。相反,他们将应用程序视为他们负责的产品
  • 分散治理 - 重点在于使用正确的工具来完成正确的作业。这意味着没有标准化模式或任何技术模式。开发人员可以自由选择最有用的工具来解决他们的问题
  • 敏捷 - 微服务支持敏捷开发。任何新功能都可以快速开发并再次丢弃

微服务优势

  • 独立开发 - 所有微服务都可以根据各自的功能轻松开发
  • 独立部署 - 基于各自的服务,可以单独部署在任何应用程序中
  • 故障隔离 - 即使应用程序的一项服务不起作用,系统仍会继续运行
  • 混合技术堆栈 - 可以使用不同的语言和技术来构建同一应用程序的不同服务
  • 细粒度缩放 - 各个组件可根据需要进行扩展,无需将所有组件扩展到一起

微服务设计最佳实践

在当今世界,复杂性已经渗透到产品中。微服务架构能够更好地保持团队的规模和功能。

以下是微服务设计的最佳实践:

现在,让我们来看一个用例来更好地理解微服务。

案例:购物车应用程序

当打开购物车应用程序时,你看到的只是一个网站。但是,在幕后,购物车应用程序有接受支付服务、顾客服务等等。

假设开发人员已经在一个整体框架中进行了创建。如下图:

购物车应用程序的整体框架

所有功能都放在一个代码库中,并在一个底层数据库下。

现在,假设市场上出现了一个新品牌,开发人员希望将这个品牌的所有细节都放在这个应用程序中。

他们不仅要重新为新标签提供服务,还必须重新构建完整的系统并进行相应部署。

为了应对这种挑战,开发人员决定将其应用程序从单体架构转移到微服务。如下图:

购物车应用程序的微服务架构

这意味着开发人员不必创建Web微服务,逻辑微服务或数据库微服务。相反,他们为搜索,推荐,客户服务等创建单独的微服务。

这种应用架构不仅有助于开发人员克服以前架构面临的挑战,还有助于轻松构建,部署和扩展购物车应用程序。

微服务设计指南

  • 作为开发人员,决定构建应用程序时,要将各个域分离,并在功能上明确。
  • 设计的每一个微服务都只专注于应用中的一个服务。
  • 确保设计的应用程序使每个服务都可以单独部署。
  • 确保微服务之间的通信是通过无状态服务器完成的。
  • 每一项服务都可以被推进到更小的服务中,拥有自己的微服务。

在设计微服务时,已经了解了基本的指导方针,现在来了解一下微服务的架构。

微服务架构是如何工作的 ?

一个典型的微服务架构(MSA)应该包括以下组件:

  1. 客户端
  2. 身份提供者
  3. API网关
  4. 消息格式
  5. 数据库
  6. 静态内容
  7. 管理
  8. 服务发现

如下图:

微服务架构

这个架构看起来有点复杂,让我们来简化一下。

1、客户端

架构始于不同类型的客户端,从不同的设备尝试执行各种管理功能,如搜索、构建、配置等。

2、身份提供者

这些来自客户端的请求将传递给身份提供者,这些提供者对客户端的请求进行身份验证,并将请求传递给API网关。然后,请求通过定义良好的API网关与内部服务通信。

3、API网关

由于客户端不直接调用服务,因此API网关作为客户端将请求转发到适当的微服务的切入点。

使用API网关的优点包括:

  • 所有服务都可以在客户端不知情的情况下进行更新。
  • 服务也可以使用非网络友好的消息传递协议。
  • API网关可执行跨切割功能,如提供安全性、负载均衡等。

在接收到客户端的请求后,内部架构由微服务组成,这些微服务通过消息相互通信来处理客户端请求。

4、消息格式

有两种类型的消息通过它们进行通信:

  • 同步消息:在客户端等待服务响应的情况下,微服务通常倾向于使用REST (Representational State Transfer),因为它依赖于无状态、客户端服务器和HTTP协议。这个协议被用作一个分布式环境,每个功能都用一个资源来表示,以执行操作。
  • 异步消息:在客户端不等待服务响应的情况下,微服务通常倾向于使用AMQP、STOMP、MQTT等协议。这些协议在这种类型的通信中使用,因为消息的性质被定义,这些消息在实现之间可以互操作。

下一个问题是,使用微服务的应用程序如何处理数据?

5、数据处理

每个微服务都拥有一个专有数据库来捕获它们的数据并实现相应的业务功能。此外,微服务的数据库只通过其服务API进行更新。参考下图:

微服务处理数据演示

微服务提供的服务被转发到任何支持不同技术栈的进程间通信的远程服务。

6、静态内容

在微服务内部进行通信后,将静态内容部署到基于云的存储服务,通过内容交付网络(CDN)直接将其交付给客户端。

除了上述组件,还有一些其他组件出现在典型的微服务架构中。

7、管理

该组件负责平衡节点上的服务和故障识别。

8、服务发现

用作微服务的指南,以找到它们之间的通信路由,由它维护节点所在的服务列表。

现在来看看这个架构的优缺点,以更好地理解何时使用这种架构。

微服务架构优缺点

微服务架构的优点微服务架构的缺点
自由使用不同的技术增加故障排除难题
每个微服务都关注单一业务能力由于远程呼叫而增加延迟
支持单独的可部署单元增加配置和其他运营工作量
允许频繁的软件发布难以保持交易安全
确保每项服务的安全性很难跟踪各种服务边界的数据
并行开发和部署多个服务服务之间很难移动代码

下面来比较一下UBER之前和现在的架构。

Uber微服务案例

Uber之前的架构

像许多初创公司一样,UBER在开始之初在单一城市运营,为单一产品打造了单体架构。当时有一个代码库似乎被清理了,并解决了UBER的核心业务问题。然而,随着UBER在全球范围内扩张,它们在可扩展性和持续集成方面面临各种各样的问题。

UBER的单体架构

上图描述了UBER之前的架构。

  • 与乘客和司机连接的REST API。
  • 三种不同的适配器与API一起使用,当预定出租车时,执行诸如账单、付款、发送电子邮件/消息等操作。
  • MySQL数据库存储所有数据。

因此,可以发现这里所有的特性,比如乘客管理、计费、通知功能、支付、行程管理和驱动管理都是在一个框架内完成的。

问题陈述

当Uber开始在世界范围扩张时,这种框架引入了各种各样的挑战。以下是一些突出的挑战。

  • 所有的功能都必须重新构建、部署和测试,以更新单一功能。
  • 在单个存储库中修复bug变得非常困难,因为开发人员不得不一次又一次地修改代码。
  • 在全球范围内引入新功能的同时,要将这些特性进行扩展是相当困难的。

解决方案

为了避免此类问题,Uber决定改变自己的架构,效仿亚马逊(Amazon)、Netflix、Twitter等其他超级增长公司。因此,Uber决定将其整体架构拆分为多个代码库,以形成一个微服务架构。

参考下面的图表,看看Uber的微服务架构。

Uber的微服务架构

  • 我们在这里看到的主要变化是引入了API网关,所有的司机和乘客都是通过这个网关连接的。从API网关,所有的内部点都连接在一起,如乘客管理、司机管理、行程管理等。
  • 每个单元是单独的可部署单元,执行单独的功能。例如:如果你想在账单微服务中更改任何内容,那么只需部署账单微服务,而不必部署其他服务。
  • 所有的功能都是单独扩展的,即每个特征之间的相互依赖被移除。

例如,我们都知道,搜索出租车的人数比预订出租车和付款的人要多。这就得到了一个推论:在乘客管理微服务上工作的流程的数量超过了处理支付的流程的数量。

通过这种方式,Uber将其架构从单一业务转移到微服务中获益。

原文链接:

raft算法与paxos算法相比有什么优势,使用场景有什么差异? - 知乎

$
0
0

Raft协议比paxos的优点是 容易理解,容易实现。它强化了leader的地位,把整个协议可以清楚的分割成两个部分,并利用日志的连续性做了一些简化: (1)Leader在时。由Leader向Follower同步日志 (2)Leader挂掉了,选一个新Leader,Leader选举算法。

但是本质上来说,它容易的地方在于流程清晰,描述更清晰,关键之处都给出了伪代码级别的描述,可以直接用于实现,而paxos最初的描述是针对非常理论的一致性问题,真正能应用于工程实现的mulit-paxos,Lamport老爷爷就提了个大概,之后也有人尝试对multi-paxos做出更为完整详细的描述,但是每个人描述的都不大一样。

Zookeeper的ZAB,Viewstamped Replication(VR),raft,multi-paxos,这些都可以被称之为Leader-based一致性协议。不同的是,multi-paxos leader是作为对经典paxos的优化而提出,通过选择一个proposer作为leader降低多个proposer引起冲突的频率,合并阶段一从而将一次决议的平均消息代价缩小到最优的两次,实际上就算有多个leader存在,算法还是安全的,只是退化为经典的paxos算法。而经典的paxos,从一个提案被提出到被接受分为两个阶段,第一个阶段去询问值,第二阶段根据询问的结果提出值。这两个阶段是无法分割的,两个阶段的每个细节都是精心设计的,相互关联,共同保障了协议的一致性。而VR,ZAB,Raft这些强调 合法leader的唯一性协议,它们直接从leader的角度描述协议的流程,也从leader的角度出发论证正确性。 但是实际上它们使用了和Paxos完全一样的原理来保证协议的安全性,当同时存在多个节点同时尝试成为leader或者不知一个节点认为自己时leader时,本质上它们和经典Paxos中多个proposer并存的情形没什么不同。

Paxos和raft都是一旦一个entries(raft协议叫日志,paxos叫提案,叫法而已)得到多数派的赞成,这个entries就会定下来,不丢失,值不更改,最终所有节点都会赞成它。Paxos中称为提案被决定,Raft,ZAB,VR称为日志被提交,这只是说法问题 。一个日志一旦被提交(或者决定),就不会丢失,也不可能更改,这一点这4个协议都是一致的Multi-paxos和Raft都用一个数字来标识leader的合法性,multi-paxos中叫proposer-id,Raft叫term,意义是一样的, multi-paxos proposer-id最大的Leader提出的决议才是有效的,raft协议中term最大的leader才是合法的。实际上raft协议在leader选举阶段,由于老leader可能也还存活,也会存在不只一个leader的情形, 只是不存在term一样的两个leader,因为选举算法要求leader得到同一个term的多数派的同意,同时赞同的成员会承诺不接受term更小的任何消息。这样可以根据term大小来区分谁是合法的leader。Multi-paxos的区分leader的合法性策略其实是一样的,谁的proproser-id大谁合法,而proposer-id是唯一的。 因此它们其实在同一个时刻,都只会存在一个合法的leader。同时raft协议的Leader选举算法,新选举出的Leader已经拥有全部的可以被提交的日志,而multi-paxos择不需要保证这一点,这也意味multi-paxos需要额外的流程从其它节点获取已经被提交的日志。因此raft协议日志可以简单的只从leader流向follower在raft协议中,而multi-paxos则需要额外的流程补全已提交的日志。 需要注意的是日志可以被提交和日志已经被提交是两个概念,它们的区别就像是我前方有块石头和我得知我前方有块石头。但是实际上,Raft和multi-Paxos一旦日志可以被提交,就能会保证不丢失,multi-paxos天然保证了这一点, 这也是为什么新leader对于尚未被确认已经提交的日志需要重新执行经典paxos的阶段一,来补全可能缺失的已经被提交的日志,Raft协议通过强制新Leader首先提交一个本term的no-op 日志,配合前面提到的Leader选举算法所保证的性质,确保了这一点。一条日志一旦被多数派的节点写入本地日志文件中,就可以被提交,但是leader只有得知这一点后,才会真正commit这条日志,此时日志才是已经被提交的。

Raft协议强调日志的连续性,multi-paxos则允许日志有空洞日志的连续性蕴含了这样一条性质:如果两个不同节点上相同序号的日志,只要term相同,那么这两条日志必然相同,且这和这之前的日志必然也相同的,这使得leader想follower同步日志时,比对日志非常的快速和方便;同时Raft协议中 日志的commit(提交)也是连续的,一条日志被提交,代表这条日志之前所有的日志都已被提交,一条日志可以被提交,代表之前所有的日志都可以被提交。日志的连续性使得Raft协议中,知道一个节点的日志情况非常简单,只需要获取它最后一条日志的序号和term。可以举个列子,A,B,C三台机器,C是Leader,term是3,A告诉C它们最后一个日志的序列号都是4,term都是3,那么C就知道A肯定有序列号为1,2,3,4的日志,而且和C中的序列号为1,2,3,4的日志一样,这是raft协议日志的连续性所强调的,好了那么Leader知道日志1,2,3,4已经被多数派(A,C)拥有了,可以提交了。同时,这也保证raft协议在leader选举的时候, 一个多数派里必然存在一个节点拥有全部的已提交的日志,这是由于最后一条被commit的日志,至少被多数派记录,而由于日志的连续性,拥有最后一条commit的日志也就意味着拥有全部的commit日志,即至少有一个多数派拥有所有已commit的日志。并且只需要从一个多数集中选择最后出最后一条日志 term最大且序号最大的节点作为leader,新leader必定是拥有全部已commit的日志(关于这一点的论证,可以通过反证法思考一下,多数集中节点A拥有最后一条已commit的日志,但是B没有,而B当选leader。根据选主的法则只能有两种可能(1)当选而A最后一条日志的term小于B;(2)A最后一条日志的term等于B,但是A的日志少于B。1,2可能嘛?)而对于multi-paxos来说,日志是有空洞的,每个日志需要单独被确认是否可以commit,也可以单独commit。因此当新leader产生后,它只好重新对每个未提交的日志进行确认,已确定它们是否可以被commit,甚至于新leader可能缺失可以被提交的日志,需要通过Paxos阶段一向其它节点学习到缺失的可以被提交的日志,当然这都可以通过向一个多数派询问完成(这个流程存在着很大的优化空间,例如可以将这个流程合并到leader选举阶段,可以将所有日志的确认和学习合并到一轮消息中,减少消息数目等)。但是无论是Raft还是multi-paxos, 新leader对于那些未提交的日志,都需要重新提交,不能随意覆写,因为两者都无法判定这些未提交的日志是否已经被之前的leader提交了。所以本质上,两者是一样的。一个日志被多数派拥有,那么它就可以被提交,但是Leader需要通过某种方式得知这一点,同时为了已经被提交的日志不被新leader覆写,新leader需要拥有所有已经被提交的日志(或者说可以被提交,因为有时候并没有办法得知一条可以被提交的日志是否已经被提交,例如当只有老leader提交了该日志,并返回客户端成功,然而老leader挂了),之后才能正常工作,并且需要重新提交所有未commit的日志 。两者的区别在于Leader确认提交和获取所有可以被提交日志的方式上,而方式上的区别又是由于是日志是否连续造成的,Raft协议利用日志连续性,简化了这个过程

在Raft和multi-paxos协议确保安全性的原理上,更进一步的说,所有的凡是 满足 集群中存活的节点数还能构成一个多数派,一致性就能满足的算法,raft协议,paxos,zab,viewstamp都是利用了 同一个性质:两个多数派集合之间存在一个公共成员。对于一致性协议来说,一旦一个变量的值被确定,那么这个变量的值应该是唯一的,不再更改的。Raft,paoxos等协议,对于一个变量v来说,一个由节点n1提出的值a只有被一个多数集q1认可并记录后,才会正式令v=a,如果另一个节点n2想要修改变量v的值为b,也需要一个多数集q2的认可,而q1和q2必然至少有一个共同的成员p,节点p已经记录了v=a。 因此只需要通过增加一些约束,让p能够告诉节点n2这个事实:v=a,使得n2放弃自己的提议,或者让节点p拒绝节点n2想要赋予v的值为b这个行为,都可以确保变量v的一致性不被破坏。这个思想对于这个四个协议来说都是一样的, 4个协议都使用一个唯一的整数作为标识符来标明leader的合法性,paxos叫做proposer-id,ZAB叫epoch,VR叫view,raft叫term。把leader看做是想要赋予变量v某个值的节点n1,n2,上面提到的情形中,如果n2是目前的合法leader,那么n2需要知道v=a这个事实,对于raft来说就是选择n2是已经记录了v=a的节点,对于multi-paxos来说,就是重新确认下v的值。如果n1是目前的合法leader,n2是老的leader,p就会根据leader的标识符拒绝掉n2的提案,n2的提案会由于得不到一个多数派的接受而失效。 最直接的从理论上阐明这个原理的是经典的paxos算法,关于这个原理更具体的阐述可以看看我在 如何浅显易懂地解说 Paxos 的算法?下的回答。所以确实在一定程度上可以视raft,ZAB,VR都是paxos算法的一种改进,一种简化,一种优化,一种具象化。Lamport老人家还是叼叼叼。。。。。。。不过值得一提的是,ZAB和raft作者确实是受了paxos很多启发, VR是几乎同时独立于paxos提出的。


Raft容易实现在于它的描述是非常规范的,包括了所有的实现细节。如上面的人说的有如伪代码。而paxos的描述侧重于理论,工程实现按照谷歌chubby论文中的说话,大家从paxos出现,写着写着,处理了n多实际中的细节之后,已经变成另外一个算法了,这时候正确性已经无法得到理论的保证。所以它的实现非常难,因为一致性协议实非常精妙的。小细节上没考虑好,整个协议的一致性就崩溃了, 而发现并更正细节上的错误在没有详尽的现成的参考的情况下是困难的,这需要对协议很深的理解。而且在Raft协议的博士论文CONSENSUS: BRIDGING THEORY AND PRACTICE,两位作者手把手事无巨细的教你如何用raft协议构建一个复制状态机。我表示智商正常的大学生,都能看懂。我相信在未来一致性现在被提起来,肯定不是现在这样,大部分人觉得好难啊,实现更难。。。。应该会成为一种常用技术。

python使用beutifulsoup来爬虫的基本套路

$
0
0
使用python3,比如爬kugo的榜单:

import requests
from bs4 import BeautifulSoup
import time

headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
}

def get_info(url):
    wb_data = requests.get(url,headers=headers)
    soup = BeautifulSoup(wb_data.text,'lxml')
    ranks = soup.select('span.pc_temp_num')
    titles = soup.select('div.pc_temp_songlist > ul > li > a')
    times = soup.select('span.pc_temp_tips_r > span')
    for rank,title,time in zip(ranks,titles,times):
        data = {'rank':rank.get_text().strip(),'singer':title.get_text().split('-')[0],'song':title.get_text().split('-')[0],'time':time.get_text().strip()
        }
        print(data)

if __name__ == '__main__':
    urls = ['http://www.kugou.com/yy/rank/home/{}-8888.html'.format(str(i)) for i in range(1,2)]
    for url in urls:
        get_info(url)
        time.sleep(5)


  在上面的代码中 from bs4 import BeautifulSoup首先导入;
然后设置headers,
然后   soup = BeautifulSoup(wb_data.text,'lxml') 中,调用BeautifulSoup,
设置lxml解析器;
然后在
ranks = soup.select('span.pc_temp_num')
    titles = soup.select('div.pc_temp_songlist > ul > li > a')
这些,XPATH用CHROME浏览器的检查功能,查看下就可以了;
然后一个循环,把数据打印出来,注意其中用strip去掉空格;
然后
urls = ['http://www.kugou.com/yy/rank/home/{}-8888.html'.format(str(i)) for i in range(1,2)]
是python中很有特色的语法,设置一个URL的模板,其中{}就是要用format中的内容去替换的;


已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



Java 虚拟机 7:内存分配原则

$
0
0

前言

对象的内存分配,往大的方向上讲,就是在堆上分配,少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节决定于当前使用的是哪种垃圾收集器组合,当然还有虚拟机中与内存相关的参数。垃圾收集器组合一般就是Serial+Serial Old和Parallel+Serial Old,前者是Client模式下的默认垃圾收集器组合,后者是Server模式下的默认垃圾收集器组合,文章使用对比学习法对比Client模式下和Server模式下同一条对象分配原则有什么区别。

TLAB

首先讲讲什么是TLAB。内存分配的动作,可以按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。哪个线程需要分配内存,就在哪个线程的TLAB上分配。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。这么做的目的之一,也是为了并发创建一个对象时,保证创建对象的线程安全性。TLAB比较小,直接在TLAB上分配内存的方式称为快速分配方式,而TLAB大小不够,导致内存被分配在Eden区的内存分配方式称为慢速分配方式。

对象优先分配在Eden区上

上面讲了不同的垃圾收集器组合对于内存分配规则是有影响的,看下影响在什么地方并解释一下原因,虚拟机参数为“-verbose:gc -XX:+PrintGCDetails -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8”,即10M新生代,10M老年代,10M新生代中8M的Eden区,两个Survivor区各1M。代码都是同一段

public class EdenAllocationTest
{
    private static final int _1MB = 1024 * 1024;
    public static void main(String[] args)
    {
        byte[] allocation1 = new byte[2 * _1MB];
        byte[] allocation2 = new byte[2 * _1MB];
        byte[] allocation3 = new byte[2 * _1MB];
        byte[] allocation4 = new byte[4 * _1MB];
    }
}

Client模式下

[GC [DefNew: 6487K->194K(9216K), 0.0042856 secs] 6487K->6338K(19456K), 0.0043281 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 9216K, used 4454K [0x0000000005180000, 0x0000000005b80000, 0x0000000005b80000)
  eden space 8192K,  52% used [0x0000000005180000, 0x00000000055a9018, 0x0000000005980000)
  from space 1024K,  18% used [0x0000000005a80000, 0x0000000005ab0810, 0x0000000005b80000)
  to   space 1024K,   0% used [0x0000000005980000, 0x0000000005980000, 0x0000000005a80000)
 tenured generation   total 10240K, used 6144K [0x0000000005b80000, 0x0000000006580000, 0x0000000006580000)
   the space 10240K,  60% used [0x0000000005b80000, 0x0000000006180048, 0x0000000006180200, 0x0000000006580000)
 compacting perm gen  total 21248K, used 2982K [0x0000000006580000, 0x0000000007a40000, 0x000000000b980000)
   the space 21248K,  14% used [0x0000000006580000, 0x0000000006869890, 0x0000000006869a00, 0x0000000007a40000)
No shared spaces configured.

Server模式下

Heap
 PSYoungGen      total 9216K, used 6651K [0x000000000af20000, 0x000000000b920000, 0x000000000b920000)
  eden space 8192K, 81% used [0x000000000af20000,0x000000000b59ef70,0x000000000b720000)
  from space 1024K, 0% used [0x000000000b820000,0x000000000b820000,0x000000000b920000)
  to   space 1024K, 0% used [0x000000000b720000,0x000000000b720000,0x000000000b820000)
 PSOldGen        total 10240K, used 4096K [0x000000000a520000, 0x000000000af20000, 0x000000000af20000)
  object space 10240K, 40% used [0x000000000a520000,0x000000000a920018,0x000000000af20000)
 PSPermGen       total 21248K, used 2972K [0x0000000005120000, 0x00000000065e0000, 0x000000000a520000)
  object space 21248K, 13% used [0x0000000005120000,0x0000000005407388,0x00000000065e0000)

看到在 Client模式下,最后分配的4M在新生代中,先分配的6M在老年代中;在Server模式下,最后分配的4M在老年代中,先分配的6M在新生代中。说明不同的垃圾收集器组合对于对象的分配是有影响的。讲下两者差别的原因:

1、Client模式下,新生代分配了6M,虚拟机在GC前有6487K,比6M也就是6144K多,多主要是因为TLAB和EdenAllocationTest这个对象占的空间,TLAB可以通过“-XX:+PrintTLAB”这个虚拟机参数来查看大小。OK,6M多了,然后来了一个4M的,Eden+一个Survivor总共就9M不够分配了,这时候就会触发一次Minor GC。但是触发Minor GC也没用,因为allocation1、allocation2、allocation3三个引用还存在,另一块1M的Survivor也不够放下这6M,那么这次Minor GC的效果其实是通过分配担保机制将这6M的内容转入老年代中。然后再来一个4M的,由于此时Minor GC之后新生代只剩下了194K了,够分配了,所以4M顺利进入新生代。

2、Server模式下,前面都一样,但是在GC的时候有一点区别。在GC前还会进行一次判断,如果要分配的内存>=Eden区大小的一半,那么会直接把要分配的内存放入老年代中。要分配4M,Eden区8M,刚好一半,而且老年代10M,够分配,所以4M就直接进入老年代去了。为了验证一下结论,我们把3个2M之后分配的4M改为3M看一下

public class EdenAllocationTest
{
    private static final int _1MB = 1024 * 1024;
    public static void main(String[] args)
    {
        byte[] allocation1 = new byte[2 * _1MB];
        byte[] allocation2 = new byte[2 * _1MB];
        byte[] allocation3 = new byte[2 * _1MB];
        byte[] allocation4 = new byte[3 * _1MB];
    }
}

运行结果为

[GC [PSYoungGen: 6487K->352K(9216K)] 6487K->6496K(19456K), 0.0035661 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC [PSYoungGen: 352K->0K(9216K)] [PSOldGen: 6144K->6338K(10240K)] 6496K->6338K(19456K) [PSPermGen: 2941K->2941K(21248K)], 0.0035258 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 9216K, used 3236K [0x000000000af40000, 0x000000000b940000, 0x000000000b940000)
  eden space 8192K, 39% used [0x000000000af40000,0x000000000b269018,0x000000000b740000)
  from space 1024K, 0% used [0x000000000b740000,0x000000000b740000,0x000000000b840000)
  to   space 1024K, 0% used [0x000000000b840000,0x000000000b840000,0x000000000b940000)
 PSOldGen        total 10240K, used 6338K [0x000000000a540000, 0x000000000af40000, 0x000000000af40000)
  object space 10240K, 61% used [0x000000000a540000,0x000000000ab70858,0x000000000af40000)
 PSPermGen       total 21248K, used 2982K [0x0000000005140000, 0x0000000006600000, 0x000000000a540000)
  object space 21248K, 14% used [0x0000000005140000,0x0000000005429890,0x0000000006600000)

看到3M在新生代中,6M通过分配担保机制进入老年代了。

大对象直接进入老年代

虚拟机参数为“-XX:+PrintGCDetails -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728”,最后那个参数表示大于这个设置值的对象直接在老年代中分配,这样做的目的是为了避免在Eden区和两个Survivor区之间发生大量的内存复制。测试代码为

public class OldTest
{
    private static final int _1MB = 1024 * 1024;
    public static void main(String[] args)
    {
         byte[] allocation = new byte[4 * _1MB];
    }
}

Client模式下

Heap
 def new generation   total 9216K, used 507K [0x0000000005140000, 0x0000000005b40000, 0x0000000005b40000)
  eden space 8192K,   6% used [0x0000000005140000, 0x00000000051bef28, 0x0000000005940000)
  from space 1024K,   0% used [0x0000000005940000, 0x0000000005940000, 0x0000000005a40000)
  to   space 1024K,   0% used [0x0000000005a40000, 0x0000000005a40000, 0x0000000005b40000)
 tenured generation   total 10240K, used 4096K [0x0000000005b40000, 0x0000000006540000, 0x0000000006540000)
   the space 10240K,  40% used [0x0000000005b40000, 0x0000000005f40018, 0x0000000005f40200, 0x0000000006540000)
 compacting perm gen  total 21248K, used 2972K [0x0000000006540000, 0x0000000007a00000, 0x000000000b940000)
   the space 21248K,  13% used [0x0000000006540000, 0x00000000068272a0, 0x0000000006827400, 0x0000000007a00000)
No shared spaces configured.

Server模式下

Heap
 PSYoungGen      total 9216K, used 4603K [0x000000000afc0000, 0x000000000b9c0000, 0x000000000b9c0000)
  eden space 8192K, 56% used [0x000000000afc0000,0x000000000b43ef40,0x000000000b7c0000)
  from space 1024K, 0% used [0x000000000b8c0000,0x000000000b8c0000,0x000000000b9c0000)
  to   space 1024K, 0% used [0x000000000b7c0000,0x000000000b7c0000,0x000000000b8c0000)
 PSOldGen        total 10240K, used 0K [0x000000000a5c0000, 0x000000000afc0000, 0x000000000afc0000)
  object space 10240K, 0% used [0x000000000a5c0000,0x000000000a5c0000,0x000000000afc0000)
 PSPermGen       total 21248K, used 2972K [0x00000000051c0000, 0x0000000006680000, 0x000000000a5c0000)
  object space 21248K, 13% used [0x00000000051c0000,0x00000000054a72a0,0x0000000006680000)

看到 Client模式下4M直接进入了老年代,Server模式下4M还在新生代中。产生这个差别的原因是 “-XX:PretenureSizeThreshold”这个参数对Serial+Serial Old垃圾收集器组合有效而对Parallel+Serial Old垃圾收集器组合无效

其他几条原则

上面列举的原则其实不重要,只是演示罢了,也不需要记住,因为实际过程中我们可能使用的并不是上面的垃圾收集器的组合,可能使用ParNew垃圾收集器,可能使用G1垃圾收集器。场景很多,重要的是要在实际使用的时候有办法知道使用的垃圾收集器对于对象分配有哪些原则,因为理解这些原则才是调优的第一步。下面列举一下对象分配的另外两条原则:

1、长期存活的对象将进入老年代。Eden区中的对象在一次Minor GC后没有被回收,则对象年龄+1,当对象年龄达到“-XX:MaxTenuringThreshold”设置的值的时候,对象就会被晋升到老年代中。

2、Survivor空间中相同年龄的所有对象大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到“-XX:MaxTenuringThreshold”设置要求的年龄。

相关文章

百度李彦宏:中国人对隐私问题没那么敏感

$
0
0

近期, Facebook备受隐私问题困扰,甚至不少名人大咖主动带头掀起了“DeleteFacebook”运动,在国内都引发了不小的关注。国内消费者对于隐私问题的重视程度远不及美国用户,百度CEO李彦宏在近期的活动上也发表了类似的看法:中国人对隐私问题没那么敏感。

2018年3月26日,中国高层发展论坛在北京举行,会上邀请了众多国内外的科技公司大佬参加,包括百度CEO李彦宏、苹果CEO 蒂姆·库克。而李彦宏的在活动中的一些言论瞬间让网友们炸开了锅。

11111111.jpg

在谈及近期热议的数据泄露和隐私问题时,李彦宏表示:

中国人更加开放,或者说对于隐私问题没有那么敏感,如果说他们愿意用隐私来交换便捷性或者效率,很多情况下他们是愿意这么做的。

但同时,李彦宏也强调,百度当下也更加注重隐私问题,而且中国相关的法律也在不断完善,百度同样也会遵循一系列原则。笔者了解到,在今年的两会上,个人信息泄漏泛滥成为网络安全领域焦点话题之一,包括周鸿祎在内的一些两会代表建议通过立法来解决这个问题,建立完善的用户隐私信息保护机制。

46ad26221e33458883df6a6589bd6c6e.jpeg

在国内人工智能和大数据应用方面,百度算是走在前列。李彦宏在现场也表达了对待用户数据的态度:

如果用这个数据会让所有者收益,而且他也愿意让你使用这个数据,我们会使用的,我想这是我们的基本做法。

其实就李彦宏所表达的观点来看,并没有什么太大问题。国内消费者的隐私意识虽然不断在加强,但整体来看并没有像美国用户那么敏感。此番言论一出,显然很多用户并不买账。在各大媒体、社交平台,大量负面抨击的评论瞬间炸开锅。但同样也有一部分网友赞同李彦宏所阐述的现状,也透露出一种无奈。

1.jpg

还是那句话“当你接入互联网的那一刻,也许你的隐私就失控了”,曾经有数据显示,国内平均每个人信息泄漏次数至少8条,现在应该远不止这个数。除了传统的网页端,安卓手机的权限管制问题也是造成个人信息泄漏的原因之一。但或许,我们还没有遭受过一次如Facebook那样的事故,没有那种深刻的反思。当然,不得不说,国内在个人信息保护方面的法律法规不够完善,也成为造成消费者这种无奈的原因之一。

有一点笔者觉得大多数人还是无法反驳的,“如果能够用隐私交换便捷性或者效率,很多情况下他们还是愿意的”,最普遍的就是以各种实名认证为基础电子支付、外卖服务、共享单车、网约车等等,你会发现因为互联网而方便的一切事物似乎都代表着你同意将自己的隐私交给某个平台。

timg (1).jpg

从媒体报道出来到现在不过几个小时的时间,百度以及李彦宏又成了网友口诛笔伐的对象,一是百度近几年几次重大负面事件造成的影响,另一种或许是对个人信息泄漏泛滥以及隐私保护无奈感的一种宣泄吧。

*本文作者:Andy,转载请注明来自FreeBuf.COM

Viewing all 15896 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>