localhost工具:本地代码的远程之路 | 京东云技术团队

在日常的开发过程中,本地代码远程调试一直是最理想的开发状态。本文通过介绍京东集团内开发的一个轻量简单的小工具”localhost”,从多角度的方案思考,到原理介绍,到最终的方案落地,在开发阶段发现问题,解决问题。

背景

起源

在很早之前,我参加了一个技术分享大会,当时现场是分享了一个本地在远程集群中的云原生开发方案,当时听完了之后就对其中本地开发的同时可以远程运行服务这部分非常感兴趣,本身作为前端开发来说,确实每次验证一些问题的时候,在本地开发阶段无法在真实的环境中调试,需要本地测试,打包,发版,验证,在处理一些兼容问题的时候,这个过程可能要重复很多次,会浪费很多时间。同时作为赛博云测的开发来说,在云测平台上经常会遇到一些前端开发同学需要调试不同设备的兼容问题,有的甚至顶不住需要线下借设备。云测平台存在的意义的就是能够线上化解决一切移动端的问题,开发的问题也是问题。

痛点

试想这样一个场景,测试同学上报了一个手机页面打开白屏的问题,云测平台上这个手机确实复现了这个问题,你搜索了一些可能的处理方式,然后修改发版验证,发现并没有用,这个时候该怎么办。

或者后端同学提前开发完,发了测试环境给前端同学实时调试接口,需要不停的修改字段或者逻辑或者debug调试问题,这个时候该怎么办。

又或者低代码的开发同学,写完物料组件之后想在实际设备中看看效果,但是不得不单独找设备来看,或者等测试同学报bug,时间都浪费在这个过程中,该怎么办。

我想开发同学或多或少都经历过这些场景,在联调或者调试一些问题的时候,总是没办法做到本地改完代码保存立马就能查看。作为一个工具平台,怎么去解决这个痛点并且能够更好的和平台结合,这个想法就一直在我心里存在着。

思考

从听那场分享会的时候,我就已经在想有什么方案可以实现这个目的,当时分享中说到了云原生开发的本地代码的处理部分,让我没想到的是,他们的方案非常直接,直接到将本地代码“搬”到了远程,实时在本地保存的时候将代码同步到远程的开发容器中,并且为了解决 http 协议传输的时间消耗,自定义了一套协议进行代码的同步,当然这个方案对于我所设想的场景实在是大材小用了,不过真的非常胆大心细,也给我了很多思路。

在后面的时间,借着代码同步的思路,我又设想了云 IDE 这个方案,本身代码同步的目的就是希望本地代码可以在远程运行,那直接通过云 IDE 开发,并直接运行服务,这样运行的服务也是在远程的,可以直接访问。这个思路是没问题的,但是按照目前大家的开发习惯,云 IDE 不是长久之计,况且为了这个想法,开发一套云 IDE,为了一口醋包了一顿饺子,可以,但没必要∠( ᐛ 」∠)_。

之后又和有些同事聊前端开发的问题,聊到了这个想法,给我提供了一个新的思路,通过 whistle 代理和 webpack 插件的方式,webpack 插件以监听模式打包,实时上传编译后的代码到远程服务器,whistle 代理用来解决调试过程中的一些问题。当然这个方案是公司其他的同学在很早之前就已经开发出来了,名字叫 Carefree,不过现在已经不维护了,比较可惜。这个方案只能解决前端开发同学的需求,并且云测平台上我们对代理服务器有些单独的处理,不是很适合。

中间又过了一段时间,我设想了一下这个需求的最终形态,之前的方案都非常重,如果我做为使用者,可能就是在难用和难受之间徘徊(没有说之前方案不好的意思,只是不适合这个需求…),我想它足够的简单和轻量,没有什么环境准备工作,拿来就能用。那最简单的方式就是不在代码上面下功夫,而是转向服务,只要维护好服务上的请求和响应,能够和本地进行交互,就可以达到我想法中所要求的。这个时候,我的想法聚集到了一个方向——内网穿透。

市面上的内网穿透的应用有很多,这又涉及到了另一个问题,安全,如果内网穿透滥用的话,很可能会造成隔离的内网服务被映射到外网从而被攻击,那损失就是把我卖了都赔不了…并且私下使用内网穿透本身也不好控制和追溯,有很大的安全隐患。

纠结了很长时间,既然不让偷偷用,那就光明正大的用,我可以自己实现一个应用,只要限制好功能和安全边界就可以了(已经和安全部门报备过了,放心)。而且自己实现,可以满足自己的所有想法,轻量简单,和云测平台结合等等,没有什么可以比实现自己的想法还令人激动的事情啦。于是便有了下面的内容。

localhost 是什么

介绍

localhost 是一个使用 Go 语言编写的轻量简单的内网穿透工具。这个工具支持 web 服务的映射,会将启动在本地 localhost 中的服务映射到远程服务器上,在访问远程对应的服务时,实际请求会利用本地和远程已经建立的隧道发送到本地服务中,达到访问本地服务的目的。为什么要使用 Go 来写呢,相对于其他的语言,Go 编译简单且编译完没有额外的运行环境要求,本地交叉编译可以得到各类系统的可执行文件,对于使用者来说非常友好。

