
热爱成就非凡
能力说明:
掌握封装、继承和多态设计Java类的方法,能够设计较复杂的Java类结构;能够使用泛型与集合的概念与方法,创建泛型类,使用ArrayList,TreeSet,TreeMap等对象掌握Java I/O原理从控制台读取和写入数据,能够使用BufferedReader,BufferedWriter文件创建输出、输入对象。
阿里云技能认证
详细说明
1. 序言DaaS 数据即服务是一种服务模式,即将数据以服务的形式,向客户提供价值,参与到客户的业务中,它也是软件即服务的一种细分领域。同时DaaS 拥有云计算的通用特点,包括以租代买,按需付费、按用付费。本文介绍 DaaS 的架构及实现选择,对于拥有大量优质数据资源的企业,可以参考构建起数据业务线,进而实现数据的资产化、价值化。需要说明的是本文中的各种图例仅是逻辑示意,均做了简化。2. 基础架构系统由四部分组成,包括:客户基于 API 自研应用,从而实现访问数据的目的。API 为数据接口,封装和抽象了数据的定义和许可的数据访问模式。数据服务是 API 功能的具体实现。数据库则存储了原始的数据,当然还有非结构化的数据,如一些图片、视频、专有文件等。这种架构适合两种情况,一是可信的环境内,二是前期的商业验证阶段,优势是结构简单,实施成本低。3. +官方应用很多情况下,客户没有应用开发能力,需要接口上叠加一个轻量级的图形化工具,比如网页、小程序。4. +应用认证增加 App认证鉴权之后,能缓解对于API 接口安全的焦虑。借助线下、线上的授权,许可特定的应用来访问特定的接口。5. +模型基于对于应用场景的理解,将原始数据进行一定的加工,生成模型数据(间接数据),对外提供模型数据。这将简化客户 app 的开发,同时也在一定程度上保护了原始数据。6. +脱敏一些数据不能直接对外,需要一些脱敏处理,可以采用动态脱敏或者静态脱敏。动态脱敏是访问时现进行计算,静态脱敏则是提前完成。7. +库内计算传统数据库提供了一些计算能力,比如常见的统计函数、存储过程等。现在的新型数据库的算力越来越强,与其将数据传来传去,受限于带宽,还不如把计算下放到数据库中。同时,这也减少了出库的数据,降低了数据安全风险。8. +计费计费有很多种方式,这里提两种,一是在 api 层同步或异步进行计费业务,另一种则是以离线的统计日志数据,生成费用。前者计费及时些,但对于工程能力要求高,同时也会造成接口访问效率的降低;后者系统更健壮,但存在滞后问题,这也可以通过商业措施来解决。9. +开发当考虑到开发场景,会增加其他的需求,比如测试环境、生产环境,比如 SDK、开发文档。但最考验技术的还是接口的版本问题。推荐阿里云 API 网关是个非常好的学习对象,对于想实现一个 DaaS 系统的朋友,其有很好的借鉴意义。当然与其重复造个轮子,不如享用当下成型的产品,将精力聚焦于核心业务的开发中。思考如何做访问加速?如何做高可用?如何做弹性?隐私计算、联邦学习、多方安全计算、可信计算、机密计算是什么?引入这些之后,DaaS架构会如何演进呢?
随着制造业数字化的发展以及物联网应用的普及,越来越非互联网、业务系统的数据被采集、记录和存储。很多系统开发者熟悉的是 Oracle、MySQL等关系型数据库,以及像 Redis 这样的键值数据库,于是在物联网应用、制造业数字化应用中也延续了相似的数据库选型。这样做的好处很直接,产品熟悉,技术难度可控,开发工期可控。但随着系统运行时间的推移,该方案面临的性能挑战越来越大,而且在业务开发中会面临很多相似的查询、统计需求需要实现。为什么呢?我们再审视一下物联网数据、制造业数据的特点。首先,数据结构相对简单,主要包含三列,时间、标签、值;第二,数据生成大多具有稳定的节奏,不存在或者与一般互联网应用那样的波峰波谷;第三,数据很少更新,更多的是一次写,多次查询;第四,数据量极其巨大,同时对于存储成本又很敏感;第五,数据分析统计中很重要的维度之一是时间;……以上这些特点和我们熟悉的交易类数据有很明显不同。虽然用关系型数据库可以存储和管理,但没有很好的利用对于数据的理解。如果能选择针对这类数据特点的专用数据库,则会让很多技术难点得到化解,而且会提高系统的稳定性。在数据库行业中,这类产品叫时序数据库。时间序列数据库是广泛应用于物联网(IoT)设备监控系统 ,企业能源管理系统(EMS),生产安全监控系统,电力检测系统等行业场景的专业数据库产品,提供百万高效写入,高压缩比低成本存储、预降采样、插值、多维聚合计算,查询结果可视化功能;解决由于设备采集点数量巨大,数据采集频率高,造成的存储成本高,写入和查询分析效率低的问题。下面介绍几款时间数据库产品供大家选择。Informix TimeSeriesInformix TimeSeries在时间序列数据库中的位置就像Oracle 在关系数据库中一样,属于经典的产品。它给后续时间数据库产品研发提供了很好的标杆作用。其针对时间序列数据的特殊存储结构、索引设计以及专用计算函数都属于创新性的设计。它也是多模数据的早期实践者,能与关系型数据库引擎并存,简化了应用系统设计、部署的复杂度。InfluxDB时序数据库 InfluxDB®版是一款专门处理高写入和查询负载的时序数据库,用于存储大规模的时序数据并进行实时分析,包括来自DevOps监控、应用指标和IoT传感器上的数据。目前有以下特点:专为时间序列数据量身打造的高性能数据存储。TSM引擎提供数据高速读写和压缩等功能。简单高效的HTTP API写入和查询接口。针对时序数据,量身打造类似SQL的查询语言,轻松查询聚合数据。允许对tag建索引,实现快速有效的查询。数据保留策略(Retention policies)能够有效地使旧数据自动失效。OpenTSDBOpenTSDB是可扩展的分布式时序数据库,底层依赖HBase。作为基于通用存储开发的时序数据库典型代表,起步比较早,在时序市场的认可度相对较高。OpenTSDB的自我定位很清晰:The Scalable Time Series Database。如果应用场景很看中扩展性,可以选择 OpenTSDB,否则就要考虑一下是否需要接受将 HBase 也纳入到技术栈和系统中了。阿里云智能TSDB阿里云智能TSDB高度兼容OpenTSDB协议,采用自研的索引,数据模型,流式聚合等技术手段提供更强大的时序能力。它不是简单的把OpenTSDB在云上部署了一份,而是基于云计算架构重新设计了底层架构;同时由于阿里云TSDB底层技术架构同OpenTSDB的实现区别巨大,对于OpenTSDB的一些运维接口不会兼容。从运维管控,功能,成本,性能等方面对比,阿里云智能TSDB相比OpenTSDB而言,优势还是很明显的。上述应用架构中,设备将原始数据通过 MQTT 协议发送到物联网平台,经由物联网平台将数据转发到消息服务系统,继而通过流计算系统对这些数据进行实时计算处理后写入到 TSDB 中存储,或者经由物联网平台直接将原始数据写入 TSDB 中存储。前端的监控系统和大数据处理系统会利用 TSDB 的数据查询和计算分析能力进行业务监控和分析结果的实时展现。阿里云TSDB for InfluxDB阿里云TSDB for InfluxDB则是云上的 InfluxDB 版,与InfluxDB 有很好的兼容性,可顺利的将将线下是数据库迁移至云上;同时省去了部署、运维管理的复杂度。基础版:单节点实例,适用于个人学习、中小规模DevOps监控、应用指标和IoT传感器的时序数据采集分析、中小企业开发测试。高可用版:采用Raft一致性协议的三节点架构,适合80%以上的用户场景,尤其是大中型企业的指标采集、业务监控(物联网、容器、工业生产等重要链路资源监控)。
数字孪生近些年热门起来,源自于数字化转型的需求及基础技术平台成熟的推动,尤其是得益于云计算平台的发展和成熟。什么是数字孪生?数字孪生和云计算的关系是?它从而而来,又走向何方呢?在船舶行业如何运用?https://help.aliyun.com/document_detail/254767.html
天津市大学软件学院专家校园行:数字化转型带来的机遇与挑战2021年11月11日下午,应天津市大学软件学院邀请,在学院D区报告厅,为在校学生做了主题为数字化转型带来的机遇与挑战的技术讲座。介绍数字技术的发展历史及最近的技术热点,以及阿里云在数字化转型服务方面的最新进展,指出了数字化转型带给企业、个人的机遇与挑战。
测试工作基本流程包括四个基本活动、即测试需求分析、测试设计、测试执行、测试分析与总结,关键成果包括《测试需求分析》、《测试方案》、《测试记录》、《测试报告》。在实际测试工作中,会出现若干环节的迭代循环,也会出现要求弱化,或者要求强化。只要是实现测试目标的必要调整,都可以按需进行。1.测试需求分析输入:原始需求,包括但不限于《产品设计文档(PRD)》、《系统需求说明书》、《立项书》、《项目合同》输出:《测试需求分析》、《测试规划》注意事项:确认测试需求范围:功能、性能、容量、稳定性、安全性等。确认测试资源约束,包括人、财、物、时间。确认测试过程质量要求。2.测试设计输入:《测试需求分析》、《测试规划》输出:《测试方案》、《测试计划》、《测试用例》注意事项:测试设计核心是面向测试目标,基于可用资源的,测试投入分配方案。充分测试是不存在的,无外泄 bug是不存在的。测试是验证质量,不能保证质量。测试用例的存在形式服务于测试执行,而非独立于测试执行。3.测试执行输入:《测试方案》、《测试计划》、《测试用例》输出:《测试记录》注意事项:测试要记录的内容,需要提前设计,否则会错失信息收集的契机。测试执行会存在无法执行的情况,必要时修订测试方案。4.测试分析总结输入:《测试记录》输出:《测试报告》注意事项:测试报告重点是回答测试结果。测试报告无需整合测试记录。测试报告可以包括对测试工作的总结。
随着技术的普及,越来越多的企业在筹划、推进物联网领域的建设项目,另一方面越来越多的 IT 企业进入到物联网服务领域。相较于其他项目,物联网项目有其特殊性,本文旨在建立起一种实施参考,以有助于项目规划的思考、项目提案的分析、项目建设实施的有序推进等工作。理解物联网技术领域的发展有两个特点:第一是,一批批技术人员前赴后继地推进,每个进展都是在既有技术总和的基础上增加了一层;第二是,伟大的进展是大时间尺度的回望,而每个当下的进步都微乎其微。物联网也是类似的发展历程,很难清晰界定物联网从何而来、从何时而来,但回望过去三十年国内技术发展,其阶段性特点会很清晰。所以遥不可及或新瓶装旧酒的感觉都很常见。物联网的含义如其字面意思,即物物之间相互联接,组成网络。怎么理解它呢?物联网的提出是相较于互联网、移动互联网而言的。互联网诞生与普及实现了电脑与电脑的相连,进而实现了组织、岗位之间的互联互通。移动互联网技术的应用与普及则在前者基础上,增加了以手机为重要代表的移动设备的互联互通,其更深刻的影响是手机背后的人被拉入到这个网络中,手机成为人外置的连接器,人成为这个网络中重要的节点。物联网则是在这二者的基础上,旨在将万事万物都接入到这个网络中,每个节点可以是计算机、手机、人、路灯、汽车等等。物联网的意义是什么?回望当互联网被发明的时候,我们无法准确说明和预言互联网的价值和对社会的影响,但它深刻的促进了社会的发展,移动互联网也是类似的情况。梅特卡夫定律表述为:网络价值随着用户数平方的增长而增长,即与用户数平方成正比。物联网的接入数将会远超既有接入终端的数量。物联网的愿景是伟大的,而前进的脚步却是细无声的。抬头看看我们的工厂,不知不觉间被物联网所包围。厂门口的停车管理系统、员工的打卡签到系统、访客的授权控制系统、围墙上的边界监控系统,生产流水线上的传感器、控制器、电子看板,仓储与物流系统等等。物联网就是如此吗?物联网的发展还在加速阶段,比如我们所津津乐道的数字孪生也只是在有限的场景应用,绝大部分设备、材料、厂房、车辆、订单、作业人员等之间的连接还很有限,彼此之间协作还很低效。这些都是未来物联网要进一步发展的方向。在物联网概念流行之前,工业领域已有类似的网络,比如厂房内部的工业控制网络,比如汽车内部的控制网络。物联网较它们而言,接入的范围更广,同时它们也是物联网的基础。企业物联网项目实施参考物联网较互联网有其特殊性:网络连接稳定性、速率不稳定。终端设备多样性,算力、电力、感知力、复杂度极度层次不齐。终端维护性可能很差,可能处在人烟罕至的地方,也可能过于分散导致巡检频率极低。终端数据大部分与时间,即为时序数据,其处理业务逻辑也有很强的时间属性。终端并发模型不再与人作息有强相关性,比如设备的定时检测就没有明显的波峰波谷。物联网的架构物联网最核心的元素有3 个:感知、传输、处理。感知:利用传感器、摄像头等获取物体、环境等信息。传输:基于互联网、工业网络、电信网络等,将感知的信息传递给需要的节点,同时也会将控制、处理指令传递给各类各样的终端。处理:对收集到的信息进行加工、分析、存储等。一般的物联网架构分为四层:云、管、边、端。端包括主要包括三类能力:感知、控制、交互。感知包括温感、烟感、压感、光感、流量计、红外传感、RFID标签等,控制包括伺服电机、步进电机、控制开关、PLC 等,交互包括音视频、触控、键盘、旋钮等。边是处理效率和算力的折中,常见的工控机就是一种边缘计算节点,将现场的数据采集传到后台服务最快也需要几十毫秒,有时还会出现断网的极端情况,这对于很多现场操作是无法接受,它们需要需要现场处理反馈;同时把所有数据都传输到服务中心需要的带宽可能非常大,但有效的信息其实并不多,需要在现场进行信息的过滤。边和端的区分是逻辑概念,在具体情况时,有些设备是边端一体,比如将边缘计算能力集成到摄像设备上,一个区域部署一台这样的设备,其他设备则仅拥有摄像能力。这样即拥有了边缘计算节点的计算能力,又降低了方案的造价。管是连接通道,将终端、边缘节点、云服务连接成一个整体。管包括传统的工控总线技术,也包括互联网技术、电信技术,还包括 NB-IoT、LoRa、Bluetooth 等技术。一些终端节点缺少联网能力,需要物联网网关协助其接入。云主要指物联网平台,可以自建的服务平台,可以是基于第三方厂商搭建的平台,主要完成复杂计算、大数据存储、应用支持等。物联网项目的实施过程物联网项目都涉及到与应用现场相结合的环节,同时涉及到软硬件一体化研发,其实施过程更复杂。下面是常规项目中会涉及到的环节,供项目设计参考。业务分析与可行性研究,包括了解既有设备、环境的摸底完成提案涉及与沟通确认根据拟建物联网工程的性质,确定所使用的周期模型需求分析,确定设计目标、性能参数根据具体情况,对现有网络进行分析逻辑网络设计(有时称为总体设计)物理网络设计(有时称为详细设计)施工方案设计(工期计划、施工流程、现场管理方案、施工人员安排、工程质量保证措施等;应用软件开发、采购方案)设计测试方案设计运行、维护方案系统开发系统试验测试现场改造升级设备分发与安装调试试运行验收正式运行与维护物联网的技术选型关于终端的技术选型受作业环境影响很大,比如高温作业导致很多对于加工件的数据采集需要间接采集,比如作业人员的操作模式也决定了终端的技术形态。一些终端设备算力充裕,且业务复杂,可引入操作系统,通常使用的安卓系统,当然标准的嵌入式操作系统也可以使用,华为、阿里等也有可裁剪的嵌入系统可以使用。鸿蒙系统也值得关注。物联网相关的通讯协议很多,既要关注其技术参数,也要关注其合规性要求,比如 NB-IoT 则需要一些接入认证。关于数据存储,使用文件系统直接存储,还是使用 MySQL 等存储均可,同时也要关注有很多物联网专用的方案供选择,端侧的 SQLlite 很简洁,服务侧的时序数据库(如 InfluxDB)则对于时序数据插入、更新、计算都很好的优化。关于是否使用第三方物联网平台,都建议先学习了解一些这些平台,一是帮助了解系统的范围边界,二是避免走弯路,三是可能会降低建造成本。平台参考阿里云物联网平台时序数据库 InfluxDBInfluxDB是一种稳定可靠,可弹性伸缩的时序数据库服务。广泛应用于互联网基础资源监控,容器监控,业务运营监控分析,物联网设备远程实时监控,工业安全生产监控,生产质量评估和故障回溯。提供时序数据自动化采集,压缩存储,类SQL查询,多维聚合计算和数据可视化分析能力。
The only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle.随着信息化和数字化的持续推进,越来越多企业和人员会涉及到软件开发业务中。了解软件设计流程成为了IT和OT、业务之间有效协作的关键基础背景知识。本文旨在让产业界的朋友对软件设计的基本流程有所了解,一是鉴别合作方的业务能力,二是便于和合作方有效协作。01 软件设计的静态视角好的软件设计需要三个阶段递进,我们先讲第一个阶段:静态视角或者蓝图视角。很多软件设计是从功能讨论开始,期望有亮点、有特色,结果很有可能是可汇报,不可使用。还有一些软件设计是从对标参考对象开始,期望有更多的功能,结果很有可能是功能比哪个都多,但员工抱怨不断。第三类常见的软件设计着手点是单个问题的拆解,结果很有可能是某个上帝可以正常使用,但在推广时各方阻力很大。建议软件设计先从人入手。第一步:梳理业务的相关角色角色的基本信息角色的代表人员的简要信息角色的诉求第二步:梳理角色的工作用一句话(10 个字以内)描述每个工作。然后描述每个工作的流程,流程中的节点具有几个特性:a、有外界的信息输入;b、向其角色、系统输出信息、文件;c、与其他角色、系统有交互。第三步:基于 IT技术的能力重新设计流程这个环节即使选做,也是必做。选做是因为变革需要契机,有时只能把一步拆成两步,先把线下搬到线上,之后再逐渐优化。必竟是这是一次难得机会,有可能让既有的工作有质的飞跃。第四步:整理功能列表并分类组合形成系统逻辑架构图此时的功能需求相对清晰,将耦合性强的功能组合到一起,将独立性强的功能隔离开。整体思路与企业组织设计的思路相似。低耦合高内聚是一种追求和目标。第五步:将逻辑架构落实为真正的软件模块架构这时要考虑软件工程的技术问题,属于纯软件的技术领域。包括微服务、队列、数据库、缓存、容器等等软件成型组件都会被考虑进来,一起为系统添砖加瓦。第六步:设计出部署架构、物理架构将软件与实物部署相结合,包括网络规划、服务器规划、数据库规划、容灾备份等等。至此,软件的静态视角设计完成,我们就拥有了软件的宏伟蓝图,就可以撸起袖子开发了。产品、UI、前端、后端、硬件、质控、质保等等一群人不亦乐乎地忙乎起来。02 为软件降生而设计在获得了软件蓝图之后,还需要为软件降生而设计。也就是要为软件交付、部署、上线等进行设计。包括但不限于要解决的问题如下:如何将软件分发到需要它的地方?如何让实施人员更高效地完成安装调试?如何将初始数据导入到系统中,包括用户账号、组织架构、业务流程、基础业务数据、老系统中的数据?如何提供培训让用户真正能把软件用起来?……只有这些问题得到提前设计与做好应对设计和开发,才不至于让软件姗姗来迟,甚至错过了降生的机会。03 为软件生存发展而设计软件所处的环境是持续变化的。所以行业内一般认为一套业务系统用几年被淘汰掉是正常的。为什么?因为之前交付的软件是静态的!为了让软件发展,需要让它能像孩子一样,不断了解世界,不断学习,不断改造升级自己,才能跟上企业的发展。需要做的设计包括但不限于:对既有功能测量、跟踪的能力适应访问压力增长的能力适应数据量不断增加而不被拖累的能力适应新业务变化发展的适配、扩展能力将数字化的思想引入到软件设计中……04 总结好的软件设计刚开始会感觉有些慢。因为一开始并没有噼里啪啦的敲代码。好的软件设计在开始阶段会不断深入谈论业务。因为失之毫厘谬以千里。软件后期修改的成本极高,包括人力成本、工期延期的风险、质量下滑的成本等。建议让业务骨干来参与到软件的需求调研和业务设计,与供应商软件架构师们一起设计;而不是让一些“闲人”来凑热闹。主动帮助供应商了解业务,因为即使再老练的供应商也不会懂多少你企业的水深水浅。软件前期多听听阶段汇报,将上线时的一次性验收拆解成很多个小验收。将压力提前分解,让软件质量更健康。
大家好! 云顶云代表阿里巴巴云栖大会百城汇的承办方,感谢各位朋友莅临此次峰会现场! 感谢各位领导对此次活动的支持!因为有各位领导的支持,我们才更有方向的,将技术普惠的峰会持续办下去。 感谢莅临此次大会的各位业界的朋友!因为有你们的信任,我们才能坚持初心,每年承办云计算峰会。希望今天的 技术分享,能给各位朋友带来一些思考、一些观察、一些新的思路。 感谢各位专家从北京等外地赶来,为天津的技术届的朋友,带来丰盛的技术大餐。 感谢阿里云 MVP 的各位运营同学们,因为你们的努力,才有了今天活动的起心动念;因为有你们的支持,才让这次 活动的方案,一步步清晰,最终呈现在大家的面前! 感谢为此峰会辛苦筹备的各位同学,感谢你们的默默付出!天津的技术发展,因你们而更精彩。 感谢此次峰会的合伙伙伴!感谢天津市河北区科技招商展示服务中心的各位同志!感谢你们辛苦准备的会场!感谢天津好利来的各位同志!给大家带来甜美的点心! 关于数智未来 全速重构今年云栖大会的主题是:数智未来 全速重构。这带给了我很多的思考和启发。 今年的新冠疫情,带给各位企业界的朋友 很多的经营压力,同时也让我们看到了技术变革带来的新的机遇与挑战。钉钉在 2020 年上半年就新增了 1 亿用户,让我们看到数字经济迸发的速度竟然如此惊人,也只有全力以赴才有可能不被时代掉队。 今年的新基建成为业界朋友广泛关注的话题,而云计算、大数据、人工智能等作为新基建的核心组成要素,将会成 为市场竞争新的关键竞争要素。因为这些技术的发展与普及,将成为中小企业挑战头部企业的技术杠杆。因为这些技术的发展与普及,让行业巨头可以进一步提升其核心竞争力,去布局新的业务发展。大数据、人工智能等技术借助云计算的交付模式,必将带给传统产业质的冲击。 在这个大趋势下,谁能更快适应?谁能更快抓住技术机遇?谁就有可能获得更好的发展。在过去的十余年的发展中,消费侧的数字化已经取得了丰富而深化的进展,百姓的衣食住行用大部分在线化、数字化、移动化。而在企业侧,这一切还在启动阶段,其包含的广大市场让人憧憬,其所要面临的挑战也将超出我们的想象。 在坐的每一位嘉宾及企业代表,当前都置身新基建大潮之中,如何更好的帮助客户,抓住数智未来?如何更好帮助 客户,领先竞争对手完成重构升级?如何帮助客户,拥抱数字经济?都是我们需要不断努力和实践的方向。 本次技术峰会就是我们在这方向的努力,希望借助这样的活动,将更多的新技术、新方案、新思路推广到广大的天津企业面前。 关于混合云方向本节峰会技术分享围绕的主题是混合云方向,是因为我们在和广大客户朋友沟通中,感受到一些市场的变化。 首先对于大部分企业的 IT 负责人及业务负责人,对于云计算的商业价值,越来越认可,对于云计算的技术红利越 来越认可。大家都在思考如何将云计算与自己的业务相结合,实现乘云破浪。 另一方面,对于上云的路径,有更多的全局性的考量,既有组织方面的因素,也有商业方面的因素,更有技术方面 的思考,希望能有符合组织实际情况的上云路径。 第三方面,是面对组织既有的固定资产,需要充分利用,同时也要面对新营销方案、新产品形态、新用户分布等技术挑战。于是很多朋友将焦点关注到混合云这种模式上。 阿里巴巴及相关企业代表分享的主题包括从企业级混合云解决方案到混合云存储解决方案及实践,从混合云K8s 集群最佳实践分享再到面向互联网业务的混合云 安全防护体系建设实践,以及混合云相关的客户案例分享。这些都是源自于朋友们的真实的问题、真实的需求。这五位技术专家的分享让我收获良多,相信大家从各自角度也会有类似的同感。 2021年 我们再相聚!云顶云科技黄军雷2020.9.17
1.背景 一个测试用例基本要素包括以下 3 点: 前置条件,或者叫被测对象的初始状态 执行步骤 预期结果 在简单模块或单元测试中,大家对于前置条件的理解很容达成共识。但在面对一个复杂系统时,则关于前置条件容易困扰,或是因为可操作性,或是因为可界定性。 2.前置条件的组成 被测对象的程序版本 在测一个库、一个类、一个可执行程序时,版本很容易定义;但面对一个网站时,要说清楚版本不是一件容易的事情。 被测对象的相关数据,包括 数据库里的数据 缓存服务中的数据 队列中的数据 配置文件中的信息 …… 测试环境 测试工具与被测对象的网络拓扑情况 测试工具、被测对象、通讯网络等计算、带宽、存储资源的情况 3.关于被测对象相关数据的准备 极简情况:测试一个类的方法 可以通过构造函数、借助 set 接口等来保证方法调用前,类处在一个确定的状态中。 正常情况:测试一个网站的注册功能 空库的情况下, 第一次执行注册 a 用户 时成功 第二次执行注册 a 用户时反馈失败。 此时都代表网站正常,但两次测试属于不同的测试用例,因为其系统的初始情况不一样。 为了可重复验证测试功能,需要在注册 a 用户,清除掉 a 用户的注册信息,以保证可重入性。此时,注册测试用例的前置条件中的数据要求就是,数据库中没有 a 用户的信息。 正常情况:测试列表的翻页功能 因为数据记录条数不同,导致页面显示的情况会不同。比如说: 空数据 不满一页的数据 10 页的数据 100 页的数据 此时,就需要让数据库里的数据处在不同的数据量情况下,才能进行有效测试。可选的方案包括: 每次测试前,人工清理和准备需要的数据 每次测试前,执行专用的数据生成 SQL(含清理数据) 在数据库里提前生成4 种数据,借助一些其他查询条件来区分。即重点测试翻页功能,其他功能就能用来辅助功能测试。 提前创建4 种数据库快照,按需恢复到需要的数据库状态。 4.说明 离开前置条件来谈测试用例执行结果,很难界定是否真是系统的 bug。 并不需要控制所有前置条件的一致性,一是单个测试用例只与有限的数据相关,二是控制绝对一致的成本很高,不划算。
1.背景 软件项目中经常涉及到软硬件资源的采购,在云计算时代这一采购工作的范围和深度都得到进一步增强。如果快捷编制出项目的资源采购计划呢? 2.步骤一览 收集需求 梳理资源需求计划 梳理资源部署计划 整理资源采购最晚到位时间 根据商务政策及策略优化采购批次设计 反馈与措施资源需求方的资源到位时间 形成资源采购计划 3. 计划编制说明 3.1 收集需求 最好的需求来源是项目的进度计划。好的进度计划上会在任务上描述所需的资源,包括服务器、数据库、网络等。但一般的项目经理或开发经理更多的描述的是对人的描述。其次要关注项目的里程碑计划、合同中的相关验收条件和标准。这些约束和限制的弹性小,需要项目组共同努力去达成。 3.2 梳理资源需求计划 将收集到的需求,转化成独立的需求清单,至少包括: 资源类型 资源型号及关键参数 用途 投入任务使用的时间 梳理出该清单后,最好与相关人员再次核对一下,减少因项目计划文档更新不及时、文字描述不准确等导致信息理解有误。 3.3 梳理资源部署计划 传统线下资源采购部署周期很长,比如一台服务器从下单到到货一般需要 2 周,还需要工程师上架、调试网络、系统优化等;比如一台数据库软件到位后,还需要安装、调试等,至少需要 1-2 天时间。顾需要在资源需求计划中增加一列部署用时,该用时包括: 备货时间 物流时间 系统部署时间(需考虑部署人员有限的约束) 3.4 整理资源采购最晚到位时间 在上述表的基础上,增加资源最晚采购到位时间: 资源最晚采购到位时间 = 资源投入任务使用的时间 + 部署时间 3.5 根据商务政策及策略优化采购批次设计 上述都是从技术侧进行梳理,下一步需要从商务侧进行优化,重点考虑 2 个因素: 供应商优惠政策:如大批次的折扣,打折季的促销,独立的特殊优惠政策。 自身的采购政策,现金流的控制策略等。 对于公司看到的现金支付计划,对于供应商此时看到的采购规划。经过多次措施后,会形成从商务和财务上更合理的采购安排。过程中可能会修改下单时间等。 3.6 反馈与措施资源需求方的资源到位时间 由于经过商务的优化,可能资源到位时间或早或晚,所以需要与资源需求方及时沟通,协商解决。 过晚影响相关任务的进度 过早可能导致打乱既有工作的安排,甚至无法接受资源的到位 3.7 形成资源采购计划 到这里时,技术和商务的需求沟通完成,也与供应商的沟通达成共识。这时才能形成正式的资源采购计划。
背景 大部分者开发者入行都是功能实现角度入行,大部分测试人员也是相似的经历。一般项目都是最后时间跟性能较劲,由于系统的复杂性和变更的成本等导致性能工作多数是草草收尾。有没有更好的工程实践呢?有!感谢刚入行的几年的开发工作经历,养成了面向性能、面向稳定性、面向功能的持续开发实践的习惯。现在这里分享给大家! 定义 本文所谈的开发包括需求、设计、实现、测试,即广义的开发。 面向性能的需求分析 离开业务需求谈高性能容易陷入为技术而技术的陷阱。抛开资源、成本谈高性能则容易导致不必要的项目投入。常规产品、系统除了功能需求外,都会伴随着性能需求。只是因其隐蔽性,导致不是所有的需求提出者都能想到或能给出准确的性能需求。此时就需要系统架构师帮助客户梳理和制定合理的性能需求。性能需求至少包括以下几个角度的信息: 什么场景? 什么数据量下? 多大的业务并发情况下? 多大的计算、网络的资源基础上? 怎么定义一个性能评估模型?如 TPCC。 面向性能的架构设计 所有架构都有其基础的性能损耗,一方面是性能得以实现的基础,另一方面也是性能上限的瓶颈。 比如引入了缓存就可能比不用缓存的要高性能,但同时引入了数据一致性问题,增加了系统的复杂度和脆弱性; 比如引入的异步处理,增加了反馈的及时性,同时导致原本一次性的操作被分解为多个操作的协同; 比如引入了微服务架构,获取了水平扩展能力,但因增加了服务间调用增加系统性能的损耗。 要逐渐积累一些基本基本组件的性能数据。 如广域网的通讯时间几十毫秒很常见; 比如数据库的读取和写入是有很大的不同; 比如很多系统都有隐式的缓存,如数据库、文件系统。 要知道架构设计的重点之一是平衡各种需求 功能需求 性能需求 容量需求 稳定性需求 可维护性需求 要将系统的性能需求拆解为子系统、子模块的性能需求,比如整体对外需要 1 秒完成数据处理,有代理、计算、存储 3 个环节,则留给计算环节的平均耗时为多少? 面向性能的系统实现 在很多情况下,系统实现和系统设计是彼此交错的两类工作。在将系统架构落实为系统实现时,要从多个层次来实现系统。一些好的开发实践包括: 在开发过程中,除了设计面向功能测试的单元测试外,还要开发面向性能的测试框架; 构建符合性能测试需求的基础数据; 随着代码的推进,周期性运行性能测试框架,持续跟踪性能劣化的趋势,将其控制在需求范围内; 同样的功能有 N 种实现方式,但性能千差万别,甚至 do while 和 for 都要反复权衡写法。 性能测试与性能优化 性能测试本质上是性能摸底,性能测试不能改变系统的性能,但有助于对系统性能指标、性能瓶颈达成共识。性能测试的设计考验的是技术人员的综合能力。性能测试的执行考验的是技术人员的耐心和细心。性能测试的度量有时会干扰被测对象的性能,如写日志、输出到屏幕、测试数据的累计都可能拉低系统的性能。性能优化的推进需要有系统的视野,不要过早陷入局部优化的泥潭,至少要做好 2 个准备,以形成改进的闭环: 系统分段度量的能力 系统改进度量的能力 性能神话 期望在测试阶段能优化性能 木已成舟,架构是性能优化的天花板,代码是性能优化的约束。 期望性能开发的银弹 从项目角度看,加缓存不一定性价比高;一个系统上的性能开发经验不一定能迁移到另一个系统上,注意场景、资源等的差异。 云顶云(yundingyun.com)是国内首批专注于云计算服务的提供商,致力于“让云计算更简单”。做为阿里云五星授权服务中心,云顶云致力于为企业和政府提供方案咨询、架构设计、部署实施、系统定制、运维托管、技术培训等全方位“4S”级公有云、私有云定制化服务。
1.问题描述 1.1 背景 大中型产品研发中,由于参与人员过多的原因,手机应用程序、后端服务研发通常会拆分开,由不同的团队负责。这即促进了专业领域的聚焦,又减少了团队管理与沟通的复杂度。 1.2 现象 好现象 内部沟通效率得到提升:手机应用程序、后端服务研发团队内部讨论、传递的信息都是和绝大数人有关的信息;沟通网络效应造成沟通负担得到遏制。 大部分人聚焦内部,少数人做边界沟通,缓解沟通能力的要求。 各自内部迭代速度加速。 坏现象 组织墙阻隔了团队间集体感。 由于缺乏跨组织交流,对合作团队工作认同感降低。 前后端联调滞后,导致项目中后期问题激增,团队氛围恶化,项目延期。 1.3 影响 产品发布节奏放缓。 产品研发成本增加。 技术方案倾向于团队折中、妥协,而非基于产品发展。 2.主因分析 核心原因在沟通阻力增加和利益不一致。 原因 1:沟通阻力增加 术业有专攻,且缺少天天耳濡目染,对跨组织的工作越来越不理解。 因物理和心理两个维度上距离增加,导致小问题得不到及时暴露和解决。如接口的定义、参数的设计、业务逻辑的真正讨论,被延期到集成阶段。 工作排期聚焦内部,对于彼此协调、依赖的事项关注不足。 原因 2:利益不一致 独立 KPI 考核 独立研发计划 前端应用面临海量客户的压力,后端面临多个前端应用需求的压力 3.项目治理方案 建立持续交付的工作模式,以持续交付用户价值为共同目标。 建立跨组织的产品级路线图。 建立以产品经理和系统架构师为核心的跨组织领导体系,拥有决策权和评价权。 后端服务团队的接口人以虚拟角色形式,参与到前端团队的研发管理,包括日会、技术会。 建立面向接口的开发模式。 定期组织跨组织的团队建设活动。 4.实施方案 4.1 组建阶段 明确授权产品经理、产品级架构师 统一研发基础设施,包括接口设计与发布流程 统一沟通工具,制定沟通计划 统一迭代节奏 4.2 实施阶段 保持后端团队代表的有效参与前端团队,需产品经理、架构师监督。 保持按节奏持续发布至测试环境,包括前端、后端,让问题在有限时间内得到暴露和解决 4.3 接口开发技术 方案一:基于 Swagger 基于接口设计、描述框架 Swagger (https://swagger.io/),构建基于接口的研发流程。 后端服务即 API 文档,前端团队清晰了解接口能力,利于持续集成。 后端持续发布接口能力,简化 API 文档维护成本。 需要前后端团队遵循开发流程,提高项目的整体效率,而非单次沟通效率。 Swagger - Simplify API development for users, teams, and enterprises with the Swagger open source and professional toolset. Find out how Swagger can help you design and document your APIs at scale.by https://swagger.io/ (1)接口设计阶段 针对业务需求清晰的接口,即通过规划的接口,启动基于Swagger的接口设计。 侧重基于真实服务代码描述接口设计 不做功能的有效实现 将设计通过的接口,发布到测试环境,供前端团队查阅和开发联调 接口设计规范:OpenAPI Specification https://swagger.io/resources/open-api/ 接口设计工具:Swagger Editor Design, describe, and document your API on the first open source editor fully dedicated to OpenAPI-based APIs. The Swagger Editor is great for quickly getting started with the OpenAPI (formerly known as the Swagger Specification) specification, with support for Swagger 2.0 and OpenAPI 3.0. https://editor.swagger.io/ 使用Yaml语言, 定义好API接口 点击 generate server code, 选择需要的语言, 即可下载自动生成的相关接口的初始化项目 点击 generate client code, 选择需要的语言, 即可以下载自动生成调用这个接口的客户端代码 接口定义查看工具:Swagger UI Swagger UI 可以将项目接口自动生产具有交互的html页面, 是一个前端页面的自动生成项目. Swagger UI的 demo见: swagger ui demo. (2)接口实现阶段 按节奏逐渐实现接口的能力。 对于已实现的能力,要清晰描述能力 对于在在研的能力,要描述清晰状态 后端服务工程引入swagger的依赖 <dependency> <groupId>io.springfox</groupId <artifactId>springfox-swagger2</artifactId <version>2.7.0</version> </dependency> <dependency> <groupId>io.springfox</groupId <artifactId>springfox-swagger-ui</artifactId <version>2.7.0</version> </dependency> 生成API的server stub和client SDK Swagger Codegen can simplify your build process by generating server stubs and client SDKs for any API, defined with the OpenAPI (formerly known as Swagger) specification, so your team can focus better on your API’s implementation and adoption. (3)接口设计变更 后端人员无需关注Swagger描述文件和接口文档,有需求变更导致接口变化,直接写代码就好了。把调用层的代码做个修改,然后生成新的描述文件和接口文档后,给到前端即可。 方案二:基于阿里云 API 网关 https://www.aliyun.com/product/apigateway API 网关(API Gateway),提供API托管服务,涵盖API发布、管理、运维、售卖的全生命周期管理。辅助用户简单、快速、低成本、低风险的实现微服务聚合、前后端分离、系统集成,向合作伙伴、开发者开放功能和数据。https://www.aliyun.com/product/apigateway 提供防攻击、防重放、请求加密、身份认证、权限管理、流量控制等多重手段保证 API 安全,降低 API 开放风险。 提供 API 定义、测试、发布、下线等全生命周期管理,并生成 SDK、API 说明文档,提升 API 管理、迭代的效率。 提供便捷的监控、报警、分析、API 市场等运维、运营工具,降低 API 运营、维护成本。 API 网关功能 API 生命周期管理 支持包括 API 发布、API 测试、API 下线等生命周期管理功能。 支持 API 日常管理、API 版本管理、API 快速回滚等维护功能。 全面的安全防护 支持多种认证方式,支持 HMAC (SHA-1,SHA-256) 算法签名。 支持 HTTPS 协议,支持 SSL 加密。 防攻击、防注入、请求防重放、请求防篡改。 灵活的权限控制 用户以 APP 作为请求 API 的身份,网关支持针对 APP 的权限控制。 只有已经获得授权的 APP 才能请求相应的 API。 API 提供者可以将调用某个API 的权限主动授予给某个APP。 若 API上架到 API 市场,购买者可以将已购买的 API 授权给自己的 APP。 精准的流量控制 流量控制可以用于管控 API的被访问频率、APP的请求频率、用户的请求频率。 流量控制的时间单位可以是分钟、小时、天。 支持流控例外,允许设置特殊的 APP 或者用户。 请求校验 支持参数类型、参数值(范围、枚举、正则)校验,无效校验会被 API 网关直接拒绝,以减少无效请求对后端造成的资源浪费,大幅降低后端服务的处理成本。 数据转换:通过配置映射规则,实现前、后端数据翻译。 支持前端请求的数据转换。 支持返回结果的数据转换。 监控报警 提供可视化的API实时监控,包括:调用量、流量大小、响应时间、错误率,在陆续增加维度。 支持历史情况查询,以便统筹分析。 可配置预警方式(短信、Email),订阅预警信息,以便实时掌握API运行情况。 自动工具 自动生成 API 文档,可供在线查看。 API 网关提供多种语言 SDK 的示例。降低 API 的运维成本。 提供可视化的界面调试工具,快速测试,快速上线。
1.需求场景 随着业务发展,一个企业开发、运营了多个网站,同时也产生了一些亟待解决的问题。 用户使用每个网站前,需要重复注册,需要记住对应的账号和密码。 用户使用每个网站时,需要一次次重新登录。 用户只是了解一个个独立的网站,企业没有在用户心中形成统一的形象。 每个产品都需要重复设计、开发和维护注册、登录等模块。 用户的信息分散在各个网站中,不利于更好的了解用户。 2.解决方案 2.1 方案说明 本解决方案基于OAuth2 协议,为网站用户提供跨网站的流畅登录体验,且拥有高性价比的弹性伸缩能力。 统一认证中心:基于 Spring Cloud Security、JWT、OAuth2 协议,提供统一认证能力,负责用户认证数据的统一管理。 需接入的网站:基于 SSO-SDK,轻量级接入统一认证体系,与统一认证中心协作,提供用户畅游企业各产品网站的最佳浏览体验。 管理中心:负责管理需接入网站的认证管理,保证统一认证体系的安全与可控。 关于用户的登录页,为保证用户的统一体验及统一企业品牌,推荐采用统一登录页的方案,同时支持少数网站需要自定义的特殊需求。 基于微服务+阿里云容器服务,提供高性价比的弹性伸缩能力。 2.2.方案优势 遵循主流的OAuth2开放协议,除能打通内部系统的用户数据外,还可在授权允许情况下,允许外部系统使用本系统的用户进行登录,如常见微信登录、QQ登录等。 Spring Security 框架技术成熟且社区活跃,稳定性有保证。 在Spring Security 框架基础上,进行增强扩展,可满足密码模式下的sso场景。 支持跨域单点登录。 基于阿里云基础设施的构建,整体系统稳定可靠。 充分发挥阿里云的弹性伸缩能力,即可控制成本,又可适应用户数量的爆发式增长。 兼顾私有云、传统 IDC 部署环境,满足不同客户的运行环境的需求。 3. 客户价值 基于此方案,帮助企业打通各产品的用户体系,且实现多种场景下的免登。企业拥有企业级的统一账号体系,建立统一企业品牌,提升用户注册与登录场景的体验。 统一的用户认证体系,实现统一认证、跨网站免登,实现 SSO。 统一的用户数据库,实现用户数据的聚合,帮助企业更懂用户。 企业级网站的统一登录页,统一品牌形象,统一用户体验。 支持产品根据特殊性选择自定义登录页。 支持用户名、手机号、邮箱等多种认证方式的扩展。 3.1 网站用户的收益 一次注册即可使用所有企业运营的产品,无需反复填写注册信息 一次登录即可所有企业运营的所有产品,即安全又便捷 3.2 企业的收益 降低用户试用企业运营产品的门槛,利于交叉营销。 减少用户反复登录,利于产品用户促活。 减少产品研发中的重复建设,降低成本,提升产品推进效率。 统一建设认证中心,便于统一和提升所有产品的账号安全。 4. 关于登录页的说明 4.1 模式一:统一登录页的SSO 此种模式无需网站实现登录页、登录接口的开发,未登录状态的用户会自动被引导到统一认证中心去登录。 4.1.1 实现原理 4.1.2 说明 技术实现整体使用spring-securiry-oauth2的 “授权码模式” 来进行实现。 4.2 模式二:网站自定义登录页 4.2.1 实现原理 4.2.2 说明 在统一认证中心与网站的实现上,除spring-securiry-oauth2之外,还需要引入云顶云研发的 “密码模式SSO” 扩展包来进行实现。 云顶云(yundingyun.com)是国内首批专注于云计算服务的提供商,致力于“让云计算更简单”。做为阿里云五星授权服务中心,云顶云致力于为企业和政府提供方案咨询、架构设计、部署实施、系统定制、运维托管、技术培训等全方位“4S”级公有云、私有云定制化服务。
1.引言 当没有手表的时候,你不清楚现在是几点。 当有了1块手表时,你知道现在是几点。 当有了2 块手表时,它们的时间显示不一致时,你又不知道现在是几点。 当你碰到有个人和你一样都有手表,但时间不一致时,你还是不知道现在是几点。 当你对着电视对标,看了眼电视显示是 6 点整,当低头调完表时,再看表这时电视又比手表快了几秒,于是又继续调表,经过几轮后,好像偏差不大了。 过了几个月,你发现手表又和电视上的不一致了…… 当学了高中物理后,知道了电视信号传播是需要时间了,知道了电视上的时间只是导播随电视画面一起传给你播放的画面,于是全国各地看到的 6 点的画面其实是有先后的。 当你出国后,发现国外有人有他们心中的“CCTV”,你又开始思考不同国家的人的时间差。 …… 2.问题分析 我们在日常生活中面临的问题,计算机系统也面临同样的问题,站在计算机系统角度面临 4 种时间。 自己的系统时间: 硬件时钟:计算机硬件有个使用电池的实时时钟(Real-time Clock, RTC)也叫(CMOS时钟,BIOS时间)。这个于电池质量和使用时长等有关。 系统时钟:又名软件时钟,由Linux内核计算为自1970年1月1日午夜UTC以来的秒数。系统时钟的初始值由硬件时钟计算。系统正常运行后,由系统内核独自运行系统时钟。 自己选择对标的基准时间:可选择自建自己的时间服务器,也可选择对标公共时间服务器 协作模块的时间:由于每个系统选取的时间坐标不同,则大家在协作时时间不一致是常态,如果凑巧一致且长期一致,真是罕见的幸事。 世界公认的标准时间:一般认为UTC和GMT是相等的,但是会存在0.9秒以内的误差,这是由于地球不规则自转引起的。 UTC(Universal Time Coordinated),即协调世界时。全世界统一的世界标准时间。需要不规则地加入闰秒。 GMT(Greenwich Mean Tim),格林尼治平均时间。 3.产品设计建议 时间不一致是常态,要基于这个前提来设计 可以以抽象的时间代替具体时间,如业务流水号 以相对时间代替绝对时间 日志要有基于自身时钟的时间戳,建立自己的时间体系,以便于自身问题的排查和定位
1、项目背景 2020年的春节被新型冠状病毒感染肺炎疫情蒙上了一层阴影,看到疫区医院IT运维志愿者的召集令以及各地同行纷纷动手开发系统为国家尽力时,我司(天津云顶云科技有限公司)作为行业的一份子,也想在这个特殊的时期做点什么,贡献自己的一份力量。 在这个时候,我们接到了合作伙伴外语教学与研究出版社的电话。原来,为了积极响应政府和教育部门“停工不停学”的号召,伙伴决定将旗下的《新概念英语》免费向社会开放,希望我们能给予技术上的支持,能尽早上线,帮助广大学生在疫情期间依然能有机会学到最好的知识。 在就产品需求、技术方案、人员情况、当地疫情等多方面的全面评估后,我们决定一起用技术奉献社会,用最短的时间完成这个公益项目的上线,并确保它能够平稳运行。 2、项目分析 2.1 时间紧 团队虽然年轻,干劲却很足,给自己立下了FLAG:从研发到上线,赶在96小时内完成目标!既然做了决定,我们就这样如火如荼地开始了紧张刺激的冲刺96小时。 2.2 压力大 结合相关的数据与经验,我们初步预估项目上线后的冲量峰值压力将会是上线前的20倍左右。 后来的实际情况也证实了这一点,2月4日上线当天,瞬间涌入的峰值压力是上线前平均值的19.4倍。因此,如何筑起高墙大坝,扛住突如其来的流量洪峰,是我们要面对的第一个难题。2.3 协作难 由于春节期间很多同学都回老家过年,项目相关的成员分散在北京、天津、山西、福建等全国各地,这也是我们团队第一次展开这么大规模的远程协作,很多问题一下子凸显了出来: 网络的问题:尤其有的同学在农村,网络不太稳定,有时信号一断只能干着急。 联调的问题:平时在公司通讯基本靠吼,或者探身看下屏幕就能了解情况,现在只能靠不停的码文字、语音、电话...... 项目管理的问题:时间紧任务重,现在只能倒排计划,就像一面开车、一面查目的地的情况... 没想到因缘际会,使我们团队可能成为了全国最早远程复工的那一波人之一 >_< 2.4 测试难 由于事发紧急,只能一边研发一边测试,这样的方式对于我们这样有着DevOps经验的团队来说倒也不是太大的难事,只是有一点比较麻烦:扛住巨大的流量压力是整个项目中最为关键的一环,如果不能做到万无一失,即使万事俱备也有可能功亏一篑。因此,我们不仅需要做足够的压力测试,还要做到严格、靠谱的压力测试;我们不仅要在测试和预发环境上做压力测试,还要在生产系统上做压力测试;我们不仅要在白天边研发边测试,还要在夜深人静压力位于谷底时在生产环境上滚动更新做压测,验证功能、查找问题、参数调优等一通操作猛如虎,然后再回滚回来确保白天用户正常使用... 3、冲刺96小时 伟人说过,一切敌人都是纸老虎。与困难狭路相逢,勇者胜!团队没有二话,只有一个字:干! 3.1 打磨需求,不放过每个细节 这个文案与这次公益行动不符,要改!这个不容易理解,要改!正向需求验证没问题,既有的系统功能呢?要验证!前台交互没问题,后台日志系统是否有影响?要分析!对其他依赖的第三方应用是否有影响?要保证兼容性!…… 3.2 持续优化,力争做到万无一失 流量增加 50%能不能抗住?流量翻倍能不能抗住?流量数十倍增加能不能自我保护?能不能动态扩容抗住压力?能不能减少流量抖动带来的不必要的弹缩?流量模型是什么样子?流量会聚集在哪个瓶颈点上?各个突发情况下,除了自动化机制外,还有哪些其他的应急措施?在这样追问、讨论中,大家不断深入思考;在各种压测数据中,大家不断探求优化的思路和可能。为了不影响既有用户的访问,所有的压测都集中深夜;为了获得真实的一手数据,敢于直接压测生产环境(这也得益于系统的鲁棒性强)。 3.3 胜利会师,圆满完成任务 连续作战 4 天 4 夜,不只 96 小时 持续发布 7 版,不断迭代完善 流量激增19.4倍,扛住了! 钉钉语音会议 30+ 次 参与的同学 20+ 名 4、解决方案 总结起来,该公益项目能快、准、狠地完成,主要得益于以下几个方面: 项目采用了微服务架构,模块之间耦合度较低,新功能上线可滚动发布,加上团队具备DevOps能力,因此保质保量地完成了研发任务。 项目完全基于阿里云的容器服务ACK构建,同时得益于阿里云强大而全面的产品矩阵来加持,使整个项目的稳定性、可靠性上更上了一层楼。 除了阿里云强大的容器服务以外,我们也用到了大量的其他产品如OSS、CDN、PTS等,强大而且全面的阿里云是本项目成功上线的幕后英雄。最终,我们利用阿里云的若干产品完成了如下方案: 这个方案具有以下特点: 应用容器化部署,享用云原生容器组资源编排能力 优化容器组集群计算资源,集群稳定性高 利用弹性伸缩以及抢占式实例,弹性低成本 解决自建集群快速扩容困难问题 内容分发网络CDN有效分担源站压力,避免网络拥塞,确保在不同区域、不同场景下加速网站内容的分发,提高资源访问速度。 4.1 方案解读:两级弹性伸缩 由于流量洪峰的不确定性(不确定什么时候到来,不确定最终的压力有多大),同时还要考虑到财务的可行性,不惜一切代价是态度,但不能作为工程实践的指南,要让花的每一分钱都有价值。因此我们最终采用两级弹性伸缩的策略: 利用ESS对整个集群进行弹性伸缩,ESS是阿里云推出的可以自动调整弹性计算资源的服务,可以根据业务需求和策略设置伸缩规则,在业务需求增长时自动为您增加ECS实例以保证计算能力,在业务需求下降时自动减少ECS实例以节约成本。 设置ESS:当CPU平均使用率达到75%或内存使用率达到80%时,会向K8S集群中添加两台ECS,以提高系统整体的服务能力。 利用K8S的HPA机制对容器资源进行弹性伸缩,最大限度利用云资源的水平弹性。HPA是实现水平伸缩的控制器,它能在当POD中业务负载上升的时候,创建新的POD来保证业务系统稳定运行,当POD中业务负载下降的时候,可以销毁POD来提高资源利用率。 设置HPA:当CPU平均使用率达到70%或内存使用率达到80%时,会水平扩展POD数量,以提高热点服务的能力。 4.2 使用HPA趟过的坑 在使用HPA的过程中,我们也遇到了一些问题,虽然历经一些波折,最终也顺利解决,这里一并记录。 问题1:在压测过程中发现,POD分布不均匀,相互间存在资源争抢的现象,导致服务器资源富裕而性能提升不上去的情况。解决办法:对于资源消耗较高的服务使用硬性反亲和,资源消耗相对较低的使用软性软亲和方式可以有效利用服务器资源,提高整体系统性能。 问题2:POD的CPU和内存的基准值配置错误,导致使用率始终超过弹性伸缩的阈值,POD直接弹缩到最大值。解决办法:调大request值,将使用率控制在HPA值之下。 问题3:POD启动消耗的资源较大,启动瞬间会将POD数量弹至最大值,从而导致整体资源使用率过高。解决办法:等服务启动稳定后再配置HPA规则即可解决。 4.3 方案解读:利用PTS进行专业准确的压力测试 PTS是阿里云推出的云化测试工具,是项目中压力测试的好帮手。它可模拟海量用户的真实业务场景,全方位验证业务站点的性能、容量和稳定性。通过较低的人力和资源成本,构造出最接近真实业务场景的复杂交互式流量,快速衡量系统的业务性能状况,为性能问题定位、容量最佳配比。 利用PTS,我们进行了100多轮不同接口不同规模的压力测试,快速地定位问题、解决问题和回归验证,是项目压力测试的绝世神器!通过这些压测实践,我们也总结了一套关于压力测试的心得: 根据接口需要达到的并发,来进行首次递增式压测,来查看目前接口能达到多大的并发。 压测完成后,查看压测数据,查看RDS,ECS,Reids等监控,从资源方面入手来查找瓶颈,来查看是否是连接数设置的问题,还是资源性能问题。 从架构方面来进行排查,从底层一步一步来排查。先将直接压接口,看看接口能达到多大 并发,然后在加上SLB来压测,来看是否是服务配置问题。 4.4 使用PTS趟过的坑 问题1:使用PTS压测时发现来源IP过于集中,如何能让压测数据更有可信度?解决办法:经优化,选择了扩展来源IP和指定地域配置来进行压测,从而实现压测数据的可信性。 问题2:模拟大量客户注册登录,最开始创建的压测创景是只使用一个账号密码来进行反复登录,也存在压测数据的可信度问题。解决办法:后来经优化场景,采用自定义参数,随机生成一些数据库中没有的账号,来进行传参,更真实的模拟了用户登录场景。 问题3:不通时间段,同一个接口压测结果相差较大。解决办法:在压测的时候有时候可能会有网络抖动,影响压测结果,同样的接口,在没有任何修改的情况下,白天和凌晨压测的结果,相差较大,白天TPS相对要高一些。由于客户的正式站不能在业务繁忙的时候进行压测,所以将测试站配置对齐正式站,选择客户业务繁忙时间,来进行压测测试站,最后来和正式站压测数据对比。PTS的报告十分直观,信息也很详尽。 4.5 方案解读:利用CDN分发加速减轻源站压力 由于终端用户分布在全国各地,但课程的音频资源放在阿里云的华东2地域(上海),距离较远的用户在使用过程中就会出现较高的延迟。为了解决这个问题,我们引入了CDN。利用CDN分布在各地的边缘节点,有效分担源站压力,避免网络拥塞,确保在不同区域、不同场景下加速网站内容的分发,提高资源访问速度。 5 项目总结 紧张刺激的96小时,通过伙伴外研社团队、云顶云团队和阿里云的精诚协作,最终顺利完成,上线后用户好评如潮,我们也在全国共克时艰的时候,为抗击疫情贡献了自己的一份微薄之力,也为云顶云在云原生、微服务的探索之路上添加了重要的一笔。以不远的将来,云顶云将继续秉持“让云计算更简单”的理念,立足于阿里云强大的技术与生态,服务更多用户,为祖国蓬勃发展的互联网事业继续贡献自己的力量。
云计算时代 Java 运行时不止 JRE 前言 Java 语言于 1995 年由 Sun 公司首次发布,次年发布了 Java 开发工具包也就是常说 Java Development Kit 简称 JDK1.0,截止到目前为止最新的版本为 JDK13.0。JRE(Java Running Environment)即 Java 运行环境,包括 JVM、核心类库、核心配置工具库等。 在云计算时代,部分开发者对 Java 运行环境的了解还局限在比较早期的基础设施角度,限制了很多架构设计,也造成了很多不必要研发投入。 本文尝试基于自己的见闻梳理一下,在当下的技术条件下,Java 的运行环境有哪些?以便于开发者可以选择一个相对更合理的基础设施上,开展研发工作。 1.0 单机时代 单机时代也是 Java 语言诞生的年度,标准的 JRE 是比较好的选择,有些开发者喜欢用 JDK 做运行环境,有其合理性。 在这个时代或者这种模式下,依然有很多选择,包括 JRE、JDK 的不同发行商的不同版本,主流的包括 Oracle、Sun 的版本,以及由 IBM、SAP、微软等发布基于OpenJDK的版本。整体基本兼容,但受一些商业版权、安全、发行商环境等原因,还是略有一些差别。另外,还有一支流是国产 CPU 厂商及操作系统厂商发布的 JDK。 Java 开发者都熟悉 JVM(Java Virtual Machine),但很多人不了解的是不同发行版中的 JVM 核心可能是不同的。有兴趣的同学可以阅读一下《深入理解Java虚拟机:JVM高级特性与最佳实践》。 在这里推荐大家试用下一下阿里发布的 OpenJDK : Alibaba Dragonwell。它是一款免费的, 生产就绪型Open JDK 发行版,提供长期支持,包括性能增强和安全修复。Alibaba Dragonwell作为Java应用的基石,支撑了阿里经济体内所有的Java业务,完全兼容 Java SE 标准,可以在任何常用操作系统(包括 Linux、Windows 和 macOS)上开发 Java 应用程序, 运行时生产环境选择Alibaba Dragonwell。GitHub地址 2.0 Web 时代 Web 时代最知名就是那只叫 Tomcat 的猫,属于 Apache 基金会的项目。Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器。虽然它具有处理HTML页面的功能,但大家更多是将其作为Servlet和JSP容器。(http://tomcat.apache.org/index.html) 这一次进步的意义在于:开发者可以专注于应用逻辑开发,而不用关心网络通讯以及如何让应用作为一个服务来运行,相关职责转交给了 Tomcat。 对等的应用服务器还有WebLogic、JBoss 等等。 3.0 大数据时代 大数据时代最知名的系统当推 Hadoop。其核心是借鉴Google的那篇MapReduce论文里所说的思想:Our abstraction is inspired by the map and reduce primitives present in Lisp and many other functional languages。 Hadoop 框架是由 Java 开发的,虽然 MapReduce 应用程序不一定用 Java 开发,但血溶于水的 Java 是比较好的选择。尤其那个著名的示例 WordCount 就是基于 Java 编写。(http://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html) 这一次进步的意义在于:Java开发者可以不用关心数据处理框架,只需要聚焦在如何用 MapReduce 的思想来拆解要做计算任务。 对等的还有Apache Spark及这两年比较火的 Apache Flink。不过不同大数据框架的计算模型有差异。 4.0 云计算时代 如今我们处在云计算时代,面临的可选方案就多了很多。善用这些新的 Java 运行环境,会让开发者的效率有质的提升。 4.0.1 伪云计算版 伪云计算版就是买一台 ECS,在上面按照单机时代或者 web 时代的模式运行 Java 程序。这种模式的好处很明显。 学习成本低,上手快。 线下迁移线上速度快,几乎不需要多少改造。 初始化阶段的货币化投入少。 这种模式本质上是在利用云计算的虚拟化特性+硬件运维服务外包,对于开发者而言没有什么质的变化,还得不断的发明轮子。 4.2 真云时代的运行时 如今公有云厂商提供了很多更多封装的Java 运行环境,以期让开发者专注于更有价值的创造工作。下面以阿里云的产品为例来介绍,如何进一步将非核心业务的开发任务外包给运行环境。 4.2.1 企业级分布式应用服务 EDAS 企业级分布式应用服务(Enterprise Distributed Application Service, 简称 EDAS)以阿里巴巴中间件团队多款久经沙场的分布式产品作为核心基础组件,面向企业级云计算市场提供高可用分布式解决方案,是阿里巴巴企业级互联网架构解决方案的核心产品。EDAS 充分利用阿里云的资源管理和服务体系,引入阿里巴巴中间件整套成熟的分布式产品,帮助企业级客户轻松构建大型分布式应用服务系统。 EDAS是一个应用托管和微服务管理的 PaaS 平台,提供应用开发、部署、监控、运维等全栈式解决方案,同时支持 Spring Cloud、Dubbo 等微服务运行环境。开发者可以选择WAR、JAR、镜像等不同模式来部署引用。 这种模式的好处是:开发者在企业级平台上编写业务代码,代码一经部署,整个系统即拥有了企业级的高可用能力,省去了自选、自学、自建、自管的行业标杆级方案的学费和时间。 4.2.2 Web应用托管服务(WEB+) Web应用托管服务(Web+)是一款用来运行并管理Web类、移动类和API类应用程序的PaaS产品,可以使用Java编写并构建应用程序。在无需管理底层基础设施的情况下,即可简单、高效、安全而又灵活的对应用进行部署、伸缩、调整和监控。 开发者只需要关注应用代码,即可在零服务器管理和配置的情况下发布一个应用部署环境。在团队内部,可通过文件共享或源代码管理的方式快速分发配置描述文件给所有成员从而快速拉起部署环境。若使用的是开源技术,可使用Web+官方或开源提供方分发的公共配置描述文件来快速搭建测试或生产环境。 这种模式的好处是:开发者可以集中精力编写代码,将管理和配置服务器、数据库、负载均衡器、防火墙和网络等工作交由Web+代劳,相对于 EDAS 会轻量一些。 5.0 函数即服务 函数即服务的核心是让开发者进一步聚焦业务代码,其中Serverless 应用引擎略重,函数计算至轻。 5.1 Serverless 应用引擎 Serverless 应用引擎(Serverless App Engine,简称 SAE)是面向应用的 Serverless PaaS 平台,帮助 PaaS 层用户免运维 IaaS,按需使用,按量计费,实现低门槛微服务应用上云,有效解决成本及效率问题。支持 Spring Cloud、Dubbo 和 HSF 等流行的开发框架,真正实现了 Serverless 架构和微服务架构的完美融合。除了微服务应用外,后续还会支持更多其它类型的应用。 区别于其它 Serverless 产品,SAE 支持 Spring Cloud、Dubbo 等开发框架,真正实现了 Serverless 架构 + 微服务架构的完美结合。支持 WAR、JAR、镜像三种方式部署,让零容器基础的初级用户也能享受 Kubernetes 的技术红利。 5.2 函数计算 函数计算(Function Compute)是一个事件驱动的全托管 Serverless 计算服务。开发者无需管理服务器等基础设施,只需编写代码并上传。函数计算会为开发者准备好计算资源,并以弹性、可靠的方式运行代码。 当前云计算的抽象粒度大多在机器级别,要管理和使用这些计算资源仍然有不小的门槛和成本。阿里云函数计算为解决计算成本和效率问题而生,将计算服务的抽象粒度提高到了函数级别,打造无服务器概念的应用设计模式。 使用函数计算,开发者将业务代码部署到函数计算,并以事件驱动的方式触发函数执行,服务就可以平稳运行。开发者无需再为环境部署、服务器扩容、服务器宕机等问题烦恼,函数计算提供弹性的扩容机制,并按量计费。此外,函数计算提供日志查询、性能监控和报警等功能,帮助快速定位问题、排查故障。 这种模式的意义在于:让开发者回归到函数层面,关注入参、出参、业务逻辑。当然额外的代价是,需要开发者重新基于新的基础设施,来构思服务架构,很多既有的经验都需要重构。 示例如下: package example; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class HelloFC implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { // 在此编写业务代码 outputStream.write(new String("hello world").getBytes()); } }' // pom.xml <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.0.0</version> </dependency> 云顶云(yundingyun.com)国内首批专注于云计算的云服务提供商,致力于“让云计算更简单”。作为阿里云五星授权服务中心,为企业和政府提供“4S”级公有云、混合云、私有云、容器等定制化服务。 为助力企业上云,云顶云技术团队拥有从方案咨询、架构设计、部署实施、系统定制、运维托管、技术培训等全方位的服务能力。
1. 传统产品研发的不得已 传统产品研发过程中,包含有很多默认的准备工作,包括环境的准备、组件的选型及部署等,如: 数据库的选型、高可用方案的设计及部署 中间件的选型、高可用方案的设计及部署 基础功能模块的设计、开发 …… 以上这些工作的重要性不言而喻,而且技术挑战性高,普通的研发人员无法担当;另一面的事实是,这些问题每天在不同的研发团队中,不停的被解决。 2. 基于云计算的产品研发模式 2.1 基本理念 专业的团队做专业的事情 不重复发明轮子 2.2 构建基于核心能力互补的三层合作体系架构 层次 模块定位 合作要求 合作模式 详细能力 核心业务层 业务技术:商业模式的核心逻辑 自主、可控 自研 产品的核心竞争力,至少要主控设计 云计算应用层 应用技术:基于云计算平台,设计核心业务逻辑的底层架构 充分发挥云计算的平台的能力,又兼顾财务计划 外协 熟悉云计算,且实践经验丰富 云计算平台层 平台技术:IaaS、PaaS 稳定可靠,一站式满足平台级需求 采购 主流优先 3. 案例剖析:四周从构思到发布千万级用户的在线系统 3.1 背景 某出版行业领军企业A拥有业内最优质的版权资源,经过数十年经营取得了卓著的市场领先地位和业界口碑。在新的时代形势下,遇到新的机遇与挑战: 如何更有效的打击盗版? 如何实现既有优质版权资源的保值增值? 如何更好的顺应数字化教育的潮流? 如何布局未来新的业务增长点? 3.2 产品需求 解决方案包括线上和线下两个环节: 线下:升级版权出版材料,增强防盗版布局,增流量入口 线上:布局在线平台,支持商品发布及应用 3.3 建设需求 建设期短 VUCA 时代市场瞬息万变,留给参与者的机会窗口期越来越短;业务方希望能尽快上线系统,不断迭代,快速验证商业模式。 稳定性高 由于直接面向市场发布产品,且要符合业务方既有的市场定位。上线的系统功能可用逐渐丰富,但品质需要有保障。 业务负载增长速率不定 由于在业务探索期,初始用户数量不高,但有明确的市场引爆计划;届时系统会面临压力暴增的情况,故系统需要根据负载情况同态扩缩容,即满足成本控制的要求,也可容纳潜在的市场增长。 3.4 三方合作 强强联合 某出版行业领军企业 优势: 优质版权资源。 优异的顶层业务模式设计能力。 深谙行业特性,产品设计更贴近用户。 云服务商(云顶云科技) 优势: 深耕云计算多年,丰富的云计算应用架构能力和经验。 拥有从销售到服务再到产品研发的完整体系,易于与业务层沟通协作。 从架构到研发,再实施、维护的全托管式服务能力。 公有云厂商(阿里云) 优势: 国内领先,国际一线公有云厂商。 产品品类丰富,一站式采购,利于技术栈精简,简化商务协作成本。 经历若干双十一的严峻考验,稳定性高。 3.5 实施效果 基于云计算的高效研发, 4 周完成从概念设计到上线发布 专业团队:产品设计高效协作 + 深谙云计算应用之道 + 完整可靠的公有云平台 聚焦业务:复用网络、存储、计算、安全等阿里云成熟技术,只开发业务代码 基于云计算的高扩展性,一套框架应对业务从 0 到千万级的弹性需求 技术挑战:业务初期的低业务量与业务爆发期时的高负载应对 架构方案:项目团队聚集业务,充分发挥阿里云平台的伸缩特性 4. 属于挑战者的黄金时代 云计算带来的不只是研发效率的提升,更深层的变革是对创业者的巨大赋能,让初创企业挑战巨头成为可能。 史前的创业模式 没产品时:自己动手丰衣足食,缓慢前行 有产品 V1.0 时:VC 希望看到增长,根据数据来估值 有好的增长率时:VC 问如果腾讯也做怎么办? 创业者一边痛苦重构系统以匹配不断增长的业务,一边积极思考怎么回答时,但腾讯版出现了…… 云计算时代的创业模式 没产品时:聚焦核心业务,不断迭代试错。 有产品 V1.0 时:借风、借势营销,瞬间引爆增长,同时依靠底层基础设施能力,扛过了业务数千倍的增长。 腾讯版出现时,你的创业产品已经占领了客户的心智。如腾讯复活微视,也难撼动抖音在用户心中的位置。 云计算时代是属于挑战者的黄金时代,只要你拥有足够好的产品模式规划能力和产品运营能力,其他一切非核心业务都可以外包、采购。一个商业idea从构思到市场验证的节奏,在不断加速,让精益创业更为可能。云计算时代真正 PK 的是产品能力和运营能力。
序言 在产品研发过程中,经常有一些所需的基础组件模块,推测有一定的通用性,于是我们会考虑引入一些开源技术。此时如何引入就需要一些注意点,包括: (1)对开源技术的可用性负责 开源技术引入系统后,属于系统的一部分,自此你需要对它的可用性负责。需要将这些代码当做自己的代码管理起来,包括源码、依赖库、组件包、相关文档等。开源技术社区是不做任何可用性的承诺的。 (2)开源技术的技术成熟度 开源技术的起因千差万别,其发展历程更是各有各的故事。开源只是代码公开,提供了一种利用群众的力量来发现问题、解决问题的能力,但是否能转换为实际,真的很难。对于普通开源技术,更多的价值是提供了一种设计参考,一种技术迭代的基础。 (3)许可授权的范围 开源不等于免费,不同的授权,不同的使用方案。开源领域的授权协议五花八门,即使你仔细研究半天,也未必能理解,它最终是怎么授权你使用。如果你开发的是商业软件,则需要注意一下,避免不必要的麻烦。 引入开源技术的 4 个阶段 这里提供一些思路,以抛砖引玉。 阶段 1:技术选型 此阶段为粗筛,去掉一些明显有风险的选型,以便下一步能聚焦在更有价值的候选项上。每个组织的的选型要求不同,但事先确定一些标准,然后针对候选项逐一评估,会让选型更有条理、更可靠。如 选型标准 GitHub star数 版本发布周期 社区活跃度 开发语言 依赖库分析 文档可用性 授权协议 应用案例 第三方评测数据 方案1 …… …… …… …… …… …… …… …… …… 方案2 …… …… …… …… …… …… …… …… …… 方案3 …… …… …… …… …… …… …… …… …… 阶段 2:技术实测 在初步选型后,需要实际测试的范围就缩小很多。这时需要从自己的应用场景中,抽象出一组测试场景,并验证其可用性。包括: 开发难易:上手实际写一下,便于掌握使用的复杂度。 场景支持度:不需要全,但需要有代表性;不需要真接入系统,模拟测试即可。 性能:不同负载下的性能表现,0.5x、1.0x、1.2x、1.5x…… 稳定性:给定负载下的,稳定运行结果,包括是否宕机,内存是否正常等。 阶段 3:工程应用 场景一:多人协作时 现代软件更多是多人协作开发,在引入新的开源技术后,需要将其引入到团队中,避免一下导致其他伙伴都编译失败,各种抱怨。如果不需要他人关注,则做好隔离设计即可。 场景二:基础组件的基础化 通常使用基础组件时,只需要一次编译发布即可,后续简单引入即可,即降低了编译效率,也保证了组件的品质(重复编译的结果不一定一致)。 场景三:酌情融入到团队的基础设施中 例如团队使用Maven来做包管理,则遵从团队的工程实践规则,将引入的开源技术的包管理起来,妥善解决由此引发的一些冲突问题。 阶段 4:回馈社区 开源是一种技术精神,作为开发者,我们既要积极使用开源技术,同时也要基于自己的能力,积极将使用中问题、尝试的改进回馈到社区,促进后续的版本解决自己的问题。 阶段 4:回馈社区 开源是一种技术精神,作为开发者,我们既要积极使用开源技术,同时也要基于自己的能力,积极将使用中问题、尝试的改进回馈到社区,促进后续的版本解决自己的问题。
1. 为什么要关注敏捷? 1.1 响应市场的研发变革 更快变化:市场、竞争、资本、技术、社会 顺势而为:为了生存而不得不适应 敏捷的起因是软件行业的自我进化,是面对不断加速的需求变更与技术复杂度双重挑战下的管理实践,希望借助一些方法论上的变化,适应变化。时至今日,我们所处的环境的变化在不断加速中,从市场、竞争、资本、技术、社会等方方面面都在经历着快速的演进。尤其是云计算的普及应用,进一步加剧了变化的加速。一个业务从灵感到上市可能是倍速的提升,进而要求其他市场的参与者也同步加速应对。变化无法拒绝,只有顺势而为,跟随变化,把握变化带来的机遇。 1.2 敏捷引发的采购变革 资金的来由:年度预算 vs 市场驱动 大部分企业的采购资金来自按年编制的年度预算,面对现在的环境,越来越多面临预算编制难,调整周期长的内部挑战,业务发展强烈需要由市场驱动来安排资金。 资金的使用:批量采购 vs 碎片化采购 根据年度预算,企业很容易实现批量采购,从而实现采购成本的降低,但受变化的影响,决策风险提升高,采购到位的产品不一定是业务当时需要的,造成资产闲置,最终的总体费用不一定低。碎片化采购模式导致在单次采购时,企业缺少谈判的话语权,采购单价难以控制,但由于按需采购,减少了资产闲置、过度采购的情况的发生。总体的费用也不一定低。 资金的决策:集中采购权 vs 下沉采购决策 按需付费导致业务人员实质决定了费用的发生。之前采购源自层层的审核,先审核后花费,而采用云计算模式后,业务一线人员的操作模式有可能会导致业务的费用有重大的差别,他们是最了解采购需求的人,也是最有可能优化使用模式的人,但却没有采购权,导致需求和决策分离,决策的质量和效率都面临挑战。业务呼吁下沉采购决策。 1.3 敏捷 –DevOps 之基 DevOps 是这几年运维岗位不断讨论和探索的实践。但业务的发展需要一个循序渐进的过程,敏捷解决了产品研发环节的效率问题,进而引发借助持续发布支持产品的持续销售的可能,而持续部署又进一步将软件的价值直接呈现在客户面前,实现了需求到价值的加速流转。而这一切的累计必然会面临部门间的协作问题,在推进敏捷、持续发布、持续部署过程中就孕育着 DevOps 的推行和实践。而且敏捷、持续部署、DevOps 等彼此借鉴相互提升,边界已经比较模糊。 1.4 敏捷 – 不止于产品 敏捷是一类方法论,不局限于产品研发、技术服务等传统敏捷适用场景。精益创业、MVP 等都是敏捷思想在企业经营领域的探索。 2. Scrum 的 “3355” 敏捷有很多种实践,但目前流行度最高的是 Scrum,本文后续以 Scrum 为例介绍敏捷具体是什么。Scrum 核心可以简化为 “3355”,即 3 个角色,3 个工件,5 个活动,5 个价值观。具体可以参考 Scrum 指南。这些都可以理解为一些最佳实践,而不是束缚你实践的条条框框。在理解每项背后的初衷后,其具体落地实践就可以因地制宜了。 3. Scrum 框架 Scrum 围绕着 Sprint 冲刺展开,从需求的管理、版本规划的制定,再到版本的开发,和传统工作模式有一些差别。最核心的是对 Sprint 这个时间盒的理解和认同,以及由此产生的相关影响的接受和遵循。这里面的核心 2 个因素,一是 Development Team 的形成,要求很高,需要很长时间的不断打磨,另一个是能容纳 Scrum 的组织氛围或环境,允许 Scrum 团队有一些不同。针对后者,很多实践是对内敏捷,对外用传统项目管理的模式来封装,从而实现夹缝中生长。
9 月 24日来自全球的阿里云 MVP 相聚杭州云栖小镇,共话技术发展与产业发展,携手践行:“平凡人的做不凡的事”。 感触一:技术界的老友聚会 因为共同的身份与价值追求,我们从世界各地相聚到一起。看到一张张熟悉的面孔,倍感亲切;而很多新面孔的加入,让 MVP 这个团体充满了活力。老朋友间除了久别后的关怀,更有合作共创的不断探索,从技术问题的论道,到商业模式的讨论,再到项目合作机会的探索,让大家有了更多的收获。 感触二:云计算价值的不断深入理解 企业上云大致分为三个层次,第一个层次倾向于将既有系统迁移上云,享受 IaaS 层带来的弹性,同时收获成熟运维解决方案服务的额外收益……第二层次,大致是基于 PaaS 层,新建或重构业务设施,享受非核心业务组件的极速就位,不必重新发明轮子,也不必重蹈前人的覆辙。比如要引入Redis,传统研发团队需要去从开源版本中选择一个版本,并尽量做测试验证,还要投入资源做部署维护,后续也不能及时且正确的升级 Redis 版本。第三个层次,大致是充分享受云计算平台的能力,用技术为业务赋能,用数据挖掘业务价值。 感触三:云上安全的探讨更透彻 云计算的安全焦虑来源于边界的变化,更深层次是对云计算的安全问题的误解。之前在云下安全,其实是一种假象。机器在自己手里,软件在自己服务器上,数据存在自己的服务器上,就安全?大部分 IT 系统投产后,安全检查或因制度原因、或因技术原因、或因效益不直接等很难有效执行。这很可能导致自己成为最后知道自己系统出现系统漏洞的情况。企业上云后,平台会协助做一些安全检查与提醒的工作。在看到这些安全提醒后,有些人会认为云计算不安全,但这恰恰凸显了云计算平台的安全优势。云平台上会提示的安全隐患,是平台帮助客户了解到安全问题,于是为了解决安全营造了可能的机会。 安全专家、产品帮助用户提前了解安全风险; 高效的安全产品部署流程,帮助用户能快速拥有安全能力; 让专业的安全人员做专业的事,帮助用户减少不必要的安全技术积累资金成本及时间成本。 感触四:云计算时代的 IT 项目管理挑战 云计算在重构 IT 系统架构的同时,也在驱使 IT 项目管理方法论和实践的提升。 开发人员不必重复发明轮子,于是业务研发投入及迭代速度可能加速,从而对 IT 管理的敏捷度、架构重构等要求不断提升。 在业务钱景不明朗前,以按需付费的采购模式,能尽快低成本试错,从而实现了快速失败的研发理念。 后续作为今年目标,想整理出一套成型的方法。 感触五:Serverless 新开发基础设施将对研发带来极大变化 Serverless 不是从天儿降的黑科技,是众多技术积累与演化的产物,也是云计算发展至如今的一种必然。Serverless在不同厂商有不同的工程实践和产品设计,以下以阿里云函数计算为例说明。1.函数计算让开发者前所未有的将精力聚焦于核心业务本身;2.函数计算让开发者充分享受云计算技术设施的技术红利,以更高速的市场响应速度;函数计算同时也为工程实践提出了新的挑战,包括: 如何本地化开发与云发布的协同? 如何高效使用全局变量,让多次函数调用高效累计? 如何高效协同多函数间的协同?类似线程间的协同。
如何只克隆部分代码? 一、需求 根据整体规划需求,多个模块的源码共存在一个仓库中。在一些场景执行中,需要考虑执行效率,仅关注部分路径的代码。即仅需获取部分路径的文件。 二、解决方案 利用Sparse Checkout模式。官方信息描述如下: Sparse checkout "Sparse checkout" allows to sparsely populate working directory. It uses skip-worktree bit (see git-update-index(1)) to tell Git whether a file on working directory is worth looking at. "git read-tree" and other merge-based commands ("git merge", "git checkout"…) can help maintaining skip-worktree bitmap and working directory update. $GIT_DIR/info/sparse-checkout is used to define the skip-worktree reference bitmap. When "git read-tree" needs to update working directory, it will reset skip-worktree bit in index based on this file, which uses the same syntax as .gitignore files. If an entry matches a pattern in this file, skip-worktree will be set on that entry. Otherwise, skip-worktree will be unset. Then it compares the new skip-worktree value with the previous one. If skip-worktree turns from unset to set, it will add the corresponding file back. If it turns from set to unset, that file will be removed. While $GIT_DIR/info/sparse-checkout is usually used to specify what files are in. You can also specify what files are not in, using negate patterns. 三、基本操作过程 1. 准备 $mkdir code_dir $cd code_dir $git init $git remote add -f origin <url> 2. 启用sparsecheckout模式 $git config core.sparsecheckout true 3. 设置排除的路径 编辑 .git/info/sparse-checkout $echo “want_dir/*” >> .git/info/sparse-checkout 4. 拉取代码 $git pull origin master 四、如何设置sparsecheckout文件 子目录的匹配 如果目录名称前带斜杠,如/docs/,将只匹配项目根目录下的docs目录 如果目录名称前不带斜杠,如docs/,其他目录下如果也有这个名称的目录,如test/docs/也能被匹配。 如果写了多级目录,如docs/05/,则不管前面是否带有斜杠,都只匹配项目根目录下的目录,如test/docs/05/不能被匹配。 通配符 “*“ (星号) 支持通配符 “*“,如可以写成以下格式: *docs/ index.* *.gif 排除项 “!” (感叹号) 支持排除项 “!”,如只想排除排除项目下的 “docs” 目录,可以按如下格式写: /* !/docs/ 五、如何关闭sparsecheckout模式 将core.sparsecheckout设为false 修改 .git/info/sparse-checkout 文件,用一个”*“号替代其中的内容 执行 checkout 或 read-tree 命令 六、注意事项 如果排除是临时性的,要及时清除相关设置,否则就是一个隐患,即导致环境不可重入。 仅限 Git 1.7以上版本 参考 https://blog.csdn.net/u022812849/article/details/53025248 http://schacon.github.io/git/git-read-tree.html#_sparse_checkout https://zhgcao.github.io/2016/05/11/git-sparse-checkout/
在 CMake 入门1/5:基于阿里云 ECS搭建体验环境,我们搭建了 CMake的运行环境,下面我们以 helloworld 为例,体验 CMake 工作的基本流程。 1 源文件说明 共包含2个文件,一个 c++文件 helloworld.cpp,另一个是CMakeLists.txt。也可到这里下载:https://github.com/huangjunlei/How2Work/tree/master/DevOps/cmakedemo 1.1 helloworld.cpp helloworld.cpp为你开发的源码文件,自由命名,自由书写内容。 #include<iostream> int main(int argc, char *argv[]){ std::cout << "Hello World!" << std::endl; return 0; } 1.2 CMakeLists.txt CMakeLists.txt为 cmake 工作的输入文件,命名固定,格式语法固定,以下为示例,实际开发中要根据工程结构来编写。 cmake_minimum_required(VERSION 2.8.9) project (hello) add_executable(hello helloworld.cpp) 第1行声明需要的最低 cmake版本 完整语法为cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]] [FATAL_ERROR]) 扩展阅读:https://cmake.org/cmake/help/v2.8.12/cmake.html#command:cmake_minimum_required 第2行声明项目名 完整语法为: project(<projectname> [languageName1 languageName2 ... ] ) 扩展阅读:https://cmake.org/cmake/help/v2.8.12/cmake.html#command:project 第3行声明执行体名称及源码列表 完整语法如下: add_executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN) 扩展阅读:https://cmake.org/cmake/help/v2.8.12/cmake.html#command:add_executable 2 编译过程 2.1 生成 Makefile cmake 的命令形式为: cmake [options] <path-to-source> cmake [options] <path-to-existing-build> 扩展阅读:https://cmake.org/cmake/help/v2.8.12/cmake.html#section_Usage Demo示例执行过程如下: [root@myecs]# cmake . -- The C compiler identification is GNU 4.8.5 -- The CXX compiler identification is GNU 4.8.5 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/cmakedemo/demo1 解释 首先,CMake检测运行环境,如没有 c++编译器会报附件三的错误;检测通过后,CMake 会生成工程所对应的 Makefile。需要强调的是,Makefile允许查看,但不要尝试编辑,而且下次执行时它也会被覆盖。 2.2 查看生成结果 [root@myecs]# ls CMakeCache.txt CMakeFiles cmake_install.cmake CMakeLists.txt helloworld.cpp Makefile [root@myecs]# ls -l Makefile -rw-r--r-- 1 root root 4767 1月 30 20:04 Makefile [root@myecs]# more Makefile # CMAKE generated file: DO NOT EDIT! # Generated by "Unix Makefiles" Generator, CMake Version 2.8 ...... # because they might be regenerated. cmake_check_build_system: $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 .PHONY : cmake_check_build_system 2.3 编译 在 Makefile 生成后,可以使用make 进行编译工程。 [root@myecs]# make Scanning dependencies of target hello [100%] Building CXX object CMakeFiles/hello.dir/helloworld.cpp.o Linking CXX executable hello [100%] Built target hello 2.4 查看编译结果 [root@myecs]# ls CMakeCache.txt CMakeFiles cmake_install.cmake CMakeLists.txt hello helloworld.cpp Makefile [root@myecs]# ls -l hello -rwxr-xr-x 1 root root 9176 1月 30 20:13 hello 2.5 执行著名程序 helloworld [root@myecs]# ./hello Hello World! 至此 cmake 使用完整流程就结束了。当然对于 helloworld 这个程序,有些杀鸡用牛刀,但利于整体理解 cmake 的应用流程。 3 相关文章 CMake 入门1/5:基于阿里云 ECS搭建体验环境
需求 文档版本清晰化,充分利用Git 的版本管理能力,轻松对比不同版的修改演进。 减少在文档格式排版上的投入,争取简历上不再有精通word。 充分利用开发者既有工具,减少工具量,少就是多。 工具链 OS:macOS Mojave V10.14.3 IDE:Visual Studio Code Visual Studio Code扩展插件: markdownlint:在写书中如有违规,会在编辑区提示你。 Markdown PDF:将 md 文件转换为 pdf、html、jgp 等,便于非技术人员阅读。 Preview:预览最终效果。 Excel to Markdown table: 将 Excel 表快速变成 markdown 格式的。 技术文档基本元素的实现 文章标题及各章节标题 用“#”来标记标题,每增加一级增加一个 # ,字号也会减小。# 和文字之间留一个空格。 # 史上最牛的设计方案 ## 1. 产品需求 ### 1.1 功能需求 #### 1.1.1 移动端需求 ##### 1.1.1.1 iOS 版需求 ###### 1.1.1.1.1 支持 Carplay ### 1.2 非功能需求 ## 2. 产品设计 ## 3. 资源需求 信息列表 在文字前面加上 * 或 数字 1. 2. 3. 等即可显示列表。 无序列表的语法示例 * 性能需求 * 稳定性需求 * 兼容性需求 无序列表的显示效果 性能需求 稳定性需求 兼容性需求 有序列表的语法示例 1. 设计约束1 2. 设计约束2 3. 设计约束3 有序列表的显示效果 设计约束1 设计约束2 设计约束3 表格 语法示意 | 序号 | 姓名 | 年龄 | |---- |:----:| ----:| | 1 | 张三 | 20 | | 2 | 李四 | 30 | | 3 | 王五 | 40 | 显示效果: 序号 姓名 年龄 1 张三 20 2 李四 30 3 王五 40 说明: ”:---:“ 居中对齐 ”---:“ 右对齐 默认左对齐 基于插件快速搞定 手工编辑大表有点反人性,基于“Excel to Markdown table”会省心很多,具体如下: 在 Excel 中建好所用表 回到VS Code 中,打开需要粘贴的 md 文件 使用快捷键“Shift + Alt + V” 完成。 嵌入代码 需要引用代码时,如果只引用一段,不用分行,可以用 ` 将语句包起来。 如果引用的语句为多行,可以将```置于这段代码的首行和末行,在开始的```后面加上语言,便于相关解析器排版配色。 示例1: bash语句 示例1:语法 ```bash #!/bin/bash echo Hello world ``` 示例1:最终效果 #!/bin/bash echo Hello world 示例2: sql语句 示例2:语法 ```sql SELECT Persons.LastName, Persons.FirstName, Orders.OrderNoFROM PersonsINNER JOIN OrdersON Persons.Id_P = Orders.Id_PORDER BY Persons.LastName ``` 示例2:最终效果 SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons INNER JOIN Orders ON Persons.Id_P = Orders.Id_P ORDER BY Persons.LastName 链接 语法 [a link](https://commonmark.org/) 最终效果 a link 图片 与链接类似,使用 [图片说明](图片地址)]] 来展示图片。 网络图片  本地图片 [本地图片](本地图片地址) 引用 在需要引用他人的参考信息时,在引用的文字前面加上 > ,例如: > TPC Benchmark E is an on-line transaction processing (OLTP) benchmark. TPC-E is more complex than previous OLTP benchmarks such as TPC-C because of its diverse transaction types, more complex database and overall execution structure. 注:> 和文本之间要保留一个字符的空格。 最终显示效果: TPC Benchmark E is an on-line transaction processing (OLTP) benchmark. TPC-E is more complex than previous OLTP benchmarks such as TPC-C because of its diverse transaction types, more complex database and overall execution structure. 生成外发文档 按 F1 按提示选择 “markdown-pdf: Export (pdf)” 按回车,即生成 PDF 文件 常用Tips 获得目录的树形展示 Mac默认没有 tree 命令,又不想安装其他工具,可以通过下面的命令来救急。 find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g' 预览效果 方式1:使用侧边预览 优点:markdown 编辑窗口与预览窗口并列,及时反馈。 不足:空间受限,会影响排版效果。 点击编辑框右上角图标启动。 方式2:使用独立页面预览 优点:完整展示效果 不足:反馈滞后 快捷键:Shift + Cmd + V 扩展阅读 https://commonmark.org/ https://thisdavej.com/build-an-amazing-markdown-editor-using-visual-studio-code-and-pandoc/
序言 CMake 入门共分为五个小节,规划如下: 基于阿里云 ECS 搭建体验环境 第一个程序 helloworld 体验有目录结构的项目构建 构建共享库 构建静态库 实验环境 本系列基于阿里云 ECS 环境进行,具体基本信息如下: ECS 配置 CPU 1核,内存 1G,网络 1M,磁盘 20G 登录后的信息 Welcome to Alibaba Cloud Elastic Compute Service ! OS 版本 [root@myecs]#uname -a Linux 3.10.0-514.26.2.el7.x86_64 #1 SMP Tue Jul 4 15:04:05 UTC 2017 x86_64 GNU/Linux [root@myecs]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) OS 自带的gcc 版本 [root@myecs]# gcc --version gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) Copyright © 2015 Free Software Foundation, Inc. 本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保; 包括没有适销性和某一专用目的下的适用性担保。 搭建体验环境 1.安装 CMake ECS 默认没有安装 CMake,需自行安装。 安装命令 [root@myecs]#yum install cmake 安装结果检查 [root@myecs]#cmake -version cmake version 2.8.12.2 详细过程输出参考,参见附一。 2.安装 gcc-c++ 非必须,但后续体验需要,否则会遇到附三的错误信息。 安装命令 [root@myecs]# yum install gcc-c++ 安装结果检查 [root@myecs]# g++ -v 使用内建 specs。 COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper 目标:x86_64-redhat-linux 配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux 线程模型:posix gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 详细过程输出参考,参见附二。 CMake相关链接 官网下载地址:https://cmake.org/download/ 在线帮助文档:https://cmake.org/documentation 关于 gcc-c++ https://pkgs.org/download/gcc-c++ 附录 附一 CMake 安装过程 [root@myecs]# yum install cmake 已加载插件:fastestmirror Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast base | 3.6 kB 00:00 epel | 4.7 kB 00:00 extras | 3.4 kB 00:00 updates | 3.4 kB 00:00 (1/6): base/7/x86_64/group_gz | 166 kB 00:00 (2/6): extras/7/x86_64/primary_db | 156 kB 00:00 (3/6): epel/x86_64/updateinfo | 956 kB 00:00 (4/6): updates/7/x86_64/primary_db | 1.4 MB 00:00 (5/6): base/7/x86_64/primary_db | 6.0 MB 00:00 (6/6): epel/x86_64/primary_db | 6.6 MB 00:00 Determining fastest mirrors 正在解决依赖关系 --> 正在检查事务 ---> 软件包 cmake.x86_64.0.2.8.12.2-2.el7 将被 安装 --> 正在处理依赖关系 libarchive.so.13()(64bit),它被软件包 cmake-2.8.12.2-2.el7.x86_64 需要 --> 正在检查事务 ---> 软件包 libarchive.x86_64.0.3.1.2-10.el7_2 将被 安装 --> 解决依赖关系完成 依赖关系解决 ================================================================================ Package 架构 版本 源 大小 ================================================================================ 正在安装: cmake x86_64 2.8.12.2-2.el7 base 7.1 M 为依赖而安装: libarchive x86_64 3.1.2-10.el7_2 base 318 k 事务概要 ================================================================================ 安装 1 软件包 (+1 依赖软件包) 总下载量:7.4 M 安装大小:27 M Is this ok [y/d/N]: y Downloading packages: (1/2): libarchive-3.1.2-10.el7_2.x86_64.rpm | 318 kB 00:00 (2/2): cmake-2.8.12.2-2.el7.x86_64.rpm | 7.1 MB 00:00 -------------------------------------------------------------------------------- 总计 28 MB/s | 7.4 MB 00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction 正在安装 : libarchive-3.1.2-10.el7_2.x86_64 1/2 正在安装 : cmake-2.8.12.2-2.el7.x86_64 2/2 验证中 : cmake-2.8.12.2-2.el7.x86_64 1/2 验证中 : libarchive-3.1.2-10.el7_2.x86_64 2/2 已安装: cmake.x86_64 0:2.8.12.2-2.el7 作为依赖被安装: libarchive.x86_64 0:3.1.2-10.el7_2 完毕! [root@myecs]# cmake -version cmake version 2.8.12.2 附二 gcc-c++安装过程 [root@myecs]# yum install gcc-c++ 已加载插件:fastestmirror base | 3.6 kB 00:00 epel | 4.7 kB 00:00 extras | 3.4 kB 00:00 updates | 3.4 kB 00:00 (1/3): extras/7/x86_64/primary_db | 156 kB 00:00 (2/3): epel/x86_64/updateinfo | 954 kB 00:00 (3/3): epel/x86_64/primary_db | 6.6 MB 00:00 Loading mirror speeds from cached hostfile 正在解决依赖关系 --> 正在检查事务 ---> 软件包 gcc-c++.x86_64.0.4.8.5-36.el7 将被 安装 --> 正在处理依赖关系 libstdc++-devel = 4.8.5-36.el7,它被软件包 gcc-c++-4.8.5-36.el7.x86_64 需要 --> 正在处理依赖关系 libstdc++ = 4.8.5-36.el7,它被软件包 gcc-c++-4.8.5-36.el7.x86_64 需要 --> 正在处理依赖关系 gcc = 4.8.5-36.el7,它被软件包 gcc-c++-4.8.5-36.el7.x86_64 需要 --> 正在检查事务 ---> 软件包 gcc.x86_64.0.4.8.5-11.el7 将被 升级 ---> 软件包 gcc.x86_64.0.4.8.5-36.el7 将被 更新 --> 正在处理依赖关系 libgomp = 4.8.5-36.el7,它被软件包 gcc-4.8.5-36.el7.x86_64 需要 --> 正在处理依赖关系 cpp = 4.8.5-36.el7,它被软件包 gcc-4.8.5-36.el7.x86_64 需要 --> 正在处理依赖关系 libgcc >= 4.8.5-36.el7,它被软件包 gcc-4.8.5-36.el7.x86_64 需要 ---> 软件包 libstdc++.x86_64.0.4.8.5-11.el7 将被 升级 ---> 软件包 libstdc++.x86_64.0.4.8.5-36.el7 将被 更新 ---> 软件包 libstdc++-devel.x86_64.0.4.8.5-36.el7 将被 安装 --> 正在检查事务 ---> 软件包 cpp.x86_64.0.4.8.5-11.el7 将被 升级 ---> 软件包 cpp.x86_64.0.4.8.5-36.el7 将被 更新 ---> 软件包 libgcc.x86_64.0.4.8.5-11.el7 将被 升级 ---> 软件包 libgcc.x86_64.0.4.8.5-36.el7 将被 更新 ---> 软件包 libgomp.x86_64.0.4.8.5-11.el7 将被 升级 ---> 软件包 libgomp.x86_64.0.4.8.5-36.el7 将被 更新 --> 解决依赖关系完成 依赖关系解决 ================================================================================ Package 架构 版本 源 大小 ================================================================================ 正在安装: gcc-c++ x86_64 4.8.5-36.el7 base 7.2 M 为依赖而安装: libstdc++-devel x86_64 4.8.5-36.el7 base 1.5 M 为依赖而更新: cpp x86_64 4.8.5-36.el7 base 5.9 M gcc x86_64 4.8.5-36.el7 base 16 M libgcc x86_64 4.8.5-36.el7 base 102 k libgomp x86_64 4.8.5-36.el7 base 157 k libstdc++ x86_64 4.8.5-36.el7 base 304 k 事务概要 ================================================================================ 安装 1 软件包 (+1 依赖软件包) 升级 ( 5 依赖软件包) 总下载量:31 M Is this ok [y/d/N]: y Downloading packages: Delta RPMs disabled because /usr/bin/applydeltarpm not installed. (1/7): cpp-4.8.5-36.el7.x86_64.rpm | 5.9 MB 00:00 (2/7): gcc-4.8.5-36.el7.x86_64.rpm | 16 MB 00:00 (3/7): gcc-c++-4.8.5-36.el7.x86_64.rpm | 7.2 MB 00:00 (4/7): libgcc-4.8.5-36.el7.x86_64.rpm | 102 kB 00:00 (5/7): libstdc++-4.8.5-36.el7.x86_64.rpm | 304 kB 00:00 (6/7): libgomp-4.8.5-36.el7.x86_64.rpm | 157 kB 00:00 (7/7): libstdc++-devel-4.8.5-36.el7.x86_64.rpm | 1.5 MB 00:00 -------------------------------------------------------------------------------- 总计 46 MB/s | 31 MB 00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction 正在更新 : libgcc-4.8.5-36.el7.x86_64 1/12 正在更新 : libstdc++-4.8.5-36.el7.x86_64 2/12 正在安装 : libstdc++-devel-4.8.5-36.el7.x86_64 3/12 正在更新 : libgomp-4.8.5-36.el7.x86_64 4/12 正在更新 : cpp-4.8.5-36.el7.x86_64 5/12 正在更新 : gcc-4.8.5-36.el7.x86_64 6/12 正在安装 : gcc-c++-4.8.5-36.el7.x86_64 7/12 清理 : gcc-4.8.5-11.el7.x86_64 8/12 清理 : libstdc++-4.8.5-11.el7.x86_64 9/12 清理 : libgcc-4.8.5-11.el7.x86_64 10/12 清理 : cpp-4.8.5-11.el7.x86_64 11/12 清理 : libgomp-4.8.5-11.el7.x86_64 12/12 验证中 : cpp-4.8.5-36.el7.x86_64 1/12 验证中 : libgomp-4.8.5-36.el7.x86_64 2/12 验证中 : gcc-4.8.5-36.el7.x86_64 3/12 验证中 : libgcc-4.8.5-36.el7.x86_64 4/12 验证中 : gcc-c++-4.8.5-36.el7.x86_64 5/12 验证中 : libstdc++-4.8.5-36.el7.x86_64 6/12 验证中 : libstdc++-devel-4.8.5-36.el7.x86_64 7/12 验证中 : libgcc-4.8.5-11.el7.x86_64 8/12 验证中 : cpp-4.8.5-11.el7.x86_64 9/12 验证中 : libgomp-4.8.5-11.el7.x86_64 10/12 验证中 : gcc-4.8.5-11.el7.x86_64 11/12 验证中 : libstdc++-4.8.5-11.el7.x86_64 12/12 已安装: gcc-c++.x86_64 0:4.8.5-36.el7 作为依赖被安装: libstdc++-devel.x86_64 0:4.8.5-36.el7 作为依赖被升级: cpp.x86_64 0:4.8.5-36.el7 gcc.x86_64 0:4.8.5-36.el7 libgcc.x86_64 0:4.8.5-36.el7 libgomp.x86_64 0:4.8.5-36.el7 libstdc++.x86_64 0:4.8.5-36.el7 完毕! 附三 未安装gcc-c++时可能遇到的报错信息 [root@myecs]# cmake . -- The C compiler identification is GNU 4.8.5 -- The CXX compiler identification is unknown -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done CMake Error: your CXX compiler: "CMAKE_CXX_COMPILER-NOTFOUND" was not found. Please set CMAKE_CXX_COMPILER to a valid compiler path or name. -- Configuring incomplete, errors occurred! See also "/home/cmakedemo/demo1/CMakeFiles/CMakeOutput.log". See also "/home/cmakedemo/demo1/CMakeFiles/CMakeError.log".
去 IOE 的前提是了解,才能谈去。Oracle 提供了22种数据类型,其中专门用于存储字符串的有6类。 字符串相关数据类型一览 CHAR : 定长类型,用 空格 来填充保证达到最大的长度;最多存储 2000 字节信息。 NCHAR : 与 CHAR 的差异是,支持 Unicode 格式的数据。 VARCHAR2 : 即 VARCHAR,变长类型,末尾不填充 空格 ;最多 4000 字节。(12c 后,可支持32767字节) NVARCHAR2 : 与 VARCHAR2的差异是,支持 Unicode 格式的数据。 RAW : 变长的二进制数据类型,不会发生数据字符集转换;最多 2000 字节。(12c 后,可支持32767字节) CLOB :10g后支持最多存储 (4GB-1)×(数据库块大小) 字节;受字符集转换的影响。 字符串语法 类型 < SIZE> 的说明 示例 VARCHAR2( < SIZE > < BYTE CHAR > ) 字节或字符数,值域(1-4000),整数。 A VARCHAR2( 20 BYTE ) CHAR( ) 字节或字符数,值域(1-2000),整数。 A CHAR( 20 CHAR ) NVARCHAR2( ) 字符数,值域 >0,上限与字符集有关,整数。 A NVARCHAR2( 20 ) NCHAR2( ) 字符数,值域 >0,上限与字符集有关,整数。 A NCHAR2( 20 ) 字符串的存储 CHAR、 VARCHAR2、 NCHAR、 NVARCHAR2都采用相同的存储格式.即 CHAR、NCHAR 实际是基于VARCHAR2、NVARCHAR2实现。 底层数据格式设计 数据块中,分为2部分 数据长度:1-3个字节 数据本身 数据长度的设计 空数据即 NULL:单字节值 0xFF 长度≤ 250:单字节值 0x01-0xFA 长度>250:3字节值表示 第1标志字节固定为:0xFE 第2、3字节为实际长度 示例 VARCHAR(20) Hello World <- 数 据 -> 11 H e l l o W o r l d ^长度^ CHAR(80) Hello World <- 数 据 -> 80 H e l l o W o r l d ^长度^ ^69个空格^ 注意点 CHAR、NCHAR 空间效率利用率低,因占用空间与数据无关,仅于列定义有关。 CHAR、NCHAR 容易给应用带来混乱,因数据末尾会补充若干空格,导致搜索结果经常非预期。 设置 MAX_STRING_SIZE为 EXTENDED后,VARCHAR2,NVARCHAR2,RAW才可以支持32767字节的存储。Oracle 默认是关闭,因启用后想再返回 STANDARD 会很痛苦。 查询工具推荐: DUMP 函数 作用:显示某个数据的数据类型代码、长度(单位为字节)及其在数据库内部实际存储的形式(字符集名),语法为: DUMP( expression [, return_format] [, start_position] [,length]) 扩展 关于字符集,请搜索 NLS(National Language Support)相关资料。
每日站会即使脱离 Scrum框架,也有利于团队的协作效率的提升。但开会是个技术活,了解Scrum 实践会对高效开会有一些启发。 Scrum指南:每日 Scrum 站会 时间要求 每日 Scrum 站会是开发团队的一个以 15 分钟为限的事件。 每日 Scrum 站会在 Sprint的每一天都举行。 每日 Scrum 站会在同一时间同一地点举行,以便降低复杂性。 内容要求 开发团队为接下来的 24 小时的工作制定计划。通过检视上次每日 Scrum 站会以来的工作和预测即将到来的 Sprint 工作来优化团队协作和性能。 开发团队借由每日 Scrum 站会来检视完成 Sprint 目标的进度,并检视完成 Sprint 待办列表的工作进度趋势。 价值 优化了开发团队达成 Sprint 目标的可能性。每天,开发团队应该知道如何以自组织团队来协同工作以达成 Sprint 目标,并在 Sprint 结束时开发出预期中的增量。 会议结构 会议的结构由开发团队设定。如果会议专注于达成 Sprint 目标的进展,开发团队可以采 用不同的方式进行。一些开发团队会以问题为导向来开会,有些开发团队会基于更多的讨 论来开会。以下为示例: 昨天,我为帮助开发团队达成 Sprint 目标做了什么? 今天,我为帮助开发团队达成 Sprint 目标准备做什么? 是否有任何障碍在阻碍我或开发团队达成 Sprint 目标? 开发团队或者开发团队成员通常会在每日 Scrum 站会后立即聚到一起进行更详细的讨论,或者为 Sprint 中剩余的工作进行调整或重新计划。 Scurm Master 的工作 Scrum Master 确保开发团队每日站会如期举行,但开发团队自己负责召开会议。 Scrum Master 教导开发团队将每日 Scrum 会议时间控制在15分钟内。 每日 Scrum 站会是开发团队的内部会议。 如果有开发团队之外的人出席会议,Scrum Master 必须确保他们不会干扰会议进行。 每日 Scrum 站会增进交流沟通、减少其他会议、发现开发过程中需要移除的障碍、突显并促进快速地做决策、提高开发团队的认知程度。 注意事项 (1)N vs N , No 1 vs N 会议根据团队情况可以设立主持,但不是必须的。如果有主持,他的角色更多的是引导团队有效的沟通,主持不是大家的汇报对象。会议是推动信息同步,进而推动价值的快速流动和创造。 (2)让其他伙伴听懂 即使密切合作的团队成员,对于其他人工作细节都不一定理解。说话和信息组织主要面向大部分参与者。即要讲工作的外部性。 谈进展和目标:从个人的外部价值来谈昨天的工作及今天的目标。 谈共享信息:从协作角度,谈对其他人的有潜在价值的信息。 谈障碍:自己工作遇到的困难及对其他人工作的关联影响。 (3)这里的开发团队不只是开发工程师 Scrum 团队是从外部视角定义的产品开发团队,统称为 Developer,不再区分更多角色。工作包括编码、测试、设计等。 当然这是很有挑战的,一是人员既有的角色意识,二是部门墙的深重,三是每个工作的占比会不同。其中第三点,在美工的岗位上体现的最为充分。 前期可以职能部门为界,后续可以借助一些特定问题,而逐渐实现跨部门的站会。 参考 《0001-2017-Scrum-Guide-Chinese-Simplified》 进阶阅读 https://mp.weixin.qq.com/s/fmg_JzGgpYqDw2Fsd8LFMA
Scrum是敏捷实践中最知名的一套框架。对于初学 Scrum 的同学,领会精髓需要实践和时间,但借助对其中最成型的部分的了解,能最快速的一窥其概貌。虽不精确,但有助于建立宏观的体感。Scrum 的核心可以简单归纳为“3355”。 3个核心角色 Scrum的三个核心角色分别是:Scrum Master、Product Owner(产品负责人)和 Scrum Team(团队)。 产品负责人 (Product Owner) Product Owner的核心工作对团队对外交付的价值负责。 定义需求 定义需求的优先级 定义需求的验收标准 定义产品发布内容与日期 敏捷教练 (Scrum Master) Scrum Master的核心工作是帮助团队遵循Scrum 框架,持续改进,以又好又快的工作。 促进团队的工作 帮助团队熟悉与掌握 Scrum 价值观与框架 帮助团队排除影响生产力的障碍 保护团队不受打扰 团队 (Scrum Team) Scrum team 对交付成果负责。 跨职能部门 自组织式的团队 小而美 3个工件 Scrum的工件主要包括:Product Backlog(产品待办事项)、Sprint Backlog (Sprint 待办事项)和 Increment(可交付产品增量)。 产品待办事项 (Product Backlog) 产品待办事项Product Backlog即产品视角的需求清单。 由 Product Owner 负责维护,包括增删及优先级。 用户故事是其中一种最佳实践。 每项需求都需要描述其外部价值。 Sprint 待办事项 (Sprint Backlog) Sprint 待办事项 Sprint Backlog即此次冲刺周期内规划要完成的内容。 来源于Product Backlog。 由团队评估和选择Product Backlog中哪些放入Sprint Backlog。 团队需要一起定义“完成”的标准。 可交付产品增量 (Increment) 可交付产品增量Increment即冲刺结束后可对外发布的产品功能增量部分。 需要关注其是可工作的软件功能增量。 需要要在Scrum Review会议上进行演示。 5个事件 Scrum的五大事件,或 event,包括:冲刺、Sprint规划、每日站会、Sprint评审会和回顾会。 冲刺 (Sprint) 冲刺Sprint或迭代是一个特殊的事件,或者说其一个容器事件。后续四个事件包含在其中。 2-4周 固定周期,固定时间开始,固定时间结束 时间盒是其一个重要的概念 Sprint规划会 (Sprint Planning Meeting) Sprint规划会的核心议题是下一次冲刺要实现的目标和范围。 确定 Sprint的目标 对产品backlog 中 item 进行估算,以作为是否放入下期的参考。 对于需求不清楚的 item,请 Product Owner 说明。 输入是 Product backlog 输出是 Sprint backlog 每日站会 (Sprint Daily Standup) 站会的目标是促进信息在团队内共享与透明。 回答3个问题 本次会议之前,我做了哪些事情? 本次会议之后,我准备做什么事情? 目前我是否碰到障碍,阻碍我达成目标? 每天15分钟 不是深入的问题讨论 每天固定时间召开 Sprint 评审会 (Sprint Review) Sprint 评审会在冲刺末期召开,检查本期的成果。 团队全体参与 邀请相关干系人参与 2-4小时 Product Owner可以拒绝接收成果 回顾会 (Sprint Retrospective) 团队一起复盘本次冲刺的过程,总结经验与教训,并形成切实可行的改进清单。 Sprint评审会结束后召开 时间2-4小时 团队全体参与 5大价值观 承诺 Commitment - 愿意对目标做出承诺 专注 Focus – 全身心都用到你承诺的工作上去 开放 Openness – 团队内所有信息对所有人开放 尊重 Respect – 每个人都有他独特的价值和经验 勇气 Courage – 勇于承诺,履行承诺,敢于说不
这两天域名备案流程中,天津信管局手机验证短信中的链接可能有问题。 【现象】点击短信中的链接,跳转至微博。由于采用的是短URL模式,怀疑是URL解析服务异常,或者由于网站URL改版。 【处理方法】说明,天津信管局通过短信验证码来验证手机的可用性。注意查收短信,收到短信后需要在小于24小时内处理完(经验值)。收到验证短信时,优先打开附带的链接完成验证码的填写。如遇到链接失效可直接查找官方地址,目前参考地址如下http://tjcainfo.miitbeian.gov.cn/state/outPortal/messageAuthentication.action填写相关信息后,会提示一下信息 【相关地址】工信部备案系统网站 http://www.miitbeian.gov.cn天津市通信管理局备案系统网站 http://tjcainfo.miitbeian.gov.cn/state/outPortal/loginPortal.action
引言 我是一个内向的人,公众场合说话时,会紧张、羞涩,但这样的我也依然有可能做一些不太属于内向者的事,比如做主持人。这对于很多熟悉我的人,在第一次听到时都有些惊诧。我想通过自己的故事,来鼓励那些和我一样的内向者,去勇敢的挑战自我、成就自我。本文包含三部分,自己的案例,背后的原理,修炼的方法。 一、真实的故事 我不是央视主持,也不是网红主播,而是普通的芸芸众生,所以我的故事是普通人的故事,也是普通人触手可及的事情。20岁前 作为一个内向者,每到逢年过节,学校都有活动,也是让我惴惴不安的日子。元旦晚会如果不幸做游戏被抽中,要出节目怎么办?万恶的击鼓传花!谁的发明?这是当年稚嫩而有趣的胡思乱想,详细很多朋友也有类似的思想挣扎。第一次公开演讲 2003年的一个夏天,收同学邀请为大一新生做一次演讲,在被到场的300人吓慌来之后,却鬼使神差的在拿到话筒的一刻心脏回归了平静,于是效果不错。那一次的意外,让我体验了自己的另一种可能。第一次做公司年会主持 2011年前后,公司组织年会,因我在总部利于沟通,于是被邀请做年会主持,内心的激烈思想斗争的同时,却满口答应了这个邀请。这样说服自己,都是自己熟悉的同事,出丑就出丑吧,难得公司花钱给我锻炼的舞台。于是在意式风情街的一个酒吧里,开始了自己的第一次年会主持。不断的实践 截止2018年,主持过4次公司年会,1次产品发布会,1次签约仪式,N次技术沙龙,N次司内培训课程。 会场:包括公司内的培训室,酒店的500人大厅,700人双层的红旗剧院,以及北京国家会议中心。 参会人数:少则10人,多达七八百人。 观众类型:从公司内部的同事为主的几乎100%熟人,到外部的100%的全是陌生人。 说明 主持人是个很苦的差事,不恰当的理解它是台上的导演。作为主持人,要提前对流程非常熟悉,还要忍受和包容所有前期准备不足留下的各种坑,甚至主持过程中,很多细节都需要主动或被动的调整;会议自始至终,你都是哪个不能走神和休息的人。 二、背后的原理 有时候,人们会表现出和平常不一样的状态,比如,一个内向的人,或许在某次活动中表现得特别外向;一个很难相处的人,或许在某个周末变得很讨人喜欢;包括我的转变。 为什么人们会有这种表现呢? 人格心理学大师、哈佛大学教授布赖恩·利特尔在新书《突破天性》里提出,我们不仅有稳定的人格特质,还有 自由特质。我们先来看看什么是稳定特质和自由特质。 稳定特质指的是,我们在思考自己是什么样的人时,会给自己贴一些标签,比如外向、讨人喜欢、神经质等等。这是用稳定的人格来解释行为。 自由特质则是人在追求特有动机时形成的人格,这些特有动机包括人们在日常生活中追求的目标、包袱、承诺和个人计划,它的来源是独特的,是一种后天塑造的人格。 我们的人格构建,正是受到了这两方面的影响。布赖恩教授说,我们身上那些相对稳定的特质,是生物因素和社会因素塑造的,而且没法改变。但我们体现出的自由特质,也就是和自己不太一样的性格,与我们的天性并不矛盾。自由特质告诉我们,我们并不完全是基因和环境塑造的,个人的动机和计划能让我们超越前两个因素的影响,慢慢成为我们想变成的样子。 三、修炼的方法 为了改变性格,你可能需要制定一些计划。布赖恩教授建议,想要更好地制定改变计划,你可以问自己下面三个问题。 第一,我是计划的主要发起者吗?个人计划最有意义的地方,是自我同一性,也就是说,你在多大程度上认同自己的个人计划,认为它确实是你想要的。很多行动失败的一个原因是,那个决定不是真的由自己做出的,或受他人蛊惑,或受环境压力。 第二,这个计划的意义是什么?你的判断依据是:它的重要性,它与你的价值观是否一致,以及它是否表达了你的自我。如果你的计划在这几个方面都有意义,就可以当成核心计划。在学生时代,我阅读刘墉的写书《肯定自我》、《超越自我》,受其影响知道每个人其实都有计划不断发展自己、拓展自己的潜能。 第三,这个计划跟其他正在推进的计划有什么联系?你要把个人计划系统看成一个整体,在这个系统中,有些计划跟其他计划密切相关。如果把这些计划做好了,就等于把其他计划也做好了。如果你在这些计划上遇到了困难,其他计划也可能不会成功。核心计划的微小改变,都会给其他计划带来重大变化。 布赖恩教授认为,人格的复杂程度远超我们的想象,假如你想了解自己,不能问“你属于什么人格类型”,而应该问“你生命中真正重要的事情是什么”。 忘却“内向者”的标签,而去思考你看重的是什么?或许就能激发自己去行动。 微信公众号“快公司FastCompany”介绍了三个方法,帮助我们克服恐惧走出舒适区,逐渐建立其能力和自信。 第一,专注地享受过程。 你有没有这样的经历:当你十分关注一个冒险举动将会带来什么结果时,“如何迈出第一步”会变得更难,不过,当你专注于享受整个过程时,一切就不再可怕了。比如,怎么才能主持好,万一出错了怎么?相比之下,主持的词应该怎么写?我的咬字是否清晰?就轻松很多。 第二,寻找低风险情境,排演练习。麻省理工领导力中心的执行董事哈尔•葛瑞格森(Hal Gregersen)介绍,消防员们面对的都是生死攸关的状况,他们之所以能够“清晰准确”完成任务,都是得益于“丰富的训练和经验”。我们可以利用每次团队开会的机会,去用心准备发言稿;争取每次参会时,都能有机会表达一下自己的观点。 第三,让自己别无选择,放手一搏。 作家斯蒂芬妮•沃扎十分恐惧社交,但为了写一篇文章,她假装当了一个星期的外向型人,她会和服务员搭讪聊天,主动和健身房课程的新学员搭档,还联系了两个她认为自己需要见一下的陌生人。这一周的经历,让她明白,自己可能不像自己曾认为的那么内向,她不再恐惧社交,反而期待认识更多的新朋友。当有人邀请你主持,或者因为某种原因,会议需要一个主持时,别犹豫,先站起来接受这个角色,后面再想怎么办? 尾声 感谢《得到》“李翔知识内参频道”!让我对此,有了理论与系统化的理解。 祝愿你可以突破自我,成为自己喜欢的自己!
目标读者: 想体验云服务器的IT从业者 刚开始学习网站搭建的同学 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,帮助开发者降低 IT 成本,提升运维效率,使开发者更专注于核心业务创新。基于阿里云ECS搭建网站环境分为以下步骤,本文重点记录了第三步,大致如下: 1.注册域名 -> 2.开通云服务器(ECS)-> 3.搭建网站环境 -> 4.发布网站内容 -> 5.域名解析与备案 一、开通云服务器 开通云服务器是很简单的,像在淘宝买东西一样,作为学习目的,可以选择最小规模的机器,足够体验。选型主要是选择服务所在的位置,选择CPU、内存,截图如下。更多可参考其官方介绍。 二、搭建网站环境 说明:为了安全,隐藏了敏感信息,但不影响大家的阅读。 1.登录云服务器 $ ssh root@... //省略的是公网IP,大家可在控制台中查看具体的实例信息root@...'s password: Last login: Fri Oct 19 08:07:03 2018 Welcome to Alibaba Cloud Elastic Compute Service ! [root@* ~]# ls[root@* ~]# pwd/root 2.安装Apache服务 [root@* ~]# yum -y install httpd已加载插件:fastestmirrorbase | 3.6 kB 00:00 epel | 3.2 kB 00:00 extras | 3.4 kB 00:00 updates | 3.4 kB 00:00 (1/7): base/7/x86_64/group_gz | 166 kB 00:00 (2/7): epel/x86_64/group_gz | 88 kB 00:00 (3/7): epel/x86_64/updateinfo | 933 kB 00:00 (4/7): extras/7/x86_64/primary_db | 204 kB 00:00 (5/7): base/7/x86_64/primary_db | 5.9 MB 00:00 (6/7): epel/x86_64/primary | 3.6 MB 00:00 (7/7): updates/7/x86_64/primary_db | 6.0 MB 00:00 Determining fastest mirrorsepel 12741/12741正在解决依赖关系--> 正在检查事务---> 软件包 httpd.x86_64.0.2.4.6-80.el7.centos.1 将被 安装--> 正在处理依赖关系 httpd-tools = 2.4.6-80.el7.centos.1,它被软件包 httpd-2.4.6-80.el7.centos.1.x86_64 需要--> 正在处理依赖关系 /etc/mime.types,它被软件包 httpd-2.4.6-80.el7.centos.1.x86_64 需要--> 正在处理依赖关系 libaprutil-1.so.0()(64bit),它被软件包 httpd-2.4.6-80.el7.centos.1.x86_64 需要--> 正在处理依赖关系 libapr-1.so.0()(64bit),它被软件包 httpd-2.4.6-80.el7.centos.1.x86_64 需要--> 正在检查事务---> 软件包 apr.x86_64.0.1.4.8-3.el7_4.1 将被 安装---> 软件包 apr-util.x86_64.0.1.5.2-6.el7 将被 安装---> 软件包 httpd-tools.x86_64.0.2.4.6-80.el7.centos.1 将被 安装---> 软件包 mailcap.noarch.0.2.1.41-2.el7 将被 安装--> 解决依赖关系完成 依赖关系解决 ================================================================= Package 架构 版本 源 大小 =================================================================正在安装: httpd x86_64 2.4.6-80.el7.centos.1 updates 2.7 M为依赖而安装: apr x86_64 1.4.8-3.el7_4.1 base 103 k apr-util x86_64 1.5.2-6.el7 base 92 k httpd-tools x86_64 2.4.6-80.el7.centos.1 updates 90 k mailcap noarch 2.1.41-2.el7 base 31 k 事务概要 =================================================================安装 1 软件包 (+4 依赖软件包) 总下载量:3.0 M安装大小:10 MDownloading packages:(1/5): httpd-tools-2.4.6-80.el7.centos.1.x86_64.rpm | 90 kB 00:00 (2/5): apr-util-1.5.2-6.el7.x86_64.rpm | 92 kB 00:00 (3/5): apr-1.4.8-3.el7_4.1.x86_64.rpm | 103 kB 00:00 (4/5): mailcap-2.1.41-2.el7.noarch.rpm | 31 kB 00:00 (5/5): httpd-2.4.6-80.el7.centos.1.x86_64.rpm | 2.7 MB 00:00 总计 10 MB/s | 3.0 MB 00:00 Running transaction checkRunning transaction testTransaction test succeededRunning transaction 正在安装 : apr-1.4.8-3.el7_4.1.x86_64 1/5 正在安装 : apr-util-1.5.2-6.el7.x86_64 2/5 正在安装 : httpd-tools-2.4.6-80.el7.centos.1.x86_64 3/5 正在安装 : mailcap-2.1.41-2.el7.noarch 4/5 正在安装 : httpd-2.4.6-80.el7.centos.1.x86_64 5/5 验证中 : mailcap-2.1.41-2.el7.noarch 1/5 验证中 : httpd-tools-2.4.6-80.el7.centos.1.x86_64 2/5 验证中 : apr-util-1.5.2-6.el7.x86_64 3/5 验证中 : apr-1.4.8-3.el7_4.1.x86_64 4/5 验证中 : httpd-2.4.6-80.el7.centos.1.x86_64 5/5 已安装: httpd.x86_64 0:2.4.6-80.el7.centos.1 作为依赖被安装: apr.x86_64 0:1.4.8-3.el7_4.1 apr-util.x86_64 0:1.5.2-6.el7 httpd-tools.x86_64 0:2.4.6-80.el7.centos.1 mailcap.noarch 0:2.1.41-2.el7 完毕! 3.添加网站管理员 [root@* ~]# adduser -d /var/www/html siteadminadduser:警告:此主目录已经存在。不从 skel 目录里向其中复制任何文件。[root@* ~]# passwd siteadmin更改用户 siteadmin 的密码 。新的 密码:重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。[root@* ~]# chown -Rf siteadmin.siteadmin /var/www/html[root@* ~]# cd /var/www[root@* www]# ls -l总用量 8drwxr-xr-x 2 root root 4096 6月 27 21:49 cgi-bindrwxr-xr-x 2 siteadmin siteadmin 4096 6月 27 21:49 html[root@* www]# cd html[root@* html]# ls -l总用量 0 4.启动Apache服务 [root@* html]# service httpd startRedirecting to /bin/systemctl start httpd.service 5.查看网站效果 打开浏览器直接用公网IP即可访问。 三、扩展阅读 阿里云大学云计算专业的入门课程中的《Clouder认证课程:网站建设--部署与发布》会更详细介绍整个过程,有需要的可以观看。如果有基础的朋友,凭直觉也能完成相关操作。
本人带过2年的运维团队,尝试回答一下这个问题。 建议给自己3个月的试用期,因为运维工作并不一定适合所有人,同时没有深度体验,很难准确判断自己是否适合做这行。 可以做一下几个角度的评估。 1、对于技术广度与深度的学习,是否有兴趣和毅力? 运维管理的是系统,尤其是现代运维,系统的复杂度对管理人员的技术栈要求很高。 运维也是快速发展的领域,新技术、新手段、新工具层出不穷,需要不断自我更新换代。 如果做不到,就可能成为网管、修电脑的…… 2、对于任务的快速响应,以及整体系统分析能力,是否具备? 运维是与业务紧密相连的,需要的不仅仅是技术思维,更需要的是业务思维、全局思维。 如果你更喜欢专注在某一点,那可能并不一定适合干运维。运维在解决问题前,需要脑中现有地图,才能上路。 3、是否能上能下? 讲架构时,举重若轻,激昂文字;处理具体问题,翻查海量日志,抽丝剥茧;时不时要趴在机房许久,折腾各类设备…… 这些都是运维工程师的日常生活。大公司好些,分工细化,但在中小公司,你就是万能的。
有一种生活叫朋友圈里的生活,但它有时就真的发生在你身旁。 在回答如何精致、有趣的生活前,先看看3个凡人的生活故事。 【故事一】北京有个一姐,有着一份稳定的生活,有着让很多人羡慕的端庄,但让她与众不同的是她对自己兴趣的追求。 一姐喜爱拉丁舞,在家里没事就琢磨、练习一个个细节,这在外人看来是枯燥无味的重复。因为对拉丁舞的热爱,一姐创建了一个公众号,把自己所思所想整理成文字,共享在网上,那里记录的都是每个动作的细节感悟与心得。为了与同好者交流,组建了一个微信群,与天南海北的拉丁舞爱好者、专家研讨技术。这一切一切都是源于对舞蹈的热爱。从今年年初,顺应自己对舞蹈技术的钻研,和朋友们对学习舞蹈的需求,也组建了自己的舞蹈工作室,不定期安排各种类型的舞蹈培训。 【故事二】天津有个同事,暂时称呼为Li,生活中简直一个优化大师。Li每逢假期必定出游,出游前攻略、预算准备详尽,回来后复盘总结,过程中乐趣无穷。跟着她去旅游,比导游还省心。各种优惠政策、消费策略了然于心,让人赞叹。同样一次消费,同样一次旅游,因为她 你会整体体验价值提升了一大块。 【故事三】最近认识了一个小帅哥,萧。瘦瘦的身体却有大大的不同。因 IT 出身,对于性能优化乐趣满满。但让人诧异的是,其还是个赛车手,而且是个摄影爱好者。展示的照片,充满意境和诗意。 年轻人如何精致or有趣的生活? 不给自己人生设限,认真的做手头当下的事情,同时又不纠结于结果。 如此,生活必定精致、有趣。 我是个内向的人,在接到当年会主持时,忐忑之后就满口答应,只是去挑战一下自己的可能。 不善于歌唱,就尝试学习舞蹈,虽然没有练成,但体会到那种身体被音乐激发后的快乐。 虽然不是销售出身,但居然也通读一本销售名著,还在内部做起了分享。 人生有无限可能,年轻可以尽情去探索。 不设限,不纠结,专注当下,精彩就在每天、每时……
国庆长假对于上班族可能是一年中最幸福的时光,可以游历大江南北,感受祖国的大好河山,而不必担心冷暖,可以与家人相聚,而没有繁荣缛节。 2018年的国庆如期而至,在举国上下欢歌笑语庆祝佳节之际,对于一些人而言,这个假期会有一些特别。 信息安全是国家安全的坚强基石,数据库因在信息系统的中特殊地位和技术难度,而成为国之重器。数据库国产化对于国家安全、对于人民生活都有着举足轻重的意义。 9月30日,经过紧急沟通后,过节期间需要突击的任务摆在了大家面前。几位同事没有怨言,纷纷承诺参加此次会战,之后拿起电话与家人沟通临时的改变和应对办法…… 他为此产品研发已投入数月,面对一个接一个的挑战都咬牙坚持克服,面对多方的协调,都尽力促成合作。为了安心工作,孩子被送回老家抚养。 他已经调入其他项目研发团队,因紧急情况需求,毫无抱怨的接受了此次冲刺攻坚。假期少了许多初为人父该有幸福时光。 她因为工具是客户对产品最重要的感知界面,而需要不断的反复优化,即是对技术的考验,更是对耐心的磨练。 她们为人母,对家庭而言有更多的意义和责任,但在这个特殊时刻,为了产品质量,牺牲了陪伴子女的时间,独自来到工作岗位,为产品把好质量关。 她为了保证产品版本的有序、可跟踪,假期协助同事完成突击的流程保证。 感谢你们为国家自主可控战略所付出的努力! 感谢你们身后家人的理解与支持! 你们是2018年国庆最可爱的人! 2018年10月8日 奋斗者
一、背景 现在有个水处理厂,现场有组态软件可以拿到智能仪表的数据。需求是:把这些数据接入到数据平台,远程监控,设置预警报警,进而实现远程控制阀门等功能 二、研讨 问: 是需要设备接入到PLC,取数,然后送出去是么?答:一般都是有局域网就走局域网,没有局域网就走公网; 既然组态软件能够拿到数据,那么自己的程序或者设备也能够拿到数据。 然后就是和服务器进行数据交互了 问:都是自己搭么,还是用了阿里云的物联网接入?答: 自己搭的 当时考虑到成本; 不过用的是阿里云的服务器 问:希望有什么解决方案,公网环境和内网环境分别有什么成熟方案?答:1.这个要首先看水处理厂的水池分布情况,对于网络边缘的覆盖。如果之前有有线接口,可以直接用。如果没有的话,就要参考你要采集的数据模型,频度和数据大小,选择Wlan,或者Lora,还有就是运营商的nb2.要考虑的是你供电及功耗,你这个采集信息的模组应该是放在水池,这样功耗要考虑,如果有电接入,不关心功耗,无线建议使用wlan,采用室外的Ap设备。当然,最重要的是模组得支持 3.如果对功耗要求高,你可以才用低功耗窄带,比如LoRa,Nb,这两个成本一个是需要部分自建,涉及Lora网关及终端模组,如果用NB,成本在运营商,流量或套餐收费搞定通讯,后端一般的Lora部署方案,都会提供一套自己的平台,一般这个要定制开发,除非有专门做水处理采集的。阿里云应该是有一套自己IOT平台,好像主推的也是Lora组网,后端分析都差不多,阿里云可以提供更全面的分析平台配合公有云。阿里推Lora也是可以理解,Nb频段是不可能给民间的,所以就用Lora了,更灵活。要是只关心后台处理,在公有云上部署分析,前面说的那些应该不用关心,呵呵。不过前面是物联网应用的关键 问: 远程控制, 关键是取数和控制,是否可以实现?答: 这个一般要分你要干啥,就跟我前面说的,数据模型; 这个很重要,要分析这个; 数据采集也有区别, 你是主动采集,还是定时上报? 这两个对于终端模组的要求不一样, 因为直接影响功耗的。 比如他定时上报,那就很省电,不用的时候就关闭,用的时候启动一下,上传数据。 非定时上报,就又分处理方法了,比如循环苏醒,看你是否有要求,然后互动,这个也都不一样,还是先看下数据模型要求。 但是整个实现远程控制,是可以做的,就废资源呗ora是从去年开始,突然火起来了,呵呵,我觉得是得益于运营商经过纠结,最终选择NB,导致大家都很难参与了,转到Lora了,当然Lora也有自己优势,比如网关统一收口,特别适合局域网,也更灵活,很多公司都可以参与。是可以选择Lora,并不一定是只有Lora,还有sigfox,zigbeen,这些都可以,但是国内不就行,zigbeen更适合智能家居,或者大房子,范围不大,所以得看实际环境。这个成本应该更低。sigfox国内也不流行,本来以为要退出了,最近又看到很多消息,不知道是不是在国内要开始发力。 只是通过市场环境,还有你说的水厂看起来lora最合适。其实如果终端量不大,推荐你用运营商的NB,省心省事,成本也还好。终端不多,又自建一套,也挺贵,还得维护 三、扩展阅读 阿里云 IoT 解决方案 https://market.aliyun.com/iot?spm=5176.9502607.401001.6.66da4d50vrHmAs
本文通过以下4个方面调研,对比介绍主流数据库对IPv6的支持程度,包括:Server服务对IPV6监听,客户端支持度,是否存在IPv6数据类型,IPv6数据相关函数功能。 一、主流数据库对比简表 数据库 服务地址监听IPv6地址 客户端支持度(待细化) IPv6相关数据类型 IPv6相关函数 Oracle yes all no no SQLServer yes all no no Informix yes all no no MySQL yes all no yes PostgreSQL yes all yes yes MariaDB yes all no yes 说明:以上仅为根据收集到的信息整理的结果。 二、国际商用主流数据库调研结果 2.1 Oracle Oracle Database and IPv6 Statement of Directionhttps://www.oracle.com/technetwork/database/enterprise-edition/oracledatabaseipv6sod-4007245.pdf Oracle数据库11g R2支持在IPv6地址环境中所有单实例特性和组件,Oracle数据库12c R1做了扩展,在一些限制下,允许所有客户端通过公网访问Oracle RAC。这些限制在Oracle 数据库12c R2取消了,即全面支持IPv6.a. Oracle Database 11g Release 2 使用IPv6的限制 除了Oracle RAC和Oracle Clusterware外,Oracle Database 11g Release 2 所有功能和组件都支持 IPv6.b. Oracle Database 12c Release 1使用IPv6的限制 Oracle Database 12c Release 1 (12.1.0.2)不支持IPv6客户端连接Oracle RAC数据库,Oracle Clusterware 不能运行在Windows上。c. Easy Connect Naming Easy Connect Naming 支持 IPv6 地址. 语法支持 IPv6 URL格式,同时保留了对IPv4地址的支持: [//]host[:port][/[service_name[:<server>]][/instance]] 为了能使用上面的语法, 主机地址需要替换为 IPv6地址,并用 “[“ 和 “]” 括起来. Easy Connect 连接串示例如下: [2001:fe8::12]:1522/sales.us.example.com 等价于下面的形式: salesdb = (DESCRIPTION= (ADDRESS=(PROTOCOL=tcp)(HOST=2001:fe8::12)(PORT=1522)) (CONNECT_DATA=(SERVICES_NAME=sales.us.example.com))) d. 包UTL_INADDR UTL_INADDR 包提帮助PL/SQL 存储过程完成网络寻址等功能,有API解析出主机名和IP地址. 待研究其对IPv6的支持度,按官方声明是支持的。 包UTL_INADDR的手册地址:https://docs.oracle.com/database/121/ARPLS/u_inaddr.htm#ARPLS071 2.2 SQLServer 官方对IPv6支持的描述 《使用 IPv6 进行连接》 SQL Server 和 SQL Server Native Client 完全支持 Internet 协议版本 4 (IPv4) 和 Internet 协议版本 6 (IPv6)。 将 Windows 配置为使用 IPv6 SQL Server时,各组件会自动识别 IPv6 的存在。 不必采用特殊的 SQL Server 配置。 支持包括但不限于下列各项: SQL Server 数据库引擎 和其他服务器组件可以同时侦听 IPv4 和 IPv6 地址。 如果同时存在 IPv4 和 IPv6,则可以使用 SQL Server 配置管理器来配置 数据库引擎 ,以便只侦听 IPv4 地址或只侦听 IPv6 地址。 根据 IPv4 地址对运行于支持 IPv4 和 IPv6 的计算机上的 SQL Server Browser 服务进行查询时,该服务会对 IPv4 地址及其列表中的第一个 IPv4 TCP 端口做出响应。 根据 IPv6 地址进行查询时,该服务会对 IPv6 地址及其列表中的第一个 IPv6 TCP 端口做出响应。 为了避免出现不一致,建议将 IPv4 和 IPv6 侦听器配置为侦听相同的端口。 SQL Server Management Studio 和 SQL Server 配置管理器等工具都接受 IPv4 和 IPv6 格式的 IP 地址。 大多数情况下,如果使用服务器主机名或完全限定的域名 (FQDN) 指定 <computer_name><instance_name>,则无须修改连接字符串。 如果服务器安装有 IPv4 和 IPv6,则其主机名或 FQDN 将会解析到多个 IP 地址,其中至少包括一个 IPv4 地址和多个 IPv6 地址。 SQL Server Native Client 会按照从 TCP/IP 接收这些 IP 地址时的顺序尝试使用它们来建立连接,并使用第一个成功建立的连接。 由于 SQL Server Native Client 无法预测顺序,因此,应将顺序视为随机顺序。 如果同时存在 IPv4 地址和 IPv6 地址,则首先尝试使用 IPv4 地址。 这一逻辑对于 ODBC、OLE DB 或 ADO.NET 的用户是透明的。 【说明】如果数据库引擎未侦听IPv4,则尝试进行IPv4连接之后,必须等待超时期限过后再尝试使用IPv6地址。为了避免出现这种情况,请直接连接到IPv6 IP地址或使用IPv6地址配置客户端的别名。 2.3 Informix 3.3.1 整体描述 IBM 关于其产品对IPv6兼容支持清单中,列举了Informix支持度。 Product (I) First release with support IPv6 basic Dual stack support IBM Informix Java Database Connectivity Driver v3.50.JC6 yes yes IBM Informix Warehouse v11.50 yes yes 从 Informix 10.00.xC4 和 Client SDK 2.90.xC4,服务在启动时会检查当前的操作系统是否支持 IPv6. 如果支持IPv6,服务将会使用;如果不支持 IPv6, 服务将会使用 IPv4 地址. 从用户视角,将 Informix 运行在一台同时支持 IPv4 和 IPv6 地址的服务器,与将Informix 部署在多 a multi-homed host. 用户可以在同时配置来IPv4和IPv6多机器上,采用以下任意方式来配置 Informix : 创建别名 (使用参数 DBSERVERALIASES ),分配给 IPv6 地址和 IPv4 地址. 配置 Informix 监听主机sqlhosts文件中的所有IP地址. 例如: #dbservername nettype hostname servicename options olserver1 onsoctcp *myhost onservice1 启动Informix Version 10.0, 如果机器支持IPv6,则SQLHOSTS文件中主机名 会映射到 IPv6地址上;如果没有配置IPv6地址,主机名会映射到 IPv4 地址上. 关于禁用支持IPv6 Informix还允许在IPv4的环境下禁用 IPv6相关功能. 全局禁用支持IPv6,包括所有机器上的实例和客户端应用: 创建空文件 $INFORMIXDIR/etc/IFX_DISABLE_IPV6 说明:informix用户必须拥有读权限,但该文件不会真正读写内容,不需要包含任何数据。 仅禁止某个数据库实例或者某个客户端应用: 在数据库服务实例上,或者运行应用的机器上,创建环境变量IFX_DISABLE_IPV6,并设置值为 yes, 即(IFX_DISABLE_IPV6=yes)。 参见Informix support for IPv6 addresses 2.3.2 使用JDBC连接Server IBM® Informix® JDBC Driver, Version 3.0及以后版本都支持IPv6. 解析连接URL的代码可以处理像IPv6地址这样更长的信息(IPv6 128位).例如:3ffe:ffff:ffff:ffff:0:0:0:12 要连接Informix服务的IPv6端口,可以使用系统属性,例如:java -Djava.net.preferIPv6Addresses=true 使用IBM Informix JDBC Driver, Version 3.0或之后的版本处理没有现式文字描述的URL时不受影响,原有行为也没有改变。 冒号 (:) 是连接URL中的关键分隔符,尤其是IPv6格式的. 用户需要使用格式严谨的URL,这样驱动才能识别IPv6地址串. 注意下面示例中的4点细节: jdbc:informix-sqli:// 是必须的. 冒号括住端口8088, 即(:8088:)是必须的. 驱动不验证3ffe:ffff:ffff:ffff:0::12 . 8088 必须是小于32k的有效数字. jdbc:informix-sqli://3ffe:ffff:ffff:ffff:0::12:8088:informixserver=X... 三、开源主流数据库调研结果 3.1 MySQL 3.1.1 MySQL对IPv6的支持主要在3个方面 MySQL对IPv6的支持体现在以下几个方面1. 基于IPv6建立其连接 MySQL服务支持客户端以IPv6地址来建立TCP/IP连接,本机可以如下的方式建立连接 shell> mysql -h ::1 前提是:1、所在机器已经支持IPv6;2、MySQL服务配置支持IPv6来建立连接。 MySQL默认启用IPv6,可以通过修改--bind-address来修改默认行为。 2. 基于IPv6来授权 MySQL账户名支持基于IPv6地址,由DBA对特定客户端进行授权. IPv6地址可以与账户名结合,在以下语句中使用,如 CREATE USER, GRANT, REVOKE. 如: mysql> CREATE USER 'bill'@'::1' IDENTIFIED BY 'secret'; mysql> GRANT SELECT ON mydb.* TO 'bill'@'::1'; 3. IPv6相关函数 IPv6函数支持在字符串和内部IPv6格式之间转换,以及检查是否是有效的IPv6地址。例如, INET6_ATON() 、INET6_NTOA() 和 INET_ATON() 、INET_NTOA()类似, 但可以处理 IPv6 地址。 3.1.2 关于bind-address 参数 bind-address的基本信息如下表 Property Value Command-Line Format --bind-address=addr System Variable bind_address Scope Global Dynamic No SET_VAR Hint Applies No Type string Default Value * MySQL服务默认监听1个或多个网络socket。每个socket绑定到1个地址上,但可以映射到多个接口上。如果想配置服务如何监听TCP/IP连接,则需要在配合--bind-address来起服务。 在MySQL 8.0.13之前, --bind-address 只接收单一地址值, 可以是确定的IP地址或者是主机名, 也可以是使用通配符来监听多个接口 (*, 0.0.0.0, or ::). 从MySQL 8.0.13起, --bind-address 既接受上面介绍的单一地址值,又可以是一个逗号分隔的地址列表.如果是后者时,不能再使用通配符来描述IP地址. IP地址可以IPv4 或IPv6地址。 当使用主机名时,服务会将主机名解析为IP地址,并绑定.如果有多个IP地址时,会解析为第一个IP地址值。 服务处理不同类型的规则如下: 当地址为 *, 服务监听所有网卡上所有地址连接,包括IPv4、IPv6,这也是缺省值. 当地址为 0.0.0.0, 服务仅监听IPv4的地址. 当地址为 ::, 服务监听所有网卡上IPv4、IPv6地址. 当地址为IPv4映射的地址, 服务仅监听这个地址,无论是IPv4形式还是IPv6形式.如服务绑定::ffff:127.0.0.1, 客户端可以这样连接:--host=127.0.0.1 或 --host=::ffff:127.0.0.1. 当地址特定IPv4、 IPv6地址(如 127.0.0.1 或 ::1), 服务仅监听这个地址。 如果任意一个地址绑定失败,服务都会产生错误,且不会启动。. 【示例】 --bind-address=* 服务监听所有IP地址,包括 IPv4 或 IPv6地址. --bind-address=198.51.100.20 服务只监听 198.51.100.20. --bind-address=198.51.100.20,2001:db8:0:f101::1 服务同时监听 198.51.100.20 (IPv4地址)和 2001:db8:0:f101::1 (IPv6 地址). --bind-address=198.51.100.20,* 会产生错误,因为在以列表形式列举IP地址时不能再使用通配符。 3.1.3 IPv6相关函数 INET6_ATON() 将IPv6转化为数值 INET6_NTOA() 将数值转化为IPv6地址串 IS_IPV4_COMPAT() 判断是否 IPv4兼容地址 IS_IPV4_MAPPED() 判断是否 IPv4映射地址 IS_IPV6() 判断是否是IPv6地址 IS_IPV4() 判断是否是IPv4地址 INET_ATON() 返回地址的数值 INET_NTOA() 将地址解析为IP地址 3.1.4 扩展阅读 使用IPv6非本地来连接 Connecting Using IPv6 Nonlocal Host Addresses 从服务商获取IPv6地址 Obtaining an IPv6 Address from a Broker 3.2 PostgresSQL(10.X) 3.2.1 支持网址数据类型 Name Storage Size Description cidr 7 or 19 bytes IPv4 and IPv6 networks inet 7 or 19 bytes IPv4 and IPv6 hosts and networks macaddr 6 bytes MAC addresses macaddr8 8 bytes MAC addresses (EUI-64 format) 说明:针对cidr、inet类型排序时,IPv4地址在IPv6地址前。 3.2.1.1 inet inet类型可存储IPv4、IPv6主机地址及子网信息,而且所有都存在一个字段中. The subnet is represented by the number of network address bits present in the host address (the “netmask”). 如果网络掩码是32,则这个地址是IPv4, 这个值不能表明是子网,只是一个主机. 在IPv6, 网址长度为 128位,所以 128位代表一个具体的主机地址.注意,如果只需要接受网络,你应该使用cidr而不是inet. 输入的格式为 address/y ,其中address 是IPv4、IPv6地址,y是网络掩码位. 如果没有 /y , 默认是32(IPv4)或128(IPv6),仅代表一个具体的主机. 3.2.1.2 cidr cidr类型支持IPv4、IPv6网络规范.输入输出格式遵循Classless Internet Domain Routing conventions. 表:cidr Type Input Examples cidr Input cidr Output abbrev(cidr) 192.168.100.128/25 192.168.100.128/25 192.168.100.128/25 192.168/24 192.168.0.0/24 192.168.0/24 192.168/25 192.168.0.0/25 192.168.0.0/25 192.168.1 192.168.1.0/24 192.168.1/24 192.168 192.168.0.0/24 192.168.0/24 128.1 128.1.0.0/16 128.1/16 128 128.0.0.0/16 128.0/16 128.1.2 128.1.2.0/24 128.1.2/24 10.1.2 10.1.2.0/24 10.1.2/24 10.1 10.1.0.0/16 10.1/16 10 10.0.0.0/8 10/8 10.1.2.3/32 10.1.2.3/32 10.1.2.3/32 2001:4f8:3:ba::/64 2001:4f8:3:ba::/64 2001:4f8:3:ba::/64 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128 2001:4f8:3:ba:2e0:81ff:fe22:d1f1 ::ffff:1.2.3.0/120 ::ffff:1.2.3.0/120 ::ffff:1.2.3/120 ::ffff:1.2.3.0/128 ::ffff:1.2.3.0/128 ::ffff:1.2.3.0/128 3.2.1.3 inet vs. cidr inet 与cidr的本质区别是, inet accepts values with nonzero bits to the right of the netmask, whereas cidr does not. 如192.168.0.1/24 对于inet合法,但对于cidr无效. 如果你不喜欢inet 和cidr的输出格式,可以使用函数 host, text, abbrev. 3.2.1.4 macaddr macaddr类型存储MAC地址,接收以下格式: '08:00:2b:01:02:03' '08-00-2b-01-02-03' '08002b:010203' '08002b-010203' '0800.2b01.0203' '0800-2b01-0203' '08002b010203' 这些例子都代表同一个地址. 通过f来接收实现大小敏感。输出为第一种形式. 3.2.1.4 macaddr8 macaddr8 类型存储以EUI-64格式存储MAC地址.注意:IPv6使用修订过的EUI-64格式,从EUI-48转换过来需要第7位应该设置为1。接收以下类型的输入: '08:00:2b:01:02:03:04:05' '08-00-2b-01-02-03-04-05' '08002b:0102030405' '08002b-0102030405' '0800.2b01.0203.0405' '0800-2b01-0203-0405' '08002b01:02030405' '08002b0102030405' 这些都代表同一地址.输出为第一种. 要将一个传统的48位MAC地址(EUI-48格式)转换为修订过的EUI-64格式(IPv6地址),使用函数macaddr8_set7bit: SELECT macaddr8_set7bit('08:00:2b:01:02:03'); macaddr8_set7bit ------------------------- 0a:00:2b:ff:fe:01:02:03 (1 row) 3.2.2 网址函数与运算符 下表介绍了可用于cidr和inet类型的运算符. 运算符 <<, <<=, >>,>>=, && 用于测试是否包含在子网中.它们只处理两个网址的网络部分(忽略主机部分),判断一个网址是否等于另一个网址或是其子集.表:cidr and inet Operators Operator Description Example < is less than inet '192.168.1.5' < inet '192.168.1.6' <= is less than or equal inet '192.168.1.5' <= inet'192.168.1.5' = equals inet '192.168.1.5' = inet '192.168.1.5' >= is greater or equal inet '192.168.1.5' >= inet '192.168.1.5' > is greater than inet '192.168.1.5' > inet '192.168.1.4' <> is not equal inet '192.168.1.5' <> inet '192.168.1.4' << is contained by inet '192.168.1.5' << inet '192.168.1/24' <<= is contained by or equals inet '192.168.1/24' <<= inet '192.168.1/24' >> contains inet '192.168.1/24' >> inet '192.168.1.5' >>= contains or equals inet '192.168.1/24' >>= inet '192.168.1/24' && contains or is contained by inet '192.168.1/24' && inet '192.168.1.80/28' ~ bitwise NOT ~ inet '192.168.1.6' & bitwise AND inet '192.168.1.6' & inet '0.0.0.255' | bitwise OR inet '192.168.1.6' |inet '0.0.0.255' + addition inet '192.168.1.6' + 25 - subtraction inet '192.168.1.43' - 36 - subtraction inet '192.168.1.43' - inet '192.168.1.19' 下表介绍了可用于cidr和inet两种类型的函数. 函数abbrev, host, text 主要用于格式化显示.表: cidr 、inet 函数 Function Return Type Description Example Result abbrev(inet) text abbreviated display format as text abbrev(inet'10.1.0.0/16') 10.1.0.0/16 abbrev(cidr) text abbreviated display format as text abbrev(cidr'10.1.0.0/16') 10.1/16 broadcast(inet) inet broadcast address for network broadcast('192.168.1.5/24') 192.168.1.255/24 family(inet) int extract family of address; 4 for IPv4, 6 for IPv6 family('::1') 6 host(inet) text extract IP address as text host('192.168.1.5/24') 192.168.1.5 hostmask(inet) inet construct host mask for network hostmask('192.168.23.20/30') 0.0.0.3 masklen(inet) int extract netmask length masklen('192.168.1.5/24') 24 netmask(inet) inet construct netmask for network netmask('192.168.1.5/24') 255.255.255.0 network(inet) cidr extract network part of address network('192.168.1.5/24') 192.168.1.0/24 set_masklen(inet,int) inet set netmask length for inet value set_masklen('192.168.1.5/24',16) 192.168.1.5/16 set_masklen(cidr,int) cidr set netmask length for cidr value set_masklen('192.168.1.0/24'::cidr,16) 192.168.0.0/16 text(inet) text extract IP address and netmask length as text text(inet'192.168.1.5') 192.168.1.5/32 inet_same_family(inet,inet) boolean are the addresses from the same family? inet_same_family('192.168.1.5/24','::1') false inet_merge(inet,inet) cidr the smallest network which includes both of the given networks inet_merge('192.168.1.5/24','192.168.2.5/24') 192.168.0.0/22 说明:任意cidr值可转换为inet;因此,上表中的支持inet函数也支持cidr. 下表介绍了 macaddr 类型的相关函数type.函数trunc(macaddr) 返回MAC 地址.表:macaddr 函数 Function Return Type Description Example Result trunc(macaddr) macaddr set last 3 bytes to zero trunc(macaddr '12:34:56:78:90:ab') 12:34:56:00:00:00 说明:macaddr类型也支持标准的关系运算(>, <=等,按辞典顺序) 和位运算(~, & and |) 下表介绍了macaddr8类型相关的函数。表macaddr8 函数 Function Return Type Description Example Result trunc(macaddr8) macaddr8 set last 5 bytes to zero trunc(macaddr8'12:34:56:78:90:ab:cd:ef') 12:34:56:00:00:00:00:00 macaddr8_set7bit(macaddr8) macaddr8 set 7th bit to one, also known as modified EUI-64, for inclusion in an IPv6 address macaddr8_set7bit(macaddr8'00:34:56:ab:cd:ef') 02:34:56:ff:fe:ab:cd:ef 说明:macaddr8类型也是标准的关系运算和位运算。 3.2.3 扩展阅读 https://www.postgresql.org/files/documentation/pdf/10/postgresql-10-A4.pdf 3.3 MariaDB(10.X) 3.3.1 IPv6相关函数 IS_IPV6(expr) :如果是IPV6地址串,则返回1,否则返回0. SELECT IS_IPV6('48f3::d432:1431:ba23:846f'); +--------------------------------------+ | IS_IPV6('48f3::d432:1431:ba23:846f') | +--------------------------------------+ | 1 | +--------------------------------------+ 1 row in set (0.02 sec) SELECT IS_IPV6('10.0.1.1'); +---------------------+ | IS_IPV6('10.0.1.1') | +---------------------+ | 0 | +---------------------+ INET6_ATON(expr) :将IP地址串转换为对应的数值。 SELECT HEX(INET6_ATON('10.0.1.1')); +-----------------------------+ | HEX(INET6_ATON('10.0.1.1')) | +-----------------------------+ | 0A000101 | +-----------------------------+ SELECT HEX(INET6_ATON('48f3::d432:1431:ba23:846f')); +----------------------------------------------+ | HEX(INET6_ATON('48f3::d432:1431:ba23:846f')) | +----------------------------------------------+ | 48F3000000000000D4321431BA23846F | +----------------------------------------------+ INET6_NTOA(expr):将数值转换为对应的IP地址串。 SELECT INET6_NTOA(UNHEX('0A000101')); +-------------------------------+ | INET6_NTOA(UNHEX('0A000101')) | +-------------------------------+ | 10.0.1.1 | +-------------------------------+ SELECT INET6_NTOA(UNHEX('48F3000000000000D4321431BA23846F')); +-------------------------------------------------------+ | INET6_NTOA(UNHEX('48F3000000000000D4321431BA23846F')) | +-------------------------------------------------------+ | 48f3::d432:1431:ba23:846f | +-------------------------------------------------------+ IS_IPV4_COMPAT(expr): 与INET6_ATON()配合判断IPV6地址是否是IPV4兼容的,是则返回1,否则返回0。 SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.1.1')); +------------------------------------------+ | IS_IPV4_COMPAT(INET6_ATON('::10.0.1.1')) | +------------------------------------------+ | 1 | +------------------------------------------+ SELECT IS_IPV4_COMPAT(INET6_ATON('::48f3::d432:1431:ba23:846f')); +-----------------------------------------------------------+ | IS_IPV4_COMPAT(INET6_ATON('::48f3::d432:1431:ba23:846f')) | +-----------------------------------------------------------+ | 0 | +-----------------------------------------------------------+ IS_IPV4_MAPPED(expr):与INET6_ATON()配合,判断IPV6地址是否是有效的IPV4映射地址,是则返回1,否则返回0。 SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.1.1')); +------------------------------------------+ | IS_IPV4_MAPPED(INET6_ATON('::10.0.1.1')) | +------------------------------------------+ | 0 | +------------------------------------------+ SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.1.1')); +-----------------------------------------------+ | IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.1.1')) | +-----------------------------------------------+ | 1 | +-----------------------------------------------+ 3.3.2 客户端 MariaDB Connector/J JDBC连接串格式如下: jdbc:(mysql|mariadb):[replication:|failover:|sequential:|aurora:]//<hostDescription>[,<hostDescription>...]/[database][?<key1>=<value1>[&<key2>=<value2>]] HostDescription如下: <host>[:<portnumber>] or address=(host=<host>)[(port=<portnumber>)][(type=(master|slave))] host必须是DNS名或者IP地址,如果是IPV6+简单host描述,则IP地址必须写在[]中,如下例。 [2001:0660:7401:0200:0000:0000:0edf:bdd7]:3306 四、云服务商流数据库调研结果 4.1 阿里云 《阿里云IPv6解决方案》 IPv6转换服务 IPv6转换服务(IPv6 Translation Service),是一种有状态的IPv6和IPv4网络地址与协议转换服务。通过IPv6转换服务,具备公网IPv4地址的服务器可快速面向IPv6网络侧用户提供访问服务。IPv6转换服务当前提供四层模式(支持TCP和UDP协议)。 4.2 百度云 为此百度云制定了IPv6改造的“三步走”方案。 第一步,将百度云网络接入IPv6网络环境,为产品提供IPv6接入访问服务; 第二步,百度云核心产品支持IPv6协议栈,拥有全球唯一的IPv6地址,并具备主动访问IPv6网络能力; 第三步,百度云所有产品支持IPv4和IPv6双协议栈,为用户提供完整的IPv6网络支持。 百度云在EIP上集成了 IPv6 终结功能,为绑定了EIP的云服务器、负载均衡等实例提供IPv6访问能力。用户无需改造现有业务架构部署,只需在EIP上开启IPv6终结功能,即可获取到一个IPv6地址,使业务获得对外提供IPv6访问服务的能力,IPv6网络客户端访问该地址的流量会被转换为IPv4流量,实现用户业务和IPv6网络的平滑对接。 IPv6地址分配原则:EIP开启IPv6终结功能后,会为该EIP分配一个全球唯一的IPv6地址,地址组成为 “2400:da00:404:2::” 前缀拼接EIP的IPv4地址,即128位IPv6地址前96位为固定前缀,后32位为对应EIP的IPv4地址。 每个EIP仅会分配一个IPv6地址,EIP关闭IPv6终结功能后该IPv6地址会被系统回收。 注意:目前百度云IPv6终结功能处于公测阶段,仅向华北-北京区域(Region)的EIP实例开放试用,用户需通过工单申请开通。 4.3 腾讯云 腾讯云IPv6技术将采用平滑过渡的方式推进: 第一步,在中国互联网的客户端和流量以IPv4为主的大环境下,提供平滑、安全的IPv6互联网入口,也提供透明的6to4转换服务访问底层核心网络和现网业务,时间是2018到2019年; 第二步,到2020年,逐步完成端到端的IPv6改造,此时IPv6与IPv4同时运行在腾讯云上; 第三步,随着中国互联网的IPv6访问和流量的比例加大,底层核心网络向IPv6过渡完成,IPv6成为网络主体,同时兼容存量的IPv4的业务。到2022年基本实现从IPv4到IPv6的切换。 五、附录 附录一、 IPv6标准简介 IPv6 IPv6的地址长度为128b,是IPv4地址长度的4倍。于是IPv4点分十进制格式不再适用,采用十六进制表示。IPv6有3种表示方法。 一、冒分十六进制表示法 格式为X:X:X:X:X:X:X:X,其中每个X表示地址中的16b,以十六进制表示,例如: ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 这种表示法中,每个X的前导0是可以省略的,例如: 2001:0DB8:0000:0023:0008:0800:200C:417A→ 2001:DB8:0:23:8:800:200C:417A 二、0位压缩表示法 在某些情况下,一个IPv6地址中问可能包含很长的一段0,可以把连续的一段0压缩为“::”。但为保证地址解析的唯一性,地址中”::”只能出现一次,例如: FF01:0:0:0:0:0:0:1101 → FF01::1101 0:0:0:0:0:0:0:1 → ::1 0:0:0:0:0:0:0:0 → :: 三、内嵌IPv4地址表示法 为了实现IPv4-IPv6互通,IPv4地址会嵌入IPv6地址中,此时地址常表示为:X:X:X:X:X:X:d.d.d.d,前96b采用冒分十六进制表示,而最后32b地址则使用IPv4的点分十进制表示,例如::192.168.0.1与::FFFF:192.168.0.1就是两个典型的例子,注意在前96b中,压缩0位的方法依旧适用 [6] 。 国际标准 Internet Protocol, Version 6 (IPv6) Specification, rfc8200 https://tools.ietf.org/html/rfc8200 List of IPv6 tunnel brokers https://en.wikipedia.org/wiki/List_of_IPv6_tunnel_brokers Format for Literal IPv6 Addresses in URL's,rfc2732https://tools.ietf.org/html/rfc2732 推广情况 IPV6 的发展是从 1992 年开始的,截止 2016 年 9 月底,全球共有超过 220 个国家和地区组织申请了 IPv6 地址,申请量已经达到 IPv4 地址的 18 万多倍,其中 25.4%的地址块已通告使用。全球 13 个根域名服务器中已有 11 个根域名服务器支持 IPv6;1346个顶级域名服务器中已有 1318 个支持 IPv6,占比达 97.9%。 全球活跃的 IPv6 路由条目超过 2.9 万条,支持 IPv6 的自治域超过 1.18 万个,已有超过 248 个运营商永久提供IPv6 的接入服务。 信息源:https://www.chyxx.com/industry/201801/606465.html 附录二、中国关于IPv6的战略布局 国家战略规格 2017-11-26 中共中央办公厅 国务院办公厅印发《推进互联网协议第六版(IPv6)规模部署行动计划》 推广情况 在网络基础设施方面,三家基础电信企业已完成26个省、上百个地市LTE网络IPv6改造,并为LTE用户分配IPv6地址,目前基础电信企业已分配IPv6地址的用户总数超过7000万。 在应用基础设施方面,基础电信企业的大型数据中心均已支持IPv6,基本建立IPv6业务受理、开通测试流程;部分内容分发网络企业、云服务平台企业已完成部分产品IPv6改造,正逐步提供IPv6商用服务。 在互联网应用方面,主要互联网企业针对用户量大、流量集中的互联网应用,均制定了IPv6改造实施方案,相关改造工作正有序开展;基础电信企业的门户网站及部分自营业务系统已完成IPv6改造并对用户提供服务。 在终端方面,国内主要的LTE终端基本具备IPv6支持能力,大部分终端默认配置支持IPv4/IPv6双栈。 信息源:http://net.yesky.com/internet/312/1102614812.shtml 附录三、判断系统是否支持IPv6 本机命令检测 最简单的验证方式是,执行命令(ping6 ::1)来验证。 $ uname -v Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 $ ping6 ::1 PING6(56=40+8+8 bytes) ::1 --> ::1 16 bytes from ::1, icmp_seq=0 hlim=64 time=0.105 ms 16 bytes from ::1, icmp_seq=1 hlim=64 time=0.131 ms 16 bytes from ::1, icmp_seq=2 hlim=64 time=0.141 ms 16 bytes from ::1, icmp_seq=3 hlim=64 time=0.138 ms ^Z [1]+ Stopped ping6 ::1 第3方网站监测 地址:http://test-ipv6.com/ 源于一个开源项目,test-IPv6.com是一个开源网站,致力于帮助终端用户确定IPv6是否可用. 附录四、Linux IPv6 HOWTO (en) Linux IPv6 HOWTO的目标是解答关于Linux系统中IPv6相关问题,包括安装、配置、使用IPv6程序. 参考 百度百科 IPv6 维基百科 IPv6 新华社授权发布 《推进互联网协议第六版(IPv6)规模部署行动计划》 国务院直接发布 《推进互联网协议第六版(IPv6)规模部署行动计划》 IBM产品兼容IPv6清单 Informix support for IPv6 addresses Internet Protocol, Version 6 (IPv6) Specification, rfc8200 https://tools.ietf.org/html/rfc8200 PostgreSQL 手册 https://www.postgresql.org/files/documentation/pdf/10/postgresql-10-A4.pdf
变化是这个时代的主旋律,更让我们焦虑和兴奋的如今变化的速度总是超出我们的想象。在这样的时代,无论是组织还是个人,都需要一种能力,以帮助自己拥抱变化,或至少能与变化和谐共处。 项目之所以是项目,核心的因素在于不确定,在于处理变化。 项目管理核心是在面对不确定性的前提下,控制不确定性的影响,完成组织的变革,或产生新产品,或交付新服务,或产生新成果。 项目管理助力组织赢在VUCA时代 VUCA时代是什么 VUCA时代的由来 因错误的假设而迷失,因错误的航标而消失 在宏观的尺度观察我们的时代 在中观的尺度观察我们的时代 在微观的尺度观察我们的时代 唯一确定的是不确定,唯一不变的是变化 你也许判断对了困境,但你可能关心错了问题 互联网但本质:无界、无价、无序 失效但经典管理理论 我们在寻找一种拥抱变化的能力 项目管理:一种拥抱变化,提高成功率的方法论 项目源于变化 项目管理的基本范畴 项目管理的导入 从培训开始 可能成为合格项目的三个潜质 项目管理人才的知识模型 项目管理的十大知识领域 组织不变的前提下,普及项目管理依然能产生价值 任职资格的牵引 是时候导入项目管理制度 真正成立项目管理办公室 项目管理办公室的价值 项目管理办公室的主要职责 是时候考虑组织变革 或许组织变更可以更加激进一些 当真正了解自己组织的项目时,也是项目制度真正落地的时候,否则就让项目经理们放手去探索 激励考虑智慧,以上仅是示意,不做参考 未来已来,你开始准备了吗?
join计算的代价很高吗? 看情况 join的代价依赖于join的条件,索引是什么样,依赖于表有多大,相关信息是否已经cache住了,使用的什么硬件,配置参数的信息,统计信息是否已经更新,同时是否还有其他运行的计算…… 晕了?别急!在以下情景下,我们依然可以找到一些规律来分析判断: 随着join的表的数量增加 随着这些表的行数的增加 有没有索引 此类情况,在工作中经常会碰到,比如:如果有一张产品表 product,但业务上需要加入一个产品的状态,包括Active、Discontinued、Recalled等。此时,我们会有3种不同的做法: 在产品表 product 中,增加一列状态号 status_id,同时增加一个新的状态表 status。 在产品表 product 中,增加一列状态号 status_id,同时让应用来定义每个状态号 status_id 对应的含义及显示。 在产品表 product 中,增加一列文本列,用来描述状态信息。 通常,我们会选择第一个做法。关于后两种的做法,通常的质疑在两个方面:join的性能和开发人员的工程化能力。后者通常与个人喜好有关,姑且不谈,咱们来一起讨论一下join的性能问题。 为便于讨论,选用PostgreSQL测试数据来讨论。以等值连接为例,让我们看看执行上面的join时,性能会有什么变化?我们担心的性能变慢,那具体会变成多慢。 以下是用来生成测试用的建表语句。 DROP FUNCTION IF EXISTS create_tables(integer, integer, boolean); CREATE FUNCTION create_tables(num_tables integer, num_rows integer, create_indexes boolean) RETURNS void AS $function_text$ BEGIN -- There's no table before the first one, so this one's a little different. Create it here instead of in our loop. DROP TABLE IF EXISTS table_1 CASCADE; CREATE TABLE table_1 ( id serial primary key ); -- Populate the first table INSERT INTO table_1 (id) SELECT nextval('table_1_id_seq') FROM generate_series(1, num_rows); -- Create and populate all the other tables FOR i IN 2..num_tables LOOP EXECUTE 'DROP TABLE IF EXISTS table_' || i || ' CASCADE;'; EXECUTE format($$ CREATE TABLE table_%1$s ( id serial primary key, table_%2$s_id integer references table_%2$s (id) ); INSERT INTO table_%1$s (table_%2$s_id) SELECT id FROM table_%2$s ORDER BY random(); $$, i, i-1); IF create_indexes THEN EXECUTE 'CREATE INDEX ON table_' || i || ' (table_' || i - 1 || '_id);'; END IF; END LOOP; END; $function_text$ LANGUAGE plpgsql; -- We'll want to make sure PostgreSQL has an idea of what's in these tables DROP FUNCTION IF EXISTS analyze_tables(integer); CREATE FUNCTION analyze_tables(num_tables integer) RETURNS void AS $function_text$ BEGIN FOR i IN 1..num_tables LOOP EXECUTE 'ANALYZE table_' || i || ';'; END LOOP; END; $function_text$ LANGUAGE plpgsql; 执行建表函数…… SELECT create_tables(10, 10000, False); SELECT * from table_1 limit 10; id ---- 1 2 3 4 5 6 7 8 9 10 (10 rows) SELECT * from table_2 limit 10; id | table_1_id ----+------------ 1 | 824 2 | 973 3 | 859 4 | 789 5 | 901 6 | 112 7 | 162 8 | 212 9 | 333 10 | 577 (10 rows) OK,现在我们可以任意创建所需要的表了。 我们还需要方法来查询,以测试join的性能。有一些不错的长查询,但我们不希望手工来编写,于是我们创建了另一个函数来生成它们。只需要告诉它有多少表参与join,以及where子句中最后一张表的最大的id,它就可以执行了。 DROP FUNCTION IF EXISTS get_query(integer, integer); CREATE FUNCTION get_query(num_tables integer, max_id integer) RETURNS text AS $function_text$ DECLARE first_part text; second_part text; third_part text; where_clause text; BEGIN first_part := $query$ SELECT count(*) FROM table_1 AS t1 INNER JOIN$query$; second_part := ''; FOR i IN 2..num_tables-1 LOOP second_part := second_part || format($query$ table_%1$s AS t%1$s ON t%2$s.id = t%1$s.table_%2$s_id INNER JOIN$query$, i, i-1); END LOOP; third_part := format($query$ table_%1$s AS t%1$s ON t%2$s.id = t%1$s.table_%2$s_id WHERE t1.id <= %3$s$query$, num_tables, num_tables-1, max_id); RETURN first_part || second_part || third_part || ';'; END; $function_text$ LANGUAGE plpgsql; 下面是一个生成查询的示例。 SELECT get_query(5, 10); get_query -------------------------------------------------- + SELECT + count(*) + FROM + table_1 AS t1 INNER JOIN + table_2 AS t2 ON + t1.id = t2.table_1_id INNER JOIN+ table_3 AS t3 ON + t2.id = t3.table_2_id INNER JOIN+ table_4 AS t4 ON + t3.id = t4.table_3_id INNER JOIN+ table_5 AS t5 ON + t4.id = t5.table_4_id + WHERE + t1.id <= 10; (1 row) Time: 1.404 ms OK,让我们花一些时间来思考一下,当我们运行这条查询时,我们实际让Postgres做了哪些事情。在这条SQL中,我们在询问表 table_5 中的 table_4_id 列有多少在表 table_4中,而且表 table_4 中 table_3_id 列有多少在表 table_2 中,而且表 table_2 中 table_1_id 列有多少在表 table_1 中,而且 table_1_id 小于等于10。 我们继续运行…… SELECT count(*) FROM table_1 AS t1 INNER JOIN table_2 AS t2 ON t1.id = t2.table_1_id INNER JOIN table_3 AS t3 ON t2.id = t3.table_2_id INNER JOIN table_4 AS t4 ON t3.id = t4.table_3_id INNER JOIN table_5 AS t5 ON t4.id = t5.table_4_id WHERE t1.id <= 10; count ------- 10 (1 row) Time: 40.494 ms 我们可以通过抛出 EXPLAIN ANALYZE 来查看进展。 EXPLAIN ANALYZE SELECT count(*) FROM table_1 AS t1 INNER JOIN table_2 AS t2 ON t1.id = t2.table_1_id INNER JOIN table_3 AS t3 ON t2.id = t3.table_2_id INNER JOIN table_4 AS t4 ON t3.id = t4.table_3_id INNER JOIN table_5 AS t5 ON t4.id = t5.table_4_id WHERE t1.id <= 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=827.93..827.94 rows=1 width=8) (actual time=43.392..43.392 rows=1 loops=1) -> Hash Join (cost=645.31..827.90 rows=9 width=0) (actual time=35.221..43.353 rows=10 loops=1) Hash Cond: (t5.table_4_id = t4.id) -> Seq Scan on table_5 t5 (cost=0.00..145.00 rows=10000 width=4) (actual time=0.024..3.984 rows=10000 loops=1) -> Hash (cost=645.20..645.20 rows=9 width=4) (actual time=34.421..34.421 rows=10 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Hash Join (cost=462.61..645.20 rows=9 width=4) (actual time=25.281..34.357 rows=10 loops=1) Hash Cond: (t4.table_3_id = t3.id) -> Seq Scan on table_4 t4 (cost=0.00..145.00 rows=10000 width=8) (actual time=0.022..4.828 rows=10000 loops=1) -> Hash (cost=462.50..462.50 rows=9 width=4) (actual time=23.519..23.519 rows=10 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Hash Join (cost=279.91..462.50 rows=9 width=4) (actual time=12.617..23.453 rows=10 loops=1) Hash Cond: (t3.table_2_id = t2.id) -> Seq Scan on table_3 t3 (cost=0.00..145.00 rows=10000 width=8) (actual time=0.017..5.065 rows=10000 loops=1) -> Hash (cost=279.80..279.80 rows=9 width=4) (actual time=12.221..12.221 rows=10 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Hash Join (cost=8.55..279.80 rows=9 width=4) (actual time=0.293..12.177 rows=10 loops=1) Hash Cond: (t2.table_1_id = t1.id) -> Seq Scan on table_2 t2 (cost=0.00..145.00 rows=10000 width=8) (actual time=0.017..5.407 rows=10000 loops=1) -> Hash (cost=8.44..8.44 rows=9 width=4) (actual time=0.054..0.054 rows=10 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Index Only Scan using table_1_pkey on table_1 t1 (cost=0.29..8.44 rows=9 width=4) (actual time=0.024..0.035 rows=10 loops=1) Index Cond: (id <= 10) Heap Fetches: 10 Planning time: 1.659 ms Execution time: 43.585 ms (26 rows) 我们可以看到,除了使用 表table_1的主键索引外,都是顺序扫描。它还可以怎么做呢?因为我们没有建任何索引来优化它。 如果我们重新做这个实验,告诉* create_tables()*去创建索引…… SELECT create_tables(10, 10000, True); 重新运行后,我们得到不同的查询计划。 EXPLAIN ANALYZE SELECT count(*) FROM table_1 AS t1 INNER JOIN table_2 AS t2 ON t1.id = t2.table_1_id INNER JOIN table_3 AS t3 ON t2.id = t3.table_2_id INNER JOIN table_4 AS t4 ON t3.id = t4.table_3_id INNER JOIN table_5 AS t5 ON t4.id = t5.table_4_id WHERE t1.id <= 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------ Aggregate (cost=88.52..88.53 rows=1 width=8) (actual time=0.411..0.411 rows=1 loops=1) -> Nested Loop (cost=1.43..88.50 rows=9 width=0) (actual time=0.067..0.399 rows=10 loops=1) -> Nested Loop (cost=1.14..85.42 rows=9 width=4) (actual time=0.054..0.304 rows=10 loops=1) -> Nested Loop (cost=0.86..82.34 rows=9 width=4) (actual time=0.043..0.214 rows=10 loops=1) -> Nested Loop (cost=0.57..79.25 rows=9 width=4) (actual time=0.032..0.113 rows=10 loops=1) -> Index Only Scan using table_1_pkey on table_1 t1 (cost=0.29..8.44 rows=9 width=4) (actual time=0.015..0.023 rows=10 loops=1) Index Cond: (id <= 10) Heap Fetches: 10 -> Index Scan using table_2_table_1_id_idx on table_2 t2 (cost=0.29..7.86 rows=1 width=8) (actual time=0.007..0.007 rows=1 loops=10) Index Cond: (table_1_id = t1.id) -> Index Scan using table_3_table_2_id_idx on table_3 t3 (cost=0.29..0.33 rows=1 width=8) (actual time=0.008..0.008 rows=1 loops=10) Index Cond: (table_2_id = t2.id) -> Index Scan using table_4_table_3_id_idx on table_4 t4 (cost=0.29..0.33 rows=1 width=8) (actual time=0.007..0.008 rows=1 loops=10) Index Cond: (table_3_id = t3.id) -> Index Only Scan using table_5_table_4_id_idx on table_5 t5 (cost=0.29..0.33 rows=1 width=4) (actual time=0.007..0.008 rows=1 loops=10) Index Cond: (table_4_id = t4.id) Heap Fetches: 10 Planning time: 2.287 ms Execution time: 0.546 ms (19 rows) 结果是使用来索引,速度快了很多。而且这与我们预期的一致。我们现在准备将这些混到一起,看看随着表和列数量的增加时会有什么变化? 需要说明一下,这些测试是运行在AWS RDS db.m4.large实例上。这是最便宜的实例,而且也不会在性能上自动扩容,所以可以作为基准。我们共运行10次,取平均值。 最初的查询,join涉及的表数量从2到200,包含3种行设置,而且没有索引。 db.m4.large 性能还是不错的。更为重要的是,我们可以计算每个增加的join的成本!对于100行的表,下面的数据显示了每次增加表所带来的执行时间的增加: 表的数量 平均增加量 时间(ms) 2-50 (0.012738 - 0.000327) / (50 - 2) = 0.259 50-100 (0.0353395 - 0.012738) / (100 - 50) = 0.452 100-150 (0.0762056 - 0.0353395) / (150 - 100) = 0.817 150-200 (0.1211591 - 0.0762056) / (200 - 150) = 0.899 甚至在参与join的表数量已经接近200时,每增加一个表只增加少于1ms的执行时间。 在讨论增加一个表用来存储产品的状态时,表增加至1000行时就过载了。所以,不考虑索引的情况下,增加一个引用的表并不会对性能产生实质性影响。 由于之前所做的基准测试的数据量不大,如果碰到大表呢?我们重新做了相同的测试,但这次每张表都包含一百万行。这次只增加到50张表。为什么?运行它需要一段时间,我只有有限都预算和耐心 百万级大表时的性能 这次运行结果曲线就没有重叠了。请看最大的1百万行的表,每增加1张join的表,它需要多运行93ms。 表的数量 平均增加量 时间(ms) 2-10 (0.8428495 - 0.0924571) / (10 - 2) = 93.799 10-20 (1.781959 - 0.8428495) / (20 - 10) = 93.911 20-30 (2.708342 - 1.781959) / (30 - 20) = 92.638 30-40 (3.649164 - 2.708342) / (40 - 30) = 94.082 40-50 (4.565644 - 3.649164) / (50 - 40) = 91.648 此次都是顺序扫描,因此我们增加索引,看看会有什么变化? 增加索引后的性能 增加索引后,性能影响很显著。当能使用到索引时,不管表中有多少行,测试结果都差不多。针对10万行的表的查询一般最慢,但并总是最慢。 表的数量 平均增加量 时间(ms) 2-50 (0.0119917 - 0.000265) / (50 - 2) = 0.244 50-100 (0.035345 - 0.0119917) / (100 - 50) = 0.467 100-150 (0.0759236 - 0.035345) / (150 - 100) = 92.638 0.811 150-200 (0.1378461 - 0.0759236) / (200 - 150) = 1.238 即使查询已经涉及到150张表,此时增加1一张表只会增加1.2ms。 最后一个测试场景,由于历时太长,等不及生成200个1百万行的表及建立索引,但又想观察性能的变化,于是选择测试50张表时的结果…… 加大数据量的测试 表的数量 平均增加量 时间(ms) 2-10 (0.0016811 - 0.000276) / (10 - 2) = 0.176 10-20 (0.003771 - 0.0016811) / (20 - 10) = 0.209 20-30 (0.0062328 - 0.003771) / (30 - 20) = 0.246 30-40 (0.0088621 - 0.0062328) / (40 - 30) = 0.263 40-50 (0.0120818 - 0.0088621) / (50 - 40) = 0.322 基于之前增加索引带来的性能改进结果,这次并没有带来太多的性能惊喜。50张1百万行的表做join,只需要12ms。Cool! 也许这些额外的join操作的成本比我们预想的要低一些,但有件事需要我们去考虑,虽然每个增加的join运算所占用的时间很小,但越多的表意味着越多的查询计划需要考虑,这很可能会导致很难找到最佳的查询计划。例如,当join的数量超过 geqo_threshold 时(默认为12),postgres 会停止参考所有可能的查询计划,改为使用通用算法。这会改变查询计划,引起对性能的负面影响。 由于每个系统的业务千差万别,一定要基于你的数据来测试你的查询。虽然我们看到增加join的成本很低,但仍然非常有必要去规范你的数据。 [原文] Cost of a Join非直译,仅为增加乐趣,向作者的严谨性致敬。
源于Linkedin的一条推文,《哪来十年如一日的坚持!那些目标一致在变的人后来这样了》,阅读后想起了十年前,那是2008年…… 十年 2008年,是对互联网懵懂的日子 那时的互联网圈最热门的是Facebook在网站上开放API,供第三方开发者接入。Facebook把自己变成了互联网上的一种操作系统,所有APP都是运行在其上,业务上、用户上都依赖于这个大平台,颠覆了我们对网站的理解。Feed信息流成为了时髦的流行词。 那时在京东购物还是非常前卫的生活方式,京东那年还和明基就投影仪的售后狠狠的干了一仗,并成为一时谈资的佳话。那时当当、凡客都是在风口,那时饭否刚刚开始…… SNS是当时最热的风口,于是随企业北上,投入到SNS的热潮中。在这样的背景下,那年我飘在北京,作为一起网的推荐系统开发者,没日没夜的忙碌着。 在那段时间里,体验了每日构建、每日发布的节奏感,体验了基于数据、以用户为中心的持续完善,也体验了人人都是产品经理的投入与烧脑。 SNS 那时租住在知春路上,夜晚在隔板间里常常漫谈江湖趣事,也在那里第一次知道了刘慈欣的《三体》,同屋的哥们聊起“黑暗森林”,“降维打击”,但无论如何也没想到它会成为后续很多年里互联网从业者的方法论,以至于不读《三体》的产品经理都不好意思和别人打招呼。 三体 2008年,是让我们揪心难过的日日夜夜 5月12日上午,在写字楼高层里忙碌,突然感到一阵摇晃,大家诧异的望着彼此,才意识到是地震了,于是百度、新浪新闻(那时还没微博),才知道是四川地震了,也影响到了山西。但此事电话线路早已瘫痪,到了下午许久才得到平安的消息。 但一切才开始,四川的新闻、图片、视频陆续穿出来…… 于是白天忙着编程开发,晚上回到住处,和同事们守在电视前,一起看……直到汶川救援到尾声。 对于生命的脆弱,人生的无常,痛彻在心,一次难以忘怀的心灵洗礼。 汶川地震 2008年,是梦想与光荣的记忆 快乐的事情,大家都会记得,由于当时开发正在关键,虽然守着北京,也仅某天晚上随人流围绕水滴、鸟巢转了一圈。 奥运会 2008年,是家的起点 2008年次贷危机影响全球,国内公司倒闭潮也此即彼伏,房地产遭受了艰巨考验,房价下跌成风。 此时,摆在的既是一个选择,更是一个挑战。 在朋友们的帮助下,让这一年更有意义。 天津奥城 2008年,《花开在眼前》发布 韩磊的嗓音与《激荡三十年》的沧桑,让时间具型在心间,而如今,又过了10年 花开在眼前 已经开了很多很多遍 每次我总是泪流满面 像一个不解风情的少年 花开在眼前 我们一起走过了从前 每次我总是写下诗篇 让大风唱出莫名的思念 …… 尾声 或坚持,或选择,在每个当下都是纯粹的选择。 只有过了很多年后,回首往事,才知道那年那事造就了今天的你。
数据泄露的代价是昂贵的。包括对商业的影响、客户信心的丧失、法律成本、罚金及所有因攻击带来的直接损失,可能会达数百万。最好的防御也是最好的进攻,所以采取以下五项基本实践,可以让数据更安全:防护、升级、管理、升级和加密。 1、使用数据库代理来避免被攻击 数据库代理或者网关代理介于应用和数据之间,接收来自应用的连接,然后代表应用去连接数据库。设计良好的数据库代理会提供过滤功能和安全模块,帮助系统获得更好的安全性、可靠性、可扩展性和性能。MaxScale Database Firewall Filter会解析通过过滤的请求,可以阻止那些不符合白名单的查询类型,而让我们正常的查询可以顺利通过。例如,你可以设置某一特定的连接只能做更新和插入,另外一个连接则必须满足特定的正则要求等。 像MaxScale这样的代理也可以保护数据库免受DDoS攻击:当很多直接连接到数据库服务时,数据库会发生过载,甚至被压垮。但代理层吸收掉部分负载,从而起到限制此类攻击影响的效果。 2、建立审计机制,加强日志机制 审计与日志相互关联、密不可分,但审计日志比常规但日志要复杂很多。审计日志能提供管理员调查可疑活动的信息,协助针对异常时间进行根本原因分析。除此之外,审计日志还有助于确保与GDPR、PCI、HIPPA、SOX的一致性。 MariaDB的审计插件可以记录大量信息,包括所有接入的连接,所有查询的执行,对每个表的访问事件等。管理员可以看到谁,在什么时间,访问了某张表,谁插入了数据,谁又删除了数据。审计插件可以将日志记录到文件或系统日志(syslog)中,如果你已经将业务分析流程建立在syslog中,就可以基于次分析审计信息了。 3、执行严格的用户账号管理 仔细管理数据库的用户账号对于数据库安全至关重要。其重要性不言而喻,在此就不赘述了。只是简单提醒一下用户账号管理的几个关键方面: 只允许从本机客户端以root用户访问 要求使用强密码 针对不同应用提供不同的数据库用户账号 限制可以访问数据库的IP地址 4、保持数据库软件和OS的更新(有些挑战) 我们都知道为什么要保持软件的更新,但现实中仍然会有各种原因导致会有很多老应用必须泡在旧的OS上,而且使用的是非常旧的数据库服务。它们可以作为一种提醒,保持系统更新是保护数据免受最新攻击的唯一途径。 这不仅限于服务器软件,也包括OS。勒索软件WannaCry就是利用一个Windows的安全漏洞。 5、加密敏感数据,包括应用、传输等等 我们统计记录了最新的一些实践经验。很多企业不太看中加密,但它却很有价值。毕竟,它能降低黑客攻击的动力,尤其是当破解需要花费的成本大于收益时。 第一阶段加密发生在应用层,即在数据库传入数据库之前。如果应用中的数据已经加密,黑客即使突破了数据库,也看不到数据。 下一阶段数据加密是在传输过程中,即数据经过加密后,再在客户端和数据库服务之间,以网络方式传输。这个类似于浏览器使用HTTPS协议传输数据。显然服务器可以看到信息,因为它需要读取你提供的信息;你也可以读取这些信息,因为是你填写的这些表单,但除了你和服务器之外,其他人不能读到。 其他 除了以上谈到的5点基本内容外,可以基于不同数据的加密技术来保证数据安全。像MariaDB可以将表空间、重做日志、二进制日志等进行加密。 参考MariaDB的《5-essential-practices-database-security》
【声明】本文基于微软《The ultimate meeting guide》编写和整理,更多参见:https://clouddamcdnprodep.azureedge.net/asm/1057331/original 引言 高效会议是促成事业成功的必要因素。它们让团队保持同步,及时获得工作所需的信息。另一面,会议也是大家容易抱怨的对象。我们对会议即爱又恨。 01 你真的需要会议吗 71%的高级管理者认为会议是效率低下或没有效果的。那什么时候开会才是必须的呢?只有能节省时间和费用时,开会才是有价值。 没有清晰议程导致会议没有产出。在决定开会前,最好评估一下大家的时间,这是最基本的需要注意的地方。之后如果确实要开,则遵从下面的最佳实践。 谁是必须参加会议? 识别关键利益相关者,只邀请他们。之后,通知相关人员,讨论了什么议题,结论是什么。 会议的行动项是什么? 区分会议的目标是不是要做决定,还是只是信息公告? 会议的规模有多大? 如果会议人数超过10人,它更适合定位为演讲,而非会议。 会议是否只是通知少数人? 如果会议大部分时间是讨论情况或者盘问信息,你只需要整理一份纪要,发送邮件或张贴在组织内部的网站上。 会议能解决问题吗? 判断一下这个会议能帮助你或其他伙伴达成一个重要的决定?或者说服特定的人员来支持提案?还是此次会议属于头脑风暴形式,用来收集产品、服务的新信息?如果你的答案都是“不”,很可能你并不需要这个会议。 是否有更好的替代方案,如使用微信群? 如果是,使用这些方案,避免开会,不打扰大家的工作安排。 推迟或取消会议,是否会导致伙伴无法完成他们所承担的任务? 如果是,则尽快召集会议。 02 简单、成功的会议的收益 高效的会议会按时甚至提前结束,当然它一定是遵循整个日程安排。会议的效率越高,你就有更多的时间去完成工作。换句话说,积极有效的会议体验会产生积极的结果。 出色的团队协作 《哈佛商业评论》调研称,只有3-5%的人员能产生额外35%协作价值。然而,即使是高效的人员也依然面临有限的时间和精力的挑战,每次邀请他们参加决策,都会导致他们只有更少的时间去做他们自己的工作。另一面,挑战在于需要鼓励大规模的有效协作。 交流是团队协作的基石,会议提供给团队成员一个传递信息的平台。当争论产生会拖延进程,影响士气,清晰规划的日程能减少对目标的干扰,保证会议按既定路线推进,从而降低无效沟通的可能性。 清晰可行动的方向 盖洛普调查指出,受访雇员中只有一半清晰理解需要他们做什么。调研数据引人深思,公司需要持续雇佣顶级人才,帮助雇员拥有与公司目标一致的努力方向。其中一条方法是让会议预期变得清晰。 如果运用得当,会议可以让重要的信息如水晶般透彻。少就是多:精简会议,聚集议题,传递直接准确的信息。当会议很容易参与时,参会者在会议结束时就能获得重要问题的重要答案。即使雇员对会议议程有一些疑惑,高效率的会议也能提供可行的方向,以便他们快速实施。 增加参与意愿 议程清晰的短会帮助雇员推进工作,协调者也会更容易将跑题的讨论拉回正轨。最终,雇员们散会时,会更愿意参加后续的会议,因为他们感到时间花费的有价值。遵循TED演讲的做法。例如,TED演讲只给每个演讲者很短的时间(18分钟),而不论主题范围,从伟大的思想到产品演示,都一样对待。 更强的责任感 雇员责任感增强可以减少对团队任务监督的投入,高效的会议恰恰能对此有帮助。结构良好、有效率的会议让所有成员理解讨论中各自的角色,帮助推进者让团队成员在项目过程中保持更多的责任感。 伴随着有效、流畅的讨论,会议可以成为最好的项目管理工具,不再是时间管理的噩梦。 高质量决策 有效的会议也会产生更好的决策,提供时间和空间来讨论相关问题。如今不同领域的团队需要保持紧密的一致性,尤其是在做关键决策时。有效的协作帮助每个都站在统一角度和层面来讨论和思考。 03 像专业人士一样开会 团队领导主持会议时如果认真筹备和有策略的推行,可以解决大部分参见的问题。下面是一些建议供参考。 确保合适的人参会 确保最重要的利益相关者可以且有意愿参会。让他们理解参会的意义,对于他们而言最重要的是什么。另外,同时规划方案B,即如果关键人员缺席会议时,议题如何能继续推进。 提供清晰的议程 没有议程的会议让人感觉是浪费时间。没有清晰的方向,参会者可能会讨论数小时却没有达成任何有价值的结论。按议程逐个讨论每个议题,指导讨论,明确每个人的职责。 会前分发议程,包括议题、期望达成的目标。这有助于发挥群体知识,让会议更可行,而非纯信息通知。让每个团队成员准确知道了解需要做的事情和如何去做,观察他们的反馈和行动。 记住时间 《哈佛商业评论》报道称,某世界顶级公司每周的周会一年累积占用30万工时,这还不包括准备时间。周会每周定期举行,逐渐让参会者不再关心时间和效率,延期结束会产生的多米诺骨牌效应,当天其他的工作效率也会降低。 漫长的会议也会容易失去焦点,结束时也没有清晰的指示。提醒参与者可用的时间,并控制好,会有助解决这个问题。 提供视觉化辅助 信息演示有助于抓住与会者的注意力,尤其是讨论到复杂细节时,或话题切换时,这样人们不会走神,错失重要信息。另外,很多人看到信息时,能更好的理解信息。 发送会议纪要 人们一旦转移至下一项工作时,很容易忘记会上讨论的事情。大脑遗忘曲线表明,对于1小时的报告,一个月后大脑只记得其中2-4分钟的内容。会后,参会者又能记住多少呢? 在会议开始时确定会议纪要编写者,能帮助其他人更好的参与会议。如果每个人都需要匆忙的记录信息,会导致误解或低效的多任务。 会后的纪要帮助大家记录会议要点。会议纪要最好尽早发送,它帮助参会者记住讨论的信息,回顾关键内容,确保所有人站在同一层面。 清晰定义行动方案或成果 再高效的会议如果没有确定行动方案,也是没有意义。所有参会者需要关注结论和行动计划。如果会后预期不清晰,参会者会对会议结果失望。 04 轻松管理在线会议 传统面对面的会议正面临越来越多的挑战。在线会议提供了更多的可能,如邀请异地人员参会,记录会议内容等。虽然有这些优点,但在线会议也带来了新的挑战。提前计划会让会议更有效果。 准备 不要让准备、议题切换等占用会议时间。未来避免技术产生的延误,要确保每个人都拥有合适的技术、邀请和接入信息。 尽早检查软硬件,不要等到最后时刻。验证URL、拨入的号码、麦克风、视频。
译者按:本文作者是亚马逊CTO Werner,今日在其个人博客上发表的关于行业产品的最新见解。如果你对数据库了解不多,则本文能够帮助建立一个宏观的理解,同时能参考亚马逊的产品来指导在企业内部进行数据库技术选型。 【译文】 我经常被问及的一个问题,为什么我们(亚马逊)提供这么多数据库产品?对我来说答案很简单:开发人员希望他们的应用程序能够很好地架构和有效扩展。为此,他们需要能够在同一个应用程序中使用多个数据库和数据模型。 一套数据库很少能满足多个不同使用场景的需求。一套数据库能满足所有场景的时代已经过去,开发人员如今正在构建高度分布式的应用程序,需要使用大量专用数据库。开发人员正在做他们最擅长的事情:将复杂的应用程序分解成更小的部分,然后选择最佳工具来解决每个问题。使用场景不同,同一个任务的最合适的工具也不同。 几十年来,因为唯一的数据库选择就是关系数据库,无论应用程序中数据的类型或功能如何,数据都会被建模为关系数据库,而不是靠使用用例来驱动对数据库对需求。数据库曾经主导来应用使用数据对数据模型。关系数据库是否为规范化模式专门设计的吗?要在数据库中强制引用完整性?当然是,但问题但关键是不是所有应用程序数据模型或用例都与关系模型匹配。 正如我之前谈到的,我们构建Amazon DynamoDB的原因之一是亚马逊当时正在推动当前领先的商业数据库的极限,我们无法维持亚马逊业务增长所需要的可用性、可扩展性和性能需求。我们发现大约70%的操作是键值查找,即只使用了主键并且返回了一行。由于不需要引用完整性和事务,我们意识到这些访问模式可以通过不同类型的数据库更好地满足。此外,随着Amazon.com的增长和扩展,无限的横向扩展需要成为一个关键的设计点 ,但简单扩展并不是一个有效的选择。这最终导致了DynamoDB的诞生,一种非关系型数据库服务,它可以扩展到超出关系数据库的限制。 这并不意味着关系数据库在当前的开发实践中不再能提供实用性,可用性,可扩展或提供高性能。事实上,我们的客户已经证明了这一点,因为Amazon Aurora仍然是AWS历史上发展最快的服务。我们在Amazon.com上遇到的是,用户以超出预期的方式在使用数据库。这正是本博客后续的核心 - 数据库是为了一个目的而构建的,将用例与数据库相匹配将有助于您更快地开发高性能,可扩展且功能更强的应用程序。 专用数据库 世界仍在变化,非关系数据库的种类继续在增加。我们越来越多地看到,客户希望基于不同数据模型构建在全网扩展的应用程序。为了满足这些需求,开发人员现在可以选择关系,键值,文档,图形,内存和搜索数据库。每一类数据库都解决了一个特定问题或一组问题。 亚马逊数据库全家福 让我们仔细看看上面每个数据库的目的: 关系:关系数据库是自描述的,因为它使开发人员能够定义数据库的模式以及数据库中行和表之间的关系和约束。开发人员依赖关系数据库(而不是应用程序代码)的功能来保证数据模式和数据库中数据的引用完整性。关系数据库的典型用例包括Web和移动应用程序,企业应用程序和在线游戏。Airbnb是客户使用Amazon Aurora构建高性能和可扩展应用程序的一个很好的例子。Aurora为Airbnb提供了一个完全托管,可扩展且功能齐全的服务,来运行他们的MySQL工作负载。 键值:键值数据库具有高度可分区性,允许在其他类型的数据库无法实现的级别进行水平扩展。游戏、广告技术和物联网等用例特别适合于键值数据模型,其中访问模式要求针对已知键值的低延迟查询/写入。DynamoDB的目的是为任何规模的工作负载提供持续的毫秒级延迟服务。这种一致的性能是Snapchat Stories功能(包括Snapchat最大的存储写入工作负载)迁移到DynamoDB的重要原因。 文档:文档数据库的使用对于开发者来说非常直观,因为应用程序层中的数据通常表示为JSON格式文档。开发者可以使用和应用程序代码中的相同文档模型格式来保留数据。Tinder是使用DynamoDB的灵活模式模型来实现开发人员效率的一个客户示例。 图:图数据库的目的是使构建和运行使用高度连接的数据集应用程序变得容易。图数据库的典型用例包括社交网络,推荐引擎,欺诈检测和知识图。Amazon Neptune是一个完全托管的图形数据库服务。Neptune支持Property Graph模型和Resource Description Framework(RDF)框架,有两个图形API可供选择:TinkerPop和RDF / SPARQL。目前的Neptune用户主要是构建知识图表,构建游戏内置的推荐和欺诈检测。例如,汤森路透通过使用Neptune帮助他们的客户浏览复杂的全球税收政策和法规网络。 内存:金融服务,电子商务,Web和移动应用程序都有排行榜,会话存储和实时分析等场景,它们需要微秒响应时间,并且随时可能出现大量流量峰值。我们构建了Amazon ElastiCache,提供Memcached和Redis,满足低延迟,高吞吐量的工作负载的需求,例如麦当劳,这些工作负载无法由基于磁盘的数据存储负担。Amazon DynamoDB Accelerator(DAX)是专用数据存储的另一个示例。构建DAX是为了使DynamoDB读取速度提高一个数量级。 搜索:许多应用程序借助输出日志,帮助开发人员解决问题。Amazon Elasticsearch Service(Amazon ES)的定位是,通过对机器产生对数据建立索引,聚合和搜索半结构化日志和指标,提供近乎实时的可视化和分析。Amazon ES也是一款功能强大的高性能搜索引擎,可用于全文搜索。Expedia正在使用150多个Amazon ES域,30 TB数据和300亿个文档,处理各种关键任务,包括运营监控和故障排除,分布式应用程序堆栈跟踪和定价优化。 使用专用数据库构建应用程序 开发人员正在构建高度分布式和松耦合的应用程序,AWS使开发人员能够使用多个AWS服务构建这些云原生应用程序。以Expedia为例。虽然对于客户来说,Expedia网站看起来像一个应用程序,但在幕后,Expedia.com由许多组件组成,每个组件都具有特定的功能。通过将诸如Expedia.com之类的应用程序分解为具有特定作业的多个组件(例如微服务,容器和AWS Lambda函数),开发人员可以通过提高规模和性能,减少运维,提高部署灵活性以及组件独立发展,来提高工作效率。构建应用程序时,开发人员可以将每个应用场景,选择最适合需要的数据库。 为了实现这一点,请查看一些使用多种不同类型的数据库来构建应用程序的客户: Airbnb使用DynamoDB存储用户的搜索历史记录,以便快速查找,以及提供个性化搜索。Airbnb还使用ElastiCache在内存中存储会话状态,以便更快地进行站点服务,并且他们使用Amazon RDS上的MySQL 作为其主要事务数据库。 Capital One使用Amazon RDS存储状态管理的交易数据,使用Amazon Redshift存储需要聚合分析的Web日志,使用DynamoDB存储用户数据,以便客户可以使用Capital One应用程序快速访问其信息。 Expedia使用Aurora,Amazon Redshift和ElastiCache构建了一个实时数据仓库,用于住宿市场定价,保证数据可用性以进行内部市场分析。数据仓库使用ElastiCache for Redis执行多数据流联合,并使用24小时回顾窗口进行自联接。数据仓库还将处理后的数据直接保存到Aurora MySQL和Amazon Redshift中,以支持运营和分析查询。 Zynga将Zynga扑克数据库从MySQL服务器场迁移到DynamoDB,并获得了巨大的性能提升。过去需要30秒的查询,现在只需要一秒钟。Zynga还使用ElastiCache(Memcached和Redis)代替自己运维对内存缓存服务。Aurora的自动化和Serverless可扩展性使其成为Zynga使用关系数据库时的首选。 强生公司使用Amazon RDS,DynamoDB和Amazon Redshift来最大限度地减少收集和配置数据所花费的时间和精力,更快速的获得洞察。AWS数据库服务正在帮助强生公司改善医生的工作流程,优化供应链和发现新药。 就像开发人员不再编写单一应用程序一样,开发人员也不再需要使用单一数据库来处理应用程序中的所有场景 - 他们可以使用的是多种数据库。虽然关系数据库仍然存在且生命力旺盛,并且仍然适用于许多用例,但是用于键值,文档,图形,内存和搜索用例的专用数据库可以帮助你优化功能、性能和扩展性 - 更重要的是 - 你的客户体验。 原文:https://www.allthingsdistributed.com/2018/06/purpose-built-databases-in-aws.html
一、什么是结构式访谈 结构式访谈又称标准化访谈(Standardized Interview),它是一种对访谈过程高度控制的访问。这种访谈的对象必须按照统一的标准和方法选取。访问的过程也是高度标准化的,即对所有被访问者提出的问题,提问的次序和方式,以及对被访者回答的记录方式等是完全统一的。 二、什么是九段式结构化访谈 九段式结构化访谈是一种推销产品或验证需求的结构化访谈方法,旨在通过设计好的对话框架来确认沟通对象的需求,验证解决方案的价值。 优点是:思路清晰,利于控制话题,易于理解。 缺点是:要将访谈框架融入对话又不漏痕迹,有些难。 三、九段式的访谈框架 九段式的访谈框架包括3个阶段,先从一个具体需求切入,再梳理其影响,最后由需求导出解决方案(注意不是产品!)。每个阶段都包括启发式提问、诱导式控制和重复确认等3步组成。具体见下表。 问题需求 诊断原因 发展影响 验证方案 开头 R1 “咱们谈谈,是什么令贵公司…(重复让客户头疼的问题)?” I1 “除了您,贵公司还有其余的部门也存在类似的问题吗?具体状况如何?” C1 “您认为需要作哪些努力解决这个问题呢?”“是否能够考虑我的几点建议” 控制 R2 “是否是因为…?” I2 “既然这个问题让您那么…?那么某某(职位衔头)也肯定为这个问题不少操心吧?” C2“也许有这么一个解决问题的路子…?您认为这个办法是否可行?如果您能…那么是否对…也有帮助?” 确认 R3“那就是说,产生这个问题(重复让客户头疼的问题)的根本原因是…” I3“据我的理解…(重复是从谁和如何了解到的),似乎这个不只是您一个部门的问题,而且是…的问题。 C3 “据我的理解,假如您能够…(概括客户可能能力变化)那么您就能解决您的问题(重复让客户头疼的问题)” 四、示例 【背景假定】访谈对象是刚拿到融资的共享单车的初创公司,需要比竞争对手更快的速度抢占市场,需要快速扩展地推团队,需要快速迭代演进产品,不缺钱,只缺人! 问题需求 诊断原因 发展影响 验证方案 开头 R1 “咱们谈谈,是什么令贵公司新办公室有那么多空位?” I1 “除了您,贵公司还有其余的部门,如销售部门,是否也存在类似的问题吗?具体状况如何?” C1 “您认为需要作哪些努力解决这个问题呢?” 控制 R2 “是否是因为招聘效率不高?” I2 “既然这个问题让您那么着急,那么CHO也肯定为这个问题不少操心吧?” C2“也许有这么一个解决问题的路子。找专业的第三方完成一面和二面,在基本符合岗位要求时,再请您和HRD做最后的面试确认呢?这样招聘效率提高很多,同时也不用扩充HR部门使得长期成本增加,毕竟这样的大规模招聘是偶然的,不是常态。您认为这个办法是否可行? 确认 R3“那就是说,产生这个问题的根本原因是招聘效率不高?” I3“据我的理解,贵司受市场压力需要快速扩展,技术部门和销售部门都需要急缺人手。 C3 “据我的理解,假如您能够通过第三方快速完成候选人的初筛,那么您就能解决您的问题” 五、注意点 1. 访谈前的准备 选择合适的访谈对象,尤其是要有可能有潜在需求。并不是每个对象都有访谈的价值。 设计中止提问的条件,不对路就不继续,降低成本。 2. 话术不是背课文 要善于针对访谈对象,将结构化提问转为对话的暗线,看似闲聊,实则在寻找插入话题的时机。 3. 后续工作 整理访谈的信息,与客户基本信息结合,与其他访谈信息合并,做需求整理分析,最终形成市场调查。 4.站在对方角度谈话 因为你需要挖掘对方的需求,而不是侃侃而谈你的产品。在不确定需求前,所有的推销都是浪费时间。 5.慎谈产品 先和对方确认需求,再确认解决方案。 在解决方案得到认可后,产品才需要引出。解决方案有争议,就没有合适的产品。 六、实践流程 结构化访谈流程
每次参加技术大会,心中总会涌现出“用技术让世界更美好”的伟大的理想,这次也不例外,Container Day是由Rancher Labs举办的容器技术大会,核心是围绕Kubernetes的研发与应用。本人参会是希望与开发前沿保持同步。 一、什么是Kubernetes? 官方的声明是: Kubernetes 是用于自动部署,扩展和管理容器化应用程序的开源系统。它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现,Kubernetes 构建在 Google 15 年生产环境经验基础之上,并结合来自社区的最佳创意和实践。(官网:https://kubernetes.io/) Google 15年生产经验?对!Kubernetes本是Google内部生产系统管理系统,但由于需要和Twitter比谁是业界技术大牛,就把其开源出来。对于行业来说,是新技术、新应用,但在Google内部却早已应用多年。 采用Kubernetes有助于企业推进CI、CD、DevOps的应用实践,有助于实现资源的高效利用。这个是从价值角度谈的。更激进的观点如下: Kubernetes 已在容器编排之战中取胜,未来很可能会成为“多云”之上的标准层,进而为分布式系统的分发和运行带来根本性的改变,而其自身则会慢慢变得像 Linux Kernel 一样,成为一种系统底层的支撑,不再引人注目。 以上是一家之言,谨慎理解。 Kubernetes的Owner是一家名为Cloud Native Computing Foundation (CNCF)的开源软件基金会,隶属于Linux基金会,成员除了国际巨头外,还有我们熟悉的京东、阿里、华为。 Kubernetes 二、有哪些有趣的见闻? 2.1 华人科技公司更加主动参与开源 Rancher Labs是一家华人创办的软件公司公司,其产品也100%开源。在CNCF中,华人企业参与其中,不再是多年前只是开源世界的黑洞,即下载量巨大,贡献度几乎为零。 2.2 国家以更加务实态度的面对开源 国家强调自主可控战略,但不是盲目的要求100%自主。开源软件的初衷之一就是希望给用户以100%的可控。这点上,双方的诉求一致。会上也看到开源厂商已经参与国家安全领域的建设。 2.3 传统行业中已有早起的鸟开始了技术探索之路 一家面向风能的传统企业,在其IT架构已开始大规划应用部署边缘计算、云计算、AI等先进技术,并结合Kubernetes实现了敏捷开发,持续实践CI、CD。目前已经能从原来的2周一发布,提升到可当天发布。 2.4 Kubernetes对于GPU会持续加强 GPU是AI中的重要资源,但Kubernetes早起版本主要关注CPU,对GPU的支持有限,但如今已经起航。分享这个信息的嘉宾,是难得的好客户,懂技术,讲需求,有策略。 2.5 以中国人寿为代表的金融行业比想象的激进 在大众眼中,中国人寿在IT领域应该是一家中规中矩的传统企业,但其内部推行Kubernetes、容器化、微服务等,都取得了很棒但效果。为其点赞! 2.6 社区的力量助力厂商 传统软件企业主要靠技术支持人员完成对客户的服务,以及软件研发等工作。但越来越多的开源企业在重新定义这一切。Kubernetes依靠广大会员及广大开发者完成开发,其代码托管在github3上。 Rancher将其产品源码开源,即利用全球资源促进开发,又借助全球资源完成测试。其产品已累计下载1亿次,这是传统软件企业难以达到测试、试用规模。Rancher同时建立社区、微信群,依靠广大容器爱好者互帮互助为核心,打造高效客服系统。 2.7 创业维艰 倒数第二个嘉宾,创业仅1周,加上自己公司总共3个,但在已经拿下一个养老保险的项目。其能放下在北邮的优厚待遇,做一些顺应其内心的事情,值得赞许! 三、待进行的探索及阅读 深入了解Kubernetes的架构 https://kubernetes.io/docs/concepts/ 深入了解Rancher并搭建一个Demo环境 https://rancher.com/docs/rancher/latest/en/quick-start-guide/ 重新理解 CI、CD、Devops http://info.rancher.com/cicd-with-docker-ebook
一个人可以如同产品一样去经营和管理,在生日之际梳理新版的点点滴滴。 一、What's New? 新角色 新挑战:初为人父,感叹女儿每天的努力,向其学习! 新部门 新伙伴:面对近百人的研发团队,如何推动大家高效协作? 二、企业级项目管理能力 PMP认证项目管理师,5A/5P(最高等级成绩) 公司级项目经理任职资格专家 研发团队 项目总监 10年项目管理实践经验 三、实战级团队管理能力 天津大学 工商管理硕士 6年部门管理实践经验 多职能部门视野:研发、实施、运维、人力、商务 四、广博的IT知识栈 语言:C、C++、PHP、Python、HTML IDE:Visual Studio 、 Eclipse、XCode OS:Windows、RedHat、macOS 数据库:MySQL/Maria DB、GBase、Redis、Memcache 数据挖掘:HTTP、Curl、XML Parser、协同过滤、NLP、SVM 云计算:ITIL、VMWare、Xen、KVM、Nagios、Apache、LVS 其他:区块链、知识管理、创新方法论TRIZ、自动控制 五、丰富的活动组织 2个研发团队级培训平台的创建 4年企业年会主持 2门企业内训课程开发与培训 六、始终如一的敬业 12小时平均在司时间,知道每个黎明的样子 坚持学习:堆积如山的书,参加业内前沿活动,跟踪业界动态 主动补位:负责团队的“其他”工作,保证一线员工聚焦目标 七、坚实的家人后盾 另一伴的拼搏精神让我感动,荣获2017年度先进个人 坚信天道酬勤、自强不息的家风,每个成员都在努力为家贡献力量
序言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 Informix是世界顶级商用数据库之一,能在MacBook上低成本的学习,则能帮助开发者对于数据库有更多的理解和认识。 本文介绍基于Docker,如何在MacBook上快速搭建体验环境。 一、环境准备 1.1下载Mac版Docker (https://store.docker.com/editions/community/docker-ce-server-centos) 1.2安装运行Mac版Docker 双击Docker.dmg 启动安装程序,拖拽至Application文件夹中。 双击应用文件夹中Docker.app ,启动Docker. 看到下面的图标表示启动完毕。 3、验证安装后的版本 $ docker --version Docker version 18.03, build c97c6d6 $ docker-compose --version docker-compose version 1.21.2, build 8dd22a9 $ docker-machine --version docker-machine version 0.14.0, build 9ba6da9 4、运行样例 $docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/engine/userguide/ 至此Docker安装完毕。 二、查找所需的Image Docker提供了和苹果、安卓类似的应用商店。https://store.docker.com/ 我此次选择的是开发者版,限制如下:https://www.ibm.com/developerworks/data/library/techarticle/dm-0801doe/index.htmlFor application development and testing only, this edition packs the full suite of Informix functionality into an attractive price point: free! The Developer Edition includes all the functionality available in the Informix Enterprise Edition with scalability constraints including processing, memory, storage, and connection limitations . It is available on a wide range of operating systems in 32- and 64-bit versions where appropriate. Customers can upgrade from the Developer Edition directly to any other edition simply by installing the new database binaries. Since the intent of the Informix Developer Edition is for system development and test only, it cannot be used in a production environment, and there is no optional support package. 三、基于Docker下载Informix镜像 输入以下命令则启动安装,过程中需要输入密码授权安装程序。 docker pull ibmcom/informix-developer-database 启动下载 下载完毕并自动安装 四、初次启动Informix 输入以下命令: docker run -it --name iif_developer_edition --privileged -p 9088:9088 -p 9089:9089 -p 27017:27017 -p 27018:27018 \ -p 27883:27883 -e LICENSE=accept ibmcom/informix-developer-database:latest 运行效果如下图: 初次启动 五、查看Informix情况 Informix安装在/opt/IBM/informix,Informix 数据库服务器默认名称为dev,使用onstat了解基本情况。 查看运行效果
MySQL 8.0的一个重要特性是对地理业务的支持。MySQL现在已拥有一类功能称之为空间参考系统(SRS),其中近500个是地理区域相关的。大多数函数还支持地理计算。大家可能会关心索引的功能的增强。 MySQL 8.0附带了用于地理数据的InnoDB空间索引。由于笛卡尔和地理数据的计算方式不同,因此不能在同一个索引中混合使用。实际上,在同一索引中的多个SRS中索引数据是没有意义的。因此,MySQL加强了几何列定义中的SRID限制。 SRID限制 在5.7及更早版本中,对于加索引的几何列的唯一要求是该类型应该是几何类型,并且该列不为空。不幸的是,我们允许将不同SRID中的几何数据插入到同一个索引中。这种做法毫无意义,尤其当某些几何体位于地理SRS中时,情况会变得更糟。 因此,MySQL 8.0增加了限制,几何列只有一个SRID: mysql> CREATE TABLE places ( -> pk INT PRIMARY KEY, -> position POINT NOT NULL SRID 4326, -> name VARCHAR(200) -> ); Query OK, 0 rows affected (0,00 sec) 如果我们试图在不同的SRID中插入一个几何体,会得到一个错误: mysql> INSERT INTO places VALUES (1, ST_GeomFromText('POINT(63.4269 10.3958)', 0), 'Nidaros Cathedral'); ERROR 3643 (HY000): The SRID of the geometry does not match the SRID of the column 'position'. The SRID of the geometry is 0, but the SRID of the column is 4326. Consider changing the SRID of the geometry or the SRID property of the column. 如果我们遵守SRID限制,则该点则可以插入: mysql> INSERT INTO places VALUES (1, ST_GeomFromText('POINT(63.4269 10.3958)', 4326), 'Nidaros Cathedral'); Query OK, 1 row affected (0,00 sec) 有了这个限制,MySQL确保我们不会将同一列中不同SRID中的数据混合在一起,从而使列可以索引。 另一件事是锁定SRID。在SRID限制中它被使用,服务器不允许我们drop掉SRS: mysql> DROP SPATIAL REFERENCE SYSTEM 4326; ERROR 3716 (SR005): Can't modify SRID 4326. There is at least one column depending on it. 究竟是哪一列呢? mysql> SELECT * FROM INFORMATION_SCHEMA.ST_GEOMETRY_COLUMNS WHERE SRS_ID=4326\G *************************** 1. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: test TABLE_NAME: places COLUMN_NAME: position SRS_NAME: WGS 84 SRS_ID: 4326 GEOMETRY_TYPE_NAME: point 1 row in set (0,00 sec) 索引 我们可以轻松地在几何列上创建索引。 mysql> CREATE SPATIAL INDEX position ON places (position); Query OK, 0 rows affected (0,00 sec) Records: 0 Duplicates: 0 Warnings: 0 由于此列位于SRID 4326中,因此索引也将位于SRID 4326. SRID 4326是地理位置的SRS,因此这将是地理位置索引。查询优化器将自动使用这个索引来优化与空间相关的函数掉执行(ST_Contains,ST_Within等),如果它发现这是最低成本的处理方法。所有的空间关系函数都支持地理计算。 一个可能令人惊讶的事实是,服务器仍然允许我们不必限制在单列上建索引,但是会警告这个索引永远不会被使用: mysql> CREATE TABLE dont_do_this ( -> pk INT PRIMARY KEY, -> position POINT NOT NULL, -> name VARCHAR(200) -> ); Query OK, 0 rows affected (0,00 sec) mysql> CREATE SPATIAL INDEX position ON dont_do_this (position); Query OK, 0 rows affected, 1 warning (0,00 sec) Records: 0 Duplicates: 0 Warnings: 1 Warning (Code 3674): The spatial index on column 'position' will not be used by the query optimizer since the column does not have an SRID attribute. Consider adding an SRID attribute to the column. 警告说明了一切。该索引将永远不会被使用。服务器允许我们仅仅为了一个原因创建索引:向后兼容mysqldump。我们应该能够从5.7加载一个mysqldump。如果在转储中存在像这样的空间索引,它们将被创建但不会使用。 MyISAM数据 值得注意的是,这只适用于InnoDB。如果我们尝试在MyISAM中的地理SRID上创建一个SRID受限列,我们会得到一个错误: mysql> CREATE TABLE places ( -> pk INT PRIMARY KEY, -> position POINT NOT NULL SRID 4326, -> name VARCHAR(200) -> ) ENGINE=MyISAM; ERROR 1178 (42000): The storage engine for the table doesn't support geographic spatial reference systems 如果我们尝试使用笛卡尔SRS的SRID,我们可以创建表: mysql> CREATE TABLE places ( -> pk INT PRIMARY KEY, -> position POINT NOT NULL SRID 3857, -> name VARCHAR(200) -> ) ENGINE=MyISAM; Query OK, 0 rows affected (0,00 sec) 原因是MyISAM不支持地理空间索引。创建表时我们已经阻止了它。 我的建议是:将InnoDB用于所有空间数据!
GBASE的企业理念是用户关注、有效创新、精益制造、主动服务。其中 有效创新 指企业的一切创新必须以产品的市场效益为目的。我们必须摈弃单纯以技术为导向的创新。任何创新的商业成功都需要技术成本、制造成本、市场成本和服务成本的投入,我们必须将有限的资源用于核心产品在主要市场上的商业成功集成创新。 GBASE所坚信的有效创新理念,不光适用于技术部门,企业的管理和市场体系的建立也要遵循此原则。要以开放的心态和务实的精神,向行业领先企业学习和借鉴。崔维力先生是有效创新的坚定践行者,在管理实践中积极主动学习先进管理方法,同时又结合公司发展特点进行应用。《金字塔原理》培训的引进与推广是崔总践行有效创新的典型事例之一。 2016年初春的一个上午,接到崔总约见的邀请,一个多小时的详谈后,了解了要解决的问题与期望的努力。 售前是公司产品价值转换的第一个环节,如何清晰、准确的传递产品价值是必须解决的问题。售前人员的文档编写又是解决这个问题的重要基础性工作。但在当时缺少系统的方法论来指导人员提升这方面能力,仅靠大家的经验总结、分享及一点点摸索无法匹配企业发展的需要。 针对这个现状,崔总希望通过体系化的培训来提升。此时,崔总通过努力已找到《金字塔原理》这本业界公认的职场写作的参考书,希望能由我根据此书结合公司业务场景,完成课程开发。当时接到这个任务有些意外,但崔总充满厚望的告诉了他的判断依据:第一是,看中我的学习能力和对新事物的接纳能力;第二是,有公众演讲的潜力;第三是,我有分享精神,在部门内部组织培训,在外也讲课分享。 整个《金字塔原理》课程的开发过程,让我见识了这位企业家对培训工作的重视与执着。 课程开发过程中,崔总超过4小时不中断的深度讨论与设计共4次,其中3次为非工作时间,包括整体结构设计,内容的取舍,案例的选取,关键内容理解与讲解。而短时间的沟通、讨论则难以计数。 为了保证课程设计的有效性,崔总邀请售前核心骨干参与试听、案例编写等。崔总坚信,只有售前同事真正需要的培训才是有价值,只有贴近售前同事工作的培训才是有必要的。这正是有效创新在具体工作中应用和体现。 从启动课程开发到课程成型,《金字塔原理》培训共修订大版本7次,小版本不计其数。崔总细心审阅,及时提出修改建议和要求。 每次讨论过程中,崔总始终保持求真务实的态度。这给我留下很深印象。虽然崔总是位严厉的领导,但在讨论时和大家平等讨论,唯实,唯真。 截止到目前为止,公司接受《金字塔原理》培训的员工,已涉及所有人员体系,从销售到售前、技术支持,再到研发和运营,累计培训二十余场,受训人数超过四百人。高效沟通已成为全员的共识和追求,金字塔原理已成为全员认可和遵循的基本方法论。 和崔总一起开发课程的过程是极富挑战的,但同时也是充满收获的。 感谢那些头脑风暴中不断碰撞出火花的时光! 感谢围绕具体问题的不断深挖的快乐! 感谢没有上下级,只有你来我往、据理力争的讨论! 感谢崔总向我们推荐《金字塔原理》这个好的方法论! 感谢崔总对课程开发的坚持与支持! 感谢崔总对有效创新的率先垂范! 继承崔总终身学习的精神,践行有效创新的理念。 热爱成就非凡!
由于职业特点,对于自己的成长也会按产品版本的来定义。37岁生日在即,为庆祝V3.7预览版的发布,梳理一下本人研发管理的成长历程。 研发管理 V0.1(2000-2005) 研发产品: 课堂、课余作业:基于C 足球机器人:基于C++,模拟,车型机器人 嵌入式控制器:基于C,嵌入式OS,国产图形控件库 管理特点:史前阶段 无章法,但凭一股兴趣与热情,徜徉于程序海洋。 研发管理 V0.2(2005-2006) 研发产品: 网页挖掘算法:基于C++,导航栏,论坛贴 网页蜘蛛系统:基于C++,论坛 管理特点:初具软件工程意识 因进入了软件公司,对于软件工程有了初步的了解,对研发管理了有了最浅层次的理解。更多的以自我管理为主。 研发管理V1.0 (2007-2010) 研发产品: 保10洁的核心后台服务:基于C++,NLP,规则推理引擎 一起网的推荐系统:基于C++,协同过滤 网络蜘蛛系统:基于C++,网页抓取 管理特点:基于项目来管理,迭代研发 有计划控制,有风险意识;使用Project来管理;软件工程流程清晰;多部门协作研发,含产品、运维、运营、测试、开发、销售; 打上了互联网基因的烙印。 研发管理V2.0 (2011-2012) 研发产品: 云服务运维平台:基于PHP、Shell脚本,虚拟化,MySQL,Nagios 管理特点:基于用户视角管理 2年的云服务管理锻炼,拥有了从用户视角来分析产品研发的能力,理解了产品应用场景的概念,也理解了产品研发人员的局限性与擅长点。 研发管理V3.0 (2013-2014) 研发产品: 大型企业应用软件:基于Java,KM,分布式,项目实施 管理特点:基于企业管理与经营视角 1年左右的客户现场实施管理,培养了先企业业务后IT支持的思维方式。与客户探讨业务,进而思考软件定制及实施的过程。 加上2年的MBA学习,对于企业管理的更多维度有了了解,同时深度接触不同岗位、角色的思维差异与其合理性。 研发管理V4.0 (2014-2017) 研发产品: 数据库:基于C、Java,国产平台,安全 管理特点:增加了与第三方商务合作的经验 通过参与产品的引进消化吸收再创新,对于商业合作有了理解和经验;对于跨国合作,有了基本的了解和经验。 借助PMP考试验证了一下,通过且5A或往年的5P 研发管理V5.0 (2018) 研发产品: 数据库:基于C、Java,国产平台,安全 管理特点:增加了对于人力资源和销售层面的理解。 对于公司层面人力资源的规划、招聘、培训、考核、淘汰等,有了全局的了解。 对于从销售商机到交付的生命周期,有了全局的了解。 估计也是少数,敢向销售推介销售方法的研发人员。哈哈,不懂销售的人力,不是好研发。 结尾 近18年的研发经历及10年的研发管理,仿佛弹指一挥间。在感叹时间飞逝之余,更心存向往。由于没有参与过开源软件的研发管理,始终对于红帽、MySQL等心存敬畏。希望未来的业余时间里,能为开源软件作出自己的贡献。
微软2017技术暨生态大会今日在北京国际饭店会议中心如期举行,参会一天个人收获不小,记录一些,留作后续研究分析。 人工智能领域 微软人工智能公开课 官网:https://channel9.msdn.com/Shows/MicrosoftAI 干货不少,适合入门学习 微软小冰 官网:http://www.msxiaoice.com/ 小冰skill list 聊天(其走红的第一炮) 出诗集(据说已经做了几百万首诗词了) 设计体恤,售价299(想买吗?) 上湖南卫视,节目为“我是未来” 出MV,今年合成的歌声必去年有质的提升 Microsoft Azure Machine Learning Studio Microsoft Azure云服务推出机器学习的模块,用户只需上传数据,利用机器学习模块提供的一些算法接口和R语言或别的语言接口,就能利用Microsoft Azure强大的云计算能力来实现自己的机器学习的任务。 官网:https://studio.azureml.net/ 免费试用 Azure 机器学习 地址:https://azure.microsoft.com/zh-cn/overview/machine-learning/ Azure 机器学习文档(预览)https://docs.microsoft.com/zh-cn/azure/machine-learning/preview/ Getting Started with Azure Machine Learning Studio https://azure.microsoft.com/en-us/resources/videos/getting-started-with-ml-studio/ AI platform Artificial Intelligence productivity for every developer and every scenario. 官网:https://www.microsoft.com/en-us/ai/ai-platform 包含认知计算、Bot Framework、Microsoft Azure Machine Learning Bot Framework 官网:https://dev.botframework.com/ 现场两个技术男兴奋的展示用这套体系小娜+Azure如何控制一辆汽车,验证了技术路径的可行性。当然还是demo中的demo。 Build and connect intelligent bots to interact with your users naturally wherever they are — from your website or app to Cortana, Skype, Teams, Office 365 mail, Slack, Facebook Messenger Skype for Business and more... 微软认知计算Cognitive Services 官网:https://azure.microsoft.com/en-us/services/cognitive-services/ Infuse your apps, websites and bots with intelligent algorithms to see, hear, speak, understand and interpret your user needs through natural methods of communication. Transform your business with AI today Visual Studio Code Tool for AI 没找到网页,但现场演示了该工具,有试用的冲动。 but anyway,我找到了另一个工具Python Tools for Visual Studio https://aka.ms/PTVS GitHub的地址:https://github.com/Microsoft/PTVS 物联网领域 Azure IoT Hub 官网:https://azure.microsoft.com/en-us/services/iot-hub/ Doc:https://docs.microsoft.com/en-us/azure/iot-hub/ Connect, monitor, and manage billions of IoT assets Get started quickly Register and provision IoT devices automatically Connect and manage billions of IoT devices and assets Establish reliable, bi-directional communication Enhance the security of your IoT solutions Ingest real-time data and upload files to the cloud 更多内容参见:https://www.microsoft.com/china/techsummit/2017/
工作中有这样一种现象:安排某人一个任务,一段时间后询问进展,结果进度大幅晚于预期,且在很久之前便因碰到一个难题而停滞了…… 聚焦目标 工作执行中碰到困难很常见,遇到困难后不同的选择反应了工作能力。具体如下: 第一种:遇到困难后,在困难那里做个标记,然后安心的去干其他的了。 第二种:遇到困难后,一个人蹲在那里发愁,发愁,发愁…… 第三种:遇到困难后,立刻去找领导反馈,干不下去了,该怎么办? 第四种:遇到困难后,往后退半步,看一下目标,思考困难是必须克服的?还是现有解决方案所带来的? 我们来分别分析一下这四种情况。 第一种选择所折射的深层次问题是,经执行领导安排的具体工作步骤,而不关心目标。优点是心态好,安排的事情尝试做了,做不下去是有原因的。不足是,耽误事。 【解决方案】 1、接受此类心理属于常见心理。因大部分人是普通人,并不会拥有很强的事业心和责任感。 2、设置多个检查点,及时把握进展,及早发现问题。 3、布置任务时,说明任务的目标是什么?任务达成与执行人的关系是什么?任务目标与任务具体方案的区别和联系。 第二种选择相比第一种,有责任心和压力感,但容易钻牛角尖。忘记了目标,而聚焦在问题的解决上! 【解决方案】 1、鼓励此类人。其发愁缘于在意工作的成败。这属于难得的品质。 2、设置检查点,定期检查 3、以具体工作为案例,帮助其分清目标和解决方案之间的差别。 4、以具体工作为案例,鼓励、启发其善用自身以外的资源。 第三种选择,好处是不耽误事,坏处是不能独当一面。 【解决方案】 1、以具体工作为案例,帮助其分清目标和解决方案之间的差别。 2、明确授权,明确职责。明确其在哪些环节,可以灵活决策,哪些地方必须汇报讨论。 3、要求其带着解决方案来沟通。 第四种选择,优点是他办事你放心,不足是此类人毕竟属于少数。 【解决方案】 1、识人用人。不同事情,不同人可能的选择不同。让合适的人做合适的事情。 2、工作启动前,约定几个检查点。其他时间充分相信。 3、发现困难,适度提供帮助。给其展示才能的空间,同时也保护其主动性。因困难过大不帮助时,会打击其主动性;困难不大时帮助,也会打击其主动性。 工作中好的状态是,不忘初心,关注目标。 既定的计划是达成的目标的解决方案之一,也只是之一。 有时遇到的问题是必须化解的,不解决目标就无法达成,那就调动一切资源来努力。 有时遇到的问题是既定计划带来的,必要时可以更换解决方案,调整计划,绕过问题。 工作中要的是达成目标,而不是解决某个困难! 目标是我们需要追求的,困难不是必须克服的。 条条大路通罗马,不死磕,不纠结,不恋战。 只要困难不碍事,那就让它随风而去……
2022年08月
2022年02月
2022年01月
2021年11月
2021年10月
2021年08月
2021年06月
2021年03月
2020年09月
2020年06月
2020年03月
2020年02月
2019年11月
2019年10月
2019年09月
序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化和反序列化是对某个对象的计算暂停和重启,将对象数据从计算态转变成存储态、传输态。
建议检查一下
新虚拟机就是一台新服务器,需要重新连接。 之前能连过,推测mac 上工具本身没有异常。
要区分一下开源包的 flink 和服务化的 flink。 开源包的 flink即项目本身 支持开发和运行多种不同种类的应用程序。它的主要特性包括:批流一体化、精密的状态管理、事件时间支持以及精确一次的状态一致性保障等。 Flink 不仅可以运行在包括 YARN、 Mesos、Kubernetes 在内的多种资源管理框架上,还支持在裸机集群上独立部署。在启用高可用选项的情况下,它不存在单点失效问题。 事实证明,Flink 已经可以扩展到数千核心,其状态可以达到 TB 级别,且仍能保持高吞吐、低延迟的特性。世界各地有很多要求严苛的流处理应用都运行在 Flink 之上。 更多的可以参考官网http://flink.apache.org/zh/flink-architecture.html
服务化的 flink 但如果应用面临一些列问题,包括部署、资源管理、与其他系统的对接,于是有了服务化的 link,两者在基本核心上一致,但增加了很多额外的能力。
c++ 程序员飘过,
支持