codenvy 端口
在 本文的 第1部分中 ,我们讨论了Codenvy平台和基本体系结构。
我们还讨论了云和桌面IDE,IDE工作区管理,SDK,插件体系结构和生命周期,Codenvy.com体系结构–用户管理和身份验证,公共项目与私有项目,IDE协作,多租户等之间的区别。
在Codenvy平台中,开发人员的工作空间跨用于服务于不同IDE功能的不同物理资源进行了虚拟化。
依赖性管理,构建器,运行器和代码助手可以在物理节点的不同群集上执行。
为了正确地虚拟化对所有这些资源的访问,我们需要实现一个VFS,该VFS支持服务和物理资源,但对IDE行为也有原生的了解。
云IDE需要为其用户项目提供存储系统。 VFS Codenvy所使用的必须具有以下属性:
基于我们在内容管理系统(例如eXo,JCR,xCMIS)和REST API(例如everREST)实现方面的经验,我们决定不使用基于HTTP的传输,例如WebDAV或CMIS。 这些选项太复杂,并且具有一些冗余的数据交换,这使它们成为不理想的解决方案。 我们将自己的VFS REST API定义为特定于IDE。
在实现的开发和演化过程中,我们创建了不同的后端实现,包括:
登录到链接到工作空间的用户帐户,可以使用户访问与工作空间关联的VFS透视图。 浏览器登录后,将向浏览器授予令牌,该令牌可与VFS API调用一起使用,以访问正确的VFS透视图。 然后,浏览器可以直接向VFS进行REST调用。
VFS REST服务的入口点具有以下URL结构: http(s)://
从我们的API返回的VFS信息表示为JavaScript对象表示法(JSON)响应,其中包含唯一的VFS标识符,指向根文件夹的指针,支持的功能列表以及可用于超链接访问某些URL模板的URL模板列表VFS功能。
可选功能取决于当前的VFS实现,并且可能包括访问控制列表(ACL),用于控制权限,文件版本控制,锁定和查询(搜索功能)。
VFS具有树形结构,其中项目列表位于工作区的顶层。
可以扩展树结构以显示文件夹,文件,以及在特殊情况下内部组织的子项目(或模块)。 此扩展是一组不同的API调用,并且在外观上我们代表的项目节点与项目的子结构不同。
共有三种资源类型:
三种资源类型的层次结构通过以下方式管理VFS的结构:
VFS的结构共有3个总体层次结构规则:1)仅允许将项目作为顶层资源(即,将工作空间的根文件夹作为父级资源); 2)项目可能具有文件,文件夹或其他项目(对于多模块项目)作为子资源,并且3)文件夹可能具有文件或文件夹作为子资源。
所有文件发现,加载和访问都通过自定义API进行。 该API使用JSON在IDE客户端之间来回传递参数。 将云IDE中的文件访问与桌面IDE中的文件访问进行比较。 在桌面IDE中,该应用程序具有对磁盘驱动器的本地访问权,并使用本机命令来操纵文件并根据操作系统进行延迟,以提供有关锁定,查找和其他访问方式的关键功能。
但是,在云环境中,有许多IDE同时运行在多个物理节点上。 IDE正在使用也在分布式节点上的一组代码助手,构建器和运行器进行协调。 多个开发人员可以同时在不同的IDE以及不同的节点上运行该工作空间。 因此,VFS的作用不仅是提供对文件的访问,而且还提供对文件的分布式受控访问。
通过将RESTful API与JSON结合使用,我们可以标准化不同类型的客户端使用的技术,无论这些客户端是在我们的基础架构中运行还是由浏览器直接访问。 我们需要采用与文件操作和访问有关的核心操作系统功能,并将其打包为这种格式。
Codenvy的虚拟文件系统API提供了逐步浏览资源树并使用其唯一标识符(UID)或路径直接访问特定资源的方法。 您可以通过其根文件夹访问数据。
虚拟文件系统的结构允许通过不在IDE中HTML应用程序进行项目的查询,搜索和排序机制。 这将允许开发人员创建自己的应用程序,这些应用程序可以直接与VFS上的Codenvy工作区进行交互。 使用POST请求的参数创建查询语句是特定于实现的。
虚拟文件系统还可以支持许多功能,包括观察,访问控制和文件内容版本控制。 这些功能中的每一个都是特定于实现的。
对于系统内收集的数据和事件,我们有以下用例。
(点击图片放大)
由于我们需要创建一个在内部环境中与在云中同样有效的解决方案,因此我们不得不排除使用诸如log.ly之类的引人注目的服务。 我们需要一个可以OEM且可以在不同云环境中运行的系统。
我们已经检测了所有主要的客户端和服务器端事件。 这些是典型的事件,例如登录和注销。 但是它也是开发人员的一流事件,例如“重构”,“构建”,“调试”,“进入”,“预览”和“导出”。 这些事件将记录为每个物理节点上存在的基于文件的消息。 邮件会长期存放,有些归档策略会随着时间的流逝而轮换它们的位置。 我们使用Pig / Hive编写程序化查询来处理消息并生成派生指标。 消息和派生指标都存储在Hadoop中。 我们选择Hadoop作为此解决方案,因为我们可以选择附加许多分析,报告和仪表板解决方案,这些解决方案在浏览,分析和关联数据方面提供了出色的体验。
今天,我们从分析的数据中提供了三项服务。 有一个管理仪表板,它是一个简单的网站,可显示对用户,采用率,参与度和病毒性的分析。 还有许多生成的报告,这些报告以CSV,Excel和PDF文件的形式生成,用于管理,这些报告是重复生成或参数化生成的。 最后,有一个RESTful API,可以授予对数据和指标的查询访问权限。 该API最终将打包并提供给开发人员以供其直接使用。
Codenvy中的每个服务器端服务(例如重构,身份验证,构建和部署)都将构建并公开为RESTful Web服务。 这些Web服务可通过以下方式访问:
Web服务列表在产品本身内发布。 您可以转到“帮助-> REST服务发现”以获取完整列表以及有关可接受哪些参数的信息。 这是可通过URL访问的函数类型的代码片段以及如何构造参数。
服务路径 | 方法 | 消耗 | 产生 | 简短的介绍 | 的角色 |
用户服务 | |||||
/组织/用户 | 开机自检 | 应用程序/ json | 应用程序/ json | 创建一个用户 | 云/管理员 |
/ organization / users /(id) | 得到 | -- | 应用程序/ json | 寻找使用者 按编号 |
云/管理员,云/经理 开发商 |
/ organization / users?alias = alias | 得到 | -- | 应用程序/ json | 寻找使用者 通过别名 |
云/管理员,云/经理 开发商 |
/ organization / users /(id) | 开机自检 | 应用程序/ json | 应用程序/ json | 更新现有用户 | 云/管理员, 开发商 |
/ organization /用户/(id)/删除 | 开机自检 | -- | -- | 删除用户 | 云/管理员, 开发商 |
/ organization / users / authenticate | 开机自检 | 应用程序/ json | -- | 验证用户 | -- |
我们当前的外壳是访问内部Web服务的浏览器层。 我们还没有为用户提供直接的bash shell。 在不久的将来,我们将提供到专用VM的SSH会话,该VM映射到专用生成器/运行器队列。 到专用VM的SSH会话将具有bash功能。 在许多方面,非SSH in-IDE外壳是一个虚拟外壳,是我们Web服务之上的抽象。 我们使用开放源代码EverREST项目(它是JAX-RS的实现)来简化这些调用。 在此处阅读有关EverREST的更多信息。
IDE和构建器/运行器之间的连接通过Web套接字处理。 在我们的服务器端基础结构中运行有一个BuilderManager和RunnerManager服务,用于控制各种IDE客户端的请求并将其路由到适当的服务。 客户上下文(即,付费还是非付费)确定了请求映射到的队列类型。 不同的队列具有不同的处理策略,例如专用VM,共享VM和具有SSH访问权限的VM。
用于操作IDE集群,构建器集群和运行器集群的物理节点的数量由HAProxy确定。 我们具有可配置的标准,这些标准确定何时应在每个群集中进行节点的扩展或收缩。 对于IDE群集,它基于活动租户的数量。 如果该阈值是300个活动租户,那么会有一个预碰撞阈值,当达到该阈值时将触发创建新的物理节点。 下降也发生相同的过程。 在需要关闭物理节点的情况下,我们不执行任何形式的租户从一个节点到另一个节点的迁移。 租户下次连接到服务时,它将在当前在线的另一个节点中重新激活,并恢复服务状态。 对于建造者和赛跑者来说,过程相同。 但是,配置标准对于那些系统的行为是唯一的。 对于构建器,我们优化了构建器的数量以尝试消除任何阻塞行为。 跑步者也是如此。
对于任何IDE功能连接到外部云服务,如GitHub上,谷歌应用程序引擎,或者持续集成服务器,我们总是使用由第三方供应商提供的直接的API。 我们使用驻留在我们的云基础架构中的代理来控制所有通信。 该代理既可以处理来自所有第三方系统的出站和入站API调用,也可以让我们对其性能和操作进行配置。
从逻辑上讲,这就是在多个节点上同时运行时系统如何全面运行。
(点击图片放大)
我们有许多不同的环境用于满足流程中不同需求。 这些环境包括:
目的 |
哪里 |
|
生产 |
具有完整SLA,支持和内置弹性的生产环境。 |
AWS |
预生产 |
运行完整的Codenvy环境,其中包含针对生产部署的精选完成功能/问题。 这些功能可以在一组sprint中实现。 该环境用于与客户进行验证,创建示例的文档,支持对即将发布的功能进行培训的支持以及用于营销以从新版本中创建资产的环境。 |
内部数据中心 |
分期 |
可以随问题更新的模拟生产环境,形成特定的冲刺。 这个环境是用于可扩展性测试,热修复验收,并为公共云环境中的配置,以第三方服务的连接。 |
AWS |
验收 |
执行开发完成并等待产品所有者接受的特定功能。 我们最多可以运行5种不同的验收环境。 可以通过我们的持续集成系统自动创建验收环境。 接受环境是单服务器的,没有弹性。 |
内部数据中心 |
作为一家为开发人员创建工具和解决方案的公司,我们花费大量时间与客户讨论他们如何管理开发项目。 与客户共享Codenvy的内部流程和技术是我们的首要任务。 这有助于我们促进围绕最佳实践的讨论,有助于改善内部流程,并使我们对开发人员面临的复杂问题有更深入的了解。
大约五年来,我们一直将Scrum用作推动开发的主要过程。 Scrum是一种迭代和增量开发(IID)方法,可帮助指导和塑造我们的日常工作。 这是一种灵活的方法,可以帮助我们的开发人员专注于开发,同时仍然提供使一切按时运行的规范。
使用Scrum可以为我们提供迭代计划,规格,实施,测试和交付功能,以推动我们的产品快速发展。
我们的产品经理是Sprint的项目所有者(PO)。 拥有非开发人员作为PO可使我们的开发人员专注于编程,而不是项目管理的精髓。 这样,产品发布流程就与开发流程保持独立。
我们使用带有Greenhopper插件的 JIRA作为我们的项目和问题跟踪工具。
开发工作在2-4周的“ Sprint”中完成,以将发行版划分为可管理的段。 在这段时间内,我们专注于将最新路线图的特定功能转换为最终测试的代码。
冲刺的固定持续时间取决于工作量和团队目前的能力。 这些持续时间可以灵活,但是只有在审查和讨论它将如何影响Sprint的目标之后才能更改。
在开始Sprint之前,我们的开发团队会从各个角度检查采购订单提供的功能,并创建详细的“ Sprint摘要”,概述确切的规格。 他们向PO展示这些摘要,以确保每个人都对期望达成一致。
一旦我们的团队和PO商定了项目规格,PO便建立Sprint Backlog。 作为此过程的一部分,团队同意“完成的功能定义”,即我们如何演示该功能以及必须满足什么条件才能“完成”。
在Sprint期间,我们的开发团队每天举行站立会议 。 团队成员讨论当前工作的状态以及发生的任何问题或障碍。 我们会缩短会议时间(约15分钟),因此不会浪费太多的编程时间,它们可帮助所有人保持一致。
在Sprint的末尾,我们的开发人员向PO演示了功能。 在演示期间,我们的采购订单将查找“冲刺摘要”中概述的特定功能。 这项接受工作发生在我们开发环境中运行的Codenvy专用实例上,其中每个实例都允许验证单个问题。
一切均获得批准后,我们的团队和采购订单将进行回顾分析,并为下一次迭代提出可能需要改进的领域。 冲刺完成后,在冲刺中分类的所有问题都将移至试生产和暂存环境中。 在那里,营销,支持和文档可以在投入生产之前执行其他功能。
我们从Scrum获得的监管和自由的结合确实是两全其美。 Scrum为我们的开发人员提供了创建高质量解决方案所需的灵活性,而又无需牺牲最后期限。
我们已接近该系统95%的自动测试覆盖率。 我们将Selenium用于任何IDE和站点功能。 我们将JUnit用于服务器端测试以及基于GWT的插件中的测试功能方法。 我们每天对无法自动化的用例和功能进行手动测试,例如与PaaS供应商集成,连接速度可能会改变接收到的结果。 我们所有的测试都会作为我们持续集成过程的一部分自动启动,并且每天至少要在签入后运行一次。
如果部署到云环境中,我们将使用Amazon和Eucalyptus制造的映像进行配置和部署。 如果要部署到PC上,我们将使用自制的RPM软件包和bash脚本。 通过Puppet编排进一步管理配置环境。
我们使用非常简单的monit,logwatch和cacti实现来监视所有系统的可用性。
翻译自: https://www.infoq.com/articles/codenvy-architecture-part-2/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1
codenvy 端口