前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nohost 实现原理 —— 远程办公下的开发测试协同提效方案

Nohost 实现原理 —— 远程办公下的开发测试协同提效方案

作者头像
用户1097444
发布2022-06-29 15:07:36
8130
发布2022-06-29 15:07:36
举报
文章被收录于专栏:腾讯IMWeb前端团队

在《Whistle 实现原理 —— 从 0 开始实现一个抓包工具》一文中给大家详细介绍了如何实现一个抓包调试工具 Whsitle。事实上 Whistle 不仅可以供开发人员本地开发调试,也可以部署到公共服务器给产品运营、测试等非开发人员用来访问测试环境、远程抓包调试。但 Whistle 是单进程服务,无法满足多人多项目同时使用,所以基于 Whistle 开发了多进程多用户的远程代理服务 -- Nohost,其主要功能:

Github 仓库:https://github.com/Tencent/nohost 有关 Whistle 的实现原理参见:Whistle 实现原理 —— 从 0 开始实现一个抓包工具

  1. 团队每个成员或业务模块分配一个 Whistle 实例。
  2. 每个 Whistle 实例可以设置多个独立的环境。
  3. 每个环境可以配置任意 Whistle 规则。
  4. 用户可以通过页面选择需要访问的环境。

更详细的场景和功能描述请参考:《Nohost 开源啦!》。

Nohost 基本架构

有点类似 Node 的 Cluster 模块,其核心思想是:将多进程多问题转成单进程 Whistle 的问题,即给每个团队成员或业务模块分配一个 Whistle 进程,并通过一个 Master 进程来管理各个 Whistle 进程以及分发请求。

交互流程图及实现原理

  1. 访问接入 Nohost 的页面,Nohost 会在页面左下角注入一个小圆点(环境切换按钮)(具体原理后面讲)。 如何接入 Nohost 参见:https://nohost.pro/docs/quickstart
  2. 点击小圆点弹出环境选择框,点击选择环境后,页面会先将选择的 账号/环境 发送到 Nohost 的 Master 进程
  1. Master 进程会先获取 clientId(如何获取参见后面的 Master 进程实现原理),将获取的 clientId 与选择的 账号/环境 存到 Master 进程的内存 LRU Cache 里面。
  2. 页面等待设置环境的接口响应或超时后自动刷新页面,这时页面所有请求也会经过 Master 进程,Master 进程通过 3 的方式获取每个请求的 clientId,并根据 clientId 获取之前选择的 账号/环境 ,再将请求转到账号对应的 Whistle 进程及执行对应环境的规则(具体实现参见后面的 Master 进程实现原理)。

这样每个人或业务只需关注自己的 Whistle 进程,功能上也就跟本地的 Whistle 差不多,也可以直接使用所有 Whistle 插件。

Master 进程实现原理

最后看下 Master 进程的实现,Master 进程可以主要有三个功能:

  1. 注入小圆点(环境切换按钮)。
  2. 记录用户环境选择状态。
  3. Whistle 进程管理与请求分发。 启动(关闭)指定 Whistle 进程并将请求转发到该进程及执行对应环境规则

注入小圆点(环境切换按钮)

小圆点的注入不是简单的往页面追加脚本,还涉及到:

  1. 解析 HTTPS 请求(不然 HTTPS 请求无法注入任何内容)。
  2. 只对 HTML 页面注入小圆点(还需要排除一些返回 json 数据,但类型写成 HTML 的接口)。Nohost 采用在 Master 里面内置一个 Whistle 进程处理上述问题: const startWhistle = require('whistle')

其中:

  1. 接收请求、解析 HTTPS 请求原理参见:Whistle 实现原理
  2. 注入小圆点,主要是由内置插件 whistle.nohost 实现的,分三部分内容:
    • 注入小圆点白名单:在 Nohost 的管理后台上传证书域名,及入口规则配置的域名、路径、正则、通配符等。
    • 插件的 rules.txt 动态获取白名单,并配置规则将上述白名单请求转发到插件。
    • 插件的 _rules.txt 配置的私有规则,对请求到插件的 html 页面注入小圆点。

这里引入了一个插件 whistle.nohost,该插件除了上述注入小圆点功能以外,还有如下的功能。

记录用户环境选择状态

点击选择环境,页面会发送请求 /.whistle-path.5b6af7b9884e1165/whistle.nohost/cgi-bin/select?name=imweb&envId=test&time=1637026271911 ,其中:

  1. /.whistle-path.5b6af7b9884e1165 是一个特殊路径,Whistle 自动拦截该路径并作为内部请求。
  2. name:账号(分组)名称。
  3. envId:环境名称的编码,encodeURIComponent(envName)

该请求会转到 Nohost 的内置的 whistle.nohost 插件进程的 uiServer,该插件会通过以下方式获取 clientId

  1. 先尝试从请求头 x-whistle-client-id 获取 clientId
  2. 如果没有请求头 x-whistle-client-id,则分别通过请求头 x-forwarded-for 或 req.socket.remoteAddress 获取 clientIp 作为 clientId

将获取的 clientId 和 name/env 存到插件进程的 LRU Cache:lru.set(clientId, name/env)

Whistle 进程管理与请求分发

对 Worker 里面的 Whistle 进程的管理也是通过 whistle.nohost 插件实现的:

  1. 插件通过实现 rulesServer 和 tunnelRulesServer 设置转发规则。
  1. 插件用上面的方式获取 clientId 并根据 clientId 获取用户选择的账号和环境。
  2. 如果没有选择任何环境,则返回空字符串,请求自动转到现网。
  3. 如果有选择环境,则通过 pfork 启动一个 Whistle 进程,并自动分配一个随机端口。
  4. 启动 Whistle 成功后获取端口,设置规则 * internal-proxy://127.0.0.1:xxxxx 让 Master 的 Whistle 进程将请求转到该端口。

internal-proxy 是 Whistle 代理直接转发协议,它可以通过用 http 的方式转发 https 请求

Nohost 插件会自动根据请求需求拉起对应进程,且如果该进程有超过 6 分钟没有请求,则会自动关闭。可以通过 Whistle 提供的方法检测进程是否有请求详见:https://github.com/Tencent/nohost/blob/master/lib/plugins/whistle.nohost/lib/whistle.js#L126

插件的完整实现代码参见:https://github.com/Tencent/nohost/blob/master/lib/plugins/whistle.nohost/lib/rulesServer.js

参考资料

  1. Github 仓库:https://github.com/Tencent/nohost
  2. 详细文档:https://nohost.pro/

相关文章

Whistle 实现原理 —— 从 0 开始实现一个抓包工具

紧追技术前沿,深挖专业领域

扫码关注我们吧!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯IMWeb前端团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Nohost 基本架构
  • 交互流程图及实现原理
  • Master 进程实现原理
    • 注入小圆点(环境切换按钮)
      • 记录用户环境选择状态
        • Whistle 进程管理与请求分发
        • 参考资料
        • 相关文章
        相关产品与服务
        访问管理
        访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档