使用

帮助文档在这里:localhost 帮助文档,可以在帮助文档里或者在赛博云测平台的云真机使用页面内进行工具下载。

就如上面说到的,localhost 是轻量简单的,使用方式非常简单,它是一个独立的可执行文件,启动的参数只有两个,启动方式如下:

# windows
localhost.exe -token xxxxxxxx -port xxxx# mac
localhost -token xxxxxxxx -port xxxx

-token 这个参数是当次使用的 token,可以在赛博云测平台的云真机使用页面上申请,每次的有效期半小时。

-port 这个参数是当前本地启动的服务的端口。

在设计客户端这部分的时候,为了尽可能降低大家的使用门槛,特意将参数设计的尽可能少,port 端口参数是必不可少的,那为什么还设计需要一个 token 参数呢,这个参数的初衷是为了识别用户的身份,类似于 ssh 协议的 key,使得行为可追溯,后来利用 token 来控制使用行为,比如单次使用有效期等等。其他的参数在不影响功能和安全的前提下,都被我排除掉了,希望它使用足够简单。

原理

整体工具分为三个部分:服务端,客户端,web 端。服务端和客户端是进行服务映射的主要部分,包含了建立通道,通道转发之类的逻辑。web 端提供了一些交互的接口,路由聚合代理转发的处理。

核心逻辑

localhost 最核心的部分就是内网穿透,它是由服务端和客户端共同完成实现的。众所周知本地启动的服务,只能本地或局域网内访问到,远程设备无法访问本地服务,但是本地的设备可以访问远程的服务,通过本地访问远程时建立的隧道进行通信,来达到远程设备能够访问本地服务的目的。

整体流程图如下:

首先在服务器中,启动了 web 端部分的服务,是整体服务中的底层服务的调度部分,其中提供了一些 client 端调用的 web 接口以及用户请求时的反向代理等功能,web 端服务是长期运行在远程服务器上,在下面会详细说明这部分做了什么。

client 端会分发给内部同学下载使用,在运行 client 端的时候,client 调用 web 的服务,启动对应的 server 端,并且将相关参数信息传入,并返回给 client 端。

server 端启动的时候,会启动监听两个端口服务,一个是监听用户请求的端口,一个是监听 client 端这边的隧道连接端口,当 client 端主动发起和远程服务器进行连接时,通过当前这个连接打通通信隧道,当用户请求进来时,通过已经建立的通信隧道,将请求报文转发到本地 client 端。

client 端启动完成,并且调用 web 端服务成功返回之后,client 端拿到相关信息连接对应的 server 端,隧道建立成功之后,等待服务端转发过来的请求信息。当监听到请求过来时,client 端会主动连接启动的指定端口的本地服务,并且将请求报文转发给当前的本地服务,同时,响应报文也会通过已有的链路原路返回,最终回到开始的请求方。

通过这种方式,就可以达到远程访问本地服务的目的,通过中转服务器进行服务的穿透,并且这种方式不需要用户关注中间过程,只需要启动提供的 client 端服务,使用简单,基本没有使用成本,不会影响代码。

路由聚合反向代理

使用过程中可能有的同学会有这样一个疑问,在 client 端启动完成之后,会返回显示访问的链接,为什么访问这个链接就可以直接访问到自己本地的服务呢?在 client 端启动时,会调用 web 端的接口服务,这个时候会记录当前的用户身份,并且在启动 server 端时,将启动的 server 端口与当前的用户 erp 形成一个映射关系,并且根据当前这个 erp 建立一个反向代理的规则。在 web 端启动的服务中,有一个监听当前请求的服务,当任何地方访问 web 端的服务时,会对访问的路由进行监听判断,如果能匹配到已有连接的 erp 信息,就会将当前访问请求报文转发到对应的 server 端服务中,然后 server 端再将请求转发到对应的 client 端。

流程图如下:

另外,在通过第一次通过聚合的 erp 路由访问之后,会记录当前访问的 ip,将 ip 与 erp 映射关系也对应上,这样,在后续的访问中,路由可以不用携带 erp 信息,也同样能够映射到当前自己的本地服务,这样可以解决一些静态资源的访问路径的问题,也可以用来解决 history 路由访问的情况。

未来

history路由处理

当前端工程的路由采用的 history 模式的时候,在上述的 erp 聚合的路由就会出现 history 路由访问不对的情况,虽然可以通过第一次访问 erp 路由之后去除 erp 来访问,但是总体来说还是会带来一些困扰,后续计划采用泛域名解析,去除路由上的处理,将用户标识通过域名来解析,路由回归用户原本的样子,这样不会造成额外的困扰和理解上的成本。

支持https

