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.rhkb.cn/news/211936.html

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

相关文章

【数据结构高阶】AVL树

上期博客我们讲解了set/multiset/map/multimap的使用,下面我们来深入到底层,讲解其内部结构: 目录 一、AVL树的概念 二、AVL树的实现 2.1 节点的定义 2.2 数据的插入 2.2.1 平衡因子的调整 2.2.1.1 调整平衡因子的规律 2.2.2 子树的旋…

识别低效io引起的free buffer waits

产生事发时间段的awr报告 Top 5 wait events 这里重点关注: 1.free buffer waits 2.enq_HW-contention 3.enq:tx-row lock contention enq:HW-contention属于水位线的争用,已经透过alter table allocate extent,提前分配空间,这里不做讨论 …

C++——红黑树

作者:几冬雪来 时间:2023年12月7日 内容:C——红黑树讲解 目录 前言: 红黑树的概念: 红黑树的性质: 红黑树的路径计算: 最长路径和最短路径: AVL树与红黑树的区别&#xff…

让你在组建企业级项目时手到擒来——浅谈各类常用工具和框架概述

文章目录 🔊博主介绍🥤本文内容📢文章总结📥博主目标 🔊博主介绍 🌟我是廖志伟,一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作…

分布式系统理论基础

目录 引言 CAP定理 CAP的工程启示 1、关于 P 的理解 2、CA非0/1的选择 3、跳出CAP 小结 本文转自:https://www.cnblogs.com/bangerlee/p/5328888.html 该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了…

Node.js版本管理工具NVM(Node Version Manager)的使用

nvm简介 nvm(Node Version Manager)是一个用于管理 Node.js 版本的工具。它可以让你在同一台计算机上安装并切换多个 Node.js 版本,非常方便。 如何安装 nvm 下载 nvm 安装包 访问 nvm下载地址 ,根据你的操作系统选择对应的安…

开源,可商业化!性能比Stable Difusion强2.5倍

文生图平台Playground宣布开源Playground V2版本,允许商业化,用户通过文本就能生成3D、动漫、素描、朋克、暗黑等多种类型1024x1024图片,同时提供免费在线体验。 Playground V2是基于Stable Diffusion XL开发而成,还从Midjourney…

台灯应该买什么样的才能护眼?学生护眼必备护眼台灯推荐

10月26日,教育部召开新闻发布会,介绍综合防控儿童青少年近视工作情况。全国综合防控儿童青少年近视工作联席会议机制办公室主任、教育部体育卫生与艺术教育司司长王登峰介绍,2018年全国儿童青少年的总体近视率53.6%,2019年总体近视…

1.2 C语言简介

一、为什么要讲C语言 C语言是编程界的长青藤,可以查看语言排名发现,虽然现在语言很多,但是C语言一直占有一定地址 来源网站:https://www.tiobe.com/tiobe-index/ 在系统、嵌入式、底层驱动等领域存在一定的唯一性(C语…

使用GPT-4V解决Pycharm设置问题

pycharm如何实现关联,用中文回答 在PyCharm中关联PDF文件类型,您可以按照以下步骤操作: 1. 打开PyCharm设置:点击菜单栏中的“File”(文件),然后选择“Settings”(设置)。…

【目标检测】进行实时检测计数时,在摄像头窗口显示实时计数个数

这里我是用我本地训练的基于yolov8环境的竹签计数模型,在打开摄像头窗口增加了实时计数显示的代码,可以直接运行,大家可以根据此代码进行修改,其底层原理时将检测出来的目标的个数显示了出来。 该项目链接:【目标检测…

SQL注入漏洞的检测及防御方法

SQL注入(SQL Injection)是一种广泛存在于Web应用程序中的严重安全漏洞,它允许攻击者在不得到授权的情况下访问、修改或删除数据库中的数据。这是一种常见的攻击方式,因此数据库开发者、Web开发者和安全专业人员需要了解它&#xf…

tomcat控制台中文信息显示乱码

问题现象 我的tomcat版本是10.1版本。 在cmd下启动tomcat,会新打开控制台输出窗口: 控制台窗口输出的中文信息是乱码: 问题原因 产生这个问题的原因是:控制台窗口的编码和输出到控制台窗口的日志信息编码不一致。 查看tomc…

【开发技能】-解决visio交叉线(跨线)交叉点弯曲问题

问题 平时工作中使用visio作图时,经常会遇到交叉线在相交时会形成一个弯曲弓形,这十分影响视图效果。可以采用下面的方法消除弓形。 方法 第一步:菜单栏--设计---连接线 第二步:选中这条交叉线---点击显示跨线 最终问题得到解决…

【Java】实现顺序表基本的操作(数据结构)

文章目录 前言顺序表1、打印顺序表2、增加元素3、在任意位置增加元素4、判断是否包含某个元素5、查找某个元素对于的位置6、获取任意位置的元素7、将任意位置的元素设为value8、删除第一次出现的关键字9、获取顺序表长度10、清空顺序表总结 前言 在了解顺序表之前我们要先了解…

编织魔法世界——计算机科学的奇幻之旅

文章目录 每日一句正能量前言为什么当初选择计算机行业计算机对自己人生道路的影响后记 每日一句正能量 人生就像赛跑,不在乎你是否第一个到达尽头,而在乎你有没有跑完全程。 前言 计算机是一个神奇的领域,它可以让人们创造出炫酷的虚拟世界…

gpt3、gpt2与gpt1区别

参考:深度学习:GPT1、GPT2、GPT-3_HanZee的博客-CSDN博客 Zero-shot Learning / One-shot Learning-CSDN博客 Zero-shot(零次学习)简介-CSDN博客 GPT-2 模型由多层单向transformer的解码器部分构成,本质上是自回归模型…

【Android】查看keystore的公钥和私钥

前言: 查看前准备好.keystore文件,安装并配置openssl、keytool。文件路径中不要有中文。 一、查看keystore的公钥: 1.从keystore中获取MD5证书 keytool -list -v -keystore gamekeyold.keystore 2.导出公钥文件 keytool -export -alias …

vue+echarts实现桑吉图的效果

前言: 在我们项目使用图形的情况下,桑吉图算是冷门的图形了,但是它可以实现我们对多级数据之间数据流向更好的展示的需求,比如,我们实际数据流向中,具有1对多,多对多的情况下,如果用…

IDEA加载阿里Java规范插件

IDEA加载阿里巴巴Java开发手册插件,在写代码的时候会自动扫描代码规范。 1、打开Settings 2、打开Plugins 3、搜索Alibaba Java Code Guidelines(XenoAmess TPM)插件,点击Install进行安装,然后重启IDE生效。 4、鼠标右…