线上问题处理流程

问题处理流程

问题反馈渠道

一般都是通过邮件、聊天群、私聊等途径反馈,尽量让监控系统及时发现问题

  • 监控系统 – 所有问题应该尽量从这里暴露出来
  • 客服
  • 运营人员
  • 业务管理部门
  • 其他

问题收集

  • 收集:所属业务、模块、影响范围、发生时间、严重程度等
  • 初步判断发生原因
  • 在”线上问题研发跟进”微信群中@相关开发人员

问题跟踪

  • 严重问题,”线上问题研发跟进”@开发人员后>10分钟无响应,电话联系相关主要负责人沟通跟进
  • 非严重问题,”线上问题研发跟进”@开发人员后>30分钟无响应,电话联系相关主要负责人沟通跟进
  • 开发人员判断是问题,录入Issue到TAPD,并发送链接到微信群”线上问题研发跟进”
  • 开发人员判断问题严重,则需要在研发响应群中告知问题及影响范围,并及时召集人员讨论处理
  • 开发人员处理Bug应及时更新状态到TAPD中,并告知相关人员对当前工作进度的影响

后续优化

问题处理完成后应该讨论是否需要优化现有的业务逻辑或代码,主要是为了消除问题影响、避免技术债务、提升体验。

例行问题分析

  • 周会

    分析一周线上问题

  • 月度质量分析会议
    1
    2
    3
    4
    5
    问题汇总分析 -- 按问题来源、模块及归属
    问题解决时长分析
    未关闭问题:处理进度、优化的方案讨论

    关键流程分析,如:XX业务的响应时间、成功率、错误码占比、用户的操作习惯等

研发协作流程

协作流程图

需求评审

一般由项目负责人/Scrum Master发起,项目组所有成员参与。

  1. 阶段目标

    所有成员详细了解需求方案及需求的关键点。

  2. 要做的准备

    • 提前一天发评审会邀和相关文档
    • 提前看需求文档,了解需求内容
    • 熟悉相关业务和代码
  3. 解决的问题

    • 项目所有成员统一需求认知
    • 初步评估需求方案,技术可行性
    • 预估项目容量

技术方案评审

技术方案的设计,一般由研发负责人或者项目技术负责人发起。
开发必须经过技术方案评审,和需求挂钩,明确回答“怎么做”

  1. 阶段目标

    梳理所有技术点的实现方案

  2. 要做的准备

    • 提前一天发评审邀请和相关文档
    • 提前评估各自的实现方案
    • 复杂的技术点,需要提前沟通
  3. 解决的问题

    • 项目组成员间沟通技术实现方案
    • 确定各端交互的方式,以文字的形式留存
    • 评估详细排期

评估排期

采用文档协作的方式来分解任务和评估排期。比如使用tencent docs或者google docs。

  1. 阶段目标

    输出全员无异议的开发计划,记录到项目管理工具(TAPD)并通过邮件发出.

    注意点:
    • 对需求进行尽量细的功能点拆分,有助于准确评估排期(精确到0.5天)
    • 根据实际项目情况,预留适当的buffer时间(大约为项目总时长的5% ~ 10%)
    • 排期一旦确定,视为对所有成员的承诺,非极端情况不可更改
  2. 排期计划规范
    • 项目名称、参与项目人员、日期、开发功能点简述、项目天数
    • 排期邮件由项目负责人汇总发出
    • 邮件需知会参与项目各方同学及leader

项目开发

  • 参考分支开发规范
  • 先在YAPI平台定义接口,前端和测试使用Mock Server来开发前端及自动化测试接口,待后端接口提供后进行联调测试。
  • 全部联调通过及单元测试通过后提交测试。

用例评审

由QA同学发起,项目组成员全部参加,评审测试用例的准确性和完整性,一般在项目开发过程中进行,没有固定时间。

  1. 阶段目标

    所有成员详细了解测试用例,并产出覆盖完整性高的测试用例。

  2. 要做的准备
    • 提前一天发评审邀请和相关文档
    • 明晰需求细节
    • 了解测试用例
    • 如果有负责的测试场景需要和开发一起制定解决方案
  3. 解决的问题
    • 评估测试用例是否覆盖到所有情况,正常路径以及异常路径
    • 借助测试用例回顾已经开发的内容和需求的细节

联调

由后端或者前端人员发起,仅开发人员参与,尽可能利用一套统一的环境,进行联调。

  1. 阶段目标

    调试完成全部需求需要完成的流程

  2. 联调规范
    • 各功能开发完成则开始联调,是否可以分阶段联调视情况而定
    • 有QA的项目,在联调过程中覆盖大多数测试用例
    • 无QA的项目,开发人员整理测试用例,并在联调过程中尽可能覆盖

代码评审

代码合并到主干之前应该经过 code review。

提测规范

  • 提测给QA的代码必须通过自测和验收
  • 提测分支若落后主干,同步之后再提测
  • 提供编译后代码,保证与上线代码一致性
  • 严禁使用QA环境调试bug
  • 阻塞测试流程的bug及时修复
  • 其余bug可定期统一修复

项目验收

在测试环境通过或者上线后,由测试人员发起,邀请PM/UI/UE等角色,对产品进行全方位的验收。

  1. 阶段目标
    • 保证需求没有遗漏,符合预期
    • 正常流程没有问题,可以使用
  2. 验收规范
    • 在单元测试完成和上线后发起
    • UI/UE进行视觉交互验收,PM进行功能验收
    • 中大型项目排期时至少预留1天验收时间,一般预留半天验收时间

招聘流程

招聘流程

1
HR推送简历->筛选简历->电话面试->技术面试->填写面试评估表格->Offer

筛选简历

最多5分钟筛选一份简历,目的是尽量筛选掉不符合岗位需求的简历。

  • 明确岗位需求
  • 考察简历与岗位需求的匹配度
    • 基本:年龄、性别、婚育、教育经历
    • 重点:职位职责、工作经验、技术匹配度