当前 localhost 工具在交互的过程中整体流程上还是 http 协议,目前只能通过把本地工程的 https 配置去除才能使用,但是和有的同学沟通下来发现有的工程中 https 请求是必须的,所以后续将会支持 https,后续设想在访问时只要是 https 的请求,就默认访问本地项目的 https,不需要额外的显式配置或声明。

结束

本地代码的远程之路,在整个过程中经历了很多方向,也产生了很多想法,最终诞生了 localhost 这个工具,在后续的时间会结合更多的场景,继续完善这个工具,希望能够让大家在工作的过程中,多快好省。

作者:京东零售 谢天

来源:京东云开发者社区 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/255406.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手写VUE后台管理系统8 - 配置404NotFound路由

设置404页面 配置路由404页面 配置路由 这里配置了两个路由,一个是主页,另外一个则匹配任意路由显示为404页面。因为只配置了两个路由,如果路径没有匹配到主页,则会被自动导向到404页面,这样就可以实现整站统一的404页…

微信小程序复制功能

在微信公众平台隐私协议中加剪贴板 设置-基本设置 审核通过后 app.json中添加 "permission": {"scope.writeClipboard": {"desc": "你的剪贴板将用于小程序的复制操作"} }, index.ts // 复制指定内容 handleCopy() {console.log(&q…

Unity中Batching优化的动态合批

文章目录 前言一、动态合批的规则1、材质相同是合批的前提,但是如果是材质实例的话,则一样无法合批。2、支持不同网格的合批3、动态合批需要网格支持的顶点条件二、我们导入一个模型并且制作一个Shader,来测试动态合批1、我们选择模型的 Mesh…

html和css写淘宝的快速导航条

目录 1、css代码 2、html代码 1、css代码 <style>* {margin: 0;padding: 0;list-style: none;text-decoration: none;}.nav {width: 900px;height: 40px;background-color: rgb(247, 249, 250);margin: 50px auto;padding-left: 30px;}.nav>li {float: left;width: 1…

06 硬件知识入门(MOSS管)

1 简介 MOS管和三极管的驱动方式完全不一样&#xff0c;以NPN型三极管为例&#xff0c;base极以小电流打开三极管&#xff0c;此时三极管的集电极被打开&#xff0c;发射极的高电压会导入&#xff0c;此时电流&#xff1a;Ic IbIe &#xff1b;电压&#xff1a;Ue>Uc>Ub…

2024年网络安全比赛--系统渗透测试(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1.在渗透机中对服务器主机进行信息收集&#xff0c;将服务器开启的端口号作为 Flag 值提交; 2.在渗透机中对服务器主机进行渗透&#xff0c;在服务器主机中获取服务器主机名称&#xff…

前端典例算法集合

前言 刷算法顺序&#xff1a;1、熟悉本文章第1点的内容&#xff1b;2、刷力扣算法&#xff0c;可以参考这本书的顺序与思想&#xff1a;代码随想录完整版PDF下载 | 合集下载 | 百度云 | | 代码随想录 (programmercarl.com) 3、刷牛客的高频考题 1、熟悉数组Array&#xff0c…

泰勒级数泰勒展开, 麦克劳林级数

一直认为泰勒展开就是泰勒级数。查度娘说不是&#xff0c;晕&#xff0c;当知识储备&#xff0c;重温高数。想当年&#xff0c;同济编的高数&#xff0c;每次都是95分&#xff08;百分制&#xff09;以上呢。 一、定义不同 泰勒级数&#xff08;英语&#xff1a;Taylor series…

使用pandas制作图表

数据可视化对于数据分析的重要性不言而喻&#xff0c;一个优秀的图表有足以一眼就看出关键所在。pandas利用matplotlib实现绘图。能够提供各种各样的图表功能&#xff0c;包括: 单折线图多折线图柱状图叠加柱状图水平叠加柱状图直方图拆分直方图箱型图区域块图形散点图饼图多子…

若依框架的搭建

若依框架 若依框架的搭建&#xff08;前后端分离版本&#xff09;环境要求IDEA拉取Gitee源码Mysql 配置Redis 配置后端启动前端配置问题解决 效果展示 若依框架的搭建&#xff08;前后端分离版本&#xff09; 简介 RuoYi-Vue 是一个 Java EE 企业级快速开发平台&#xff0c;基…

编程应用实例,商超进销存管理系统软件,支持扫描条形码也可以自编码

一、前言 软件特色&#xff1a; 1、功能实用&#xff0c;操作简单&#xff0c;不会电脑也会操作&#xff0c;软件免安装&#xff0c;已内置数据库。软件在关闭的时候&#xff0c;可以设置会员数据备份到U盘&#xff0c;数据本机备份一份&#xff0c;U盘备份一份&#xff0c;双…

流量分析1--菜刀666

1&#xff1a;菜刀666&#xff1a; 题目描述 分析流量包&#xff0c;过滤http数据流 追踪TCP数据流 对比第5个流和第7个流发现&#xff0c;同样的目录下 多出了6666.jpg。猜测是由攻击者上传&#xff0c;直接在请求包里搜索FFD8--FFD9 保存为1.jpg 利用foremost工具对1.jpg进…