您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

localhost工具:本地代码的远程之路

时间:2023-12-07 11:30:34  来源:京东云开发者  作者:

在日常的开发过程中,本地代码远程调试一直是最理想的开发状态。本文通过介绍京东集团内开发的一个轻量简单的小工具”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 最核心的部分就是内网穿透,它是由服务端和客户端共同完成实现的。众所周知本地启动的服务,只能本地或局域网内访问到,远程设备无法访问本地服务,但是本地的设备可以访问远程的服务,通过本地访问远程时建立的隧道进行通信,来达到远程设备能够访问本地服务的目的。

整体流程图如下:

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 端。

流程图如下:

localhost工具:本地代码的远程之路

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

未来

history 路由处理

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

支持 https

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

结束

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

 

作者:京东零售 谢天
来源:京东云开发者社区 转载请注明来源


Tags:localhost   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
localhost工具:本地代码的远程之路
在日常的开发过程中,本地代码远程调试一直是最理想的开发状态。本文通过介绍京东集团内开发的一个轻量简单的小工具”localhost”,从多角度的方案思考,到原理介绍,到最终的方案...【详细内容】
2023-12-07  Search: localhost  点击:(145)  评论:(0)  加入收藏
关于本地主机 Localhost (127.0.0.1) 的一些科普小知识
当您(或您的计算机)呼叫一个 IP 地址时,您通常是在尝试联系互联网上的另一台计算机。 但是,如果您调用 IP 地址 127.0.0.1,那么您正在与 localhost 进行通信 – 原则上是与...【详细内容】
2022-07-02  Search: localhost  点击:(739)  评论:(0)  加入收藏
给本地localhost建立安全HTTPS
概述在前端开发领域某些特性下需要依赖HTTPS,例如:navigator.geolocation.getCurrentPosition / new Notification 等。由于大多数开发环境中都只是HTTP协议下,所以会导致调试...【详细内容】
2019-09-24  Search: localhost  点击:(2601)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(5)  评论:(0)  加入收藏
站内最新
站内热门
站内头条