电话面试

不超过30 分钟,快速过滤明显不符合岗位要求的人,节省双方的时间成本。

大致流程:

  • 浏览候选人简历,对其中有疑问的地方如:跳槽频繁、职业经历空档、学历问题或其他疑问事先划线标出来
  • 双方选手相互介绍后,先核对一下简历的细节,如果公司有隐性的标准比如学历、工作经验年限、婚育等可以问到
  • 就过完工作经验与岗位匹配度进行判断,过程中考察其语言表达和逻辑能力等细节。
  • 聊聊离职动机与期望薪资以及候选人对职业的发展规划
  • 结束电话面试。

技术面试

  • 第一轮

    • 面试官:1~2个,技术Leader/高级工程师
    • 基础 - Java基础,数据结构,算法,网络,操作系统等
    • 深度原理 - 就了解、做过、学习过的技术框架、中间件进行灵魂拷问
    • 逻辑题
    • 给出问题,在纸/电脑上写程序
  • 第二轮

    • 面试官:2个,技术Leader/高级工程师 + 其他组的高级工程师(比如面试后台则为测试或者前端)
    • 针对以往的项目经验及做过的技术方案进行考察
    • 针对沟通能力和协作能力做考察
  • 终试

    • 技术负责人复试
    • 离职动机薪资期望
    • 职业规划、发展方向、学习能力、领导力等
    • 让对方提问

    面试中碰到好的候选人,在面试结束时可以对他们说:“最迟在两天内可以收到我们的通知,如果没有请直接联系我或者HR”。

如果对这个人不是很感兴趣,可以直接拒绝。

填写面试评估表格

面试完毕记得填写评估表格,可以提供后续面试参考以及回溯比较作用,表格存放在共享文档系统(tencent/google docs)中。

电话面试评估表:

记录项值:[符合、不符合] [基本匹配、匹配度高、不匹配]

候选人 面试官 基本条件 职位职责 工作经验 技术能力
张三 小明 符合 符合 匹配 匹配
李四 老赵 符合 不符合 匹配度高 匹配

技术面试评估表:

四个等级:优秀、良好、一般、较差

候选人 面试官 基础技术 逻辑能力 沟通能力 协作能力
张三 三丰、逍遥 良好 一般 优秀 良好
李四 紫霞、玉帝 优秀 良好 优秀 良好

Offer

通过比较选定候选人后,让HR谈薪资并发Offer

ActiveMQ InactivityIOException

问题现象

生产服务器上,ActiveMQ Produce和Consumer端同时报如下错误,导致不能正常工作。

1
2019-03-26 23:01:18,815 | WARN  | Transport Connection to: tcp://xx.xx.xx.xx:59582 failed: org.apache.activemq.transport.InactivityIOException: Channel was inactive for too (>30000) long: tcp://xx.xx.xx.xx:59582 | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ InactivityMonitor Worker

官网解释

1
2
3
The maximum inactivity duration (before which the socket is considered dead) in milliseconds. 
On some platforms it can take a long time for a socket to appear to die, so we allow the broker to kill connections if they are inactive for a period of time.
Use by some transports to enable a keep alive heart beat feature. Set to a value <= 0 to disable inactivity monitoring.

配置JMS连接最大闲置时间(消息服务器无消息)
该wireFormat.maxInactivityDuration 的默认值是30000ms
wireFormat.maxInactivityDuration=0 这样的参数, wireFormat.maxInactivityDuration是心跳参数。
避免ActiveMQ在一段时间没有消息发送时抛出 “Channel was inactive for too long”异常。

该异常会关闭连接,虽然client端会重连成功,但是不能发送数据,然后继续报下面异常:

1
[ WARN ]  Transport (tcp://xx.xx.xx.xx:61616) failed, reason:  java.net.SocketException: Connection reset, attempting to automatically reconnect

解决方案

1
2
设置wireFormat.maxInactivityDuration=0,禁用InactivityMonitor
改为tcp://xx.xx.xx.xx:61616?wireFormat.maxInactivityDuration=0

Git分支模型(参考阿里Aone Flow)

分支定义

  1. master
    1
    2
    3
    长期分支,存在与整个项目开发过程。

    由项目主要技术负责人管理该分支。
  2. release/xxx
    1
    2
    3
    4
    release/test 和 release/prod
    既可以为长期分支也可以为短期分支,可能存在于一个或者多个版本之间.

    由测试负责人负责人管理该分支。
  3. feature/fixbug/hotfix
    1
    2
    3
    4
    5
    临时分支
    用于开发的具体功能特性和修复bug的分支,功能完成后删除.
    格式为:feature_$date_$name_$description
    fixbug_$date_$name_$description
    hotfix_$date_$name_$description

分支策略

  1. 规则1

    开始工作前,从主干创建特性分支

    • 每当开始一件新的工作项(比如新的功能或是bug)的时候,从最新已发布版本的主干Master上创建一个以feature(bugfix)/前缀命名的特性分支,然后在这个分支上提交代码修改。
    • 每个工作项(可以是一个人完成,或是多个人协作完成)对应一个特性分支,所有的修改都不允许直接提交到主干。
  2. 规则2

    通过合并特性分支,形成发布分支

    • 从主干上拉出一条新分支,将所有本次要集成或发布的特性分支依次合并过去,从而得到发布分支。发布分支通常以release/前缀命名。
    • 每条发布分支与具体的环境相对应,比如release/test分支对应部署测试环境,release/prod分支对应线上正式环境等等,并与流水线工具相结合,串联各个环境上的代码质量扫描和自动化测试关卡,将产出的部署包直接发布到相应环境上。
    • release/prod从master上拉取的时候master可能已经有其他更新上线了,此时从master拉取拉取的release/prod合并相关feature分支后需要进行回归测试。
  3. 规则3

    发布到线上正式环境后,合并相应的发布分支到主干,在主干添加标签,同时删除该发布分支关联的特性分支

    • 完成了线上正式环境的部署,就意味着相应的功能真正地发布了,此时应该将这条发布分支合并到主干。
    • 为了避免在代码仓库里堆积大量历史上的特性分支,还应该清理掉已经上线部分特性分支。
    • 主干分支上的最新版本始终与线上版本一致,如果要回溯历史版本,只需在主干分支上找到相应的版本标签即可。
  4. 其他

    • 对于hotfix,可以创建一条新的发布分支对应线上环境(相当于hotfix分支),同时为这个分支创建临时流水线,以保障必要的发布前检查和冒烟测试能够自动执行。
    • 如果非得修一个历史版本的Bug,在主干分支找到版本标签位置,然后从那个位置创建hotfix分支,这种情况比较少见

开发流程

  1. 新功能开发时,开发人员从Master拉取代码生成特性分支。

  2. 单元测试完成后等待测试负责人拉取release/test分支,然后提交Pull Request

  3. 开发负责人或者其他开发人员对Pull Request进行代码Review

  4. 代码Review完成后,测试负责人合并Pull Request到release/test,如果遇到合并冲突,则让相应的开发人员把feature/bug/hotfix分支重新以master为基准进行提交以及让相应的开发人员协助解决。

  5. 测试人员使用流水线工具进行代码质量扫描和自动化测试

  6. 测试人员进行测试

  7. 完成测试后,查看Master是否比拉取release/test时有更新,如果没有直接使用release/test上线,否则从最新Master拉取分支release/prod分支合并相关PR并进行回归测试

  8. 提交上线申请上线

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    开发人员A从Master拉取代码生成feature_20190818_A_get_users
    开发人员B从Master拉取代码生成feature_20190819_B_login

    测试负责人Y从Master拉取release/test
    开发人员A提交Pull Request PR1
    开发人员B提交Pull Request PR2

    开发负责人F和开发人员C评审PR1 PR2,评审通过

    测试负责人Y合并代码到release/test
    测试人员X进行测试,完成后发现Master和拉取release/test时一样,直接使用release/test进行构建申请发布

结构化行为面试法

准备

  1. 掌握候选人基本信息
    1
    2
    3
    年龄、性别、学历、专业
    行业背景
    技术范围、工作经验
  2. 对候选人的期望值
    1
    2
    3
    4
    5
    6
    技术要求
    比如:Java基础扎实,熟悉分布式系统开发,对AB、C、D技术熟练使用/掌握原理/有优化经验,实践过并发大于100的系统等
    能力素质
    例如:沟通能力、协调能力、领导力等
    个性特质
    例如:外向型、严谨、细致等,需要结合领导风格、团队风格、企业文化环境
    最好公司有自己的能力素质模型 – 待整理
  3. 其他
    1
    2
    3
    4
    列出提问的问题:
    问题要求:清晰、准确、易理解
    多维度: 项目经验、技术能力、沟通、协作、规划等
    面试流程(确定面几轮、谁来面?如何决策)

开场

  1. 暖场

    暖场的作用在于减少候选人的压力,便于后续从面试的过程中获取真实的行为事例。

    暖场话术示例(继续补充):

    1
    2
    3
    4
    5
    茶水或者咖啡?
    天气状况,适宜出游 or 太热太冷只可宅?
    路况如何,到达公司所需时长,是否顺利?
    哪里人,靠近什么名胜或者有什么特产?(注意避免地域性偏见)
    毕业于什么学校,学校有什么有名的人物或者事迹?
  2. 开篇话术

    介绍自己、面试流程和面试重点

    示例:

    1
    2
    3
    4
    面试官:您好,王先生,请坐。自我介绍一下,我是今天的面试官XXX,这位是YYY,欢迎来参加今天的面试。
    求职者:谢谢。
    面试官:面试的过程中我们会提出一些问题,请您以过去经历当中的具体事例来回答,而这部分将占用大部分的面谈时间,在回答的过程中请注意简明扼要、抓住重点。需要说明的是面试的过程中我会视情况调整话题,以确保多谈一些您过往曾经做过的事情。最后我会留一些时间让您询问跟这份工作以及我们公司相关的问题。
    我们现在正式开始,OK?
  3. 对方自我介绍

    注意倾听不要打断,有问题等介绍完再去问。

问问题

  1. 提问话术

    问题短而精,基于事的行为问题(为什么这么做),少问假设性问题

    标准化能力行为提问:

    1
    2
    3
    4
    请谈谈 你在工作中快速掌握新知识的 一些经验
    请举 一个 体现"沟通能力"的 栗子
    请描述 一件 在跨部门合作成功的 经历
    请举 一个 证明你有效与人合作并共同完成了一件重要的事情的 栗子

    过去行为示例:

    1
    2
    3
    4
    请举例说明 你过往是如何 获得了XX技能并把该技能转化到实际工作中
    请举例说明 你过往是如何 处理线上突发的Bug
    请举例说明 你过往是如何 进行Code Review
    请举例说明 你过往是如何 帮助下属/同事成长

    过去行为示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    分享一下 你在过往工作 所使用的git分支模型
    分享一下 你在过往工作 所做过的MYSQL优化
    分享一下 你在过往工作 所做过的技术分享
    讲述一下 你在上一份工作中遇到的最难解决的问题 你是怎么处理的?
    回忆 你在同一时间内需要同时处理多项工作时 你是如何处理的?
    在过去 你和领导意见不一致时 你是如何处理的?
    分享一下 你在面对新的工作环境时 你是怎么处理的?
    分享一下 你在过往工作中最有价值的一件事 当时你是怎么做的?
    分享一下 你在遇到服务/Mysql变慢的问题时 你是怎么处理的?
  2. 如何避免面试中出现的虚假的回答?

    运用STAR进行有效追问,面试官需要敏锐地观察并进行细节追问,追问的目的在于获取行为事例或者对不完整事例进行补充

    1
    2
    3
    4
    S指情景(Situation):这件事发生的时间、地点、人物等背景介绍。
    T指任务(Task):这件事情发生在什么场景下,你要完成什么任务,面对什么抉择或者困难?
    A指行动(Action):你扮演什么角色?做了哪些事情?
    R指结果(Result):事情的结果如何?你收到了什么反馈?
  3. 层层递进问题法

    针对候选人的项目经验和过往的技术能力问题层层递进,直到候选人答不上来为止

    比如HashMap:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    HashMap的使用场景
    为什么用HashMap
    HashMap的原理
    HashMap的初始化、增长、键值获取
    HashMap如何减少碰撞
    Hash函数如何实现
    为什么改为红黑树,不用二叉树 -> 为什么不一致用红黑树
    HashMap有序嘛 -> 有没有有序的Map -> 有序的Map怎么实现的,怎么保证有序性
    HashTable和HashMap的区别
    ConcurrentHashMap可以完全替代Hashtable嘛
    ConcurrentHashMap的版本迭代中发生了哪些变动,各个版本都有什么问题
    ConcurrentHashMap用到的锁的逻辑部分是怎么实现的

    候选人:我是谁?我为什么要来面试?这个面试官太强了吧…

逻辑能力+写代码

针对技术面试一定要有逻辑能力和代码能力的部分

  1. 逻辑题

    例如(继续补充):

    1
    2
    3
    4
    5
    马路上的井盖为什么是圆的?
    有人把车停在旅馆外,丢失了他的财物,他接下来会干什么?
    你需要确认朋友Bob是否有你正确的电话号码,但不能直接问他。你须在一张卡片上写下这个问题,然后交给Eva,由Eva把卡片交给Bob,再转告你答案。除了在卡片上写下这个问题外,你还必须怎样写,才能确保Bob在给出答案的同时,不让Eva知道你的电话号码?
    假设你是海盗船的船长,船员们即将对黄金的分配方案投票。如果赞成票不到半数的话,你会被杀死。你怎样才能在保证自己存活的情况下拿到最多的黄金?

  2. 算法题

    例如(继续补充):

    1
    2
    3
    4
    5
    排序算法
    哈希算法
    红黑树
    合并有序链表
    约瑟夫问题(求最后一个人序号、求最小的m使得K个被处决K个不被处决)
  3. 其他代码能力

    例如(继续补充):

    1
    2
    3
    4
    写一个生产者消费者模式
    写一个死锁
    写一个你认为最好的单例模式
    给盲人设计一个ATM/电梯

评估表现(待补充)

  1. 依据上述记录的事实来进行多维度评估

  2. 填写表格并作出相应的决定

    使用公司拥有的能力模型来设计打分表,并进行结果评估,然后做出候选人对比。

带新员工

导图

注意点

  1. 遵从 PDCA(Plan->Do->Check->Action) 的原则
    • 就计划达成一致并讲解计划
    • 引导思考,最终可以自己寻找找到解决方案(给答案->给线索->自己摸索)
    • 进行阶段性检查,确保计划执行的正确性,解决过程中遇到的问题以及对计划做出调整
  2. 以身作则,多肯定和鼓励引导做出正确的选择和避免犯错,多沟通并积极主动去完成每一件事。
  3. 用心、有耐心以及有责任心。
  4. …待补充

导师制

目的

传道授业解惑

  1. 帮助新员工熟悉环境、业务以及进行例行化工作指导
  2. 在各个阶段观察和帮助新员工,避免工作不饱和,不明确工作目标。
  3. 传递公司的价值观和规章制度,绩效考核制度等等关键信息
  4. 帮助新员工融入新的集体,快速融入公司的节奏。
  5. 及时发现新员工是否满足工作要求,做出及时的调整

导师的选拔条件

  1. 在公司工作一年以上,绩效必须好
  2. 部门业务骨干,有能力进行业务指导
  3. 充分认可公司文化,有能力进行思想引导
  4. 为人正直热情,责任心强,有较强的计划、组织、管理、沟通能力,有能力为新员工制定合理的计划、安排相应的工作任务
  5. 一名导师名下不能超过两个学生

导师奖惩

  1. 以补助的形式给导师每月XXX元的“导师费”
  2. 定期评选“优秀导师”,被评为“优秀导师”的可得到公司XXX元的奖励
  3. 连带责任,如果徒弟犯了错误导师连带追责,甚至降职
  4. 没有担任过导师的员工,不得提拔为行政干部;不能继续担任导师的,不能再晋升

导师的管理主体

  1. 部门Leader、总监
  2. 人力资源部

主要内容

  1. 业务知识培训
  2. 开发规范和流程培训
  3. 需要使用到的相关技术培训
  4. 公司相关制度

可能的周期和计划

  • 第一月:熟悉环境,制定计划,开发规范和业务培训
    • 第一天:帮助熟悉工作环境
    • 第一周:制定培养计划,布置工作和学习任务
    • 第二周:主动询问,有问必答
    • 第一月末:沟通,总结,做计划
  • 第二月:安排工作,监督学习成果和工作绩效,及时就计划是否需要修改作出沟通
  • 第三月:安排工作,监督学习成果和工作绩效,及时就计划是否需要修改作出沟通
  • 帮助转正答辩

CentOS 7下Cloudera Manager及CDH 6.1.0安装过程详解

一、概念介绍

1、CDH 概览

CDH是Apache Hadoop和相关项目的最完整、最受测试和最流行的发行版。CDH提供Hadoop的核心元素-可伸缩存储和分布式计算-以及基于web的用户界面和重要的企业功能。CDH是Apache许可的开放源码,是唯一提供统一批处理、交互式SQL和交互式搜索以及基于角色的访问控制的Hadoop解决方案。

CDH 提供以下特性:

  • 灵活性:存储任何类型的数据并使用各种不同的计算框架进行操作,包括批处理、交互式SQL、免费文本搜索、机器学习和统计计算。
  • 集成:在一个完整的Hadoop平台上快速启动和运行,该平台与广泛的硬件和软件解决方案一起工作。
  • 安全:处理和控制敏感数据。
  • 可伸缩性:启用广泛的应用程序和规模,并扩展它们以满足您的需求。
  • 高可用性:满怀信心地执行任务关键的业务任务。
  • 兼容性:利用您现有的IT基础设施和投资。

CDH 组件如下图:

2、Cloudera Manager 概览

Cloudera Manager 是用于管理cdh集群的端到端应用程序。Cloudera Manager通过向CDH集群的每个部分提供细粒度的可见性并对其进行控制来设置企业部署标准-授权运营商提高性能、提高服务质量、提高遵从性和降低管理成本。使用Cloudera Manager,您可以轻松地部署和集中操作完整的CDH堆栈和其他托管服务。应用程序自动化安装过程,将部署时间从数周减少到分钟;为您提供在集群范围内运行主机和服务的实时视图;提供一个单一的中央控制台来执行整个集群的配置更改;并集成各种报告和诊断工具,以帮助您进行操作。

Cloudera Manager 的架构如上图所示(cs结构),主要由如下几部分组成:

  • 服务端/Server:
    Cloudera Manager 的核心。主要用于管理 web server 和应用逻辑。它用于安装软件,配置,开始和停止服务,以及管理服务运行的集群。
  • 代理/agent:
    安装在每台主机上。它负责启动和停止的进程,部署配置,触发安装和监控主机。
  • 数据库/Database:
    存储配置和监控信息。通常可以在一个或多个数据库服务器上运行的多个逻辑数据库。例如,所述的 Cloudera 管理器服务和监视,后台程序使用不同的逻辑数据库。
  • Cloudera Repository:由cloudera manager 提供的软件分发库。
  • 客户端/Clients:
    提供了一个与 Server 交互的接口。

Cloudera Manager包括server端和agent;server端主要作用是监控集群分发配置集群等,agent端主管集群各节点。
CDH是CM的安装包,本地或者云端,其中包括hadoop的生态系统需要的所有组件,通过Cloudera Manager统一管理和安装。
CDH除了可以通过cm安装也可以通过yum,tar,rpm安装。

二、环境准备

1、软件版本选择

类目 版本 下载地址
操作系统 CentOS Linux release 7.5.1804 (Core) 阿里云或者其他
数据库 MySQL 5.7.25 官网下载
JDK jdk-8u202-linux-x64.rpm Oracle 官网下载
Cloudera Manager Cloudera Manager 6.1.0 官方地址
CDH CDH 6.1.0 使用parcels安装

2、节点准备(四个节点)

名称 IP CM管理软件
namenode1 192.168.0.23 Cloudera Manager Server&Agent ,MySQL
datanode1 192.168.0.70 Cloudera Manager Agent
datanode2 192.168.0.74 Cloudera Manager Agent
datanode3 192.168.0.155 Cloudera Manager Agent

3、配置主机名和hosts解析(所有节点)

编辑/etc/hostname,在每个节点上修改主机名(主机名不能出现下划线):

1
namenode1
1
datanode1
1
datanode2
1
datanode3

在对应的节点上使用命令使其立刻生效:

1
hostnamectl set-hostname namenode1
1
hostnamectl set-hostname datanode1
1
hostnamectl set-hostname datanode2
1
hostnamectl set-hostname datanode3

编辑文件/etc/hosts,增加如下内容(所有节点)。

1
2
3
4
192.168.0.23  namenode1
192.168.0.70 datanode1
192.168.0.74 datanode2
192.168.0.155 datanode3

编辑 /etc/sysconfig/network(所有节点):

1
2
NETWORKING=yes
HOSTNAME=xxxnodexx

使用命令使其立刻生效

1
source /etc/sysconfig/network

4、关闭防火墙(所有节点)

1
2
systemctl stop firewalld.service
systemctl disable firewalld.service
1
firewall-cmd --state

5、关闭SELinux(所有节点)

1
2
sed -i 's\#SELINUX=enforcing\#SELINUX=disabled\#g' /etc/selinux/config
setenforce 0
1
/usr/sbin/sestatus -v

6、添加定时任务(所有节点)

1
echo "$((RANDOM%60)) $((RANDOM%24)) \* \* \* /usr/sbin/ntpdate time1.aliyun.com" >> /var/spool/cron/root

7、禁用透明大页面压缩(所有节点)

CDH配置需要

1
2
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo never > /sys/kernel/mm/transparent_hugepage/enabled

并将上面的两条命令写入开机自启动/etc/rc.local

8、优化交换分区(所有节点)

1
2
echo "vm.swappiness = 10" \>\> /etc/sysctl.conf
sysctl -p

9、配置 JDK (所有节点)

卸载自带的OpenJdk:

1
2
rpm -qa | grep java  #查询java相关的包
rpm -e java*** --nodeps #根据查找到的软件包信息卸载

在Oracle官网下载JDK的RPM包

1
rpm -ivh jdk-8u202-linux-x64.rpm

10、安装数据库(namenode1)

我们这里安装 MYSQL5.7.25,版本是支持的。

10.1 卸载自带mariadb

centos 7 默认安装的是mariadb,如果不卸载直接安装的话会报错。

1
2
rpm -qa | grep mariadb #查看安装信息
rpm -e mariadb-libs* --nodeps #根据查找到的软件包信息卸载

10.2 下载安装文件

下载地址如下:

1
2
3
4
https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-community-common-5.7.25-1.el7.x86_64.rpm
https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-community-libs-5.7.25-1.el7.x86_64.rpm
https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-community-client-5.7.25-1.el7.x86_64.rpm
https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-community-server-5.7.25-1.el7.x86_64.rpm

10.3 安装MySQL

按以下顺序安装

1
2
3
4
rpm -ivh mysql-community-common-5.7.21-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.21-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.21-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.21-1.el7.x86_64.rpm

如果出现以下缺少libnuma错误,请先安装libnuma

1
yum install libnuma*

10.4 设置数据库(namenode1)

启动服务

1
service mysqld start

查看初始密码

1
vim /var/log/mysqld.log 

修改密码
mysql -uroot -p #使用mysqld.log中的临时密码登录

1
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root123!!!';

授权用户root使用密码passwd从任意主机连接到mysql服务器

1
2
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'Root123!!!' WITH GRANT OPTION;
flush privileges;

11、安装 MySQL JDBC 驱动(所有节点)

用于各节点连接数据库。

1
2
3
4
5
6
wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.47.tar.gz
tar xf mysql-connector-java-5.1.46.tar.gz

mkdir -p /usr/share/java/
cd mysql-connector-java-5.1.47
cp mysql-connector-java-5.1.47-bin.jar /usr/share/java/mysql-connector-java.jar

三、安装 CM 和 CDH

1、配置 Cloudera Manager 仓库(namenode1)

1.1. 下载rpm包

CM主要下面的三个软件包:

1
2
3
4
5
cloudera-manager-agent-6.1.0-769885.el7.x86_64.rpm
cloudera-manager-daemons-6.1.0-769885.el7.x86_64.rpm
cloudera-manager-server-6.1.0-769885.el7.x86_64.rpm
cloudera-manager-server-db-2-6.1.0-769885.el7.x86_64.rpm
allkeys.asc

地址如下,下载完成放在cm6.1.0目录:

1
2
3
4
5
https://archive.cloudera.com/cm6/6.1.0/redhat7/yum/RPMS/x86_64/cloudera-manager-agent-6.1.0-769885.el7.x86_64.rpm
https://archive.cloudera.com/cm6/6.1.0/redhat7/yum/RPMS/x86_64/cloudera-manager-daemons-6.1.0-769885.el7.x86_64.rpm
https://archive.cloudera.com/cm6/6.1.0/redhat7/yum/RPMS/x86_64/cloudera-manager-server-6.1.0-769885.el7.x86_64.rpm
https://archive.cloudera.com/cm6/6.1.0/redhat7/yum/RPMS/x86_64/cloudera-manager-server-db-2-6.1.0-769885.el7.x86_64.rpm
https://archive.cloudera.com/cm6/6.1.0/allkeys.asc

CDH主要有如下几个文件:

1
2
3
CDH-6.1.0-1.cdh6.1.0.p0.770702-el7.parcel
CDH-6.1.0-1.cdh6.1.0.p0.770702-el7.parcel.sha256
manifest.json

地址如下,下载完成放在cdh6.1.0目录:

1
2
3
https://archive.cloudera.com/cdh6/6.1.0/parcels/CDH-6.1.0-1.cdh6.1.0.p0.770702-el7.parcel
https://archive.cloudera.com/cdh6/6.1.0/parcels/CDH-6.1.0-1.cdh6.1.0.p0.770702-el7.parcel.sha256
https://archive.cloudera.com/cdh6/6.1.0/parcels/manifest.json

cloudera-manager-daemonsserveragent 必须安装的。

1.2 安装http服务

1
2
sudo yum -y install httpd 
sudo service httpd start

在浏览器输入服务器地址,检查是否启动成功。

1.3 制作本地repo

在cm6.1.0 cdh6.1.0 同级目录输入如下命令:

1
2
createrepo cm6.1.0
createrepo cdh6.1.0

将cm6.1.0 与cdh6.1.0移到/var/www/html目录下:

1
mv cm6.1.0 cdh6.1.0 /var/www/html

在浏览器中查看目录:
http://ip/cm6.1.0
http://ip/cdh6.1.0

1.3 制作本地repo源

sudo vi /etc/yum.repos.d/cm.repo

1
2
3
4
5
[cmrepo]
name = cm_repo
baseurl =http://ip/cm6.1.0/
enable = true
gpgcheck = false

sudo vi /etc/yum.repos.d/cm.repo

1
2
3
4
5
[cdhrepo]
name = cdh_repo
baseurl =http://ip/cdh6.1.0/
enable = true
gpgcheck = false

1.4 把repo源文件传输到其他节点

1
2
scp /etc/yum.repos.d/cm.repo root@datanodeX:/etc/yum.repos.d/
scp /etc/yum.repos.d/cdh.repo root@datanodeX:/etc/yum.repos.d/

2、安装 CM Server 和 Agent(所有节点)

  • namenode1:
1
yum install cloudera-manager-daemons cloudera-manager-agent cloudera-manager-server
  • datanode0[1-3]:
1
yum install cloudera-manager-daemons cloudera-manager-agent

3、为 Cloudera 各软件创建数据库(namenode1)

使用root登陆数据库,创建以下数据库和账号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE DATABASE scm DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON scm.* TO 'scm'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE amon DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON amon.* TO 'amon'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE rman DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON rman.* TO 'rman'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE hue DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON hue.* TO 'hue'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE metastore DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON metastore.* TO 'hive'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE sentry DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON sentry.* TO 'sentry'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE nav DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON nav.* TO 'nav'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE navms DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON navms.* TO 'navms'@'%' IDENTIFIED BY 'YZHdata2019!!!';
CREATE DATABASE oozie DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON oozie.* TO 'oozie'@'%' IDENTIFIED BY 'YZHdata2019!!!';

4、设置 Cloudera Manager 数据库(namenode1)

1
2
3
4
5
6
7
8
9
[root@namenode1 ~]# /opt/cloudera/cm/schema/scm_prepare_database.sh mysql scm scm

Enter SCM password: YZHdata2019!!!
JAVA_HOME=/usr/java/jdk1.8.0_162
Verifying that we can write to /etc/cloudera-scm-server
Creating SCM configuration file in /etc/cloudera-scm-server
Executing: /usr/java/jdk1.8.0_162/bin/java -cp /usr/share/java/mysql-connector-java.jar:/usr/share/java/oracle-connector-java.jar:/usr/share/java/postgresql-connector-java.jar:/opt/cloudera/cm/schema/../lib/* com.cloudera.enterprise.dbutil.DbCommandExecutor /etc/cloudera-scm-server/db.properties com.cloudera.cmf.db.
[ main] DbCommandExecutor INFO Successfully connected to database.
All done, your SCM database is configured correctly!

5、安装 CDH

5.1 配置CDH的软件包 parcels(namenode1)

把下载的CDH相关文件copy到/opt/cloudera/parcel-repo/目录

1
2
3
cp /var/www/html/cm6.1.0/CDH-6.1.0-1.cdh6.1.0.p0.770702-el7.parcel /opt/cloudera/parcel-repo/
cp /var/www/html/cm6.1.0/CDH-6.1.0-1.cdh6.1.0.p0.770702-el7.parcel.sha256 /opt/cloudera/parcel-repo/
cp /var/www/html/cm6.1.0/manifest.json /opt/cloudera/parcel-repo/

修改属主属组

1
chown cloudera-scm.cloudera-scm /opt/cloudera/parcel-repo/*

5.2 启动 Cloudera Manager Server

1
systemctl start cloudera-scm-server

如果启动中有什么问题,可以查看日志。

1
tail -f /var/log/cloudera-scm-server/cloudera-scm-server.log

在最后显示的日志中,有显示启动监听的端口。

1
2
Started ServerConnector@da518cb{SSL,[ssl, http/1.1]}{0.0.0.0:7183}
Started ServerConnector@a77165b{HTTP/1.1,[http/1.1]}{0.0.0.0:7180}

四、初始化 Cloudera Manager

浏览器打开http://192.168.0.23:7180,用户名和密码默认都是admin


接收许可。


这里我们选择免费版,收费版请自行选择。

五、集群安装


指定要添加的节点。


选择存储库,之前我们已经在 CM Server 节点配置好了。


不进行勾选,选择我们自己安装的 JDK。


提供 SSH 登录凭据。


安装 agents,因为之前我们已经安装了,所以这里速度会很快。


安装选定的Parcel,之前我们已经下载好,并配置好放在的 CM Server 节点的/opt/cloudera/parcel-repo


检查主机正确性。

六、集群设置

选择要安装的服务,可以根据自己的需求进行软件安装。


自定义角色分配。


数据库设置。


审核更改,如果有特定目录的设定或者参数的设定,可以在这里进行更正。


首次运行。


安装完成。

七、管理集群

首页Dashboard。


HDFS。


HBase。

RESTfule API规范

REST


RESTful本身是一种风格而不是规范,本文为该风格的规范实现的最佳实践,本文档详细说明了HTTP RESTful API的定义和使用规范,作为接口调用者和实现者的重要参考。

接口风格

遵循RESTful设计风格,同时控制复杂度及易于使用,仅遵循大部分原则。 遵循原则:

  • 使用https协议
  • 版本号放入URL或Header
  • 只提供json返回格式
  • post,put上使用json作为输入
  • 使用http状态码作为错误提示
  • Path(路径)尽量使用名词,不使用动词,把每个URL看成一个资源
  • 使用HTTP动词(GET,POST,PUT,DELETE)作为action操作URL资源
  • 过滤信息
    • limit:指定返回记录数量
    • offset:记录开始位置
    • direction:请求数据的方向,取值prev-上一页数据;next-下一页数据
    • page:第几页
    • per_page:每页条数
    • total_count:总记录数
    • total_pages:总页数,等于page时,表示当前是最后一页
    • sort:column1,column2排序字段
    • orderby:排序规则,desc或asc
    • q:搜索关键字(uri encode之后的)
  • 返回结果
    • GET:返回资源对象
    • POST:返回新生成的资源对象
    • PUT:返回完整的资源对象
    • DELETE:返回一个空文档
  • 速率限制
    • X-RateLimit-Limit: 每个IP每个时间窗口最大请求数
    • X-RateLimit-Remaining: 当前时间窗口剩余请求数
    • X-RateLimit-Reset: 下次更新时间窗口的时间(UNIX时间戳),达到下个时间窗口时,Remaining恢复为Limit

未遵循原则:

  • Hypermedia API(HATEOAS),通过接口URL获取接口地址及帮助文档地址信息
  • 限制返回值的域,fields=id,subject,customer_name
  • 缓存,使用ETag和Last-Modified

参考:

模块和版本说明

接口模块相互对立且有版本管理,模块名作为APP配置项进行存储,每个模块的版本号version和endpoint在应用初始化时调用api模块信息接口(通过传递客户端应用名称和版本号获取各个API模块的endpoint和version)获取并存储。

  • 示例模块及最新版本号:

模块模块用途最新版本号account帐户v1sms短信v1open一些开放接口,不需要公共参数v1

公共参数

Headers

公共请求参数是指每个接口都可能需要传递的参数,公共参数通过header传递。

参数是否必须说明及header格式app所有接口必须请求客户端应用标识,取值*-ios、*-android、*-pc、*-h5
header格式:
X-Co-App: $appuser_idApp登录后所有接口都传,
Web通过session机制获取用户标识
header格式:
Authorization: CoAPI base64(user_id:token)tokenApp登录后所有接口都传,
Web通过session机制获取授权访问令牌
header格式:
Authorization: CoAPI base64(user_id:token)

  • Web应用通过cookies传递session id,user_id和token无需传递,接口会从session自动获取;
  • 同一token值在App和Web各应用间通用(token即为session id);
  • APP修改user-agent,在原有user-agent的尾部添加$app/$versionNetType/$value。如:
    • Dalvik/2.1.0 (Linux; U; Android 6.0.1; MI 4LTE MIUI/V7.5.3.0.MXGCNDE) $app-android/3.0.0 NetType/4G
    • Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) $app-ios/3.0.0 NetType/WIFI
  • app取值及释义示例

app取值客户端名称【域名】admin-pc管理中心PC网页版【admin.url.com】admin-h5管理中心手机网页版【admin.url.com】admin-ios管理中心iOS版admin-android管理中心Android版

Cookies

  • 用于告知服务端是否支持Webp的Cookie:cookie name是supportWebp,取值是1(支持)和0(不支持),未传递时服务端默认取值为0。
  • Webview植入Session的Cookie:

JWT & OAuth2

  • Json Web Token可用于替代session-cookie机制。但会存在一些问题,比如为过期token强制失效问题(用户修改了密码后,无法强制其他的终端token全部失效)。
  • OAuth2是授权其他开发者访问自己应用有限权限的授权机制。

权限

  • 权限分为
    • none:无需任何授权;
    • token:需要用户登录授权,可通过header AuthorizationCookie CoSID传递;
    • admintoken:需要管理员登录授权,可通过header AuthorizationCookie CoCPSID传递;
    • token || admintoken:用户登录授权或管理员登录授权都可以;图片
    • sign:需要签名,一般用于服务端内部相互调用。

状态码说明

正确
接口正常访问情况下,服务器返回2××的HTTP状态码。

HTTP状态码200 OK - 表示已在响应中发出、资源更改成功(GET、PUT)201 Created - 新资源被创建(POST)204 No Content - 资源被删除(DELETE)

错误
当用户访问接口出错时,服务器会返回给一个合适的4××或者5××的HTTP状态码;以及一个application/json格式的消息体,消息体中包含错误码code和错误说明message。

  • 5××错误(500=<status code)为服务器或程序出错,客户端只需要提示“服务异常,请稍后重试”即可,该类错误不在每个接口中列出。
  • 4××错误(400=<status code<500)为客户端的请求错误,需要根据具体的code做相应的提示和逻辑处理,message仅供开发时参考,不建议作为用户提示。
  • 部分错误示例:

codemessageHTTP状态码InvalidToken未登录或授权过期,请登录401 UnauthorizedValidationError输入字段验证出错,缺少字段或字段格式有误422 Unprocessable EntityAccountNotExist账户名不存在404 Not FoundInvalidPassword密码错误401 UnauthorizedNotFound请求的资源不存在404 Not FoundAccountHasExist账户名已经存在409 ConflictMobileHasBinded手机号已经绑定其他账户409 ConflictInvalidSign参数签名验证未通过403 ForbiddenInvalidSMSCode短信验证码错误403 ForbiddenExpiredSMSCode过期的短信验证码403 ForbiddenFrequencyLimit发送过于频繁,请稍后再试403 ForbiddenTimesExceeded达到最大发送次数限制,请明天再试403 ForbiddenVerifyTimesExceeded达到最大校验次数,请明天再试403 ForbiddenRateLimitExceeded接口调用次数超过限制,请稍后再试429 Too Many Requests InternalError服务异常,请稍后再试500 Internal Server Error

参数传递

遵循RESTful规范,使用了GET, POST, PUT, DELETE共4种请求方法。

  1. GET:请求资源,返回资源对象
  2. POST:新建资源,返回新生成的资源对象
  3. PUT:新建/更新资源,返回完整的资源对象
  4. DELETE:删除资源,返回body为空
  • GET请求不允许有body, 所有参数通过拼接在URL之后传递,所有的请求参数都要进行遵循RFC 3986的URL Encode。
  • DELETE删除单个资源时,资源标识通过path传递,批量删除时,通过在body中传递JSON。
  • POST, PUT请求,所有参数通过JSON传递,可选的请求参数,只传有值的,无值的不要传递,contentType为application/json。

4种请求动作中,GET、PUT、DELETE是幂等的;只有POST是非幂等的。幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。 是非幂等是判断接口使用POST还是PUT的决定条件

注意: APP端获取json数据时,对于数值类型字段必须以数值类型转换,无论传递过来的值是否带引号。图片图片

速率限制Rate Limiting

  • 为了防止API被恶意调用,对API调用进行速率限制。
  • 速率限制为每IP每15分钟5000次(dev/qa为10W)调用(15分钟是一个时间窗口)。
  • 限制是针对所有接口模块一起计算的(Redis key为APIRL:{IP}),暂时没有特殊的模块或单个接口(未来可能有)。
  • 你可以通过每个接口返回的HTTP headers了解当前速率限制的情况:
    • X-RateLimit-Limit: 每个IP每个时间窗口最大请求数
    • X-RateLimit-Remaining: 当前时间窗口剩余请求数
    • X-RateLimit-Reset: 下次更新时间窗口的时间(UNIX时间戳),达到下个时间窗口时,Remaining恢复为Limit
  • 超出速率限制,返回以下错误图片

安全注意事项

  • 用户登录后用户的token;aliyun OSS的bucket、AccessKey ID与AccessKey secret;微视频的appid、sign、bucket;这些关键数据通过调用接口获得,需要在客户端以安全的方式存储。
  • 音频视频在APP内的存储,不允许被拷贝(即使越狱或root后拿走也无法使用)。

测试工具

推荐Chrome浏览器插件Postman作为接口测试工具, Postman下载地址
图片

文档生成工具

调用示例

  • 伪代码图片
  • PHP图片

API模块信息获取

  • App配置文件中仅存储api模块名,App初始化时请求获取api模块信息,获取各个api模块的信息(endpoint和version)。
  • Copyrights © 2018-2024 李一
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信